@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/dist/cli.cjs
CHANGED
|
@@ -363,7 +363,7 @@ var acp = __toESM(require("@agentclientprotocol/sdk"), 1);
|
|
|
363
363
|
var EMPTY_USAGE = { used: 0, size: 0, cost: null };
|
|
364
364
|
|
|
365
365
|
// src/version.ts
|
|
366
|
-
var VBOT_VERSION = "0.1.
|
|
366
|
+
var VBOT_VERSION = "0.1.5";
|
|
367
367
|
|
|
368
368
|
// src/agents/acp.ts
|
|
369
369
|
var AgentAbortError = class extends Error {
|
|
@@ -426,6 +426,11 @@ var AcpAgent = class {
|
|
|
426
426
|
const label = options.find((entry) => entry.value === value)?.label ?? value;
|
|
427
427
|
return { value, label, options };
|
|
428
428
|
}
|
|
429
|
+
// 不跑 prompt 也能读模型:session/new|resume|load 的 configOptions 里带 model 项。
|
|
430
|
+
async warmup(savedSessionId) {
|
|
431
|
+
await this.start();
|
|
432
|
+
await this.ensureSession(savedSessionId);
|
|
433
|
+
}
|
|
429
434
|
resetSession() {
|
|
430
435
|
this.session = null;
|
|
431
436
|
}
|
|
@@ -762,7 +767,7 @@ var HELP_ROWS = [
|
|
|
762
767
|
["/stop", "Abort the current request"],
|
|
763
768
|
["/status", "Show agent, session and queue status"],
|
|
764
769
|
["/agent [name]", "Show or switch agent backend"],
|
|
765
|
-
["/model [name]", "Show or switch model"],
|
|
770
|
+
["/model [name]", "Show or switch model (/model list for all)"],
|
|
766
771
|
["/cost", "Show context usage and cost"],
|
|
767
772
|
["/version", "Show vbot version"],
|
|
768
773
|
["/help", "Show this help"]
|
|
@@ -770,6 +775,7 @@ var HELP_ROWS = [
|
|
|
770
775
|
var HELP_FOOTER = "Other /commands are sent to the agent as prompts.";
|
|
771
776
|
var NEW_BUSY_TEXT = "Cannot reset the session while a request is running. Use /stop first.";
|
|
772
777
|
var MODEL_BUSY_TEXT = "Cannot switch model while a request is running. Use /stop first.";
|
|
778
|
+
var INLINE_OPTION_LIMIT = 8;
|
|
773
779
|
var HELP_TEXT = [
|
|
774
780
|
table(
|
|
775
781
|
["Command", "Description"],
|
|
@@ -833,9 +839,11 @@ function compactPath(path) {
|
|
|
833
839
|
function modelText(runtime) {
|
|
834
840
|
const current = runtime.agent().currentModel();
|
|
835
841
|
if (current) return current.label;
|
|
842
|
+
const cached = runtime.state().model;
|
|
843
|
+
if (cached) return `${cached.label} (last known)`;
|
|
836
844
|
const configured = runtime.config().agent.model;
|
|
837
845
|
if (configured) return `${configured} (configured, not applied yet)`;
|
|
838
|
-
return "unknown (
|
|
846
|
+
return "unknown (send /model list)";
|
|
839
847
|
}
|
|
840
848
|
function handleSlashCommand(runtime, text, send) {
|
|
841
849
|
const [rawCommand, ...args] = text.split(/\s+/);
|
|
@@ -925,7 +933,11 @@ function handleAgent(runtime, args, send) {
|
|
|
925
933
|
async function handleModel(runtime, args, send) {
|
|
926
934
|
const model = args.join(" ").trim();
|
|
927
935
|
if (!model) {
|
|
928
|
-
|
|
936
|
+
await reportModel(runtime, send, false);
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
if (model.toLowerCase() === "list") {
|
|
940
|
+
await reportModel(runtime, send, true);
|
|
929
941
|
return;
|
|
930
942
|
}
|
|
931
943
|
if (runtime.queue().status().busy) {
|
|
@@ -940,7 +952,12 @@ async function handleModel(runtime, args, send) {
|
|
|
940
952
|
runtime.saveConfig();
|
|
941
953
|
return accepted;
|
|
942
954
|
});
|
|
943
|
-
const applied = runtime.agent().currentModel()
|
|
955
|
+
const applied = runtime.agent().currentModel();
|
|
956
|
+
if (applied) {
|
|
957
|
+
runtime.state().model = { value: applied.value, label: applied.label };
|
|
958
|
+
runtime.saveState();
|
|
959
|
+
}
|
|
960
|
+
const label = applied?.label ?? model;
|
|
944
961
|
if (!supported) {
|
|
945
962
|
send(
|
|
946
963
|
`Model saved: ${model}. This agent does not expose a runtime model option; it will be used on the next session if supported.`
|
|
@@ -948,34 +965,83 @@ async function handleModel(runtime, args, send) {
|
|
|
948
965
|
return;
|
|
949
966
|
}
|
|
950
967
|
send(
|
|
951
|
-
hadSession ? `Model switched to: ${
|
|
968
|
+
hadSession ? `Model switched to: ${label}` : `Model set to: ${label}. It will apply when the session starts.`
|
|
952
969
|
);
|
|
953
970
|
}
|
|
954
|
-
function
|
|
955
|
-
const
|
|
956
|
-
if (
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
971
|
+
async function reportModel(runtime, send, wantList) {
|
|
972
|
+
const live = runtime.agent().currentModel();
|
|
973
|
+
if (live) {
|
|
974
|
+
send(renderModel(live, wantList));
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
const cached = runtime.state().model;
|
|
978
|
+
if (cached && !wantList) {
|
|
979
|
+
send(renderCachedModel(cached));
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
const name = runtime.config().agent.name;
|
|
983
|
+
send(`Reading ${wantList ? "model list" : "model"} from ${name}... (starting the agent)`);
|
|
984
|
+
try {
|
|
985
|
+
await runtime.serialize(
|
|
986
|
+
() => runtime.agent().warmup(runtime.state().acpSessionId ?? void 0)
|
|
987
|
+
);
|
|
988
|
+
} catch (error) {
|
|
989
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
990
|
+
send(`Could not read the model from ${name}: ${reason}`);
|
|
991
|
+
if (cached) send(renderCachedModel(cached));
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
const refreshed = runtime.agent().currentModel();
|
|
995
|
+
if (refreshed) {
|
|
996
|
+
runtime.state().model = { value: refreshed.value, label: refreshed.label };
|
|
997
|
+
runtime.saveState();
|
|
998
|
+
send(renderModel(refreshed, wantList));
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
send(cached ? renderCachedModel(cached) : unknownModelText(runtime));
|
|
1002
|
+
}
|
|
1003
|
+
function renderModel(model, wantList) {
|
|
1004
|
+
const lines = [`Current: ${model.label}`];
|
|
1005
|
+
const total = model.options.length;
|
|
1006
|
+
if (total === 0) {
|
|
1007
|
+
lines.push("", "This agent does not expose a model list.");
|
|
1008
|
+
return lines.join("\n");
|
|
964
1009
|
}
|
|
965
|
-
|
|
966
|
-
if (current.options.length > 0) {
|
|
1010
|
+
if (wantList || total <= INLINE_OPTION_LIMIT) {
|
|
967
1011
|
lines.push(
|
|
968
1012
|
"",
|
|
969
1013
|
table(
|
|
970
1014
|
["Model", ""],
|
|
971
|
-
|
|
1015
|
+
model.options.map((option) => [
|
|
972
1016
|
option.label,
|
|
973
|
-
option.value ===
|
|
1017
|
+
option.value === model.value ? "\u2190 current" : ""
|
|
974
1018
|
])
|
|
975
1019
|
)
|
|
976
1020
|
);
|
|
977
|
-
|
|
978
|
-
|
|
1021
|
+
lines.push("", "Switch: /model <name>");
|
|
1022
|
+
return lines.join("\n");
|
|
1023
|
+
}
|
|
1024
|
+
lines.push(
|
|
1025
|
+
"",
|
|
1026
|
+
table(["Model", ""], [[model.label, "\u2190 current"]]),
|
|
1027
|
+
"",
|
|
1028
|
+
`${total} models available \xB7 Switch: /model <name> \xB7 List: /model list`
|
|
1029
|
+
);
|
|
1030
|
+
return lines.join("\n");
|
|
1031
|
+
}
|
|
1032
|
+
function renderCachedModel(cached) {
|
|
1033
|
+
return [
|
|
1034
|
+
`Current: ${cached.label} (last known)`,
|
|
1035
|
+
"",
|
|
1036
|
+
"Cached from the last session; the agent has not started in this process yet.",
|
|
1037
|
+
"Send /model list to read the live value from the agent."
|
|
1038
|
+
].join("\n");
|
|
1039
|
+
}
|
|
1040
|
+
function unknownModelText(runtime) {
|
|
1041
|
+
const configured = runtime.config().agent.model;
|
|
1042
|
+
const lines = ["Current: unknown"];
|
|
1043
|
+
if (configured) lines.push("", `Configured: ${configured}`);
|
|
1044
|
+
lines.push("", "This agent does not expose a runtime model option.");
|
|
979
1045
|
return lines.join("\n");
|
|
980
1046
|
}
|
|
981
1047
|
function statusText(runtime) {
|
|
@@ -1052,6 +1118,7 @@ async function switchAgent(ctx, name) {
|
|
|
1052
1118
|
ctx.state.agent = name;
|
|
1053
1119
|
ctx.state.acpSessionId = null;
|
|
1054
1120
|
ctx.state.usage = { ...EMPTY_USAGE };
|
|
1121
|
+
ctx.state.model = null;
|
|
1055
1122
|
ctx.saveConfig();
|
|
1056
1123
|
ctx.saveState();
|
|
1057
1124
|
await previous.close().catch(() => void 0);
|
|
@@ -1088,9 +1155,16 @@ function emptyState(token, agent, cwd) {
|
|
|
1088
1155
|
cwd,
|
|
1089
1156
|
createdAt: now,
|
|
1090
1157
|
lastUsedAt: now,
|
|
1091
|
-
usage: { ...EMPTY_USAGE }
|
|
1158
|
+
usage: { ...EMPTY_USAGE },
|
|
1159
|
+
model: null
|
|
1092
1160
|
};
|
|
1093
1161
|
}
|
|
1162
|
+
function parseCachedModel(value) {
|
|
1163
|
+
if (!value || typeof value !== "object") return null;
|
|
1164
|
+
const record = value;
|
|
1165
|
+
if (typeof record.value !== "string" || typeof record.label !== "string") return null;
|
|
1166
|
+
return { value: record.value, label: record.label };
|
|
1167
|
+
}
|
|
1094
1168
|
function loadState(token) {
|
|
1095
1169
|
const path = statePath(token);
|
|
1096
1170
|
if (!(0, import_node_fs4.existsSync)(path)) return null;
|
|
@@ -1105,7 +1179,8 @@ function loadState(token) {
|
|
|
1105
1179
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : process.cwd(),
|
|
1106
1180
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1107
1181
|
lastUsedAt: typeof parsed.lastUsedAt === "string" ? parsed.lastUsedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
1108
|
-
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE }
|
|
1182
|
+
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE },
|
|
1183
|
+
model: parseCachedModel(parsed.model)
|
|
1109
1184
|
};
|
|
1110
1185
|
} catch {
|
|
1111
1186
|
return null;
|
|
@@ -1501,6 +1576,8 @@ async function processPrompt(ctx, item, signal) {
|
|
|
1501
1576
|
});
|
|
1502
1577
|
ctx.state.acpSessionId = result.sessionId;
|
|
1503
1578
|
ctx.state.usage = result.usage;
|
|
1579
|
+
const model = ctx.getAgent().currentModel();
|
|
1580
|
+
if (model) ctx.state.model = { value: model.value, label: model.label };
|
|
1504
1581
|
ctx.saveState();
|
|
1505
1582
|
for (const chunk of splitMessage(result.text || "(no output)")) {
|
|
1506
1583
|
await item.reply(chunk);
|