@khorsheed/dsh-local-agent-kimi 0.1.0-rc.8 → 0.2.0-rc.3

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.en.md +16 -16
  3. package/README.i18n.yaml +2 -2
  4. package/README.md +17 -17
  5. package/cordis.patch.yml +18 -28
  6. package/lib/client.js +813 -321
  7. package/lib/index.js +1713 -1178
  8. package/lib/tool.js +40 -0
  9. package/lib/types/client/SettingsCard.d.ts +75 -24
  10. package/lib/types/client/SettingsCard.js +110 -137
  11. package/lib/types/client/index.d.ts +6 -25
  12. package/lib/types/client/index.js +134 -51
  13. package/lib/types/client/locales.d.ts +34 -24
  14. package/lib/types/client/locales.js +38 -28
  15. package/lib/types/endpoint-auth.d.ts +202 -0
  16. package/lib/types/endpoint-auth.js +287 -0
  17. package/lib/types/index.d.ts +19 -2
  18. package/lib/types/index.js +146 -19
  19. package/lib/types/kimi-cli-provider.d.ts +31 -4
  20. package/lib/types/kimi-cli-provider.js +71 -34
  21. package/lib/types/live-driver.d.ts +9 -0
  22. package/lib/types/live-driver.js +21 -10
  23. package/lib/types/live-switch.d.ts +16 -1
  24. package/lib/types/live-switch.js +11 -1
  25. package/lib/types/model-broker.d.ts +12 -2
  26. package/lib/types/model-broker.js +9 -5
  27. package/lib/types/model-catalog.d.ts +44 -1
  28. package/lib/types/model-catalog.js +110 -17
  29. package/lib/types/model-configuration.d.ts +26 -0
  30. package/lib/types/model-configuration.js +43 -0
  31. package/lib/types/provision.d.ts +102 -31
  32. package/lib/types/provision.js +257 -45
  33. package/lib/types/records.d.ts +0 -20
  34. package/lib/types/records.js +1 -40
  35. package/lib/types/tool.d.ts +54 -0
  36. package/lib/types/tool.js +34 -0
  37. package/locale/en.json +2 -2
  38. package/locale/zh.json +2 -2
  39. package/package.json +26 -24
  40. package/lib/invariant.js +0 -31
  41. package/lib/types/credential-guard.d.ts +0 -29
  42. package/lib/types/credential-guard.js +0 -107
  43. package/lib/types/invariant.d.ts +0 -16
  44. package/lib/types/invariant.js +0 -33
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.2.0-rc.3(2026-10-22)
4
+
5
+ (版本号说明:家族的 dsh-headless 包 0.2.0-rc.2 曾被发布后又撤回,npm 永久烧掉该版本号;为守住家族「同一版本线」纪律(check:release-groups),本波家族整体上移 rc.3,内容即 rc.2 计划稿。)
6
+
7
+ - **BREAKING:OAuth 移除,端点 key 成为唯一认证方式**。注入用 kimi-cli ≥2.1 的原生 `api_key_env`:作用域 `config.toml` 的 managed provider 声明从环境变量读 key,key 只存在于 `<scopedHome>/endpoint-auth.json`(0600)与子进程环境,`config.toml` 无秘密;一把幂等迁移把既有 config 改到该形态(摘 OAuth 子表、替换内联 `api_key`、钉住 `base_url`)。**升级前必须配好 `baseUrl` + `apiKey`**,否则升级后读作未认证(README 带迁移说明);`credentials/` 与 `oauth/` 残留由 provision 清扫,credential-guard 哨兵随 OAuth 一并删除。
8
+ - **设置卡端点凭据表单,并补上「验证端点并获取模型」按钮**:表单与家族其他卡一致(编辑默认 scope 的 endpoint-auth.json);验证探测已保存端点的 `/v1/models`(kimi 服务没有已确认的无 token 探测,故探测带凭据进行)。
9
+ - **「可用模型」有序短名单取代自由文本 model 字段**:与家族其他卡共用同一组件——`<scopedHome>/models.json`,首项即默认模型,端点目录弹窗勾选添加、拖拽排序;`model` 配置键作为回退静默生效。
10
+ - **模型目录切换为端点供给**:目录 = 端点 `/v1/models` 实际供应的模型(解析 kimi 自有的 `display_name` / `think_efforts` / `context_length`,兼容纯 OpenAI 形态中转);命中 managed 模型表的端点 id 以表键为候选值——即 kimi-cli 的可运行名。写名单时自动为尚未建表的列出值补写 `config.toml` 的 managed models 表,让「添加」在同一次写入里变得可运行(手改过的既有表永不被重写);自由输入随之关闭。
11
+ - **设置卡并入「本机 Agent 委派」家族卡**:本包卡读作「本机 Kimi 委派」,作为家族卡的一节呈现;家族卡随后修复为无条件注册——原先的命名空间门控让它在 prod 上永不挂载(2026-10-21)。与旧版家族核混装时回落为独立卡。
12
+ - **适配宿主 0.2.1 线**:委派链路迁移到 subagent `startActivation`(宿主 0.2.1 删除旧的 `ctx.subagents.start()`);加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.1。
13
+
14
+ ## 0.2.0-rc.1(2026-09-30)
15
+
16
+ - **家族折叠:委派工具收进本包**。新增 `./tool` 组合入口(`src/tool.ts`)——`subagent_kimi` 委派工具由 agent 预设点名 `name: '@khorsheed/dsh-local-agent-kimi/tool'` 按会话授予,Config 两字段(`provider` / `toolName`)全部可选、默认即本包取值,预设行无需配置;行 id `tool-subagent-kimi` 不变。bundle patch 不再插 profile 根工具行,本包自挂载恰好一行(provider 行),插件清单一个 provider 一张卡。实现共享自家族核 `@khorsheed/dsh-local-agent` 的 `./tool-factory` 导出;对 `@khorsheed/dsh-local-agent-tool-subagent` 的依赖移除(该包退役)。
17
+
3
18
  ## 0.1.0-rc.8(2026-09-30)
4
19
 
5
20
  家族同版联动:加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.0(0.2.0 的兼容闸会禁用 peer 区间不覆盖宿主版本的已装插件)。无功能变更。
package/README.en.md CHANGED
@@ -10,12 +10,12 @@ Getting the model to hand a whole chunk of work to another coding agent used to
10
10
 
11
11
  ## Features
12
12
 
13
- - **Delegate from any preset** — the `subagent_kimi` tool mounts at the profile root; standard/code/minimal/cordis and future presets need no per-preset variants.
13
+ - **Per-session delegation grant** — the `subagent_kimi` tool is this package's `./tool` composition entry, granted to the sessions of an agent preset that names it (e.g. dev mode); sessions on other presets never see it.
14
14
  - **Scoped home** — config, credentials, and sessions live under `$DSH_HOME/local-agent/kimi`, never in your `~/.kimi-code`.
15
- - **Device-code login** — `/kimi login` shows the auth URL in the session; `/kimi logout` clears scoped credentials for a fresh account.
15
+ - **Endpoint credential (the only auth mode)** — fill `baseUrl` + `apiKey` on the card's Authentication section (saved as the default scope's `endpoint-auth.json`, mode 0600, local only) or preconfigure the profile row, and the scope is authenticated; every named scope may override the deployment pair field by field with its own `endpoint-auth.json`. The managed provider reads the key through its `api_key_env` indirection from the child process's environment — the key never lands in `config.toml` (an evaluation-condition input). Container rounds share the host's credential; nothing is authorized inside a unit. There is no web login and no device code. The "Verify endpoint & list models" button next to it runs a token-free probe against the SAVED endpoint (`GET <baseUrl>/v1/models`, Bearer header) and answers with reachability plus the served model list.
16
16
  - **Resumable delegations** — pass back the self-described `resume` handle to continue the same Kimi session, with real per-round usage and timing.
17
17
  - **Session records and transcript replay** — `/kimi sessions` lists this harness's delegations (never your personal sessions); `/kimi session <id>` renders the session's wire log as a readable transcript — thinking, tool calls, and results included.
18
- - **Settings card** — the card on the plugin detail view (0.1.5: Settings → Plugins → configurable plugins) shows auth status and the scoped sessions at a glance; login/logout, the default model, and the resident-mode switch all hot-apply, no reload.
18
+ - **Settings card** — a section of the core's「Local Agent Delegation」family card on the Plugins page (on an older core, this package's own `plugins.item` card; mounted while the Host serves the `local-agent-kimi` namespace) shows auth status and the scoped sessions at a glance; login/logout, the available-models shortlist (ordered, the first entry is the default; empty = the legacy chain), and the resident-mode switch all hot-apply, no reload.
19
19
  - **Model readback and per-cell working directory** — every settled round reads back the model from the wire.jsonl usage/request records into the delegation record; orchestrators pass a `cwd` per cell, and a resume in a different directory is rejected.
20
20
  - **Resident driver (optional)** — `live: true` keeps one resident `kimi acp` process per member, one `session/prompt` per round, with runtime-level graceful cancel; off — or a channel that cannot come up — means the one-shot `kimi -p` path.
21
21
 
@@ -29,13 +29,13 @@ dsh plugin --profile web add @khorsheed/dsh-local-agent
29
29
  dsh plugin --profile web add @khorsheed/dsh-local-agent-kimi
30
30
  ```
31
31
 
32
- Restart the web instance to activate, then run `/kimi login` once from a session. Uninstall:
32
+ Restart the web instance to activate, then fill the endpoint and key in the Kimi section's Authentication block of the「Local Agent Delegation」family card (the Plugins page) — or preconfigure the profile row; with neither, the status reads unauthenticated. Uninstall:
33
33
 
34
34
  ```sh
35
35
  dsh plugin --profile web remove @khorsheed/dsh-local-agent-kimi
36
36
  ```
37
37
 
38
- The scoped home is kept on purpose so a reinstall needs no fresh login — delete `$DSH_HOME/local-agent/kimi` to remove every trace.
38
+ The scoped home is kept on purpose so a reinstall keeps its credential — delete `$DSH_HOME/local-agent/kimi` to remove every trace.
39
39
 
40
40
  ## Config
41
41
 
@@ -48,7 +48,7 @@ base_url = "https://your-router.example/v1"
48
48
 
49
49
  Edit **only this key** — provisioning never overwrites an existing config, and the `[services.moonshot_*]` base URLs must stay (they route the built-in search/fetch tools).
50
50
 
51
- ⚠️ **OAuth token exposure**: the scoped OAuth token is sent to whatever endpoint serves the request — point `base_url` only at endpoints you control or trust.
51
+ ⚠️ **Credential exposure**: the endpoint key is sent to whatever endpoint serves the request — point `baseUrl` only at endpoints you control or trust.
52
52
 
53
53
  Plugin config of its own (optional, in the profile patch layer):
54
54
 
@@ -78,9 +78,9 @@ Plugin config of its own (optional, in the profile patch layer):
78
78
 
79
79
  So: the one-shot drive never touches your `config.toml`; the resident drive rewrites its `default_model` line.
80
80
 
81
- The settings card's "Default model" writes the provider setting for subsequent rounds. Its shared picker displays the scoped model directory, discovery source and completeness, plus an explicit model-ID input when needed. Clearing the selection follows the effective configuration/default chain. Saving does not interrupt an active round and requires no reload. If the shared picker is unavailable, the card retains its text-input fallback. Per-member model and effort changes use the durable controls described below.
81
+ The settings card's「Available models」section maintains an **ordered model shortlist**: "Add model" checks entries off the endpoint's served catalog, so the list can only hold what the endpoint actually serves; drag rows to reorder. **The first entry is the default model** — every delegation round starts the CLI with it (an argv flag one-shot, or the scoped `default_model` rewrite before a resident spawn), outranked only by member session overrides and delegation-level picks. The list persists in the scoped home's `models.json` (each named scope may carry its own, the same file mechanism as the endpoint credential), every edit saves immediately and applies to the next round. **Empty = the legacy chain** (the `model` key → the scoped config's top-level `default_model` → the CLI built-in). kimi's `-m` resolves against the scoped config's `[models."…"]` tables (verified against kimi-cli 2.1.1: a bare endpoint id without a table is not runnable), so adding a served id that has no table yet provisions its managed table in the same write (the endpoint-reported display name, effort levels and context window ride along). Per-member model and effort changes use the durable controls described below.
82
82
 
83
- The rich directory uses native ACP session model/configuration metadata when a live member exposes it, preserving labels and the current model's reasoning options. Before that it shows the member's scoped configuration as incomplete, configuration-sourced candidates. Reads create no disposable ACP sessions. Directory refresh and subscriptions use the shared core cache. The shared model picker and member effort controls are connected. Busy selections apply at the next complete turn boundary, including tool continuations; core owns current/pending state, cancellation and retry, while frozen evaluation members reject changes.
83
+ The directory's vocabulary comes from the endpoint itself (`GET <baseUrl>/v1/models`); the scoped config's model tables only enrich it: when a served id matches a managed table's `model`, the candidate's value is the TABLE KEY (the name `-m` actually runs), and display name / reasoning efforts prefer the endpoint's answer with the table as fallback. A resident member's native ACP configOptions remain that member's authoritative directory (labels plus the current model's reasoning options). With no credential, a rejected credential, an unreachable-shape answer or no models served, the directory loads empty with the reason; a transport failure keeps the last good snapshot and retries on the cache's schedule. Reads create no disposable ACP sessions. Directory refresh and subscriptions use the shared core cache. The shared model picker and member effort controls are connected. Busy selections apply at the next complete turn boundary, including tool continuations; core owns current/pending state, cancellation and retry, while frozen evaluation members reject changes.
84
84
 
85
85
  **A delegation's own model outranks this key.** An orchestrator may name the model for ONE delegation through the facade's `DelegationCallOptions.model`, which sits above this key (the layer order is in the family core README). The first round's request is recorded and every resume round re-requests it — `resume` takes no model of its own. In resident mode it becomes the member's **start model**: bound through the scoped-config rewrite before the runtime spawns; a resident runtime already bound to another model is retired first and respawns onto the new one, `session/load`-ing the same CLI session.
86
86
 
@@ -88,16 +88,16 @@ The rich directory uses native ACP session model/configuration metadata when a l
88
88
 
89
89
  **This is not an evaluation gap.** A run freezes its condition at setup: change the key mid-run and the next round's model read-back sees declared ≠ observed and fails the run as misattributed (frozen decision 5).
90
90
 
91
- **Evaluation snapshot (`effectiveSettings`).** The harness declares a live-read snapshot of its fairness-relevant settings for the evaluation condition hash: drive (exec/live, following the live preference), reasoning effort (read from the scoped config's `[thinking] effort`, falling back to the model's `default_effort`), whether tool use is auto-approved (the scoped config carries the `Bash(*)` allow rule), whether a custom endpoint is pinned (hostname only; the managed endpoint does not count as pinned), the configured model (the plugin config's `model` key first — it overrules the file every round — then the scoped config's top-level `default_model`; absent when neither names one — never guessed), and the CLI version (`kimi --version`, cached against the executable's path + mtime; absent when the CLI cannot be asked). `/kimi status` and the `LocalAgentStatus` Remote attach the same snapshot — this is the read side of web-eval frozen decisions 2 through 4.
91
+ **Evaluation snapshot (`effectiveSettings`).** The harness declares a live-read snapshot of its fairness-relevant settings for the evaluation condition hash: drive (exec/live, following the live preference), reasoning effort (read from the scoped config's `[thinking] effort`, falling back to the model's `default_effort`), whether tool use is auto-approved (the scoped config carries the `Bash(*)` allow rule), whether a custom endpoint is pinned (hostname only; the managed endpoint does not count as pinned), the configured model (the scope's `models.json` first entry first, then the plugin config's `model` key — it overrules the file every round — then the scoped config's top-level `default_model`; absent when none names one — never guessed), and the CLI version (`kimi --version`, cached against the executable's path + mtime; absent when the CLI cannot be asked). `/kimi status` and the `LocalAgentStatus` Remote attach the same snapshot — this is the read side of web-eval frozen decisions 2 through 4.
92
92
 
93
93
  ## Compatibility
94
94
 
95
- - npm release line (`@deepseek-ai/dsh@0.1.5-rc.1`): ✅ public API compatible — live generation rides the local-agent transient Remote and public Conversation nodes; suffix checkpoints provide recovery, and native final messages retain transcript and usage semantics. minHost is 0.1.5-rc.1; older hosts stay on the previous release line. 0.1.5 retired the per-chunk session event: token-granularity deltas no longer land in the child session log — they ride the run-progress channel and the round settles as one combined assistant/message (identical final text); a late-arriving usage whose carrier message already mirrored is dropped with a warn (the host has no usage-backfill event).
96
- - source line (deepseek-harness master): ✅ (verifiedHost: 0.1.5-rc.1) — the `thinkingEffort` config item (default high, provision-time only) and the `effectiveSettings` evaluation snapshot are plugin-level: they read and write scoped files only, with no host-API dependency on either host line.
95
+ - npm release line (`@deepseek-ai/dsh@0.1.5-rc.1`): ✅ public API compatible — live generation rides the local-agent transient Remote and public Conversation nodes; suffix checkpoints provide recovery, and native final messages retain transcript and usage semantics. minHost is 0.1.5-rc.1; older hosts stay on the previous release line. 0.1.5 retired the per-chunk session event: token-granularity deltas no longer land in the child session log — they ride the run-progress channel and the round settles as one combined assistant/message (identical final text); a late-arriving usage whose carrier message already mirrored is dropped with a warn (the host has no usage-backfill event). The settings card renders as a section of the core's「Local Agent Delegation」family card (the core's `plugins.item` entry on the Plugins page, 0.1.7-alpha.1+; on an older core this package falls back to its own `plugins.item` card), mounted through `configForms.whileServed` while the Host serves the `local-agent-kimi` namespace; 0.1.5 renders no card (the host removed the `settings.plugin.item` seat) — every other surface is unchanged.
96
+ - source line (deepseek-harness master): ✅ (verifiedHost: 0.2.1-rc.1) — host-021 wave: full build+test green against the 0.2.1-rc.1 tree; delegation migrated to `ctx.subagents.startActivation` (managed activation), and run.id is now unique per execution. The `thinkingEffort` config item (default high, provision-time only) and the `effectiveSettings` evaluation snapshot are plugin-level: they read and write scoped files only, with no host-API dependency on either host line.
97
97
 
98
98
  ## Known Limitations
99
99
 
100
- - **Login is interactive** — device-code only, one login at a time per harness, no API-key path.
100
+ - **No web login** — the endpoint credential is the only auth path (the card or the profile row; a kimi-for-coding platform key or a relay key alike). The kimi-subscription OAuth path is not part of this package.
101
101
  - **Process bookkeeping touches the real home** — kimi writes content-free `~/.kimi-code/server/instances/*.json` regardless of `KIMI_CODE_HOME`; config, credentials, and sessions stay scoped.
102
102
  - **`/kimi` commands need a Web session** — headless profiles can still delegate through a composition that mounts the tool row.
103
103
 
@@ -106,15 +106,15 @@ The rich directory uses native ACP session model/configuration metadata when a l
106
106
  <details>
107
107
  <summary>Internals (click to expand)</summary>
108
108
 
109
- **Scoped home and login.** Every Kimi process the bundle starts runs with `KIMI_CODE_HOME=$DSH_HOME/local-agent/kimi`. Login is device-code only: `/kimi login` surfaces the authorization URL and code in the session, the CLI polls in the background, and credentials land in the scoped home. `/kimi logout` removes the scoped credentials and OAuth cache (the kimi CLI has no logout command). On first boot the scoped home is provisioned with a `config.toml` — the user's own config with every `api_key` blanked, or a minimal managed config when the user has none — because the CLI refuses to authenticate without provider and model definitions; an existing config is never overwritten.
109
+ **Scoped home and credentials.** Every Kimi process the bundle starts runs with `KIMI_CODE_HOME=$DSH_HOME/local-agent/kimi`. Authentication is endpoint-key only: the scope's `endpoint-auth.json` (mode 0600) merges field by field over the profile row's `baseUrl`/`apiKey`; the managed provider (`managed:kimi-code`) declares `api_key_env = "DSH_KIMI_ENDPOINT_KEY"` in config.toml (the kimi CLI natively reads the key from a named environment variable — mutually exclusive with an inline `api_key`), so the key lives only in endpoint-auth.json and in the child process's environment, and `config.toml` never carries a secret and stays a legitimate evaluation-condition input. The card's Authentication section edits exactly this file for the default scope (through the family gateway's `endpointAuth`/`configureEndpoint` Remotes); saving a baseUrl re-points the managed provider's `base_url` in the same write (clearing it falls back to kimi's own service), and an idempotent pre-spawn pass applies hand-edits just as immediately. The one-shot `kimi -p`, the resident `kimi acp`, and container rounds (`containerExecSpawn`'s name-only env forwarding) share the same injection. On first boot the scoped home is provisioned with a `config.toml` — the user's own config with every `api_key` blanked and migrated onto the env-key shape, or a minimal managed config when the user has none. The OAuth era's `credentials/` and `oauth/` directories are swept on every provision — this package no longer reads them, and keeping them would let a dead grant authenticate while the status reads unauthenticated. `/kimi logout` deletes the scope's `endpoint-auth.json`; when the credential comes entirely from the profile row, logout refuses and names the profile as the place to edit.
110
110
 
111
- **Mounting.** The bundle patch registers the `kimi` harness and mounts the `subagent_kimi` tool at the profile root; the `kimi-cli` one-shot provider spawns `kimi -p` under the scoped home. The family core (`local-agent` row, shared scoped-homes root) ships in `@khorsheed/dsh-local-agent`'s own patch, declared here as a dependency. The browser settings card ships with this package's own `./client` half, composing the family core's shared building blocks (the auth block, the model picker): a standalone install renders it on this package's plugin detail view, a family-bundle install renders it through the row-level configure entry on the bundle's detail view, and a 0.1.5 host renders it under Settings → Plugins → configurable plugins. The identity triangle stays consistent: the `cordis.patch.yml` row id, tsdown's `clientBundle('@khorsheed/dsh-local-agent-kimi')`, and `src/invariant.ts`'s `PACKAGE_NAME`; the invariant companion also pins one contract — a registered `kimi` harness must name `KIMI_CODE_HOME` as its scoped-home variable.
111
+ **Mounting.** The bundle patch registers the `kimi` harness (exactly one provider row); the `subagent_kimi` tool is this package's `./tool` composition entry (sharing the family core's `./tool-factory` implementation), granted per session by an agent preset that names it — the dev preset's `tool-subagent-kimi` row is the grant point. The `kimi-cli` one-shot provider spawns `kimi -p` under the scoped home. The family core (`local-agent` row, shared scoped-homes root) ships in `@khorsheed/dsh-local-agent`'s own patch, declared here as a dependency. The browser settings card ships with this package's own `./client` half, composing the family core's shared building blocks (the auth block, the model picker): it renders as a section of the core's「Local Agent Delegation」family card, mounted through `configForms.whileServed` while the Host serves the `local-agent-kimi` namespace — one section for a standalone install, a family bundle, or a mode pack alike (on an older core, this package's own `plugins.item` card instead). The identity triangle stays consistent: the `cordis.patch.yml` row id, the package.json name, and tsdown's `clientBundle('@khorsheed/dsh-local-agent-kimi')`.
112
112
 
113
113
  **Session records and transcripts.** `/kimi sessions` lists the scoped home's `session_index.jsonl` — this harness's delegations, never the user's personal sessions. `/kimi session <id>` reads that session's `wire.jsonl` and renders a readable transcript: user prompts, thinking, and assistant replies are tagged with their wire turn number (1-based, matching the child session's `turn/start` numbering), tool calls render with arguments and results paired to their calls (file-editing calls render patch-style, unknown content types keep a visible marker), and kimi's auto-permission `<system-reminder>` messages are filtered out. The settings card shows auth status and the scoped sessions narrowed to the current workspace; while a login is pending the status keeps re-probing until credentials land.
114
114
 
115
115
  **Model readback and the cwd override.** After every settled round the provider reports the actual model from the wire.jsonl `usage.record` (falling back to `llm.request`) events' `model` field — last one seen, since a resumed session's later rounds append later records — through the `settled` run-progress event, and merges it into the delegation record's `observedModel` field; absence is recorded, never guessed. An orchestrator may also pass a per-round working directory through the facade's `DelegationCallOptions.cwd` (recorded as the record's `cwd`); when a resume round resolves to a different directory than the recorded first round, it fails loud before any process spawns — a CLI session continues in the directory its first round ran in.
116
116
 
117
- **Model broker.** The harness registers a `modelBroker` with the registry: the settings card reads the memberless `modelInfo` (effective layer + choices) and the member composer reads and writes the per-member override through the gateway. The resolution order is fixed: override → the delegation's recorded model → the plugin `model` key → the scoped `default_model` → the CLI's built-in default (which names nothing). Choices are the deduped union of the key, the scoped default, the config's `[models."…"]` tables, and the recent saves. The override and the start-model ledger are in-memory (cleared on restart); `setMemberModel` throws while the member has a round in flight, and otherwise retires the resident runtime when its bound model differs from the new effective one (a same-model switch is a no-op) — the next round respawns lazily.
117
+ **Model broker.** The harness registers a `modelBroker` with the registry: the settings card reads the memberless `modelInfo` (effective layer + choices) and the member composer reads and writes the per-member override through the gateway. The resolution order is fixed: override → the delegation's recorded model → the scope's `models.json` first entry → the plugin `model` key → the scoped `default_model` → the CLI's built-in default (which names nothing). Choices: a non-empty `models.json` is the COMPLETE vocabulary (nothing outside the endpoint's served catalog sneaks in); empty falls back to the legacy chain — the deduped union of the key, the scoped default, the config's `[models."…"]` tables, and the recent saves. The override and the start-model ledger are in-memory (cleared on restart); `setMemberModel` throws while the member has a round in flight, and otherwise retires the resident runtime when its bound model differs from the new effective one (a same-model switch is a no-op) — the next round respawns lazily.
118
118
 
119
119
  **Tool-call accounting.** Every settled round also reports how many tool calls it made, on the `settled` run-progress event (`toolCalls: { count, byName }`). What is counted is the transcript's `tool.call` lines carrying THIS ROUND'S TURN — deliberately not the mirror window: in resident mode a live poll may have drained the settle pass's delta, and a resume round must not inherit the earlier rounds' calls. `byName` keys are the tool names the wire gave, verbatim. One accounting per round, never cumulative; a round that called nothing carries no field at all (absent is not zero).
120
120
 
@@ -122,7 +122,7 @@ The rich directory uses native ACP session model/configuration metadata when a l
122
122
 
123
123
  **Isolation and accounting.** The child is a fresh session in the delegating session's workspace; the parent receives only the final answer or the exact error — child context, commentary, tool activity, and diffs never cross into the parent session. The provider opens `turn/start` at spawn and closes `turn/end` at settle, including on failure or abort (reason `error`/`aborted`), so durations equal real CLI runtime. Every mirrored step (assistant message, tool call/result) is wrapped in a `step/start`–`step/end` boundary pair at the same (turn, step) — the host's live conversation assembler registers a step only at its boundaries, so without them assistant messages do not render in the real-time view (only a full rebuild recovers them); the token granularity's streaming snapshots and completion folds also land before `turn/end`, boundaries included. Usage is the sum of the round's `usage.record` deltas (each one LLM request, not cumulative), carried on the round's final mirrored assistant message; the mirror filters kimi's auto-permission `<system-reminder>` messages, renders tool calls with arguments, pairs results to their calls, and advances incrementally so earlier messages never duplicate. Aborting settles the tool result immediately (SIGTERM→grace→SIGKILL) and keeps the partial work already mirrored.
124
124
 
125
- **Named scopes.** `/kimi login --scope <name>` opens a second `KIMI_CODE_HOME` at `<homesRoot>/kimi@<name>`; the directory is provisioned with the same two steps in the same order (provider/model config first, then the permission rules — the permission write reads the config file). From then on that scope has its own login, its own wire log and its own transcript mirror. A scoped delegation is exec-only (the resident `kimi acp` is bound per member to the default scoped home) and carries **no member channel**: the bridge declaration is written into a scoped home's `mcp.json` and the socket is a single homes-root one, so a named absence beats a half-wired presence.
125
+ **Named scopes.** a named scope opens a second `KIMI_CODE_HOME` at `<homesRoot>/kimi@<name>`; the directory is provisioned with the same two steps in the same order (provider/model config first, then the permission rules — the permission write reads the config file). From then on that scope has its own endpoint-auth.json, its own wire log and its own transcript mirror. A scoped delegation is exec-only (the resident `kimi acp` is bound per member to the default scoped home) and carries **no member channel**: the bridge declaration is written into a scoped home's `mcp.json` and the socket is a single homes-root one, so a named absence beats a half-wired presence.
126
126
 
127
127
  **Container delegation.** An orchestrator may run the round inside an **already-acquired container** through the facade's `DelegationCallOptions.exec` (`{ container, workdir, env? }`): the argv becomes `docker exec -w <workdir> [-e NAME…] <container> kimi -p …` and everything else (the wire.jsonl mirror and readback, settle, recording) is byte-for-byte unchanged. `env` must name the in-container `KIMI_CODE_HOME`, and it should be the read-write bind mount of the host scoped home — the transcript mirror and the model readback read the host copy of the wire log. A container round always takes the exec one-shot (the resident `kimi acp` is a host process) and **does not write** the member-bridge entry into `mcp.json`: that declaration names a host node path the unit cannot start, and leaving a broken server in a shared config file is worse than running one round without the member channel.
128
128
 
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/local-agent-kimi/README.en.md
5
- packages/local-agent-kimi/README.en.md: 55a56e7b217fbfc9a0eb499c6d483e7ed78fad4b
6
- packages/local-agent-kimi/README.md: 9598f26d60e53ba2d8c934739c27ab419ecdbfcc
5
+ packages/local-agent-kimi/README.en.md: 15fa4b8608ecf1d1e535cfe69f2d4b0e116a62cb
6
+ packages/local-agent-kimi/README.md: 62b45828587f0341ab8569c5d687d5dead5b0413
package/README.md CHANGED
@@ -10,18 +10,18 @@
10
10
 
11
11
  ## 特性
12
12
 
13
- - **任意 preset 都能委派**——`subagent_kimi` 工具挂在 profile 根,standard/code/minimal/cordis 及未来的 preset 都无需逐变体。
13
+ - **按会话授予的委派**——`subagent_kimi` 工具是本包的 `./tool` 组合入口,由点名它的 agent 预设(如开发模式)授予该预设的会话;其余预设的会话看不到它。
14
14
  - **作用域目录**——config、凭据、会话全部留在 `$DSH_HOME/local-agent/kimi`,与你自己的 `~/.kimi-code` 互不干扰。
15
- - **device-code 登录**——`/kimi login` 把授权 URL 呈现在会话中;`/kimi logout` 清除作用域凭据,换账号即重新登录。
15
+ - **端点凭据(唯一的认证方式)**——设置卡「认证」区填 `baseUrl` + `apiKey`(保存进默认 scope 的 `endpoint-auth.json`,0600,只存本机)或预配在 profile 配置行即已认证;每个命名 scope 可用自己的 `endpoint-auth.json` 按字段覆盖部署级配置。managed provider 经 `api_key_env` 从子进程环境读 key——密钥不落 `config.toml`(它要进评测条件指纹)。容器轮与宿主轮用同一套凭据,容器里不需要再授权一次。没有网页登录、没有 device-code。旁边的「验证端点并获取模型」按钮对**已保存**的端点跑一次无 token 探测(`GET <baseUrl>/v1/models`,Bearer 头),回执可达性与端点当前供应的模型列表。
16
16
  - **可续聊的委派**——把结果自述的 `resume` 句柄传回,即继续同一个 Kimi 会话,并按轮记录真实用量与耗时。
17
17
  - **会话记录与转写回放**——`/kimi sessions` 列出本 harness 的委派记录(绝不含你的私人会话);`/kimi session <id>` 把该会话的 wire 日志渲染成可读转写——思考、工具调用与结果一目了然。
18
- - **设置卡片**——插件详情页(0.1.5:设置 → 插件 → 可配置插件)上的卡片一眼看清认证状态与作用域会话,登录/退出、默认模型、常驻模式开关全部热生效,无需重载。
18
+ - **设置卡片**——core 的「本机 Agent 委派」家族卡里的一节(Plugins 页;旧版 core 上回落为本包自己的 `plugins.item` 卡,宿主服务 `local-agent-kimi` 命名空间时挂载)一眼看清认证状态与作用域会话,登录/退出、可用模型(有序短名单,第一个为默认;留空 = 跟随旧链)、常驻模式开关全部热生效,无需重载。
19
19
  - **模型回读与独立工作目录**——每轮从 wire.jsonl 的 usage/request 记录回读实际模型,写进委派记录;编排器可用 `cwd` 选项给每格独立目录,resume 换目录即拒绝。
20
20
  - **常驻驱动(可选)**——`live: true` 让每个成员常驻一个 `kimi acp` 进程,按轮 `session/prompt`,支持运行时级优雅取消;关闭或通道不可用即回一次性 `kimi -p`。
21
21
 
22
22
  ## 安装
23
23
 
24
- 需要一个可运行的 dsh profile,且 `PATH` 上有 Kimi Code CLI(`kimi`)——插件既不替你安装,也不替你登录。
24
+ 需要一个可运行的 dsh profile,且 `PATH` 上有 Kimi Code CLI(`kimi`)——插件既不替你安装,也不替你准备凭据。
25
25
 
26
26
  ```sh
27
27
  # 两个都得点名:`dsh plugin add` 只调和直接依赖。
@@ -29,13 +29,13 @@ dsh plugin --profile web add @khorsheed/dsh-local-agent
29
29
  dsh plugin --profile web add @khorsheed/dsh-local-agent-kimi
30
30
  ```
31
31
 
32
- 重启 web 实例后生效,然后在会话里执行一次 `/kimi login`。卸载:
32
+ 重启 web 实例后生效,然后在「本机 Agent 委派」家族卡(Plugins 页)的 Kimi 一节「认证」区填端点与 key 即可(也可预配在 profile 的本包配置行);都不配则状态为未认证。卸载:
33
33
 
34
34
  ```sh
35
35
  dsh plugin --profile web remove @khorsheed/dsh-local-agent-kimi
36
36
  ```
37
37
 
38
- 作用域目录会被刻意保留,重装后无需重新登录——删除 `$DSH_HOME/local-agent/kimi` 即可清除全部痕迹。
38
+ 作用域目录会被刻意保留,重装后凭据仍在——删除 `$DSH_HOME/local-agent/kimi` 即可清除全部痕迹。
39
39
 
40
40
  ## 配置
41
41
 
@@ -48,7 +48,7 @@ base_url = "https://your-router.example/v1"
48
48
 
49
49
  **只改写这一个键**——预置逻辑从不覆盖已存在的 config,且 `[services.moonshot_*]` 的 base_url 必须保留(它们路由内置的搜索/抓取工具)。
50
50
 
51
- ⚠️ **OAuth token 暴露**:作用域登录的 OAuth token 会发送给处理请求的端点——`base_url` 只指向你控制或信任的端点。
51
+ ⚠️ **凭据暴露**:端点 key 会发送给处理请求的端点——`baseUrl` 只指向你控制或信任的端点。
52
52
 
53
53
  插件自身配置(可选,写在 profile patch 层):
54
54
 
@@ -78,9 +78,9 @@ base_url = "https://your-router.example/v1"
78
78
 
79
79
  也就是说:一次性驱动不碰你的 `config.toml`,常驻驱动会改写其中的 `default_model` 一行。
80
80
 
81
- 设置卡「默认模型」修改后续轮次使用的 provider 配置。共享选择器展示当前作用域的模型目录、发现来源和完整性,并保留按需填写模型 ID 的入口。清空选择后跟随有效配置及默认值链。保存不会打断当前轮次,也无需重载;共享选择器不可用时,卡片保留文本输入兜底。成员级模型和推理强度修改使用下文的持久控制面。
81
+ 设置卡「可用模型」区维护一份**有序模型短名单**:点「添加模型」从端点当前供应的目录里勾选加入,列表里只会有端点真实供应的模型;拖动行调整顺序。**第一个模型就是默认模型**——每轮委派以它起 CLI(一次性 argv 旗标,常驻模式起进程前改写作用域 `default_model`),优先级只低于成员会话级覆盖与委派级指定。列表保存在作用域目录的 `models.json`(每个命名 scope 可各有一份,与端点凭据同一套文件机制),编辑即保存,下一轮委派生效。**留空 = 回退旧链**(`model` 键 → 作用域 `config.toml` 的顶层 `default_model` → CLI 内置)。kimi 的 `-m` 按作用域 config 的 `[models."…"]` 表解析(kimi-cli 2.1.1 实测:裸端点 id 没有表不能跑),所以加入一个还没有表的端点 id 时,同一次写入会按 managed 形状补上它的表(端点上报的显示名/推理档位/上下文窗口随行)。成员级模型和推理强度修改使用下文的持久控制面。
82
82
 
83
- 丰富目录优先使用常驻成员提供的 ACP 原生模型和配置元数据,保留显示名及当前模型的推理选项。此前显示该成员 scoped 配置候选,并明确标为配置来源、不完整。查询不创建临时 ACP 会话。目录刷新与订阅共用 core 缓存,共用模型菜单和成员 effort 控制已接入。运行中选择排到下一完整轮次(含工具续跑);core 统一持有当前/待生效配置、撤销与重试,冻结评测成员禁止变更。
83
+ 目录词汇来自端点本身(`GET <baseUrl>/v1/models`),作用域 config 的模型表只做元数据补全:端点供应的 id 命中某张 managed 表的 `model` 时,候选值取**表键**(`-m` 真正可运行的名字),显示名与推理档位端点优先、表兜底。常驻成员的 ACP 原生 configOptions 仍是该成员的权威目录(保留显示名及当前模型的推理选项)。端点无凭据、拒绝凭据、不应答或答非 `/models` 形态时,目录带原因空载;传输故障保留最后一次成功快照并按缓存节奏重试。查询不创建临时 ACP 会话。目录刷新与订阅共用 core 缓存,共用模型菜单和成员 effort 控制已接入。运行中选择排到下一完整轮次(含工具续跑);core 统一持有当前/待生效配置、撤销与重试,冻结评测成员禁止变更。
84
84
 
85
85
  **委派级的模型优先。** 编排器可以经门面 `DelegationCallOptions.model` 给**某一次委派**点名模型,它排在这个键之前(顺序见家族核心 README)。首轮请求的值记进委派记录,resume 轮照它重发——resume 不接受 model 参数。常驻模式下它成为该成员的**起始模型**:起进程前改写作用域 `default_model` 绑定;已有常驻 runtime 绑着别的模型时先退役,以新模型重起并 `session/load` 续上同一个 CLI 会话。
86
86
 
@@ -88,16 +88,16 @@ base_url = "https://your-router.example/v1"
88
88
 
89
89
  **这不是评测的缺口。** 评测 run 的条件在建立时冻结:run 跑到一半改这个键,下一轮的模型回读会发现声明模型 ≠ 实测模型,run 直接判为 misattributed 而失败(冻结决策 5)。
90
90
 
91
- **评测快照(effectiveSettings)。** 本 harness 向注册表声明一份实时读取的公平性设置快照,供评测条件哈希使用:drive(exec/live,随 live 偏好)、推理强度(读作用域 config 的 `[thinking] effort`,缺则回模型 `default_effort`)、是否自动批准(作用域 config 是否带 `Bash(*)` 放行规则)、端点是否固定(只报主机名;managed 端点不算固定)、已配置模型(先看插件配置的 `model` 键——它每轮覆盖;没有才读作用域 config 的顶层 `default_model`;都没有就不给字段)、CLI 版本(`kimi --version`,按可执行文件路径+mtime 缓存;探测不到即字段缺位)。`/kimi status` 与 `LocalAgentStatus` Remote 附带同一份快照。web-eval 冻结决策 2 到 4 的显式化即由此读取。
91
+ **评测快照(effectiveSettings)。** 本 harness 向注册表声明一份实时读取的公平性设置快照,供评测条件哈希使用:drive(exec/live,随 live 偏好)、推理强度(读作用域 config 的 `[thinking] effort`,缺则回模型 `default_effort`)、是否自动批准(作用域 config 是否带 `Bash(*)` 放行规则)、端点是否固定(只报主机名;managed 端点不算固定)、已配置模型(先看作用域 `models.json` 的首项,没有才看插件配置的 `model` 键——它每轮覆盖;再没有才读作用域 config 的顶层 `default_model`;都没有就不给字段)、CLI 版本(`kimi --version`,按可执行文件路径+mtime 缓存;探测不到即字段缺位)。`/kimi status` 与 `LocalAgentStatus` Remote 附带同一份快照。web-eval 冻结决策 2 到 4 的显式化即由此读取。
92
92
 
93
93
  ## Compatibility
94
94
 
95
- - npm 发布线(`@deepseek-ai/dsh@0.1.5-rc.1`):✅ 公开 API 兼容——生成中的内容走 local-agent 瞬时 Remote 与公开 Conversation 节点;后缀检查点负责恢复,最终原生消息保留转写与用量语义。minHost 为 0.1.5-rc.1,更旧宿主请停留在旧发布线。0.1.5 退役了 per-chunk 会话事件:token 粒度的增量不再落进子会话日志——改走 run-progress 通道,轮次 settle 为一条合并的 assistant/message(最终文本一致);晚到的 usage 若其载体消息已经镜像,则带一条 warn 丢弃(宿主没有 usage 回填事件可挂)。
96
- - 源码线(deepseek-harness master):✅(verifiedHost: 0.1.5-rc.1)——`thinkingEffort` 配置项(默认 high、仅预置期生效)与 `effectiveSettings` 评测快照均为插件级实现:只读写作用域文件,在两条宿主线上都不依赖宿主 API。
95
+ - npm 发布线(`@deepseek-ai/dsh@0.1.5-rc.1`):✅ 公开 API 兼容——生成中的内容走 local-agent 瞬时 Remote 与公开 Conversation 节点;后缀检查点负责恢复,最终原生消息保留转写与用量语义。minHost 为 0.1.5-rc.1,更旧宿主请停留在旧发布线。0.1.5 退役了 per-chunk 会话事件:token 粒度的增量不再落进子会话日志——改走 run-progress 通道,轮次 settle 为一条合并的 assistant/message(最终文本一致);晚到的 usage 若其载体消息已经镜像,则带一条 warn 丢弃(宿主没有 usage 回填事件可挂)。设置卡渲染为 core「本机 Agent 委派」家族卡的一节(Plugins 页 core 的 `plugins.item` 条目,0.1.7-alpha.1+;旧版 core 上回落为本包自己的 `plugins.item` 卡),`configForms.whileServed` 随宿主服务的 `local-agent-kimi` 命名空间挂载;0.1.5 线不再呈现卡片(宿主删除了 `settings.plugin.item` 席位),其余表面不变。
96
+ - 源码线(deepseek-harness master):✅(verifiedHost: 0.2.1-rc.1)——host-021 波对 0.2.1-rc.1 树全量 build+test 绿;委派迁移到 `ctx.subagents.startActivation`(受管 activation),run.id 改为每次执行唯一。`thinkingEffort` 配置项(默认 high、仅预置期生效)与 `effectiveSettings` 评测快照均为插件级实现:只读写作用域文件,在两条宿主线上都不依赖宿主 API。
97
97
 
98
98
  ## 已知限制
99
99
 
100
- - **登录需要一次交互**——仅 device-code,每个 harness 同一时间只允许一次登录,没有 API key 路径。
100
+ - **没有网页登录**——认证只有端点凭据一条路(设置卡/profile 行,kimi-for-coding 平台 key 或中转 key 均可);kimi 会员的 OAuth 路径不在本包。
101
101
  - **进程簿记会写真实 home**——无论 `KIMI_CODE_HOME` 如何,kimi 都会写入无实质内容的 `~/.kimi-code/server/instances/*.json`;config、凭据、会话仍在作用域内。
102
102
  - **`/kimi` 命令需要 Web 会话**——headless profile 仍可通过挂载工具行的组合进行委派。
103
103
 
@@ -106,15 +106,15 @@ base_url = "https://your-router.example/v1"
106
106
  <details>
107
107
  <summary>内部结构(点击展开)</summary>
108
108
 
109
- **作用域目录与登录。** 本包启动的每个 Kimi 进程都以 `KIMI_CODE_HOME=$DSH_HOME/local-agent/kimi` 运行。登录只走 device-code:`/kimi login` 把授权 URL 和验证码呈现在会话中,CLI 在后台轮询,凭据写入作用域目录。`/kimi logout` 删除作用域内的凭据与 OAuth 缓存(kimi CLI 没有 logout 命令)。首次启动时作用域目录会被预置一份 `config.toml`——把用户自己的 config 中所有 `api_key` 抹空后复制,用户没有 config 时则写入最小 managed config——因为没有 provider 与 model 定义 CLI 就拒绝认证;已存在的 config 永不覆盖。
109
+ **作用域目录与凭据。** 本包启动的每个 Kimi 进程都以 `KIMI_CODE_HOME=$DSH_HOME/local-agent/kimi` 运行。认证是端点凭据制:scope 的 `endpoint-auth.json`(0600)按字段覆盖 profile 配置行的 `baseUrl`/`apiKey`;managed provider(`managed:kimi-code`)在 config.toml 里声明的是 `api_key_env = "DSH_KIMI_ENDPOINT_KEY"`(kimi CLI 原生支持从指定环境变量读 key,与内联 `api_key` 互斥),key 只存在于 endpoint-auth.json 和子进程环境里,`config.toml` 永不携带秘密、可以安全进入评测条件哈希。设置卡「认证」区编辑的就是默认 scope 的 endpoint-auth.json(经家族 gateway 的 `endpointAuth`/`configureEndpoint` Remote);保存 baseUrl 时同一次写入会把 managed provider 的 `base_url` 重指过去(清空即回落到 kimi 官方服务),每轮 spawn 前还有一次幂等校准,手改文件同样即时生效。一次性 `kimi -p`、常驻 `kimi acp`、容器轮(`containerExecSpawn` 按名字转发环境变量)三条路共用同一套注入。首次启动时作用域目录会被预置一份 `config.toml`——把用户自己的 config 中所有 `api_key` 抹空后复制并迁移到 env-key 形态,用户没有 config 时则写入最小 managed config。OAuth 时代的 `credentials/` 与 `oauth/` 目录在每次 provision 时被清扫——本包不再读取它们,留着只会让一份失效授权在状态显示未认证时仍悄悄可用。`/kimi logout` 删除 scope 的 `endpoint-auth.json`;凭据完全来自 profile 配置行时 logout 拒绝并提示去改 profile。
110
110
 
111
- **挂载。** bundle patch 注册 `kimi` harness,并把 `subagent_kimi` 工具挂到 profile 根;`kimi-cli` 一次性 provider 在作用域目录下 spawn `kimi -p`。家族 core(`local-agent` 行,共享作用域目录根)随 `@khorsheed/dsh-local-agent` 自己的 patch 提供,本包把它声明为依赖。浏览器设置卡片由本包的 `./client` 半提供,复用家族 core 的共享构件(认证块、模型选择器):独立安装落在本包插件详情页,随家族 bundle 安装落在 bundle 详情的行级配置入口,0.1.5 宿主落在设置 → 插件 → 可配置插件。身份三角保持一致:`cordis.patch.yml` 的行 id、tsdown 的 `clientBundle('@khorsheed/dsh-local-agent-kimi')`、`src/invariant.ts` 的 `PACKAGE_NAME`;invariant 伴生插件还钉住一条契约——`kimi` harness 注册时作用域目录变量必须是 `KIMI_CODE_HOME`。
111
+ **挂载。** bundle patch 注册 `kimi` harness(恰好一行 provider 行);`subagent_kimi` 工具是本包的 `./tool` 组合入口(实现共享自家族核的 `./tool-factory` 导出),由点名它的 agent 预设按会话授予——dev 预设的 `tool-subagent-kimi` 行是授予点。`kimi-cli` 一次性 provider 在作用域目录下 spawn `kimi -p`。家族 core(`local-agent` 行,共享作用域目录根)随 `@khorsheed/dsh-local-agent` 自己的 patch 提供,本包把它声明为依赖。浏览器设置卡片由本包的 `./client` 半提供,复用家族 core 的共享构件(认证块、模型选择器):渲染为 core「本机 Agent 委派」家族卡的一节,宿主服务 `local-agent-kimi` 命名空间时经 `configForms.whileServed` 挂载——独立安装、家族 bundle、模式包都是同一节(旧版 core 上回落为本包自己的 `plugins.item` 卡)。身份三角保持一致:`cordis.patch.yml` 的行 id、package.json 的 name、tsdown 的 `clientBundle('@khorsheed/dsh-local-agent-kimi')`。
112
112
 
113
113
  **会话记录与转写。** `/kimi sessions` 列出作用域目录下的 `session_index.jsonl`——本 harness 的委派,绝不是用户的私人会话。`/kimi session <id>` 读取该会话的 `wire.jsonl` 渲染成可读转写:用户提示、思考与助手回复逐行标注 wire 轮次号(1 起,与子会话 `turn/start` 编号一致),工具调用带参数渲染、结果按调用配对(文件编辑类调用渲染成 patch 形态,不认识的内容类型保留可见标记),kimi 自动权限模式的 `<system-reminder>` 消息被过滤。设置卡片呈现认证状态与收窄到当前工作区的作用域会话;登录进行中时状态会持续重新探测,直到凭据落地。
114
114
 
115
115
  **模型回读与 cwd 覆盖。** 每轮 settle 后,provider 把 wire.jsonl 里 `usage.record`(次选 `llm.request`)事件 `model` 字段的实际模型(最后一个为准——resume 会话后续轮次追加在文件尾部)随 `settled` 进度事件上报,并合并进 `delegations.jsonl` 的 `observedModel` 字段;取不到即缺位,绝不猜测。编排器还可以经门面 `DelegationCallOptions.cwd` 给本轮指定工作目录(记录进 `cwd` 字段);resume 轮解析出的目录若与首轮记录不一致,进程启动前即 fail loud——CLI 会话延续的是首轮所在目录的上下文。
116
116
 
117
- **Model broker。** 本 harness 向注册表声明 `modelBroker`:设置卡读无成员的 `modelInfo`(生效层 + 候选),成员 composer 经 gateway 读写成员级 override。解析顺序固定:override → 委派记录模型 → 插件 `model` 键 → 作用域 `default_model` → CLI 内置默认(不指名任何模型)。候选 = 本键 + 作用域默认 + config 的 `[models."…"]` 表 + 最近存值,去重。override 与起始模型账本都在内存(重启即清);`setMemberModel` 在成员有进行中轮次时抛错,否则在常驻 runtime 绑定模型 ≠ 新生效值时将其退役(同模型是 no-op),下一轮懒重起。
117
+ **Model broker。** 本 harness 向注册表声明 `modelBroker`:设置卡读无成员的 `modelInfo`(生效层 + 候选),成员 composer 经 gateway 读写成员级 override。解析顺序固定:override → 委派记录模型 → 作用域 `models.json` 首项 → 插件 `model` 键 → 作用域 `default_model` → CLI 内置默认(不指名任何模型)。候选:作用域 `models.json` 非空时它就是**全部**词汇(端点目录外的一个也不混入);为空时回退旧链 = 本键 + 作用域默认 + config 的 `[models."…"]` 表 + 最近存值,去重。override 与起始模型账本都在内存(重启即清);`setMemberModel` 在成员有进行中轮次时抛错,否则在常驻 runtime 绑定模型 ≠ 新生效值时将其退役(同模型是 no-op),下一轮懒重起。
118
118
 
119
119
  **工具调用计数。** 每轮 settle 时,provider 顺带数出本轮的工具调用,随 `settled` 进度事件上报(`toolCalls: { count, byName }`)。数的是 transcript 里**本轮 turn** 的 `tool.call` 行——刻意不按镜像窗口数:常驻模式下 settle 那一遍的 delta 可能已被 live 轮询清空,而 resume 轮也不该把前几轮的调用算进来。`byName` 的键是 wire 给出的工具名,原样保留。本轮一份,绝不累计;一次都没调用就整个字段缺位(缺席 ≠ 0)。
120
120
 
@@ -122,7 +122,7 @@ base_url = "https://your-router.example/v1"
122
122
 
123
123
  **隔离与记账。** 子会话是委派会话工作区内一个全新会话;父级只收到最终回答或精确错误——子会话的上下文、评论、工具活动与 diff 永不跨入父级会话。provider 在 spawn 时开 `turn/start`、settle 时关 `turn/end`,失败或被中止也会关(reason `error`/`aborted`),因此耗时等于真实 CLI 运行时长。每个镜像 step(assistant 消息、工具调用/结果)都包在同 (turn, step) 的 `step/start`–`step/end` 边界对里——宿主会话的实时装配只在边界上登记 step,缺了边界 assistant 消息在实时视图里不渲染(整页刷新重建时才补回);token 粒度的流式快照与收尾折叠也在 `turn/end` 之前落地并带边界。用量是该轮 delta 内所有 `usage.record` 之和(每条是一次 LLM 请求的口径、非累计),挂在当轮最后一条镜像的 assistant 消息上;镜像过滤 kimi 自动权限模式的 `<system-reminder>` 消息、工具调用带参数渲染、结果按调用配对,并增量推进,早期消息绝不重复。中止会让工具结果立即 settle(SIGTERM→grace→SIGKILL),并保留已镜像的部分成果。
124
124
 
125
- **命名 scope。** `/kimi login --scope <名>` 在 `<homesRoot>/kimi@<名>` 里另开一份 `KIMI_CODE_HOME`:目录建立时跑同一份 provision(provider/model 配置,然后是权限规则——顺序不能反,权限写入要读配置文件),之后该 scope 各自登录、各自 wire 日志、各自转写镜像。带 scope 的委派只走 exec(常驻 `kimi acp` 按成员绑缺省目录),且**不带成员通道**:成员桥声明写在作用域目录的 `mcp.json` 里、socket 又是 homes 根级单例,与其半接上不如这一轮明确不要。
125
+ **命名 scope。** `/kimi login --scope <名>` 在 `<homesRoot>/kimi@<名>` 里另开一份 `KIMI_CODE_HOME`:目录建立时跑同一份 provision(provider/model 配置,然后是权限规则——顺序不能反,权限写入要读配置文件),之后该 scope 各自的 endpoint-auth.json、各自 wire 日志、各自转写镜像。带 scope 的委派只走 exec(常驻 `kimi acp` 按成员绑缺省目录),且**不带成员通道**:成员桥声明写在作用域目录的 `mcp.json` 里、socket 又是 homes 根级单例,与其半接上不如这一轮明确不要。
126
126
 
127
127
  **容器内委派。** 编排器可以经门面 `DelegationCallOptions.exec`(`{ container, workdir, env? }`)让本轮跑在一个**已取得的容器**里:argv 变成 `docker exec -w <workdir> [-e NAME…] <container> kimi -p …`,其余(wire.jsonl 镜像与回读、settle、记录)逐字节不变。`env` 必须给出容器内的 `KIMI_CODE_HOME`,且它应当是宿主作用域目录的 rw bind 挂载点——转写镜像与模型回读读的是宿主那份 wire 日志。容器轮固定走 exec 一次性驱动(常驻 `kimi acp` 是宿主进程),且**不写** `mcp.json` 的成员桥条目:那条声明带着宿主 node 路径,容器里起不来,与其在共享配置文件里留一个坏 server,不如这一轮不要成员通道。
128
128
 
package/cordis.patch.yml CHANGED
@@ -1,34 +1,24 @@
1
- # The dsh-local-agent-kimi bundle patch: register the Kimi harness and mount
2
- # its delegation tool. The family core row (`local-agent`, shared scoped-homes
3
- # root) lives in the framework bundle @khorsheed/dsh-local-agent's own patch.
4
- # This bundle declares that package as an npm dependency, which makes the
5
- # core's module resolvable — it does NOT mount the core row: `dsh plugin add`
6
- # reconciles only the profile's direct dependencies, so the core must be
7
- # installed explicitly alongside this bundle, or this provider stays pending.
8
- # No other patch inserts the core row id.
1
+ # The dsh-local-agent-kimi bundle patch: register the Kimi harness. The family
2
+ # core row (`local-agent`, shared scoped-homes root) lives in the framework
3
+ # bundle @khorsheed/dsh-local-agent's own patch. This bundle declares that
4
+ # package as an npm dependency, which makes the core's module resolvable — it
5
+ # does NOT mount the core row: `dsh plugin add` reconciles only the profile's
6
+ # direct dependencies, so the core must be installed explicitly alongside this
7
+ # bundle, or this provider stays pending. No other patch inserts the core row
8
+ # id.
9
9
  #
10
- # Two rows are inserted:
11
- # - local-agent-kimi: this bundle's plugin registers the `kimi` harness
12
- # (KIMI_CODE_HOME, `kimi login`, session_index records).
13
- # - tool-subagent-kimi: the family-owned delegation tool (schema
14
- # description/prompt plus optional resume) over the `kimi-cli` provider.
15
- # The toolName stays `subagent_kimi` — the same model-facing name the
16
- # official tool-subagent row used — so presets and prompts keep working,
17
- # while the family tool adds continuation: a later round may pass the dsh
18
- # child session id returned by the first delegation to continue the same
19
- # kimi conversation.
10
+ # Exactly ONE row is inserted: the provider (this bundle's plugin registers the
11
+ # `kimi` harness — KIMI_CODE_HOME, `kimi login`, session_index records). The
12
+ # `subagent_kimi` delegation tool is no longer a profile-root row: since the
13
+ # family fold it ships as this package's `./tool` composition entry
14
+ # (`name: '@khorsheed/dsh-local-agent-kimi/tool'` in an agent preset), granted
15
+ # per session — the dev preset's `tool-subagent-kimi` row is the grant point.
16
+ # The model-facing toolName stays `subagent_kimi` and the tool keeps its
17
+ # continuation parameter: a later round may pass the dsh child session id
18
+ # returned by the first delegation to continue the same kimi conversation.
20
19
  #
21
- # The subagent_kimi tool row mounts at the profile root, so every agent
22
- # preset (standard/code/minimal/cordis and future ones) can delegate without
23
- # per-preset variants. The provider starts no Kimi process until a tool call
24
- # or /kimi login.
20
+ # The provider starts no Kimi process until a tool call or /kimi login.
25
21
 
26
22
  - insert:
27
23
  - id: local-agent-kimi
28
24
  name: '@khorsheed/dsh-local-agent-kimi'
29
-
30
- - id: tool-subagent-kimi
31
- name: '@khorsheed/dsh-local-agent-tool-subagent'
32
- config:
33
- provider: kimi-cli
34
- toolName: subagent_kimi