@vicvic-im/agent-bot 0.1.4 → 0.1.5
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 +8 -2
- package/dist/agents/acp.d.ts +1 -0
- package/dist/agents/acp.d.ts.map +1 -1
- package/dist/agents/types.d.ts +5 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/bin-server.cjs +101 -24
- package/dist/bin-server.cjs.map +1 -1
- package/dist/bin-server.js +1 -1
- package/dist/{chunk-3FUDOPAV.js → chunk-NHQ5OF2Q.js} +102 -25
- package/dist/chunk-NHQ5OF2Q.js.map +1 -0
- package/dist/{chunk-X65ZARFF.js → chunk-NQJQ7ZRY.js} +2 -2
- package/dist/cli.cjs +101 -24
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/core/dispatcher.d.ts +1 -1
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/state.d.ts +7 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/switch.d.ts.map +1 -1
- package/dist/index.cjs +101 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/server.cjs +101 -24
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-3FUDOPAV.js.map +0 -1
- /package/dist/{chunk-X65ZARFF.js.map → chunk-NQJQ7ZRY.js.map} +0 -0
package/README.md
CHANGED
|
@@ -83,8 +83,9 @@ Unknown `/commands` are forwarded to the agent as prompts.
|
|
|
83
83
|
Output notes:
|
|
84
84
|
|
|
85
85
|
- `/status`, `/agent`, `/model`, `/cost` and `/help` render Markdown tables; the vicvic.im Web and RN clients already render GFM tables. `/status` starts with a one-line summary because conversation previews and push notifications only show the first line.
|
|
86
|
-
- `/model` with no argument reports the model the ACP session actually selected (`currentValue` mapped to its option name)
|
|
87
|
-
- `/
|
|
86
|
+
- `/model` with no argument reports the model the ACP session actually selected (`currentValue` mapped to its option name), never a misleading `default`. Resolution order: live session → cached value from the previous run (`last known`, survives `vbot restart` and `/new`) → start the agent once to read it. `pi` warms up in ~3 s; `codex` cold start can take ~100 s, so vbot replies `Reading model from codex...` first.
|
|
87
|
+
- `/model list` prints the full option table (pi exposes 46 models); plain `/model` inlines options only when there are 8 or fewer. `/status` never starts the agent — it shows the cached value marked `(last known)` when no session is live.
|
|
88
|
+
- `/new` and `/model <name>` are rejected while a request is running (`Use /stop first`): resetting the session mid-turn drops the streamed reply and switches the model under a running turn. `/new` does not reset the model.
|
|
88
89
|
|
|
89
90
|
## Configuration
|
|
90
91
|
|
|
@@ -137,6 +138,11 @@ The pairing token is a long-lived credential. Do not commit `vbot.json`; the fil
|
|
|
137
138
|
|
|
138
139
|
## Development
|
|
139
140
|
|
|
141
|
+
Release: bump `package.json` **and** `src/version.ts` (`VBOT_VERSION`), build, then publish from this
|
|
142
|
+
folder (`npx -y npm@11 publish --access public`). `npm publish` returns before the version is
|
|
143
|
+
fetchable — poll `npm view @vicvic-im/agent-bot version` until it matches, and do not republish the
|
|
144
|
+
same version (409 staged). See `docs/techs/current/npm-package-release.md`.
|
|
145
|
+
|
|
140
146
|
```bash
|
|
141
147
|
pnpm --filter @vicvic-im/agent-bot build
|
|
142
148
|
pnpm --filter @vicvic-im/agent-bot test
|
package/dist/agents/acp.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class AcpAgent implements AgentBackend {
|
|
|
26
26
|
capabilities(): AgentCapabilities;
|
|
27
27
|
sessionId(): string | null;
|
|
28
28
|
currentModel(): AgentModelState | null;
|
|
29
|
+
warmup(savedSessionId?: string): Promise<void>;
|
|
29
30
|
resetSession(): void;
|
|
30
31
|
start(): Promise<void>;
|
|
31
32
|
private doStart;
|
package/dist/agents/acp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp.d.ts","sourceRoot":"","sources":["../../src/agents/acp.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,eAAe,EACf,SAAS,EACT,eAAe,EACf,cAAc,EAEf,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,qBAAa,eAAgB,SAAQ,KAAK;;CAKzC;AAED,qBAAa,eAAgB,SAAQ,KAAK;IAGtC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM;CAK1B;AAyBD,0CAA0C;AAC1C,qBAAa,QAAS,YAAW,YAAY;IAczC,QAAQ,CAAC,IAAI,EAAE,SAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAdzB,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAuB;gBAGhC,IAAI,EAAE,SAAS,EACP,MAAM,EAAE,WAAW;IAGtC,YAAY,IAAI,iBAAiB;IASjC,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,YAAY,IAAI,eAAe,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"acp.d.ts","sourceRoot":"","sources":["../../src/agents/acp.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,eAAe,EACf,SAAS,EACT,eAAe,EACf,cAAc,EAEf,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,qBAAa,eAAgB,SAAQ,KAAK;;CAKzC;AAED,qBAAa,eAAgB,SAAQ,KAAK;IAGtC,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM;CAK1B;AAyBD,0CAA0C;AAC1C,qBAAa,QAAS,YAAW,YAAY;IAczC,QAAQ,CAAC,IAAI,EAAE,SAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAdzB,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,GAAG,CAAkC;IAC7C,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAuB;gBAGhC,IAAI,EAAE,SAAS,EACP,MAAM,EAAE,WAAW;IAGtC,YAAY,IAAI,iBAAiB;IASjC,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,YAAY,IAAI,eAAe,GAAG,IAAI;IAUhC,MAAM,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,YAAY,IAAI,IAAI;IAId,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,OAAO;YA8EP,aAAa;IA+CrB,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAkEtD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IASvB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmBzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB5B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,UAAU;CAWnB"}
|
package/dist/agents/types.d.ts
CHANGED
|
@@ -84,5 +84,10 @@ export interface AgentBackend {
|
|
|
84
84
|
sessionId(): string | null;
|
|
85
85
|
/** 当前模型;后端未暴露模型配置项或会话未建立时返回 null。 */
|
|
86
86
|
currentModel(): AgentModelState | null;
|
|
87
|
+
/**
|
|
88
|
+
* 启动进程并建立/恢复会话(不跑 prompt),用于在未收到消息时读取真实模型。
|
|
89
|
+
* 失败时抛错,由调用方决定如何降级。
|
|
90
|
+
*/
|
|
91
|
+
warmup(savedSessionId?: string): Promise<void>;
|
|
87
92
|
}
|
|
88
93
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,IAAI,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,WAAW,EAAE,KAAwC,CAAC;AAEnE,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,mCAAmC;IACnC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,2CAA2C;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sCAAsC;IACtC,GAAG,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD,mBAAmB;IACnB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,sCAAsC;IACtC,YAAY,IAAI,IAAI,CAAC;IACrB,kBAAkB;IAClB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,YAAY,IAAI,iBAAiB,CAAC;IAClC,+BAA+B;IAC/B,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,qCAAqC;IACrC,YAAY,IAAI,eAAe,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"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"}
|
package/dist/bin-server.cjs
CHANGED
|
@@ -266,9 +266,16 @@ function emptyState(token, agent, cwd) {
|
|
|
266
266
|
cwd,
|
|
267
267
|
createdAt: now,
|
|
268
268
|
lastUsedAt: now,
|
|
269
|
-
usage: { ...EMPTY_USAGE }
|
|
269
|
+
usage: { ...EMPTY_USAGE },
|
|
270
|
+
model: null
|
|
270
271
|
};
|
|
271
272
|
}
|
|
273
|
+
function parseCachedModel(value) {
|
|
274
|
+
if (!value || typeof value !== "object") return null;
|
|
275
|
+
const record = value;
|
|
276
|
+
if (typeof record.value !== "string" || typeof record.label !== "string") return null;
|
|
277
|
+
return { value: record.value, label: record.label };
|
|
278
|
+
}
|
|
272
279
|
function loadState(token) {
|
|
273
280
|
const path = statePath(token);
|
|
274
281
|
if (!(0, import_node_fs2.existsSync)(path)) return null;
|
|
@@ -283,7 +290,8 @@ function loadState(token) {
|
|
|
283
290
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : process.cwd(),
|
|
284
291
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
285
292
|
lastUsedAt: typeof parsed.lastUsedAt === "string" ? parsed.lastUsedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
286
|
-
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE }
|
|
293
|
+
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE },
|
|
294
|
+
model: parseCachedModel(parsed.model)
|
|
287
295
|
};
|
|
288
296
|
} catch {
|
|
289
297
|
return null;
|
|
@@ -365,7 +373,7 @@ var import_node_stream = require("stream");
|
|
|
365
373
|
var acp = __toESM(require("@agentclientprotocol/sdk"), 1);
|
|
366
374
|
|
|
367
375
|
// src/version.ts
|
|
368
|
-
var VBOT_VERSION = "0.1.
|
|
376
|
+
var VBOT_VERSION = "0.1.5";
|
|
369
377
|
|
|
370
378
|
// src/agents/acp.ts
|
|
371
379
|
var AgentAbortError = class extends Error {
|
|
@@ -428,6 +436,11 @@ var AcpAgent = class {
|
|
|
428
436
|
const label = options.find((entry) => entry.value === value)?.label ?? value;
|
|
429
437
|
return { value, label, options };
|
|
430
438
|
}
|
|
439
|
+
// 不跑 prompt 也能读模型:session/new|resume|load 的 configOptions 里带 model 项。
|
|
440
|
+
async warmup(savedSessionId) {
|
|
441
|
+
await this.start();
|
|
442
|
+
await this.ensureSession(savedSessionId);
|
|
443
|
+
}
|
|
431
444
|
resetSession() {
|
|
432
445
|
this.session = null;
|
|
433
446
|
}
|
|
@@ -764,7 +777,7 @@ var HELP_ROWS = [
|
|
|
764
777
|
["/stop", "Abort the current request"],
|
|
765
778
|
["/status", "Show agent, session and queue status"],
|
|
766
779
|
["/agent [name]", "Show or switch agent backend"],
|
|
767
|
-
["/model [name]", "Show or switch model"],
|
|
780
|
+
["/model [name]", "Show or switch model (/model list for all)"],
|
|
768
781
|
["/cost", "Show context usage and cost"],
|
|
769
782
|
["/version", "Show vbot version"],
|
|
770
783
|
["/help", "Show this help"]
|
|
@@ -772,6 +785,7 @@ var HELP_ROWS = [
|
|
|
772
785
|
var HELP_FOOTER = "Other /commands are sent to the agent as prompts.";
|
|
773
786
|
var NEW_BUSY_TEXT = "Cannot reset the session while a request is running. Use /stop first.";
|
|
774
787
|
var MODEL_BUSY_TEXT = "Cannot switch model while a request is running. Use /stop first.";
|
|
788
|
+
var INLINE_OPTION_LIMIT = 8;
|
|
775
789
|
var HELP_TEXT = [
|
|
776
790
|
table(
|
|
777
791
|
["Command", "Description"],
|
|
@@ -835,9 +849,11 @@ function compactPath(path) {
|
|
|
835
849
|
function modelText(runtime) {
|
|
836
850
|
const current = runtime.agent().currentModel();
|
|
837
851
|
if (current) return current.label;
|
|
852
|
+
const cached = runtime.state().model;
|
|
853
|
+
if (cached) return `${cached.label} (last known)`;
|
|
838
854
|
const configured = runtime.config().agent.model;
|
|
839
855
|
if (configured) return `${configured} (configured, not applied yet)`;
|
|
840
|
-
return "unknown (
|
|
856
|
+
return "unknown (send /model list)";
|
|
841
857
|
}
|
|
842
858
|
function handleSlashCommand(runtime, text, send) {
|
|
843
859
|
const [rawCommand, ...args] = text.split(/\s+/);
|
|
@@ -927,7 +943,11 @@ function handleAgent(runtime, args, send) {
|
|
|
927
943
|
async function handleModel(runtime, args, send) {
|
|
928
944
|
const model = args.join(" ").trim();
|
|
929
945
|
if (!model) {
|
|
930
|
-
|
|
946
|
+
await reportModel(runtime, send, false);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
if (model.toLowerCase() === "list") {
|
|
950
|
+
await reportModel(runtime, send, true);
|
|
931
951
|
return;
|
|
932
952
|
}
|
|
933
953
|
if (runtime.queue().status().busy) {
|
|
@@ -942,7 +962,12 @@ async function handleModel(runtime, args, send) {
|
|
|
942
962
|
runtime.saveConfig();
|
|
943
963
|
return accepted;
|
|
944
964
|
});
|
|
945
|
-
const applied = runtime.agent().currentModel()
|
|
965
|
+
const applied = runtime.agent().currentModel();
|
|
966
|
+
if (applied) {
|
|
967
|
+
runtime.state().model = { value: applied.value, label: applied.label };
|
|
968
|
+
runtime.saveState();
|
|
969
|
+
}
|
|
970
|
+
const label = applied?.label ?? model;
|
|
946
971
|
if (!supported) {
|
|
947
972
|
send(
|
|
948
973
|
`Model saved: ${model}. This agent does not expose a runtime model option; it will be used on the next session if supported.`
|
|
@@ -950,34 +975,83 @@ async function handleModel(runtime, args, send) {
|
|
|
950
975
|
return;
|
|
951
976
|
}
|
|
952
977
|
send(
|
|
953
|
-
hadSession ? `Model switched to: ${
|
|
978
|
+
hadSession ? `Model switched to: ${label}` : `Model set to: ${label}. It will apply when the session starts.`
|
|
954
979
|
);
|
|
955
980
|
}
|
|
956
|
-
function
|
|
957
|
-
const
|
|
958
|
-
if (
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
981
|
+
async function reportModel(runtime, send, wantList) {
|
|
982
|
+
const live = runtime.agent().currentModel();
|
|
983
|
+
if (live) {
|
|
984
|
+
send(renderModel(live, wantList));
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
const cached = runtime.state().model;
|
|
988
|
+
if (cached && !wantList) {
|
|
989
|
+
send(renderCachedModel(cached));
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
const name = runtime.config().agent.name;
|
|
993
|
+
send(`Reading ${wantList ? "model list" : "model"} from ${name}... (starting the agent)`);
|
|
994
|
+
try {
|
|
995
|
+
await runtime.serialize(
|
|
996
|
+
() => runtime.agent().warmup(runtime.state().acpSessionId ?? void 0)
|
|
997
|
+
);
|
|
998
|
+
} catch (error) {
|
|
999
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
1000
|
+
send(`Could not read the model from ${name}: ${reason}`);
|
|
1001
|
+
if (cached) send(renderCachedModel(cached));
|
|
1002
|
+
return;
|
|
966
1003
|
}
|
|
967
|
-
const
|
|
968
|
-
if (
|
|
1004
|
+
const refreshed = runtime.agent().currentModel();
|
|
1005
|
+
if (refreshed) {
|
|
1006
|
+
runtime.state().model = { value: refreshed.value, label: refreshed.label };
|
|
1007
|
+
runtime.saveState();
|
|
1008
|
+
send(renderModel(refreshed, wantList));
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1011
|
+
send(cached ? renderCachedModel(cached) : unknownModelText(runtime));
|
|
1012
|
+
}
|
|
1013
|
+
function renderModel(model, wantList) {
|
|
1014
|
+
const lines = [`Current: ${model.label}`];
|
|
1015
|
+
const total = model.options.length;
|
|
1016
|
+
if (total === 0) {
|
|
1017
|
+
lines.push("", "This agent does not expose a model list.");
|
|
1018
|
+
return lines.join("\n");
|
|
1019
|
+
}
|
|
1020
|
+
if (wantList || total <= INLINE_OPTION_LIMIT) {
|
|
969
1021
|
lines.push(
|
|
970
1022
|
"",
|
|
971
1023
|
table(
|
|
972
1024
|
["Model", ""],
|
|
973
|
-
|
|
1025
|
+
model.options.map((option) => [
|
|
974
1026
|
option.label,
|
|
975
|
-
option.value ===
|
|
1027
|
+
option.value === model.value ? "\u2190 current" : ""
|
|
976
1028
|
])
|
|
977
1029
|
)
|
|
978
1030
|
);
|
|
979
|
-
|
|
980
|
-
|
|
1031
|
+
lines.push("", "Switch: /model <name>");
|
|
1032
|
+
return lines.join("\n");
|
|
1033
|
+
}
|
|
1034
|
+
lines.push(
|
|
1035
|
+
"",
|
|
1036
|
+
table(["Model", ""], [[model.label, "\u2190 current"]]),
|
|
1037
|
+
"",
|
|
1038
|
+
`${total} models available \xB7 Switch: /model <name> \xB7 List: /model list`
|
|
1039
|
+
);
|
|
1040
|
+
return lines.join("\n");
|
|
1041
|
+
}
|
|
1042
|
+
function renderCachedModel(cached) {
|
|
1043
|
+
return [
|
|
1044
|
+
`Current: ${cached.label} (last known)`,
|
|
1045
|
+
"",
|
|
1046
|
+
"Cached from the last session; the agent has not started in this process yet.",
|
|
1047
|
+
"Send /model list to read the live value from the agent."
|
|
1048
|
+
].join("\n");
|
|
1049
|
+
}
|
|
1050
|
+
function unknownModelText(runtime) {
|
|
1051
|
+
const configured = runtime.config().agent.model;
|
|
1052
|
+
const lines = ["Current: unknown"];
|
|
1053
|
+
if (configured) lines.push("", `Configured: ${configured}`);
|
|
1054
|
+
lines.push("", "This agent does not expose a runtime model option.");
|
|
981
1055
|
return lines.join("\n");
|
|
982
1056
|
}
|
|
983
1057
|
function statusText(runtime) {
|
|
@@ -1054,6 +1128,7 @@ async function switchAgent(ctx, name) {
|
|
|
1054
1128
|
ctx.state.agent = name;
|
|
1055
1129
|
ctx.state.acpSessionId = null;
|
|
1056
1130
|
ctx.state.usage = { ...EMPTY_USAGE };
|
|
1131
|
+
ctx.state.model = null;
|
|
1057
1132
|
ctx.saveConfig();
|
|
1058
1133
|
ctx.saveState();
|
|
1059
1134
|
await previous.close().catch(() => void 0);
|
|
@@ -1380,6 +1455,8 @@ async function processPrompt(ctx, item, signal) {
|
|
|
1380
1455
|
});
|
|
1381
1456
|
ctx.state.acpSessionId = result.sessionId;
|
|
1382
1457
|
ctx.state.usage = result.usage;
|
|
1458
|
+
const model = ctx.getAgent().currentModel();
|
|
1459
|
+
if (model) ctx.state.model = { value: model.value, label: model.label };
|
|
1383
1460
|
ctx.saveState();
|
|
1384
1461
|
for (const chunk of splitMessage(result.text || "(no output)")) {
|
|
1385
1462
|
await item.reply(chunk);
|