@khorsheed/dsh-local-agent-kimi 0.2.0 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -1,4 +1,13 @@
1
1
  # 变更记录
2
+ ## 0.2.1(2026-10-27)
3
+
4
+ - **修复几个模式套件一起装时设置存不上**:卡片上的开关和设置改存在本 harness 自己的目录里,不再写进配置文件;原来配好的值照常生效。
5
+ - **保存失败就说保存失败**:设置被拒时显示「保存失败」,不再假装「已保存」。
6
+ - **常驻模式(live)默认打开**:遇到问题可以在卡片上关掉,改回每次新起一个。
7
+ - **端点表单跟着登录、登出刷新**:登出后不再显示「API Key 已配置」,验证端点也不再报找不到凭据。
8
+ - **读不到登录状态时直说**:显示「读取登录状态失败」。
9
+ - **常驻轮次上报 token 用量**:协作间里 Kimi 成员的消息现在显示用了多少 token。
10
+
2
11
  ## 0.2.0(2026-10-26)
3
12
 
4
13
  rc.3 之后到正式版的变化:
package/README.en.md CHANGED
@@ -15,7 +15,7 @@ Getting Kimi Code to help used to mean opening a terminal, pasting things in, an
15
15
  - **Keep talking, no cold start**: not happy with the result? Have the agent follow up, or open the sub-session and message Kimi yourself; it's the same Kimi session.
16
16
  - **Paste a key and go**: enter the endpoint and API key on the settings card, press "Save credential", then "Verify endpoint & list models" to check it connects.
17
17
  - **Pick your models**: under "Available models", tick models the endpoint offers and drag to reorder; the top one is the default. You can also switch model and reasoning effort inside a sub-session.
18
- - **Resident mode is faster**: turn on "Resident mode (live)" and the Kimi process stays up, streaming output into the sub-session; stopping doesn't restart it.
18
+ - **Resident mode is faster**: "Resident mode (live)" is on by default and the Kimi process stays up, streaming output into the sub-session; stopping doesn't restart it.
19
19
  - **Look back at past hand-offs**: `/kimi sessions` lists the tasks you gave Kimi, and `/kimi session <id>` turns one into a readable record.
20
20
 
21
21
  ## Install
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: 8f0813f18bc811196a0eb15c90fa5b6660515a51
6
- packages/local-agent-kimi/README.md: 2257a947e66a8db09eea80bd83faa57ba335c709
5
+ packages/local-agent-kimi/README.en.md: 9bbf625595e4dd499f6cba80ee912e7b0638f12a
6
+ packages/local-agent-kimi/README.md: edc66bd1d1d0093f3d4b8c7c60e6b23e76030fb9
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  - **接着聊,不冷启动**:结果不满意就让 agent 追问,或者打开子会话直接给它发消息,继续的是同一个 Kimi 会话。
16
16
  - **填好 key 就能用**:在设置卡片里填端点地址和 API Key,点「保存凭据」,再点「验证端点并获取模型」确认能连上。
17
17
  - **自己挑模型**:在「可用模型」里从端点供应的模型中勾选、拖动排序,排第一的就是默认模型;子会话里也能临时换模型和推理强度。
18
- - **常驻模式更快**:打开「常驻模式(live)」,Kimi 进程常驻,输出实时流进子会话,停下也不用重开进程。
18
+ - **常驻模式更快**:「常驻模式(live)」默认开着,Kimi 进程常驻,输出实时流进子会话,停下也不用重开进程。
19
19
  - **翻看以前的委派**:`/kimi sessions` 列出交给 Kimi 的历史任务,`/kimi session <编号>` 把其中一次整理成可读的记录。
20
20
 
21
21
  ## 安装
package/lib/client.js CHANGED
@@ -93,6 +93,83 @@ window.__ModuleLoader__.load({
93
93
  });
94
94
  return channel;
95
95
  }
96
+ /**
97
+ * Bind a settings card to the harness's own card-settings store (card-settings.ts
98
+ * on the host) layered over the row's host settings form: reads are the
99
+ * form's value with the stored overrides on top; writes go to the store only,
100
+ * never the profile patch — so they cannot be refused when several suites
101
+ * insert the same row. A host without the store keeps the plain row scope.
102
+ * @param ctx - the provider's client context.
103
+ * @param harness - the harness name (`dsh`, `kimi`, …).
104
+ * @param entryId - the plugin row id the base values come from.
105
+ * @returns the bound scope.
106
+ */
107
+ function bindCardSettingsScope(ctx, harness, entryId) {
108
+ const row = bindSettingsScope(ctx, entryId);
109
+ const gateway = () => {
110
+ const remote = ctx.get("remote.localAgentGateway");
111
+ return typeof remote?.cardSettings === "function" && typeof remote.setCardSettings === "function" ? remote : void 0;
112
+ };
113
+ const listeners = /* @__PURE__ */ new Set();
114
+ let stored;
115
+ let cached;
116
+ const emit = () => {
117
+ for (const listener of [...listeners]) listener();
118
+ };
119
+ const load = () => {
120
+ gateway()?.cardSettings(harness).then((result) => {
121
+ if (!result.ok || result.value === void 0) return;
122
+ stored = result.value;
123
+ emit();
124
+ }).catch(() => {});
125
+ };
126
+ const write = async (patch) => {
127
+ const remote = gateway();
128
+ if (remote === void 0) return false;
129
+ try {
130
+ const result = await remote.setCardSettings(harness, patch);
131
+ if (!result.ok || result.value === void 0) return false;
132
+ stored = result.value;
133
+ emit();
134
+ return true;
135
+ } catch {
136
+ return false;
137
+ }
138
+ };
139
+ return {
140
+ getSnapshot: () => {
141
+ const rowSnapshot = row.getSnapshot();
142
+ if (cached !== void 0 && cached.rowSnapshot === rowSnapshot && cached.stored === stored) return cached.snapshot;
143
+ const overrides = stored ?? {};
144
+ const snapshot = gateway() === void 0 ? rowSnapshot : {
145
+ ...rowSnapshot,
146
+ value: rowSnapshot.value === void 0 && stored === void 0 ? void 0 : {
147
+ ...rowSnapshot.value,
148
+ ...overrides
149
+ },
150
+ writable: true,
151
+ status: rowSnapshot.status === "loading" && stored !== void 0 ? "ready" : rowSnapshot.status === "unavailable" && stored !== void 0 ? "ready" : rowSnapshot.status
152
+ };
153
+ cached = {
154
+ rowSnapshot,
155
+ stored,
156
+ snapshot
157
+ };
158
+ return snapshot;
159
+ },
160
+ subscribe: (listener) => {
161
+ if (listeners.size === 0) load();
162
+ listeners.add(listener);
163
+ const off = row.subscribe(listener);
164
+ return () => {
165
+ listeners.delete(listener);
166
+ off();
167
+ };
168
+ },
169
+ set: (field, value) => gateway() === void 0 ? row.set(field, value) : write({ [field]: value }),
170
+ unset: (field) => gateway() === void 0 ? row.unset(field) : write({ [field]: null })
171
+ };
172
+ }
96
173
  //#endregion
97
174
  //#region src/client/locales.ts
98
175
  /** `local-agent-kimi` namespace dictionaries. */
@@ -202,8 +279,13 @@ window.__ModuleLoader__.load({
202
279
  * re-probes so a mid-session credential loss cannot leave a stale green dot.
203
280
  * @module @khorsheed/dsh-local-agent/client — auth status bus
204
281
  */
205
- const statuses = /* @__PURE__ */ new Map();
206
- const listeners = /* @__PURE__ */ new Set();
282
+ const BUS_KEY = Symbol.for("dsh.local-agent.auth-status");
283
+ const bus = globalThis[BUS_KEY] ??= {
284
+ statuses: /* @__PURE__ */ new Map(),
285
+ listeners: /* @__PURE__ */ new Set()
286
+ };
287
+ const statuses = bus.statuses;
288
+ const listeners = bus.listeners;
207
289
  /** Record one harness's latest probe result and notify subscribers. */
208
290
  function publishAuthStatus(harnessId, status) {
209
291
  if (statuses.get(harnessId) === status) return;
@@ -261,30 +343,30 @@ window.__ModuleLoader__.load({
261
343
  document.head.appendChild(tag);
262
344
  }
263
345
  var ProviderAuthBlock_module_css_default = {
264
- "title": "On5p7W_title",
265
- "rowName": "On5p7W_rowName",
266
- "rowCard": "On5p7W_rowCard",
267
346
  "rowActions": "On5p7W_rowActions",
347
+ "loginPrompt": "On5p7W_loginPrompt",
348
+ "rowCard": "On5p7W_rowCard",
349
+ "openPage": "On5p7W_openPage",
350
+ "loginButton": "On5p7W_loginButton",
351
+ "section": "On5p7W_section",
352
+ "promptText": "On5p7W_promptText",
353
+ "codeInput": "On5p7W_codeInput",
268
354
  "retryButton": "On5p7W_retryButton",
269
- "credentialDot": "On5p7W_credentialDot",
270
- "rowTag": "On5p7W_rowTag",
355
+ "dotOn": "On5p7W_dotOn",
271
356
  "dotPending": "On5p7W_dotPending",
272
- "codeInput": "On5p7W_codeInput",
357
+ "dotOff": "On5p7W_dotOff",
273
358
  "rows": "On5p7W_rows",
274
- "promptText": "On5p7W_promptText",
275
359
  "rowHead": "On5p7W_rowHead",
276
- "section": "On5p7W_section",
277
360
  "status": "On5p7W_status",
278
- "rosterError": "On5p7W_rosterError",
279
361
  "intro": "On5p7W_intro",
280
- "rowIdentity": "On5p7W_rowIdentity",
281
- "dotOn": "On5p7W_dotOn",
282
- "loginButton": "On5p7W_loginButton",
362
+ "rowTag": "On5p7W_rowTag",
363
+ "title": "On5p7W_title",
283
364
  "logoutButton": "On5p7W_logoutButton",
284
- "loginPrompt": "On5p7W_loginPrompt",
285
- "openPage": "On5p7W_openPage",
286
- "dotOff": "On5p7W_dotOff",
287
- "rowPending": "On5p7W_rowPending"
365
+ "credentialDot": "On5p7W_credentialDot",
366
+ "rosterError": "On5p7W_rosterError",
367
+ "rowPending": "On5p7W_rowPending",
368
+ "rowIdentity": "On5p7W_rowIdentity",
369
+ "rowName": "On5p7W_rowName"
288
370
  };
289
371
  //#endregion
290
372
  //#region ../local-agent/src/client/ProviderAuthBlock.tsx
@@ -437,8 +519,8 @@ window.__ModuleLoader__.load({
437
519
  const statusKind = usePublishedAuthStatus(harness.id) ?? view.status;
438
520
  const authenticated = statusKind === "authenticated";
439
521
  const loginPending = pendingSince !== void 0;
440
- const loginable = view.loginable ?? true;
441
- const logoutable = view.logoutable ?? true;
522
+ const loginable = view.loginable ?? statusKind !== "unavailable";
523
+ const logoutable = view.logoutable ?? statusKind !== "unavailable";
442
524
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
443
525
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
444
526
  className: ProviderAuthBlock_module_css_default.rowHead,
@@ -471,7 +553,7 @@ window.__ModuleLoader__.load({
471
553
  statusKind === "checking" && t("loading"),
472
554
  statusKind === "authenticated" && t("settings.authenticated"),
473
555
  statusKind === "anonymous" && t("settings.notAuthenticated"),
474
- statusKind === "unavailable" && t("error")
556
+ statusKind === "unavailable" && t("settings.statusFailed")
475
557
  ]
476
558
  }),
477
559
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
@@ -564,8 +646,8 @@ window.__ModuleLoader__.load({
564
646
  }
565
647
  var AuthStatusDot_module_css_default = {
566
648
  "dotPending": "OFjNUG_dotPending",
567
- "credentialDot": "OFjNUG_credentialDot",
568
649
  "dotOff": "OFjNUG_dotOff",
650
+ "credentialDot": "OFjNUG_credentialDot",
569
651
  "dotOn": "OFjNUG_dotOn"
570
652
  };
571
653
  //#endregion
@@ -582,7 +664,7 @@ window.__ModuleLoader__.load({
582
664
  }
583
665
  //#endregion
584
666
  //#region \0dsh-css:../local-agent/src/client/ModelListSection.module.css.mjs
585
- const css$1 = "._4eeJ7W_block{flex-direction:column;gap:10px;display:flex}._4eeJ7W_blockTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;margin:0;font-size:13px;font-weight:500;line-height:1.4;display:flex}._4eeJ7W_info{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:help;background:0 0;border:0;border-radius:50%;padding:0 2px;font-size:12px;line-height:1}._4eeJ7W_row{align-items:center;gap:12px;display:flex}._4eeJ7W_saved{color:var(--dsw-alias-state-success-primary);font-size:12px}._4eeJ7W_errorText{color:var(--dsw-alias-state-error-primary);font-size:12px}._4eeJ7W_hint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}._4eeJ7W_modelInput{min-width:0;font:inherit;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:5px 8px;font-size:13px;line-height:1.4}._4eeJ7W_modelSave{appearance:none;font:inherit;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;flex:none;padding:5px 10px;font-size:13px;line-height:1.4}._4eeJ7W_modelList{flex-direction:column;gap:8px;display:flex}._4eeJ7W_modelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:grab;border-radius:8px;align-items:center;gap:8px;padding:6px 8px;display:flex}._4eeJ7W_modelRowDragging{opacity:.6;cursor:grabbing}._4eeJ7W_modelDrag{color:var(--dsw-alias-label-tertiary);cursor:grab;user-select:none}._4eeJ7W_modelRowValue{font-size:13px;font-family:var(--dsw-alias-font-mono,monospace);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._4eeJ7W_modelRowLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;max-width:40%;font-size:12px;overflow:hidden}._4eeJ7W_modelDefaultChip{color:var(--dsw-alias-success,#1a9e54);background:color-mix(in srgb, var(--dsw-alias-success,#1a9e54) 12%, transparent);border-radius:999px;padding:1px 8px;font-size:11px;line-height:1.4}._4eeJ7W_modelDelete{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:2px 4px;font-size:12px}._4eeJ7W_modelAdd{appearance:none;border:1px dashed var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 12px;font-size:13px}._4eeJ7W_dialogBackdrop{z-index:100;background:#00000052;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._4eeJ7W_dialog{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;flex-direction:column;gap:10px;width:min(520px,100vw - 48px);max-height:min(560px,100vh - 96px);padding:16px;display:flex;box-shadow:0 12px 40px #00000059}._4eeJ7W_dialogHead{justify-content:space-between;align-items:center;display:flex}._4eeJ7W_dialogTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600}._4eeJ7W_dialogClose{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:2px 4px;font-size:13px}._4eeJ7W_dialogHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}._4eeJ7W_dialogToolbar{align-items:center;gap:8px;display:flex}._4eeJ7W_dialogToolbar ._4eeJ7W_modelInput{flex:1}._4eeJ7W_dialogSelectAll{appearance:none;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;padding:4px 6px;font-size:13px}._4eeJ7W_dialogList{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;flex:1;gap:2px;min-height:120px;max-height:320px;padding:6px;display:flex;overflow-y:auto}._4eeJ7W_dialogItem{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:8px;padding:6px 8px;font-size:13px;display:flex}._4eeJ7W_dialogItemAdded{opacity:.55;cursor:default}._4eeJ7W_dialogItemValue{font-family:var(--dsw-alias-font-mono,monospace)}._4eeJ7W_dialogItemLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._4eeJ7W_dialogActions{justify-content:flex-end;gap:8px;display:flex}._4eeJ7W_dialogConfirm{appearance:none;color:var(--dsw-alias-text-on-brand,#fff);background:var(--dsw-alias-brand-primary);cursor:pointer;border:0;border-radius:8px;padding:6px 14px;font-size:13px}";
667
+ const css$1 = "._4eeJ7W_block{flex-direction:column;gap:10px;display:flex}._4eeJ7W_blockTitle{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;margin:0;font-size:13px;font-weight:500;line-height:1.4;display:flex}._4eeJ7W_info{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:help;background:0 0;border:0;border-radius:50%;padding:0 2px;font-size:12px;line-height:1}._4eeJ7W_row{align-items:center;gap:12px;display:flex}._4eeJ7W_saved{color:var(--dsw-alias-state-success-primary);font-size:12px}._4eeJ7W_errorText{color:var(--dsw-alias-state-error-primary);font-size:12px}._4eeJ7W_hint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}._4eeJ7W_modelInput{min-width:0;font:inherit;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:8px;flex:1;padding:5px 8px;font-size:13px;line-height:1.4}._4eeJ7W_modelSave{appearance:none;font:inherit;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:8px;flex:none;padding:5px 10px;font-size:13px;line-height:1.4}._4eeJ7W_modelList{flex-direction:column;gap:8px;display:flex}._4eeJ7W_modelRow{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);cursor:grab;border-radius:8px;align-items:center;gap:8px;padding:6px 8px;display:flex}._4eeJ7W_modelRowDragging{opacity:.6;cursor:grabbing}._4eeJ7W_modelDrag{color:var(--dsw-alias-label-tertiary);cursor:grab;user-select:none}._4eeJ7W_modelRowValue{font-size:13px;font-family:var(--dsw-alias-font-mono,monospace);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}._4eeJ7W_modelRowLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;max-width:40%;font-size:12px;overflow:hidden}._4eeJ7W_modelDefaultChip{color:var(--dsw-alias-success,#1a9e54);background:color-mix(in srgb, var(--dsw-alias-success,#1a9e54) 12%, transparent);border-radius:999px;padding:1px 8px;font-size:11px;line-height:1.4}._4eeJ7W_modelDelete{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:2px 4px;font-size:12px}._4eeJ7W_modelAdd{appearance:none;border:1px dashed var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border-radius:8px;padding:5px 12px;font-size:13px}._4eeJ7W_dialogBackdrop{z-index:100;background:#00000052;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}._4eeJ7W_dialog{background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);border-radius:12px;flex-direction:column;gap:10px;width:min(520px,100vw - 48px);max-height:min(560px,100vh - 96px);padding:16px;display:flex;box-shadow:0 12px 40px #00000059}._4eeJ7W_dialogHead{justify-content:space-between;align-items:center;display:flex}._4eeJ7W_dialogTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:600}._4eeJ7W_dialogClose{appearance:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:2px 4px;font-size:13px}._4eeJ7W_dialogHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px}._4eeJ7W_dialogToolbar{align-items:center;gap:8px;display:flex}._4eeJ7W_dialogToolbar ._4eeJ7W_modelInput{flex:1}._4eeJ7W_dialogSelectAll{appearance:none;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;padding:4px 6px;font-size:13px}._4eeJ7W_dialogList{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;flex:1;gap:2px;min-height:120px;max-height:320px;padding:6px;display:flex;overflow-y:auto}._4eeJ7W_dialogItem{color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:8px;padding:6px 8px;font-size:13px;display:flex}._4eeJ7W_dialogItemAdded{opacity:.55;cursor:default}._4eeJ7W_dialogItemValue{font-family:var(--dsw-alias-font-mono,monospace)}._4eeJ7W_dialogItemLabel{color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}._4eeJ7W_dialogActions{justify-content:flex-end;gap:8px;display:flex}._4eeJ7W_dialogConfirm{appearance:none;color:var(--dsw-alias-label-primary-foreground,#fff);background:var(--dsw-alias-button-primary-fill,#1f2329);cursor:pointer;border:0;border-radius:8px;padding:6px 14px;font-size:13px}._4eeJ7W_dialogConfirm:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-button-primary-fill,#1f2329))}._4eeJ7W_dialogConfirm:disabled{opacity:.4;cursor:default}";
586
668
  const tagId$1 = "@khorsheed/dsh-local-agent-kimi/ModelListSection.module.css";
587
669
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
588
670
  const tag = document.createElement("style");
@@ -592,39 +674,39 @@ window.__ModuleLoader__.load({
592
674
  document.head.appendChild(tag);
593
675
  }
594
676
  var ModelListSection_module_css_default = {
595
- "dialogConfirm": "_4eeJ7W_dialogConfirm",
596
- "modelDelete": "_4eeJ7W_modelDelete",
597
- "dialogItemLabel": "_4eeJ7W_dialogItemLabel",
598
- "modelDrag": "_4eeJ7W_modelDrag",
677
+ "saved": "_4eeJ7W_saved",
678
+ "row": "_4eeJ7W_row",
679
+ "modelRowDragging": "_4eeJ7W_modelRowDragging",
680
+ "dialogItem": "_4eeJ7W_dialogItem",
681
+ "errorText": "_4eeJ7W_errorText",
682
+ "modelInput": "_4eeJ7W_modelInput",
683
+ "dialogHead": "_4eeJ7W_dialogHead",
684
+ "dialogTitle": "_4eeJ7W_dialogTitle",
599
685
  "modelRowValue": "_4eeJ7W_modelRowValue",
600
- "modelRow": "_4eeJ7W_modelRow",
686
+ "dialogClose": "_4eeJ7W_dialogClose",
601
687
  "dialogItemAdded": "_4eeJ7W_dialogItemAdded",
602
688
  "modelSave": "_4eeJ7W_modelSave",
603
- "modelInput": "_4eeJ7W_modelInput",
689
+ "modelDelete": "_4eeJ7W_modelDelete",
690
+ "dialog": "_4eeJ7W_dialog",
604
691
  "blockTitle": "_4eeJ7W_blockTitle",
605
- "row": "_4eeJ7W_row",
692
+ "dialogConfirm": "_4eeJ7W_dialogConfirm",
693
+ "modelRow": "_4eeJ7W_modelRow",
606
694
  "block": "_4eeJ7W_block",
607
- "saved": "_4eeJ7W_saved",
608
- "dialog": "_4eeJ7W_dialog",
695
+ "modelDrag": "_4eeJ7W_modelDrag",
696
+ "dialogHint": "_4eeJ7W_dialogHint",
697
+ "dialogToolbar": "_4eeJ7W_dialogToolbar",
698
+ "dialogSelectAll": "_4eeJ7W_dialogSelectAll",
699
+ "dialogActions": "_4eeJ7W_dialogActions",
609
700
  "hint": "_4eeJ7W_hint",
610
- "dialogItem": "_4eeJ7W_dialogItem",
611
- "info": "_4eeJ7W_info",
612
- "dialogBackdrop": "_4eeJ7W_dialogBackdrop",
701
+ "modelAdd": "_4eeJ7W_modelAdd",
613
702
  "dialogItemValue": "_4eeJ7W_dialogItemValue",
614
- "dialogHint": "_4eeJ7W_dialogHint",
615
- "dialogHead": "_4eeJ7W_dialogHead",
703
+ "dialogBackdrop": "_4eeJ7W_dialogBackdrop",
616
704
  "dialogList": "_4eeJ7W_dialogList",
617
- "dialogToolbar": "_4eeJ7W_dialogToolbar",
618
- "errorText": "_4eeJ7W_errorText",
619
- "modelDefaultChip": "_4eeJ7W_modelDefaultChip",
620
- "modelRowDragging": "_4eeJ7W_modelRowDragging",
705
+ "dialogItemLabel": "_4eeJ7W_dialogItemLabel",
706
+ "info": "_4eeJ7W_info",
621
707
  "modelList": "_4eeJ7W_modelList",
622
708
  "modelRowLabel": "_4eeJ7W_modelRowLabel",
623
- "modelAdd": "_4eeJ7W_modelAdd",
624
- "dialogTitle": "_4eeJ7W_dialogTitle",
625
- "dialogActions": "_4eeJ7W_dialogActions",
626
- "dialogSelectAll": "_4eeJ7W_dialogSelectAll",
627
- "dialogClose": "_4eeJ7W_dialogClose"
709
+ "modelDefaultChip": "_4eeJ7W_modelDefaultChip"
628
710
  };
629
711
  //#endregion
630
712
  //#region ../local-agent/src/client/ModelListSection.tsx
@@ -996,33 +1078,33 @@ window.__ModuleLoader__.load({
996
1078
  document.head.appendChild(tag);
997
1079
  }
998
1080
  var SettingsCard_module_css_default = {
999
- "blockTitle": "apHkUa_blockTitle",
1000
- "chevronOpen": "apHkUa_chevronOpen",
1001
- "rowLabel": "apHkUa_rowLabel",
1002
- "switch": "apHkUa_switch",
1003
- "knob": "apHkUa_knob",
1004
- "saved": "apHkUa_saved",
1005
1081
  "info": "apHkUa_info",
1006
- "modelSave": "apHkUa_modelSave",
1082
+ "card": "apHkUa_card",
1083
+ "header": "apHkUa_header",
1084
+ "headText": "apHkUa_headText",
1085
+ "chevron": "apHkUa_chevron",
1086
+ "blockTitle": "apHkUa_blockTitle",
1087
+ "description": "apHkUa_description",
1088
+ "endpointField": "apHkUa_endpointField",
1007
1089
  "switchOn": "apHkUa_switchOn",
1008
1090
  "errorText": "apHkUa_errorText",
1009
- "body": "apHkUa_body",
1010
1091
  "configuredChip": "apHkUa_configuredChip",
1011
- "modelInput": "apHkUa_modelInput",
1012
- "chevron": "apHkUa_chevron",
1013
- "block": "apHkUa_block",
1014
1092
  "hint": "apHkUa_hint",
1015
- "endpointLabel": "apHkUa_endpointLabel",
1016
1093
  "nameRow": "apHkUa_nameRow",
1017
- "headText": "apHkUa_headText",
1018
- "card": "apHkUa_card",
1019
- "endpointField": "apHkUa_endpointField",
1020
1094
  "row": "apHkUa_row",
1095
+ "body": "apHkUa_body",
1021
1096
  "endpointFields": "apHkUa_endpointFields",
1022
- "description": "apHkUa_description",
1097
+ "endpointLabel": "apHkUa_endpointLabel",
1098
+ "chevronOpen": "apHkUa_chevronOpen",
1099
+ "saved": "apHkUa_saved",
1100
+ "knob": "apHkUa_knob",
1101
+ "modelSave": "apHkUa_modelSave",
1102
+ "modelInput": "apHkUa_modelInput",
1103
+ "block": "apHkUa_block",
1023
1104
  "cardOpen": "apHkUa_cardOpen",
1024
1105
  "name": "apHkUa_name",
1025
- "header": "apHkUa_header"
1106
+ "rowLabel": "apHkUa_rowLabel",
1107
+ "switch": "apHkUa_switch"
1026
1108
  };
1027
1109
  //#endregion
1028
1110
  //#region src/client/SettingsCard.tsx
@@ -1053,6 +1135,7 @@ window.__ModuleLoader__.load({
1053
1135
  const endpointUnavailable = endpointAuth === void 0 || endpointState === "unavailable";
1054
1136
  const endpointLoading = !endpointUnavailable && endpointState === null;
1055
1137
  const apiKeyConfigured = endpointState !== null && endpointState !== "unavailable" && endpointState.apiKeySet;
1138
+ const authPublished = usePublishedAuthStatus("kimi");
1056
1139
  (0, react.useEffect)(() => {
1057
1140
  if (!active || endpointAuth === void 0) return;
1058
1141
  let stale = false;
@@ -1067,7 +1150,8 @@ window.__ModuleLoader__.load({
1067
1150
  }, [
1068
1151
  active,
1069
1152
  endpointAuth,
1070
- endpointSaved
1153
+ endpointSaved,
1154
+ authPublished
1071
1155
  ]);
1072
1156
  const saveEndpoint = () => {
1073
1157
  if (endpointAuth === void 0) return;
@@ -1092,8 +1176,9 @@ window.__ModuleLoader__.load({
1092
1176
  const write = (field, value) => {
1093
1177
  setSaved(false);
1094
1178
  setError(false);
1095
- scope.set(field, value).then(() => {
1096
- setSaved(true);
1179
+ scope.set(field, value).then((accepted) => {
1180
+ if (accepted === false) setError(true);
1181
+ else setSaved(true);
1097
1182
  }, () => {
1098
1183
  setError(true);
1099
1184
  });
@@ -1461,7 +1546,7 @@ window.__ModuleLoader__.load({
1461
1546
  en
1462
1547
  }), "local-agent-kimi: dictionaries");
1463
1548
  const t = ctx.locale.bind(NS);
1464
- const scope = bindSettingsScope(ctx, "local-agent-kimi");
1549
+ const scope = bindCardSettingsScope(ctx, "kimi", "local-agent-kimi");
1465
1550
  const authT = ctx.locale.bind("local-agent");
1466
1551
  const gateway = () => ctx.get("remote.localAgentGateway");
1467
1552
  const cardFace = () => ({
package/lib/index.js CHANGED
@@ -4089,7 +4089,16 @@ var KimiAcpLiveDriver = class {
4089
4089
  });
4090
4090
  result.then(() => {
4091
4091
  if (turnOpened) {
4092
- const round = { ...roundModel === void 0 ? {} : { observedModel: roundModel } };
4092
+ let usage;
4093
+ for (const event of childSession.snapshotEvents()) {
4094
+ if (event.type !== "assistant/message") continue;
4095
+ const data = event.data;
4096
+ if (data.turn === turn && data.usage !== void 0) usage = addTokenUsage(usage, data.usage);
4097
+ }
4098
+ const round = {
4099
+ ...roundModel === void 0 ? {} : { observedModel: roundModel },
4100
+ ...usage === void 0 ? {} : { usage }
4101
+ };
4093
4102
  localAgent?.recordRoundSettled?.(childSession.id, round);
4094
4103
  }
4095
4104
  this.armIdleTimer(String(childSession.id));
@@ -5344,7 +5353,7 @@ const inject = [
5344
5353
  * the user layer exactly as before.
5345
5354
  */
5346
5355
  const SETTINGS_FIELDS = {
5347
- live: z.boolean().default(false),
5356
+ live: z.boolean().default(true),
5348
5357
  liveMirrorGranularity: z.union([z.const("event"), z.const("token")]).default("token"),
5349
5358
  model: z.string(),
5350
5359
  recentModels: z.array(z.string()).default([])
@@ -5438,7 +5447,7 @@ function apply(ctx, config) {
5438
5447
  const model = vol(config.model);
5439
5448
  const recentModels = vol(config.recentModels);
5440
5449
  return {
5441
- live: vol(config.live) ?? false,
5450
+ live: vol(config.live) ?? true,
5442
5451
  liveMirrorGranularity: vol(config.liveMirrorGranularity) ?? "token",
5443
5452
  ...model === void 0 ? {} : { model },
5444
5453
  ...recentModels === void 0 ? {} : { recentModels }
@@ -5455,6 +5464,7 @@ function apply(ctx, config) {
5455
5464
  }
5456
5465
  const face = settingsFace(ctx, {
5457
5466
  namespace: KIMI_SETTINGS_NAMESPACE,
5467
+ harness: "kimi",
5458
5468
  legacySchema: KIMI_SETTINGS_SCHEMA,
5459
5469
  legacyBase,
5460
5470
  read: readSettings
@@ -7,7 +7,7 @@ import { IconChevronDownOutlineMedium } from './icons.js';
7
7
  // the block carries no runtime identity to share.
8
8
  import { ProviderAuthBlock, } from '@khorsheed/dsh-local-agent/src/client/ProviderAuthBlock.tsx';
9
9
  import { AuthStatusDot } from '@khorsheed/dsh-local-agent/src/client/AuthStatusDot.tsx';
10
- import { publishAuthStatus, useHarnessAuthStatus } from '@khorsheed/dsh-local-agent/src/client/auth-status.ts';
10
+ import { publishAuthStatus, useHarnessAuthStatus, usePublishedAuthStatus } from '@khorsheed/dsh-local-agent/src/client/auth-status.ts';
11
11
  import { ModelListSection } from '@khorsheed/dsh-local-agent/src/client/ModelListSection.tsx';
12
12
  import css from './SettingsCard.module.css';
13
13
  /**
@@ -43,6 +43,10 @@ function useCardState(active, useSettings, scope, endpointAuth) {
43
43
  const endpointUnavailable = endpointAuth === undefined || endpointState === 'unavailable';
44
44
  const endpointLoading = !endpointUnavailable && endpointState === null;
45
45
  const apiKeyConfigured = endpointState !== null && endpointState !== 'unavailable' && endpointState.apiKeySet;
46
+ // A login or logout elsewhere in the card (the auth block) changes what
47
+ // the store holds — logout deletes the saved key: re-read, or the form
48
+ // keeps saying 已配置 for a key that is gone.
49
+ const authPublished = usePublishedAuthStatus('kimi');
46
50
  useEffect(() => {
47
51
  if (!active || endpointAuth === undefined)
48
52
  return;
@@ -51,7 +55,7 @@ function useCardState(active, useSettings, scope, endpointAuth) {
51
55
  setEndpointState(state ?? 'unavailable'); }, () => { if (!stale)
52
56
  setEndpointState('unavailable'); });
53
57
  return () => { stale = true; };
54
- }, [active, endpointAuth, endpointSaved]);
58
+ }, [active, endpointAuth, endpointSaved, authPublished]);
55
59
  // The credential save: one `configureEndpoint` call carrying only the
56
60
  // dirty fields (a blank draft clears its field); the answer is the
57
61
  // post-write resolved state, so the chips and the auth probe flip without
@@ -81,7 +85,11 @@ function useCardState(active, useSettings, scope, endpointAuth) {
81
85
  const write = (field, value) => {
82
86
  setSaved(false);
83
87
  setError(false);
84
- void scope.set(field, value).then(() => { setSaved(true); }, () => { setError(true); });
88
+ // The host answers a refused write with `false` (ConfigForm), not a rejection.
89
+ void scope.set(field, value).then((accepted) => { if (accepted === false)
90
+ setError(true);
91
+ else
92
+ setSaved(true); }, () => { setError(true); });
85
93
  };
86
94
  return {
87
95
  snapshot, saved, error, ready, live, write,
@@ -1,4 +1,4 @@
1
- import { bindSettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
1
+ import { bindCardSettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
2
2
  /**
3
3
  * Local-agent-kimi plugin, browser half: the kimi settings card — a section
4
4
  * of the family core's「本机 Agent 委派」family card on the Plugins page
@@ -44,7 +44,7 @@ export const inject = ['slots', 'remote', 'remote.commands', 'locale'];
44
44
  export function apply(ctx) {
45
45
  ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'local-agent-kimi: dictionaries');
46
46
  const t = ctx.locale.bind(NS);
47
- const scope = bindSettingsScope(ctx, 'local-agent-kimi');
47
+ const scope = bindCardSettingsScope(ctx, 'kimi', 'local-agent-kimi');
48
48
  // The auth block's copy lives in the family core's dictionary; binding is
49
49
  // stable per namespace and late dictionary registration still resolves.
50
50
  const authT = ctx.locale.bind('local-agent');
@@ -40,7 +40,7 @@ export const inject = ['localAgent', 'subagents', 'subprocess', 'settings'];
40
40
  * the user layer exactly as before.
41
41
  */
42
42
  const SETTINGS_FIELDS = {
43
- live: z.boolean().default(false),
43
+ live: z.boolean().default(true),
44
44
  liveMirrorGranularity: z.union([z.const('event'), z.const('token')]).default('token'),
45
45
  // `model` deliberately carries NO default: an unset key must resolve to
46
46
  // undefined, which is what keeps the pre-key behavior byte-identical.
@@ -161,7 +161,7 @@ export function apply(ctx, config) {
161
161
  const model = vol(config.model);
162
162
  const recentModels = vol(config.recentModels);
163
163
  return {
164
- live: vol(config.live) ?? false,
164
+ live: vol(config.live) ?? true,
165
165
  liveMirrorGranularity: vol(config.liveMirrorGranularity) ?? 'token',
166
166
  ...model === undefined ? {} : { model },
167
167
  ...recentModels === undefined ? {} : { recentModels },
@@ -175,6 +175,8 @@ export function apply(ctx, config) {
175
175
  }
176
176
  const face = settingsFace(ctx, {
177
177
  namespace: KIMI_SETTINGS_NAMESPACE,
178
+ // Card writes live in the harness's own store (card-settings.ts), never the profile patch.
179
+ harness: 'kimi',
178
180
  legacySchema: KIMI_SETTINGS_SCHEMA,
179
181
  legacyBase,
180
182
  read: readSettings,
@@ -1488,8 +1488,20 @@ export class KimiAcpLiveDriver {
1488
1488
  // a round that never opened owns no span to observe. Degrades
1489
1489
  // silently on a core predating recordRoundSettled.
1490
1490
  if (turnOpened) {
1491
+ // The round's spend for the room's usage chip: every folded step of
1492
+ // this turn carries its own usage (the uncarried rest rides the last
1493
+ // one), so the turn's sum is the round total.
1494
+ let usage;
1495
+ for (const event of childSession.snapshotEvents()) {
1496
+ if (event.type !== 'assistant/message')
1497
+ continue;
1498
+ const data = event.data;
1499
+ if (data.turn === turn && data.usage !== undefined)
1500
+ usage = addTokenUsage(usage, data.usage);
1501
+ }
1491
1502
  const round = {
1492
1503
  ...roundModel === undefined ? {} : { observedModel: roundModel },
1504
+ ...usage === undefined ? {} : { usage },
1493
1505
  };
1494
1506
  const registry = localAgent;
1495
1507
  registry?.recordRoundSettled?.(childSession.id, round);
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "local-agent",
9
9
  "kimi"
10
10
  ],
11
- "version": "0.2.0",
11
+ "version": "0.2.1",
12
12
  "type": "module",
13
13
  "main": "lib/index.js",
14
14
  "types": "lib/types/index.d.ts",
@@ -69,7 +69,7 @@
69
69
  "dsh": ">=0.1.5-rc.1 <0.3.0-0"
70
70
  },
71
71
  "dependencies": {
72
- "@khorsheed/dsh-local-agent": "^0.2.0"
72
+ "@khorsheed/dsh-local-agent": "^0.2.1"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@deepseek-ai/cordis": "^4.0.1",