@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/server.cjs
CHANGED
|
@@ -250,7 +250,7 @@ var acp = __toESM(require("@agentclientprotocol/sdk"), 1);
|
|
|
250
250
|
var EMPTY_USAGE = { used: 0, size: 0, cost: null };
|
|
251
251
|
|
|
252
252
|
// src/version.ts
|
|
253
|
-
var VBOT_VERSION = "0.1.
|
|
253
|
+
var VBOT_VERSION = "0.1.5";
|
|
254
254
|
|
|
255
255
|
// src/agents/acp.ts
|
|
256
256
|
var AgentAbortError = class extends Error {
|
|
@@ -313,6 +313,11 @@ var AcpAgent = class {
|
|
|
313
313
|
const label = options.find((entry) => entry.value === value)?.label ?? value;
|
|
314
314
|
return { value, label, options };
|
|
315
315
|
}
|
|
316
|
+
// 不跑 prompt 也能读模型:session/new|resume|load 的 configOptions 里带 model 项。
|
|
317
|
+
async warmup(savedSessionId) {
|
|
318
|
+
await this.start();
|
|
319
|
+
await this.ensureSession(savedSessionId);
|
|
320
|
+
}
|
|
316
321
|
resetSession() {
|
|
317
322
|
this.session = null;
|
|
318
323
|
}
|
|
@@ -649,7 +654,7 @@ var HELP_ROWS = [
|
|
|
649
654
|
["/stop", "Abort the current request"],
|
|
650
655
|
["/status", "Show agent, session and queue status"],
|
|
651
656
|
["/agent [name]", "Show or switch agent backend"],
|
|
652
|
-
["/model [name]", "Show or switch model"],
|
|
657
|
+
["/model [name]", "Show or switch model (/model list for all)"],
|
|
653
658
|
["/cost", "Show context usage and cost"],
|
|
654
659
|
["/version", "Show vbot version"],
|
|
655
660
|
["/help", "Show this help"]
|
|
@@ -657,6 +662,7 @@ var HELP_ROWS = [
|
|
|
657
662
|
var HELP_FOOTER = "Other /commands are sent to the agent as prompts.";
|
|
658
663
|
var NEW_BUSY_TEXT = "Cannot reset the session while a request is running. Use /stop first.";
|
|
659
664
|
var MODEL_BUSY_TEXT = "Cannot switch model while a request is running. Use /stop first.";
|
|
665
|
+
var INLINE_OPTION_LIMIT = 8;
|
|
660
666
|
var HELP_TEXT = [
|
|
661
667
|
table(
|
|
662
668
|
["Command", "Description"],
|
|
@@ -720,9 +726,11 @@ function compactPath(path) {
|
|
|
720
726
|
function modelText(runtime) {
|
|
721
727
|
const current = runtime.agent().currentModel();
|
|
722
728
|
if (current) return current.label;
|
|
729
|
+
const cached = runtime.state().model;
|
|
730
|
+
if (cached) return `${cached.label} (last known)`;
|
|
723
731
|
const configured = runtime.config().agent.model;
|
|
724
732
|
if (configured) return `${configured} (configured, not applied yet)`;
|
|
725
|
-
return "unknown (
|
|
733
|
+
return "unknown (send /model list)";
|
|
726
734
|
}
|
|
727
735
|
function handleSlashCommand(runtime, text, send) {
|
|
728
736
|
const [rawCommand, ...args] = text.split(/\s+/);
|
|
@@ -812,7 +820,11 @@ function handleAgent(runtime, args, send) {
|
|
|
812
820
|
async function handleModel(runtime, args, send) {
|
|
813
821
|
const model = args.join(" ").trim();
|
|
814
822
|
if (!model) {
|
|
815
|
-
|
|
823
|
+
await reportModel(runtime, send, false);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
if (model.toLowerCase() === "list") {
|
|
827
|
+
await reportModel(runtime, send, true);
|
|
816
828
|
return;
|
|
817
829
|
}
|
|
818
830
|
if (runtime.queue().status().busy) {
|
|
@@ -827,7 +839,12 @@ async function handleModel(runtime, args, send) {
|
|
|
827
839
|
runtime.saveConfig();
|
|
828
840
|
return accepted;
|
|
829
841
|
});
|
|
830
|
-
const applied = runtime.agent().currentModel()
|
|
842
|
+
const applied = runtime.agent().currentModel();
|
|
843
|
+
if (applied) {
|
|
844
|
+
runtime.state().model = { value: applied.value, label: applied.label };
|
|
845
|
+
runtime.saveState();
|
|
846
|
+
}
|
|
847
|
+
const label = applied?.label ?? model;
|
|
831
848
|
if (!supported) {
|
|
832
849
|
send(
|
|
833
850
|
`Model saved: ${model}. This agent does not expose a runtime model option; it will be used on the next session if supported.`
|
|
@@ -835,34 +852,83 @@ async function handleModel(runtime, args, send) {
|
|
|
835
852
|
return;
|
|
836
853
|
}
|
|
837
854
|
send(
|
|
838
|
-
hadSession ? `Model switched to: ${
|
|
855
|
+
hadSession ? `Model switched to: ${label}` : `Model set to: ${label}. It will apply when the session starts.`
|
|
839
856
|
);
|
|
840
857
|
}
|
|
841
|
-
function
|
|
842
|
-
const
|
|
843
|
-
if (
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
858
|
+
async function reportModel(runtime, send, wantList) {
|
|
859
|
+
const live = runtime.agent().currentModel();
|
|
860
|
+
if (live) {
|
|
861
|
+
send(renderModel(live, wantList));
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
const cached = runtime.state().model;
|
|
865
|
+
if (cached && !wantList) {
|
|
866
|
+
send(renderCachedModel(cached));
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
const name = runtime.config().agent.name;
|
|
870
|
+
send(`Reading ${wantList ? "model list" : "model"} from ${name}... (starting the agent)`);
|
|
871
|
+
try {
|
|
872
|
+
await runtime.serialize(
|
|
873
|
+
() => runtime.agent().warmup(runtime.state().acpSessionId ?? void 0)
|
|
874
|
+
);
|
|
875
|
+
} catch (error) {
|
|
876
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
877
|
+
send(`Could not read the model from ${name}: ${reason}`);
|
|
878
|
+
if (cached) send(renderCachedModel(cached));
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
const refreshed = runtime.agent().currentModel();
|
|
882
|
+
if (refreshed) {
|
|
883
|
+
runtime.state().model = { value: refreshed.value, label: refreshed.label };
|
|
884
|
+
runtime.saveState();
|
|
885
|
+
send(renderModel(refreshed, wantList));
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
send(cached ? renderCachedModel(cached) : unknownModelText(runtime));
|
|
889
|
+
}
|
|
890
|
+
function renderModel(model, wantList) {
|
|
891
|
+
const lines = [`Current: ${model.label}`];
|
|
892
|
+
const total = model.options.length;
|
|
893
|
+
if (total === 0) {
|
|
894
|
+
lines.push("", "This agent does not expose a model list.");
|
|
895
|
+
return lines.join("\n");
|
|
851
896
|
}
|
|
852
|
-
|
|
853
|
-
if (current.options.length > 0) {
|
|
897
|
+
if (wantList || total <= INLINE_OPTION_LIMIT) {
|
|
854
898
|
lines.push(
|
|
855
899
|
"",
|
|
856
900
|
table(
|
|
857
901
|
["Model", ""],
|
|
858
|
-
|
|
902
|
+
model.options.map((option) => [
|
|
859
903
|
option.label,
|
|
860
|
-
option.value ===
|
|
904
|
+
option.value === model.value ? "\u2190 current" : ""
|
|
861
905
|
])
|
|
862
906
|
)
|
|
863
907
|
);
|
|
864
|
-
|
|
865
|
-
|
|
908
|
+
lines.push("", "Switch: /model <name>");
|
|
909
|
+
return lines.join("\n");
|
|
910
|
+
}
|
|
911
|
+
lines.push(
|
|
912
|
+
"",
|
|
913
|
+
table(["Model", ""], [[model.label, "\u2190 current"]]),
|
|
914
|
+
"",
|
|
915
|
+
`${total} models available \xB7 Switch: /model <name> \xB7 List: /model list`
|
|
916
|
+
);
|
|
917
|
+
return lines.join("\n");
|
|
918
|
+
}
|
|
919
|
+
function renderCachedModel(cached) {
|
|
920
|
+
return [
|
|
921
|
+
`Current: ${cached.label} (last known)`,
|
|
922
|
+
"",
|
|
923
|
+
"Cached from the last session; the agent has not started in this process yet.",
|
|
924
|
+
"Send /model list to read the live value from the agent."
|
|
925
|
+
].join("\n");
|
|
926
|
+
}
|
|
927
|
+
function unknownModelText(runtime) {
|
|
928
|
+
const configured = runtime.config().agent.model;
|
|
929
|
+
const lines = ["Current: unknown"];
|
|
930
|
+
if (configured) lines.push("", `Configured: ${configured}`);
|
|
931
|
+
lines.push("", "This agent does not expose a runtime model option.");
|
|
866
932
|
return lines.join("\n");
|
|
867
933
|
}
|
|
868
934
|
function statusText(runtime) {
|
|
@@ -939,6 +1005,7 @@ async function switchAgent(ctx, name) {
|
|
|
939
1005
|
ctx.state.agent = name;
|
|
940
1006
|
ctx.state.acpSessionId = null;
|
|
941
1007
|
ctx.state.usage = { ...EMPTY_USAGE };
|
|
1008
|
+
ctx.state.model = null;
|
|
942
1009
|
ctx.saveConfig();
|
|
943
1010
|
ctx.saveState();
|
|
944
1011
|
await previous.close().catch(() => void 0);
|
|
@@ -975,9 +1042,16 @@ function emptyState(token, agent, cwd) {
|
|
|
975
1042
|
cwd,
|
|
976
1043
|
createdAt: now,
|
|
977
1044
|
lastUsedAt: now,
|
|
978
|
-
usage: { ...EMPTY_USAGE }
|
|
1045
|
+
usage: { ...EMPTY_USAGE },
|
|
1046
|
+
model: null
|
|
979
1047
|
};
|
|
980
1048
|
}
|
|
1049
|
+
function parseCachedModel(value) {
|
|
1050
|
+
if (!value || typeof value !== "object") return null;
|
|
1051
|
+
const record = value;
|
|
1052
|
+
if (typeof record.value !== "string" || typeof record.label !== "string") return null;
|
|
1053
|
+
return { value: record.value, label: record.label };
|
|
1054
|
+
}
|
|
981
1055
|
function loadState(token) {
|
|
982
1056
|
const path = statePath(token);
|
|
983
1057
|
if (!(0, import_node_fs2.existsSync)(path)) return null;
|
|
@@ -992,7 +1066,8 @@ function loadState(token) {
|
|
|
992
1066
|
cwd: typeof parsed.cwd === "string" ? parsed.cwd : process.cwd(),
|
|
993
1067
|
createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
994
1068
|
lastUsedAt: typeof parsed.lastUsedAt === "string" ? parsed.lastUsedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
995
|
-
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE }
|
|
1069
|
+
usage: parsed.usage && typeof parsed.usage === "object" ? { ...EMPTY_USAGE, ...parsed.usage } : { ...EMPTY_USAGE },
|
|
1070
|
+
model: parseCachedModel(parsed.model)
|
|
996
1071
|
};
|
|
997
1072
|
} catch {
|
|
998
1073
|
return null;
|
|
@@ -1388,6 +1463,8 @@ async function processPrompt(ctx, item, signal) {
|
|
|
1388
1463
|
});
|
|
1389
1464
|
ctx.state.acpSessionId = result.sessionId;
|
|
1390
1465
|
ctx.state.usage = result.usage;
|
|
1466
|
+
const model = ctx.getAgent().currentModel();
|
|
1467
|
+
if (model) ctx.state.model = { value: model.value, label: model.label };
|
|
1391
1468
|
ctx.saveState();
|
|
1392
1469
|
for (const chunk of splitMessage(result.text || "(no output)")) {
|
|
1393
1470
|
await item.reply(chunk);
|