🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

有界决策工具 ZhengSJCode/jev-dsh

DeepSeek Harness
ZhengSJCode35 天前有提交已提供中文文档扫描:含敏感能力

让智能体对上下文做校准过的有界选择与评分

29.7/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ZhengSJCode/jev-dsh
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · skill
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 35 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 24 处,展示前 24 条)
  • 读取本地文件
    adapter/install.mjs:89
    return await readFile(patchPath, 'utf8')
  • 写入本地文件
    adapter/install.mjs:117
    await writeFile(patchPath, next, 'utf8')
  • 写入本地文件
    e2e/mock-llm.mjs:27
    if (process.env.MOCK_APPEND !== '1') writeFileSync(logPath, '')
  • 写入本地文件
    e2e/mock-llm.mjs:60
    appendFileSync(logPath, `${JSON.stringify({ headers: req.headers, body })}\n`)
  • 读取本地文件
    install.mjs:171
    return await readFile(patchPath, 'utf8')
  • 写入本地文件
    install.mjs:205
    await writeFile(patchPath, next, 'utf8')
  • 读取本地文件
    kernel/cli.mjs:45
    const text = readFileSync(join(home, '.credentials.yaml'), 'utf8')
  • 读取本地文件
    kernel/cli.mjs:77
    process.stdout.write(readFileSync(join(here, 'README.md'), 'utf8').split('\n').slice(0, 24).join('\n'))
  • 读取本地文件
    kernel/cli.mjs:86
    const space = ActionSpace.fromJson(readFileSync(actionsPath, 'utf8'))
  • 读取本地文件
    kernel/cli.mjs:100
    : JSON.parse(readFileSync(options.demoScript, 'utf8')).steps
  • 读取密钥环境变量
    kernel/cli.mjs:108
    apiKey: options.apiKey ?? process.env.TYPESAFE_API_KEY ?? credentialFromStore('TYPESAFE_API_KEY'),
  • 读取本地文件
    kernel/mock/mock-scripted.mjs:28
    const script = JSON.parse(readFileSync(scriptPath, 'utf8'))
  • 写入本地文件
    kernel/mock/mock-scripted.mjs:29
    if (process.env.MOCK_APPEND !== '1') writeFileSync(logPath, '')
  • 读取本地文件
    kernel/mock/mock-scripted.mjs:44
    const index = readFileSync(logPath, 'utf8').split('\n').filter(Boolean).length
  • 写入本地文件
    kernel/mock/mock-scripted.mjs:45
    appendFileSync(logPath, `${JSON.stringify({ call: index, body })}\n`)
  • 写入本地文件
    kernel/src/controller.js:262
    writeFileSync(this.tracePath, JSON.stringify(run.toDict(), null, 1))
  • 发起网络请求
    kernel/src/provider.js:88
    const res = await this.fetch(this.baseUrl, {
  • 读取密钥环境变量
    mock/mock-systemone.mjs:24
    const requiredKey = process.env.MOCK_REQUIRE_KEY
  • 写入本地文件
    mock/mock-systemone.mjs:27
    if (process.env.MOCK_APPEND !== '1') writeFileSync(logPath, '')
  • 写入本地文件
    mock/mock-systemone.mjs:118
    appendFileSync(logPath, `${JSON.stringify({
  • 读取本地文件
    preset/install.mjs:111
    return await readFile(patchPath, 'utf8')
  • 写入本地文件
    preset/install.mjs:139
    await writeFile(patchPath, next, 'utf8')
  • 读取本地文件
    src/checkout.js:70
    return existsSync(join(explicit, marker)) ? explicit : undefined
  • 读取本地文件
    src/checkout.js:72
    return checkoutCandidates().find(candidate => existsSync(join(candidate, marker)))
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 有界选择
  • 评分判断
  • 智能体工具与技能

README

由 DeepSeek 最新模型翻译生成
jev-dsh — 第一层:把 System One(TypeSafe Jev)接成 DSH 的决策循环 给 DSH 一个 system_one 工具 + 一个技能:agent 可以对已有上下文做校准过的有界决策(choice / noul / score),而不是把 Jev 当聊天模型塞进模型选择器。 已经可以用了,而且离线可验证(不需要真 API key)。 为什么是工具而不是模型 Jev 是 决策模型,不是 chat 模型:线协议只有 POST /v1/systemone,输入 state + 类型化 questions,输出带概率的 answers;不生成文本、不流式、不调工具。实测 /v1/chat/completions → 404、/v1/responses → 404、/v1/systemone → 403(存在、缺 key)。 DSH 的 llm-pi-ai 只认三种 chat 协议,所以这条路本来就不通(详见 research.md)。 生态里的正确形态就是“工具 + 技能”——pi-system-one 对 Pi 就是这么做的,本实现复用了它的客户端与技能文本,只重写了 Pi 专属的外壳。
展开完整文档(README 剩余 1 节)
jev-dsh — 第一层:把 System One(TypeSafe Jev)接成 DSH 的决策循环

给 DSH 一个 system_one 工具 + 一个技能:agent 可以对已有上下文做校准过的有界决策(choice / noul / score),而不是把 Jev 当聊天模型塞进模型选择器。

已经可以用了,而且离线可验证(不需要真 API key)。

为什么是工具而不是模型

Jev 是 决策模型,不是 chat 模型:线协议只有 POST /v1/systemone,输入 state + 类型化 questions,输出带概率的 answers;不生成文本、不流式、不调工具。实测 /v1/chat/completions → 404、/v1/responses → 404、/v1/systemone → 403(存在、缺 key)。
DSH 的 llm-pi-ai 只认三种 chat 协议,所以这条路本来就不通(详见 research.md)。

生态里的正确形态就是“工具 + 技能”——pi-system-one 对 Pi 就是这么做的,本实现复用了它的客户端与技能文本,只重写了 Pi 专属的外壳。

快速开始

装进默认 profile($DSH_HOME/profiles/web)
node install.mjs # 只写行,设置全部留给环境变量
node install.mjs --base-url https://api.typesafe.ai --model jev-latest
node install.mjs --anonymous # 本地 Reflex:http://localhost:8008,不带凭据

只看会写什么 / 卸载
node install.mjs --print
node install.mjs --uninstall

install.mjs 往 profile 的 cordis.patch.yml 写一个受管块:工具行(绝对路径,因为 out-of-tree 插件不是按包名加载的)+ 一条 skill-filesystem 的 customSkillDirs 指向本包的 skills/。该文件被 hmr 行热监听,运行中的 profile 会自行重组,无需重启。

带任一设置参数时,安装器会明确写出 baseUrl: https://api.typesafe.ai、model: jev-latest、 apiKeyEnv: TYPESAFE_API_KEY;不带参数则一个字段都不写。

命名与凭据(都用 TypeSafe 自己的名字)

环境变量:TYPESAFE_BASE_URL、TYPESAFE_MODEL、TYPESAFE_API_KEY、TYPESAFE_TIMEOUT_MS、 TYPESAFE_PATH、TYPESAFE_API_KEY_ENV。这样已经有 TypeSafe SDK 变量的部署不用再导一套。

| 规则 | 说明 |
| 默认凭据引用 | TYPESAFE_API_KEY;行里的 apiKeyEnv 或环境变量 TYPESAFE_API_KEY_ENV 可以换成别的引用 |
| 存储位置 | $DSH_HOME/.credentials.yaml 的 refs:——就是 Models 页 credentials.set(ref, value) 写的那份文件,改了热生效、不用重启 |
| 查找顺序 | 先 ctx.credentials.resolve(ref)(其内部优先级是“启动环境 > 存储文件 > .env”),进程环境兜底 |
| 未点名 + 解析不到 | 不报错,不带凭据发请求:本地 Reflex 就该这么用,端点自己会回答它要不要 key |
| 点名 + 解析不到 | 明确报错并指出引用名,不会静默发匿名请求(与 llm-pi-ai 对 apiKeyEnv 的处理一致) |

最小配置:只把密钥写进凭据文件即可,不用改 profile。

$DSH_HOME/.credentials.yaml
version: 1
refs:
TYPESAFE_API_KEY: sk-…

注意:install.mjs 默认写的是真实 web profile。只想试的话用
DSH_PROFILE_DIR= node install.mjs。
另外,hmr 行的 root 列表会被后安装的插件覆盖(手机插件也这么写,它是另一个仓库),两个都装时只有最后安装的那个能热重载源码。

工具怎么用

{
"state": "工单:我的打款连续三天失败,没人回复。客户等级:growth。",
"questions": {
"team": { "type": "choice", "instructions": "哪个团队应该接手?",
"criteria": { "billing": "打款、发票、退款", "technical": "缺陷、故障、集成" } },
"urgent": { "type": "noul", "instructions": "这表达了紧急吗?" },
"frustration": { "type": "score", "instructions": "客户有多烦躁?",
"criteria": ["平静", "烦躁", "非常生气"] }
}
}

宽容的入参(会修复表示,修不了的报错点名到字段):

| 输入 | 处理 |
| context / evidence | state 的别名;同时给两个会被拒(只有调用方知道哪个是本意) |
| pick / select / yesno / rating / scale | 类型别名 → choice / noul / score |
| 省略 type | 按 criteria 形状推断:数组→score,对象→choice,无→noul |
| question / prompt / ask;options / levels / labels | instructions / criteria 的别名 |
| "id": "问题文本" | 裸字符串 → noul |
| 数组形式 [{ "id": "team", ... }] | 与 map 形式等价 |
| criteria: ["a","b"](choice) | 展开为 {a: null, b: null} |
| criteria: ["是","否"](noul) | 展开为 {true: "是", false: "否"} |

拒绝并给出可操作信息的情形:缺 state、同时给两个 state 别名、缺/空 questions、未知类型、 choice 没有 criteria、score 少于两级或多于十级、choice 超过 255 项、缺 instructions、重复 id、数组形式缺 id、state 超过 128KB(提示裁剪,服务端上限 32k token)。

返回给模型的是分布而不只是赢家:

system-one · jev-1.13.0 · 5ms · in 128 / out 16 tok [choice] team → billing (confidence 0.7) billing 0.7 · technical 0.3 [noul] urgent → 0.9 [score] frustration → 1 (confidence 0.8) Calm 0.1 · Frustrated 0.8 · Very angry 0.1

验证(全部离线可跑)

| 层 | 命令 | 结果 |
| 入参修复/拒绝 | node test/normalize.test.mjs | 30 项断言通过 |
| 渲染 | node test/render.test.mjs | 6 项通过 |
| 工具 schema 过 harness 真校验器 | ./test/schema.test.sh | 13 项通过:parameters/output 被 assertSupportedJsonSchema 接受;TYPESAFE_ 命名、环境变量回退、以及 install.mjs --print 写出的 apiKeyEnv: TYPESAFE_API_KEY / --anonymous 形态都与运行时一致 |
| 真实 HTTP 执行(含错误路径) | node test/execute.e2e.mjs | 19 项通过:自起 mock/mock-systemone.mjs,断言线上 body、Bearer 头、403、未点名凭据匿名发请求、点名凭据缺失报错、未配置端点、TYPESAFE_ 环境变量 |
| 决策循环驱动手机 | node test/adapter.e2e.mjs | 14 项通过:观察步不打扰模型、refs 永远来自最新一屏、重复 tap 被挡下 |
| 长候选表(翻译 App 选语言那一类) | node test/adapter-candidates.e2e.mjs | 8 项通过:40 行候选 + 目标概率 0.2 默认照常动手;设了 gate.candidates 之后被拒的是那一行,tap 仍在菜单里 |
| 重放一次录下来的会话 | node test/replay-session.test.mjs | 8 项通过:goal/历史从转录里读出来、世界按转录回答、换了选择报 DIFFERENT、转录没问过的报 unrecorded |
| 决策循环本身 | cd kernel && npm test | loop.e2e.mjs 九条终止路径 + candidates.test.mjs 20 项(低目标概率、坏分布 fail-closed、候选下限、左中文右英文整条跑通) |
| 真实 DSH 全链路 | 见下 | 插件挂载 → 工具注册(tools=25)→ 模型调用 → 真实 HTTP → 结果以 role:"tool" 回传 → 技能进入会话目录 |
| 凭据库分支(和 OpenAI 同一条路) | 见下 | 密钥只放在 $DSH_HOME/.credentials.yaml 的 refs: { TYPESAFE_API_KEY: … },环境变量不设 → 请求带上正确 Bearer;把该文件移走 → 立即报 no credential for TYPESAFE_API_KEY(反向对照,证明来源就是存储文件) |

上表里驱动手机的两条(adapter.e2e.mjs、adapter-candidates.e2e.mjs)是唯一跨到另一个仓库的测试:它们要真的 mobile_test_* 工具,才能证明"先观察后决策""refs 来自最新一屏"。
本仓库对手机没有运行时依赖——profile 用路径点名 capabilities——所以手机不在场时这两条跳过而不是失败(test/phone-core.mjs 按 DSH_PHONE_CORE → 同级的 phone-core/ 或 dsh-phone/phone-core/ 顺序找)。单独 clone 本仓库 npm test 依然全绿。

全链路那条的做法:测试 profile 里用 install.mjs 装本插件,再用 e2e/llm-overlay.yml 把 agent 自己的模型指向 e2e/mock-llm.mjs(一个只会返回 system_one 工具调用的假 chat 端点),于是整条链路不需要任何真实 key:

node mock/mock-systemone.mjs & # :8940,带 key 校验
node e2e/mock-llm.mjs & # :8942,会调用 system_one
DSH_PROFILE_DIR= node install.mjs --base-url http://127.0.0.1:8940 --model jev-latest
凭据走存储文件(不设 TYPESAFE_API_KEY 环境变量): printf 'version: 1\nrefs:\n TYPESAFE_API_KEY: mock-key\n' > /.credentials.yaml
DSH_HOME= MOCK_CHAT_API_KEY=mock-key \
node /apps/cli/lib/bin.js --profile headless \
--patch e2e/llm-overlay.yml "Judge this ticket"
→ TOOL-LOOP-OK tools=25 result=system-one · jev-1.13.0 · 5ms | [choice] team → billing …

目录结构

jev-dsh/
├── package.json 插件包(纯 ESM JS,无构建步骤) ├── install.mjs 写/删 profile 里的受管块(--print / --uninstall / --base-url …)
├── src/
│ ├── tools.js 插件入口:system_one 的定义与注册(apply / createToolDefinitions) │ ├── normalize.js 入参修复与拒绝(纯函数,可单测) │ ├── client.js 端点与凭据绑定,system-one-core 的 HttpSystemOneProvider │ ├── credential.js 凭据引用怎么解析(存储文件 / 环境变量) │ ├── checkout.js DSH checkout 在哪(DSH_CHECKOUT → 逐级向上 → 两个惯例位置) │ └── render.js 答案 → 模型可读文本 ├── adapter/ 同一条决策循环,但挂成 harness 的 LlmAdapter(llm-systemone 行) │ 由安装器写行:install.mjs 之外还有 adapter/install.mjs ├── preset/install.mjs 装「Jev」模式(模式 = persona + systemone 路由 + 一个工具行) ├── kernel/ 移植自 SystemOneHarness 的 loop:observe → encode → ask → gate → execute ├── skills/system-one/ SKILL.md + references/use-cases.md(源自 pi-system-one,改了 2 处) ├── tools/store-key.mjs 把密钥写进 $DSH_HOME/.credentials.yaml 的 refs:,不经过 shell 与屏幕 ├── mock/mock-systemone.mjs 脚本化 /v1/systemone 端点 ├── e2e/ mock-llm.mjs、llm-overlay.yml、测试 profile ├── test/ normalize / render / say / space / decide / adapter / 执行与 schema ├── notes/ research.md(调研与实测)、USAGE.md(当前怎么用) └── vendor/ 第三方快照:system-one-core(运行时唯一依赖)、pi-system-one 出处与许可见 vendor/README.md

把一次真实会话重放一遍

改门、改菜单、改候选表之后,"这次是不是好点了"不该靠感觉。tools/replay-session.mjs 把一次录下来的会话按当前代码再问一遍:同一句 goal、同一屏、同一段历史,逐条对照当时做了什么。
sh
真端点(凭据取 TYPESAFE_API_KEY 或 $DSH_HOME/.credentials.yaml)
node tools/replay-session.mjs --session 9057753a --turn 2

没有 key 时用脚本答案,链路与测试同一套
node tools/replay-session.mjs --session 9057753a --turn 2 --script /tmp/steps.json

全部轮次
node tools/replay-session.mjs --session 9057753a --all --steps 8

每步标 same / DIFFERENT / unrecorded,退出码非 0 表示有对不上的地方。三条规矩:

- 世界只从转录来:循环问什么,就用当时录下的那条结果回答,顺序对得上才用;对不上就不编。
- 同名不同 kind 不算"改了选择":把 tap 的结果喂给 launch 会让循环基于一个没发生过的世界推理,所以那种情况记 unrecorded,而不是拿去对齐。
- 多帧 zstd 必须整份解:DSH 每 flush 一次追加一帧,Node 自带的解码器只解第一帧。截断的转录比拒绝更危险,所以这里优先用 zstd CLI,只有它缺席且解出来不完整时才明确报错。

几个实现决定

- system-one-core 是 vendored(vendor/system-one-core)而不是 npm 依赖:out-of-tree 插件按绝对路径加载、裸模块名会按 profile 目录解析,那里没有包。相对路径导入是确定性的,也就不需要在宿主机上装任何东西。
- 不导出 Config schema:声明 schemastery schema 需要 import @deepseek-ai/schemastery,同样在 profile 目录不可解析。改用 loader 行 config + 环境变量,行为一致。
- 原始 JSON-Schema 定义而非 defineTool(...):理由同上(@deepseek-ai/dsh-tools 不可导入);入参检查因此由本包自己负责,normalize.js 就是那份检查,schema.test.sh 借 harness 的校验器补上类型层面。
- 工具始终注册:端点没配时报一条可操作的错误(no endpoint configured; set TYPESAFE_BASE_URL …),比静默不注册更容易发现和排查。
- 门的两个问题分开判:动作的 confidence 与设计者声明的参数按风险阈值取最弱值;from: 参数(选项由环境这一步枚举)改成判"分布是否自洽 + 选中是否 argmax",绝对下限是 gate.candidates (默认 0)。理由与代价写在 kernel/README.md:把候选概率折进风险最小值,会让 120 行的语言选择器永远无法行动——那是“该点哪一个”的问题,不是“要不要点”的问题。
- refusal 缩到出问题的那一层:动作弱就从菜单里拿掉动作(withoutChoices),目标弱就从名单里拿掉那一项(withoutCandidate),而不是一律删动作。否则一个控件没把握的代价是这一回合不能再点任何东西,而屏幕本身并没有变得更难。窄化同时进 next_action.criteria 的校验,所以被拿掉的选项即使被重新选中也会被拒(“没被展示的就不能选”要能扛住模型无视菜单)。

没做的

- pi-system-one 的 /so config、/judge 命令面:那是 Pi 的斜杠命令与 UI API (ExtensionAPI:session_start、resources_discover、ui.notify),DSH 没有对应物。
- UHP:SystemOneHarness(Python)已经是 UHP Core 合规的服务,DSH 侧要做客户端才行,属于另一件事。
- 真模型复测:本机没有 TYPESAFE_API_KEY,也没有本地 Reflex 端点,所以延迟/定价/真答案分布都还是文档值。拿到 key 后把 TYPESAFE_BASE_URL 指向真端点跑同一条全链路即可。
预览分享卡片长什么样 ↓ZhengSJCode/jev-dsh
分享 · DeepSeek Harness Hub
ZhengSJCode/jev-dsh

让智能体对上下文做校准过的有界选择与评分

回到顶部