@aiwayds/dsh-mcp-adapter 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -4
- package/README.zh.md +51 -5
- package/lib/index.d.ts +340 -23
- package/lib/index.js +829 -74
- package/lib/index.js.map +1 -1
- package/lib/jev/backends.d.ts +35 -0
- package/lib/jev/backends.js +48 -0
- package/lib/jev/backends.js.map +1 -0
- package/lib/jev/client.d.ts +133 -0
- package/lib/jev/client.js +288 -0
- package/lib/jev/client.js.map +1 -0
- package/lib/jev/config.d.ts +82 -0
- package/lib/jev/config.js +55 -0
- package/lib/jev/config.js.map +1 -0
- package/lib/jev/dual.d.ts +42 -0
- package/lib/jev/dual.js +42 -0
- package/lib/jev/dual.js.map +1 -0
- package/lib/jev/gate.d.ts +51 -0
- package/lib/jev/gate.js +141 -0
- package/lib/jev/gate.js.map +1 -0
- package/lib/jev/log.d.ts +93 -0
- package/lib/jev/log.js +138 -0
- package/lib/jev/log.js.map +1 -0
- package/lib/jev/seams.d.ts +118 -0
- package/lib/jev/seams.js +364 -0
- package/lib/jev/seams.js.map +1 -0
- package/lib/jev/thresholds.d.ts +37 -0
- package/lib/jev/thresholds.js +44 -0
- package/lib/jev/thresholds.js.map +1 -0
- package/lib/rank.d.ts +157 -0
- package/lib/rank.js +327 -0
- package/lib/rank.js.map +1 -0
- package/lib/usage.d.ts +232 -0
- package/lib/usage.js +362 -0
- package/lib/usage.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ This plugin keeps the official `dsh-mcp-client` as the connection layer (transpo
|
|
|
16
16
|
|
|
17
17
|
- every `mcp__*` tool schema is **folded out** of the assembled prompt (`system-prompt/assemble` waterfall);
|
|
18
18
|
- two **constant meta-tools** take their place, so standing prompt cost is O(1) in the number of servers/tools:
|
|
19
|
-
- **`mcp_list`** — compact catalog (tool names + truncated descriptions, no schemas); pass `tool` to expand one tool's full schema on demand, `server` to filter, `verbose` for everything;
|
|
19
|
+
- **`mcp_list`** — compact catalog (tool names + truncated descriptions, no schemas); pass `tool` to expand one tool's full schema on demand, `server` to filter, `query` for a relevance-ranked shortlist, `verbose` for everything;
|
|
20
20
|
- **`mcp_call`** — dispatch `{ tool, arguments }` to the still-registered definition, passing the run context through.
|
|
21
21
|
|
|
22
22
|
Tools stay registered in `ctx.tools`, so TUI rendering and `tools.restrict()` masking keep working — only the prompt payload changes. A folded, constant tool list is also friendlier to KV-prefix caching than upstream's per-resync generation swap.
|
|
@@ -68,7 +68,7 @@ One thing deliberately **stays**: the plugin's gate file at `~/.dsh/storages/mcp
|
|
|
68
68
|
|
|
69
69
|
To purge that state too, delete the `storages/mcp-adapter/` directory yourself; ids will be re-allocated from scratch on reinstall.
|
|
70
70
|
|
|
71
|
-
Upgrading from a dsh 0.1.5 install: the old `mcp-adapter:` section of `settings.yaml`
|
|
71
|
+
Upgrading from a dsh 0.1.5 install: the old `mcp-adapter:` section of `settings.yaml` (which the 0.1.7 host renames to `settings.yaml.imported` after its one-shot import, since the section name does not match this plugin's entry id) is **absorbed once automatically**: on the next plugin boot, if no gate file exists yet, the stable ids and the disabled set are read from `settings.yaml.imported` (fallback: the still-present `settings.yaml`), sanitized and written straight into `gate.json` — no `/mcp disable <id>` re-latching needed. The pass is recorded in `<dsh home>/storages/mcp-adapter/legacy-import.json` (a present marker means it never re-runs; an existing gate.json is left untouched). Your `config:` values in the profile patch carry over unchanged.
|
|
72
72
|
|
|
73
73
|
## Config
|
|
74
74
|
|
|
@@ -79,8 +79,17 @@ Upgrading from a dsh 0.1.5 install: the old `mcp-adapter:` section of `settings.
|
|
|
79
79
|
| `servers` | `[]` | server-name whitelist: when non-empty, only these servers' tools are folded / cataloged / dispatchable (all three consult the same list) |
|
|
80
80
|
| `descriptionLimit` | `200` | max chars per tool description in the `mcp_list` catalog |
|
|
81
81
|
| `storageDir` | `""` | gate storage directory override; empty = `<dsh home>/storages/mcp-adapter` (read once at plugin start — moving it takes effect on restart) |
|
|
82
|
+
| `jevEnabled` | `false` | System One master switch — **default off**: false means zero decision calls anywhere, and the usage counters keep recording |
|
|
83
|
+
| `jevBackend` | `"zen"` | decision backend: `zen` (free opencode-zen tier) / `native` (typesafe first-party) / `openrouter`; each needs its own API key (`JEV_ZEN_API_KEY` / `TYPESAFE_API_KEY` / `OPENROUTER_API_KEY`, or the macOS keychain) |
|
|
84
|
+
| `jevModel` | `""` | pinned model id; empty = the backend's own default resolved at call time (`jev-1.13-free` / `jev-1.13.0` / `typesafe/jev-1.13`) — an upgrade is a deliberate act |
|
|
85
|
+
| `jevTimeoutMs` | `3000` | per-request timeout in ms; one attempt, no retry — the calling lane's next cadence is the retry |
|
|
86
|
+
| `jevSecretFile` | `""` | extra literal secrets for the outbound secret gate (`JEV_SECRET_FILE` semantics); swapping the path reloads the list |
|
|
87
|
+
| `jevLayaFallback` | `false` | **default off**: also call a local laya endpoint on every decision request; its answer is logged for comparison and takes over only when the primary backend fails |
|
|
88
|
+
| `jevLayaUrl` | `"http://127.0.0.1:8000/v1/systemone"` | that local laya-serve endpoint |
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
The last seven rows are the System One decision layer ([below](#self-evolution-system-one)); all of them are opt-in, and the default install makes no outbound decision call at all.
|
|
91
|
+
|
|
92
|
+
Every field is declared **volatile** (the dsh 0.1.7 settings contract): all twelve appear on the plugin's settings page under the `dsh-mcp-adapter` entry, and editing them there applies **without restarting the plugin** — the fold boundary, catalog and dispatch pick the new values up on their very next use, and the `jev*` switches are re-read the same way, so flipping `jevEnabled` in the settings page takes effect on the very next dispatch. (`storageDir` is the one exception: the storage location itself is read once at plugin start, as its row says.) The `config:` block in your profile patch keeps working exactly as before.
|
|
84
93
|
|
|
85
94
|
```yaml
|
|
86
95
|
config:
|
|
@@ -94,6 +103,42 @@ config:
|
|
|
94
103
|
|
|
95
104
|
**Trust boundary:** by default every `prefix`-matching tool is folded — the prefix is a naming convention, not a security boundary, so tools registered by third-party plugins that happen to use `mcp__*` names fold too. To trust only the official client's servers, list them explicitly in `servers`; everything else stays native (still callable directly, just outside the meta-tools).
|
|
96
105
|
|
|
106
|
+
## Self-evolution (System One)
|
|
107
|
+
|
|
108
|
+
An optional decision layer, **off by default**: with `jevEnabled: false` the plugin makes no outbound decision call anywhere and behaves exactly as it did before. With it on, three things happen — and all three are advisory.
|
|
109
|
+
|
|
110
|
+
**Usage accounting (always on, never networked).** Every finished `mcp_call` dispatch, successes and failures alike, is counted per tool (`calls`, `errors`, first/last used) into `usage.json` in the plugin's own gate directory, right beside `gate.json`. This runs regardless of `jevEnabled`, so turning the switch on later reuses everything already counted.
|
|
111
|
+
|
|
112
|
+
**Keep suggestions (the self-evolving part).** Every 20 recorded calls — crossing 20, 40, 60 … — the plugin asks the decision backend, in **one batched request fired in the background**, which of the currently *folded* tools that were actually called earn a permanent place in every prompt instead of being looked up and expanded on every use. The dispatch that crossed the threshold returns long before any of this runs; nothing awaits it. The answer is written to `suggestions.json`; a failed round leaves the previous batch exactly as it was.
|
|
113
|
+
|
|
114
|
+
**Viewing them.** `/mcp suggest` renders the current batch — probability, band, the usage evidence behind it, and the `keep` fragment the row would translate to — plus the recorded totals. The view says so itself: `display only — nothing was written to keep, prefix, or the server gate.` You paste the fragment into your own config; **this plugin never edits your configuration**, and no decision path ever writes `keep`, `prefix` or the server gate on its own.
|
|
115
|
+
|
|
116
|
+
The same backend, asked by the model rather than by the counter, powers the two model-facing searches:
|
|
117
|
+
|
|
118
|
+
- `mcp_list { "query": "<what you want to do>" }` — a **subset** view: a lexical prefilter over tool names and descriptions first (deterministic, no network), then an optional rerank of that shortlist. The answer says how many tools matched in total and points back at the unfiltered catalog; a no-argument `mcp_list` call is still the full catalog, and a no-query call makes no decision call at all.
|
|
119
|
+
- `mcp_call` with an unregistered tool name — the error keeps its original sentence and gains a `Did you mean: "…"?` tail, ordered by a lexical near-miss pass (edit distance first, then shared name tokens) and optionally reranked. The tail always labels where its order came from (`lexical` or `jev reranked`), so an unranked guess never reads like a ranked one.
|
|
120
|
+
|
|
121
|
+
**Fail-open:** an unreachable, slow or unhelpful backend is indistinguishable from a disabled one — every decision path falls back to the lexical behavior it had before, and a failed suggestion round costs you that round's rows and nothing else.
|
|
122
|
+
|
|
123
|
+
**Privacy:** the counters, the suggestions and the decision log (`decisions.jsonl`) never leave the machine — they are three files in the gate directory. With `jevEnabled` on, tool names, the leading 200 chars of their descriptions, the usage counts and the model's own query text **do** go out to the decision backend as the question context; every outbound body is scanned by a built-in secret gate (JWT, provider keys, GitHub/Slack/AWS tokens, PEM blocks, plus whatever literals you list in `jevSecretFile`) and a hit aborts the call before anything leaves the process. `jevBackend` decides where: `zen` (the free opencode-zen tier, default), `native` (typesafe first-party) or `openrouter`. The local laya pace-maker (`jevLayaFallback`) is off by default.
|
|
124
|
+
|
|
125
|
+
### Not the local laya backend — not yet (measured against laya 0.3.20)
|
|
126
|
+
|
|
127
|
+
**Leave `jevLayaFallback` off.** Measured head-to-head against the free `zen` tier on this plugin's own three seams, with real MCP tool catalogs driven through `jevAskDual` in parallel:
|
|
128
|
+
|
|
129
|
+
| Seam | zen (free) | laya 0.3.20 | pure lexical |
|
|
130
|
+
| --- | --- | --- | --- |
|
|
131
|
+
| keep suggestions (12 tools, batched noul) | AUC **1.000** — hot 0.71 / borderline 0.48 / fold 0.11 | AUC **0.333**, worse than chance: every probability lands in 51–55% | — |
|
|
132
|
+
| `mcp_list {query}` ranking (10 queries) | **8/10** | 4/10 — ranks `read_file` below a SQL `query` | 6/10 |
|
|
133
|
+
| did-you-mean rerank (6 misspellings) | 5/6 | 4/6 | 5/6 |
|
|
134
|
+
| Chinese query, semantic fallback (5 queries) | **5/5** | 1/5 — anchors on one tool regardless of the query | 0 (no lexical match) |
|
|
135
|
+
|
|
136
|
+
laya answers roughly 8–10× faster (70 ms–1 s vs 0.6–6 s), but the discrimination is not close. It cannot read the call-frequency signal the keep suggestion is *about* — a tool called 412 times and one called once come back at the same confidence — and cross-language query matching, which the catalog seam leans on, is where it collapses outright. laya's own runtime warns that the bundled checkpoint's confidence values are uncalibrated.
|
|
137
|
+
|
|
138
|
+
So the pace-maker stays a degraded-mode safety net only: when the primary backend fails, laya's answer takes over **degraded** — relative order only, never absolute scores against the calibrated bands, and keep suggestions are skipped that round rather than shown with an uncalibrated number. Both sources' verdicts still land in `decisions.jsonl`, which makes the comparison free to run continuously.
|
|
139
|
+
|
|
140
|
+
**Revisit when** laya ships a typed-decisions checkpoint (or a version whose calibration is published instead of warned about) and this table inverts — then re-measure against your own catalogs before believing it.
|
|
141
|
+
|
|
97
142
|
## Notes
|
|
98
143
|
|
|
99
144
|
- `mcp_call` only accepts `prefix`-matching tools (and, when `servers` is set, whitelisted servers) — it can never be used to bypass another tool's own pre-execute pipeline.
|
|
@@ -110,7 +155,8 @@ The plugin registers one slash command on the platform `commands` service — co
|
|
|
110
155
|
|---|---|
|
|
111
156
|
| `/mcp` or `/mcp list` | Tree overview — every server line carries its stable `[<id>]`; disabled ones show `⏸ disabled` and hide their tools; closed by a folding-health footer |
|
|
112
157
|
| `/mcp list <name>` | `<name>` matching a server → that server's full tool list (a disabled server adds a `⏸` note); matching a full tool name → full description + complete input schema |
|
|
113
|
-
| `/mcp config` | The effective `prefix` / `keep` / `servers` / `descriptionLimit`, each with its hitting tools, plus the persistent enable/disable inventory |
|
|
158
|
+
| `/mcp config` | The effective `prefix` / `keep` / `servers` / `descriptionLimit`, each with its hitting tools, plus the persistent enable/disable inventory, the seven `jev*` settings and the recorded usage counters |
|
|
159
|
+
| `/mcp suggest` | The current keep-suggestion batch: per tool a probability, a band, the usage evidence and the exact `keep` fragment, plus the recorded totals. Read-only: it writes nothing to `keep`, `prefix` or the gate |
|
|
114
160
|
| `/mcp disable <id>` | Latch a whole server off: its tools force-fold out of every prompt — keep and `servers` exemptions included — it disappears from the `mcp_list` catalog, and `mcp_call` refuses it with an `/mcp enable <id>` hint |
|
|
115
161
|
| `/mcp enable <id>` | Restore it under the same stable id |
|
|
116
162
|
|
package/README.zh.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
- 每个匹配的 `mcp__*` 工具 schema 被**折叠出**装配后的 prompt(`system-prompt/assemble` waterfall);
|
|
18
18
|
- 原位换上两个**恒定 meta-tool**,常驻 prompt 成本对 server/工具数量而言是 O(1):
|
|
19
|
-
- **`mcp_list`** — 紧凑目录(工具名 + 截断描述,不含 schema);传 `tool` 按需展开单个工具的完整 schema,传 `server` 过滤,传 `verbose` 全量内联;
|
|
19
|
+
- **`mcp_list`** — 紧凑目录(工具名 + 截断描述,不含 schema);传 `tool` 按需展开单个工具的完整 schema,传 `server` 过滤,传 `query` 拿相关性精排的子集,传 `verbose` 全量内联;
|
|
20
20
|
- **`mcp_call`** — 按 `{ tool, arguments }` 把调用分发到仍然注册着的定义上,运行上下文原样透传。
|
|
21
21
|
|
|
22
22
|
工具本身仍注册在 `ctx.tools` 里,所以 TUI 渲染、`tools.restrict()` 掩蔽照常工作——变的只是 prompt 载荷。折叠后恒定的工具列表也比上游"每次重同步就换代"的模式更利于 KV 前缀缓存。
|
|
@@ -60,7 +60,7 @@ dsh plugin --profile <name> remove @aiwayds/dsh-mcp-adapter
|
|
|
60
60
|
|
|
61
61
|
连这份状态也想清掉的话,请自行删除 `storages/mcp-adapter/` 目录;重装时 id 会重新分配。
|
|
62
62
|
|
|
63
|
-
从 dsh 0.1.5 升级:旧 `settings.yaml` 里的 `mcp-adapter:`
|
|
63
|
+
从 dsh 0.1.5 升级:旧 `settings.yaml` 里的 `mcp-adapter:` 小节(0.1.7 宿主首次启动时把该文件一次性导入并改名为 `settings.yaml.imported`,旧段名与本插件 entry id 不同名)会被**一次性自动承接**:下次插件启动时若尚无门闩文件,则从 `settings.yaml.imported`(兜底仍在的 `settings.yaml`)读取 stable id 与 disabled 门闩,消毒后直接写入 `gate.json`——无需再逐条 `/mcp disable <id>` 重新闩上。承接过程记录在 `<dsh home>/storages/mcp-adapter/legacy-import.json`(该 marker 存在即永不重跑;已有 gate.json 则完全不介入)。profile patch 里该 entry 的 `config:` 配置原样继承,不受影响。
|
|
64
64
|
|
|
65
65
|
## 配置
|
|
66
66
|
|
|
@@ -71,6 +71,17 @@ dsh plugin --profile <name> remove @aiwayds/dsh-mcp-adapter
|
|
|
71
71
|
| `servers` | `[]` | server 白名单:非空时只有这些 server 的工具会被折叠 / 进目录 / 可分发(三处共用同一份名单) |
|
|
72
72
|
| `descriptionLimit` | `200` | `mcp_list` 目录里每条工具描述的最大字符数 |
|
|
73
73
|
| `storageDir` | `""` | 门闩存储目录覆盖;空 = `<dsh home>/storages/mcp-adapter`(插件启动时读一次,改后需重启插件生效) |
|
|
74
|
+
| `jevEnabled` | `false` | System One 总开关——**默认关闭**:false 表示任何环节都不发决策请求,而调用统计照常累积 |
|
|
75
|
+
| `jevBackend` | `"zen"` | 决策后端:`zen`(opencode-zen 免费档)/ `native`(typesafe 直连)/ `openrouter`;各自需要自己的 API key(`JEV_ZEN_API_KEY` / `TYPESAFE_API_KEY` / `OPENROUTER_API_KEY`,或 macOS 钥匙串) |
|
|
76
|
+
| `jevModel` | `""` | 钉死的模型 id;空 = 调用时解析后端自带默认(`jev-1.13-free` / `jev-1.13.0` / `typesafe/jev-1.13`)——升级是一次有意为之的动作 |
|
|
77
|
+
| `jevTimeoutMs` | `3000` | 单次请求超时(毫秒);只试一次、不重试——下一次节奏就是重试 |
|
|
78
|
+
| `jevSecretFile` | `""` | 出站密钥闸的额外字面量密钥清单(`JEV_SECRET_FILE` 语义);换路径即热更清单 |
|
|
79
|
+
| `jevLayaFallback` | `false` | **默认关闭**:每次决策请求同时并行打一发本地 laya;其答案只作对比记录,仅在主后端失败时接管 |
|
|
80
|
+
| `jevLayaUrl` | `"http://127.0.0.1:8000/v1/systemone"` | 该本地 laya-serve 端点 |
|
|
81
|
+
|
|
82
|
+
后七行即 System One 决策层(见下节),全部是可选开关——默认安装下插件不会发出任何一次对外决策请求。
|
|
83
|
+
|
|
84
|
+
以上字段全部声明为 **volatile**(dsh 0.1.7 settings 契约):十二个键都会出现在插件设置页(entry `dsh-mcp-adapter`)中,在设置页修改**无需重启插件即可生效**——折叠边界、目录与分发在下一次使用时立即采用新值;`jev*` 开关同样每次使用时现读,在设置页打开 `jevEnabled` 后,下一次分发立即生效。(唯一例外是 `storageDir`:存储位置本身在插件启动时读一次,如其表行所述。)profile patch 里的 `config:` 写法照旧可用。
|
|
74
85
|
|
|
75
86
|
```yaml
|
|
76
87
|
config:
|
|
@@ -82,10 +93,44 @@ config:
|
|
|
82
93
|
- github
|
|
83
94
|
```
|
|
84
95
|
|
|
85
|
-
以上字段全部声明为 **volatile**(dsh 0.1.7 settings 契约):五个键都会出现在插件设置页(entry `dsh-mcp-adapter`)中,在设置页修改**无需重启插件即可生效**——折叠边界、目录与分发在下一次使用时立即采用新值。profile patch 里的 `config:` 写法照旧可用。
|
|
86
|
-
|
|
87
96
|
**信任边界:** 默认所有匹配 `prefix` 的工具都会被折叠——前缀只是命名约定而非安全边界,第三方插件恰好用 `mcp__*` 注册的工具同样会折叠。若只信任官方 client 的 server,请在 `servers` 里显式列出;其余保持原生(仍可直调,只是不走 meta-tool)。
|
|
88
97
|
|
|
98
|
+
## 自我进化(System One 决策层)
|
|
99
|
+
|
|
100
|
+
一个**默认关闭**的可选决策层:`jevEnabled: false` 时插件任何地方都不发对外决策请求,行为与接入前完全一致。打开后只发生三件事,且三件都是建议性的。
|
|
101
|
+
|
|
102
|
+
**调用统计(常开,永不走网络)。** 每一次走完的 `mcp_call` 分发(成功与失败都算)按工具计数(`calls`、`errors`、首次/最近使用时间),落进插件自有门闩目录里与 `gate.json` 并排的 `usage.json`。统计与 `jevEnabled` 无关——事后打开开关,此前攒下的计数直接复用。
|
|
103
|
+
|
|
104
|
+
**keep 建议(自我进化的部分)。** 每累计 20 次调用(越过 20、40、60……)触发一次后台批量提问:问决策后端,当前**处于折叠态**、且确实被调用过的工具里,哪些值得常驻每一条 prompt(省掉每次都要查目录、展开 schema 的成本)。触发它的那次分发早就返回了,这些活没人 await。答案写入 `suggestions.json`;这一轮失败则原样保留上一批。
|
|
105
|
+
|
|
106
|
+
**查看。** `/mcp suggest` 渲染当前这批建议——每行给出概率、档位、支撑它的调用证据,以及该行对应的 `keep` 片段——外加已记录的总量。视图自己会写明:`display only — nothing was written to keep, prefix, or the server gate.` 片段由你亲手粘进配置;**本插件永不修改你的配置**,任何一条决策路径都不会自行写入 `keep`、`prefix` 或门闩。
|
|
107
|
+
|
|
108
|
+
同一个后端,除了被计数器调用,也服务模型侧的两处检索:
|
|
109
|
+
|
|
110
|
+
- `mcp_list { "query": "<你想做什么>" }` — 是一个**子集**视图:先做一遍词法预筛(对工具名与描述,确定性、无网络),再对该批候选做可选重排。答案会说明总共命中多少个工具,并指回未过滤的完整目录;无参 `mcp_list` 依然是完整目录,而不带 query 的调用根本不会发起决策请求。
|
|
111
|
+
- `mcp_call` 打到未注册的工具名 — 报错保留原句,末尾追加 `Did you mean: "…"?` 建议:先按词法近似排序(编辑距离优先,其次共享的名字 token),可选再重排。末尾始终标注排序来源(`lexical` 或 `jev reranked`),没排过序的猜测不会被当成排过序的。
|
|
112
|
+
|
|
113
|
+
**故障放行(fail-open):** 后端不可达、超时或给不出可用答案,与开关关闭不可区分——每条决策路径都退回它原本的词法行为;建议那一轮失败,代价仅是这一批没有更新。
|
|
114
|
+
|
|
115
|
+
**隐私:** 计数、建议与决策日志(`decisions.jsonl`)都不出本机——它们是门闩目录里的三个文件。打开 `jevEnabled` 后,工具名、其描述的前 200 字、调用计数以及模型自己的 query 文本**会**作为问题上下文发给决策后端;每个出站请求体都会先过内置密钥闸(JWT、各家 provider key、GitHub/Slack/AWS 令牌、PEM 块,外加你在 `jevSecretFile` 里列的字面量),命中即在出进程前中止这次调用。发往哪里由 `jevBackend` 决定:`zen`(opencode-zen 免费档,默认)、`native`(typesafe 直连)或 `openrouter`。本地 laya 陪跑(`jevLayaFallback`)默认关闭。
|
|
116
|
+
|
|
117
|
+
### 别把本地 laya 当后端——暂时不建议(实测针对 laya 0.3.20)
|
|
118
|
+
|
|
119
|
+
**`jevLayaFallback` 保持关闭。** 用真实 MCP 工具目录、经 `jevAskDual` 并行与免费档 `zen` 头对头,在本插件自己的三条缝上实测:
|
|
120
|
+
|
|
121
|
+
| 缝 | zen(免费档) | laya 0.3.20 | 纯词法 |
|
|
122
|
+
| --- | --- | --- | --- |
|
|
123
|
+
| keep 建议(12 工具批量 noul) | AUC **1.000**——高频 0.71 / 边界 0.48 / 该折叠 0.11 | AUC **0.333**,比随机还差:概率全挤在 51–55% | — |
|
|
124
|
+
| `mcp_list {query}` 排序(10 问) | **8/10** | 4/10——把 `read_file` 排到 SQL `query` 之下 | 6/10 |
|
|
125
|
+
| did-you-mean 重排(6 错拼) | 5/6 | 4/6 | 5/6 |
|
|
126
|
+
| 中文 query 语义兜底(5 问) | **5/5** | 1/5——不管问什么都锚在同一个工具上 | 0(词法零命中) |
|
|
127
|
+
|
|
128
|
+
laya 快约 8–10 倍(70 毫秒–1 秒 vs 0.6–6 秒),但判别力差得不是一点:它读不出 keep 建议**赖以成立**的调用频次信号——调用 412 次和调用 1 次的工具给回来的置信度一样高;而目录排序缝依赖的跨语言 query 匹配,是它彻底塌掉的地方。laya 自己的运行时也在警告内置 checkpoint 的置信度未校准。
|
|
129
|
+
|
|
130
|
+
所以陪跑只当降级模式的安全网:主路失败时 laya 的答案**降级**接管——只借相对排序,绝不拿它的绝对分数去撞校准过的档位,那一轮的 keep 建议直接跳过,而不是拿未校准的数字糊弄你。两边的判定行照旧都进 `decisions.jsonl`,等于这份对比免费持续跑着。
|
|
131
|
+
|
|
132
|
+
**何时再看:** 等 laya 出 typed-decisions checkpoint(或某个版本不再只"警告未校准"而是公开校准结果),并且上表被翻转时——届时先拿你自己的目录重测一遍再信。
|
|
133
|
+
|
|
89
134
|
## 备注
|
|
90
135
|
|
|
91
136
|
- `mcp_call` 只接受匹配 `prefix` 的工具(配置了 `servers` 时还须在白名单内)——它不可能被用来绕过其它工具自己的 pre-execute 管线。
|
|
@@ -102,7 +147,8 @@ config:
|
|
|
102
147
|
|---|---|
|
|
103
148
|
| `/mcp` 或 `/mcp list` | 树形总览——每行 server 带 stable `[<id>]` 前缀;disabled 的标 `⏸ disabled` 且不列工具;尾部附折叠健康行 |
|
|
104
149
|
| `/mcp list <name>` | `<name>` 匹配某 server → 该 server 全部工具(disabled 的附加 `⏸` 说明行);匹配完整工具名 → 完整描述 + 完整 input schema |
|
|
105
|
-
| `/mcp config` | 当前生效的 `prefix` / `keep` / `servers` / `descriptionLimit` 及各自命中清单,外加持久 enable/disable
|
|
150
|
+
| `/mcp config` | 当前生效的 `prefix` / `keep` / `servers` / `descriptionLimit` 及各自命中清单,外加持久 enable/disable 台账、七个 `jev*` 设置与已记录的调用统计 |
|
|
151
|
+
| `/mcp suggest` | 当前这批 keep 建议:每行给出概率、档位、调用证据与对应的 `keep` 片段,外加已记录总量。只读:不向 `keep`、`prefix` 或门闩写任何东西 |
|
|
106
152
|
| `/mcp disable <id>` | 把一个 server 整体闩上:工具强制折叠出 prompt(keep 与 `servers` 豁免一并覆盖)、从 `mcp_list` 目录消失、`mcp_call` 拒绝并给 `/mcp enable <id>` 指引 |
|
|
107
153
|
| `/mcp enable <id>` | 用同一个 stable id 复原 |
|
|
108
154
|
|