@vicvic-im/agent-bot 0.1.1 → 0.1.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.
- package/README.md +9 -3
- package/dist/agents/acp.d.ts +2 -1
- package/dist/agents/acp.d.ts.map +1 -1
- package/dist/agents/types.d.ts +16 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/bin-server.cjs +1422 -0
- package/dist/bin-server.cjs.map +1 -0
- package/dist/bin-server.d.ts +2 -0
- package/dist/bin-server.d.ts.map +1 -0
- package/dist/bin-server.js +19 -0
- package/dist/bin-server.js.map +1 -0
- package/dist/{chunk-QQ2NXJ3L.js → chunk-CDBYOHVL.js} +2 -2
- package/dist/{chunk-SCVC76UL.js → chunk-ELLWQDOY.js} +217 -105
- package/dist/chunk-ELLWQDOY.js.map +1 -0
- package/dist/cli.cjs +246 -119
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +32 -17
- package/dist/cli.js.map +1 -1
- package/dist/core/dispatcher.d.ts +3 -1
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/pm2.d.ts +7 -0
- package/dist/core/pm2.d.ts.map +1 -0
- package/dist/index.cjs +210 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/server.cjs +210 -96
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +10 -10
- package/dist/chunk-SCVC76UL.js.map +0 -1
- /package/dist/{chunk-QQ2NXJ3L.js.map → chunk-CDBYOHVL.js.map} +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/core/cli-path.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { execFileSync } from \"node:child_process\";\nimport { basename, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { ensureConfig } from \"./commands/setup.js\";\nimport { findConfigPath, loadConfig } from \"./config.js\";\nimport { readPackageVersion, resolveServerEntry } from \"./core/cli-path.js\";\nimport { runBot } from \"./server.js\";\n\ninterface GlobalOptions {\n config?: string;\n}\n\nfunction processName(cwd: string): string {\n return `vbot-${basename(resolve(cwd)).replace(/[^a-zA-Z0-9._-]+/g, \"-\")}`;\n}\n\n// pm2 是可选的外部工具。通过固定的 /usr/bin/env 调用,避免把任意 PATH 条目当作可执行文件;\n// Windows 一期不承诺后台模式,检测失败时退回前台运行。\nconst ENV_BIN = \"/usr/bin/env\";\n\nfunction
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/core/cli-path.ts","../src/core/pm2.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { execFileSync } from \"node:child_process\";\nimport { basename, resolve } from \"node:path\";\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { ensureConfig } from \"./commands/setup.js\";\nimport { findConfigPath, loadConfig } from \"./config.js\";\nimport { readPackageVersion, resolveServerEntry } from \"./core/cli-path.js\";\nimport { ensurePm2, hasPm2 } from \"./core/pm2.js\";\nimport { runBot } from \"./server.js\";\n\ninterface GlobalOptions {\n config?: string;\n}\n\nfunction processName(cwd: string): string {\n return `vbot-${basename(resolve(cwd)).replace(/[^a-zA-Z0-9._-]+/g, \"-\")}`;\n}\n\n// pm2 是可选的外部工具。通过固定的 /usr/bin/env 调用,避免把任意 PATH 条目当作可执行文件;\n// Windows 一期不承诺后台模式,检测失败时退回前台运行。\nconst ENV_BIN = \"/usr/bin/env\";\n\nfunction pm2(args: string[], capture = false): string {\n return execFileSync(ENV_BIN, [\"pm2\", ...args], {\n stdio: capture ? \"pipe\" : \"inherit\",\n encoding: \"utf8\",\n });\n}\n\nfunction resolveName(configPath?: string): string {\n const path = findConfigPath(configPath);\n if (!path) return \"vbot\";\n try {\n const { config } = loadConfig(path);\n return processName(config.agent.cwd);\n } catch {\n return \"vbot\";\n }\n}\n\nfunction cliPath(): string {\n const path = process.argv[1];\n if (!path) throw new Error(\"Cannot resolve vbot entry; run the installed binary.\");\n return path;\n}\n\nconst program = new Command();\nprogram\n .name(\"vbot\")\n .description(\"Connect local coding agents to vicvic.im\")\n .version(readPackageVersion(cliPath()));\n\nprogram\n .command(\"start\")\n .description(\"Start vbot (prompts for config on first run)\")\n .option(\"--foreground\", \"run in the foreground instead of pm2\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action(async (options: GlobalOptions & { foreground?: boolean }) => {\n const { path } = await ensureConfig(options.config);\n if (options.foreground) {\n await runBot(path);\n return;\n }\n if (!hasPm2()) console.log(pc.yellow(\"pm2 not found, installing globally...\"));\n if (!ensurePm2()) {\n console.error(pc.red(\"Failed to install pm2. Please install manually: npm i -g pm2\"));\n console.log(pc.yellow(\"Running in the foreground instead.\"));\n await runBot(path);\n return;\n }\n const name = resolveName(path);\n try {\n pm2([\"describe\", name], true);\n pm2([\"restart\", name, \"--update-env\"]);\n } catch {\n pm2([\n \"start\",\n resolveServerEntry(cliPath()),\n \"--name\",\n name,\n \"--stop-exit-codes\",\n \"2\",\n \"--log-date-format\",\n \"YYYY-MM-DD HH:mm:ss\",\n \"--\",\n path,\n ]);\n }\n pm2([\"save\"], true);\n console.log(pc.green(`✔ ${name} started. Use \"vbot logs\" to view output.`));\n });\n\nprogram\n .command(\"stop\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action((options: GlobalOptions) => {\n try {\n pm2([\"stop\", resolveName(options.config)]);\n } catch {\n console.error(pc.red(\"Failed to stop vbot. Is it running?\"));\n }\n });\n\nprogram\n .command(\"restart\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action((options: GlobalOptions) => {\n try {\n pm2([\"restart\", resolveName(options.config), \"--update-env\"]);\n } catch {\n console.error(pc.red('Failed to restart vbot. Try \"vbot start\".'));\n }\n });\n\nprogram\n .command(\"status\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action((options: GlobalOptions) => {\n try {\n pm2([\"describe\", resolveName(options.config)]);\n } catch {\n console.log(pc.yellow(\"vbot is not running.\"));\n }\n });\n\nprogram\n .command(\"logs\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action((options: GlobalOptions) => {\n try {\n pm2([\"logs\", resolveName(options.config), \"--lines\", \"50\"]);\n } catch {\n console.error(\"Failed to show logs. Is pm2 installed?\");\n }\n });\n\nprogram\n .command(\"delete\")\n .option(\"-c, --config <path>\", \"config file path\")\n .action((options: GlobalOptions) => {\n try {\n pm2([\"delete\", resolveName(options.config)]);\n } catch {\n console.error(\"Failed to delete vbot process.\");\n }\n });\n\nprogram.parseAsync(process.argv).catch((error: unknown) => {\n console.error(pc.red(error instanceof Error ? error.message : String(error)));\n process.exitCode = 1;\n});\n","import { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * 全局安装时 argv[1] 是 bin 目录的符号链接(如 ~/.nvm/.../bin/vbot),\n * 必须 realpath 后定位包内同目录的 server.js;直接 dirname(argv[1]) 会指向 bin 目录。\n */\nexport function resolveServerEntry(cliPath: string): string {\n const real = realpathSync(cliPath);\n const candidate = join(dirname(real), \"bin-server.js\");\n if (!existsSync(candidate)) {\n throw new Error(`Server bundle not found at ${candidate}. Reinstall @vicvic-im/agent-bot.`);\n }\n return candidate;\n}\n\n/** 从真实 dist/cli.js 位置向上读取包版本,避免符号链接导致读错 package.json。 */\nexport function readPackageVersion(cliPath: string): string {\n try {\n const raw = readFileSync(join(dirname(realpathSync(cliPath)), \"..\", \"package.json\"), \"utf8\");\n return (JSON.parse(raw) as { version?: string }).version ?? \"0.1.0\";\n } catch {\n return \"0.1.0\";\n }\n}\n","import { execFileSync } from \"node:child_process\";\n\n// pm2 是可选的外部工具。通过固定的 /usr/bin/env 调用,避免把任意 PATH 条目当作可执行文件。\nconst ENV_BIN = \"/usr/bin/env\";\n\ntype Exec = typeof execFileSync;\n\nexport function hasPm2(exec: Exec = execFileSync): boolean {\n try {\n exec(ENV_BIN, [\"pm2\", \"--version\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/** 与 ccbot 一致:pm2 缺失时自动全局安装;安装失败返回 false,由调用方退前台。 */\nexport function ensurePm2(exec: Exec = execFileSync): boolean {\n if (hasPm2(exec)) return true;\n try {\n exec(ENV_BIN, [\"npm\", \"i\", \"-g\", \"pm2\"], { stdio: \"inherit\" });\n return hasPm2(exec);\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["execFileSync","cliPath","ENV_BIN","execFileSync"]}
|
|
@@ -2,7 +2,7 @@ import type { AgentBackend, AgentName } from "../agents/types.js";
|
|
|
2
2
|
import type { VbotConfig } from "../config.js";
|
|
3
3
|
import type { BotQueue } from "./queue.js";
|
|
4
4
|
import type { VbotState } from "./state.js";
|
|
5
|
-
export declare const HELP_TEXT
|
|
5
|
+
export declare const HELP_TEXT: string;
|
|
6
6
|
export interface Runtime {
|
|
7
7
|
config(): VbotConfig;
|
|
8
8
|
agent(): AgentBackend;
|
|
@@ -10,6 +10,8 @@ export interface Runtime {
|
|
|
10
10
|
state(): VbotState;
|
|
11
11
|
saveState(): void;
|
|
12
12
|
saveConfig(): void;
|
|
13
|
+
/** 串行化对 agent 内部状态的写操作(复用 server 的 gate,避免与进行中的 turn 竞争)。 */
|
|
14
|
+
serialize<T>(task: () => Promise<T>): Promise<T>;
|
|
13
15
|
/** 切换后端;返回给用户的提示。失败时抛错。 */
|
|
14
16
|
switchAgent(name: AgentName): Promise<string>;
|
|
15
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/core/dispatcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/core/dispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAqB,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAoB5C,eAAO,MAAM,SAAS,QAOV,CAAC;AAEb,MAAM,WAAW,OAAO;IACtB,MAAM,IAAI,UAAU,CAAC;IACrB,KAAK,IAAI,YAAY,CAAC;IACtB,KAAK,IAAI,QAAQ,CAAC;IAClB,KAAK,IAAI,SAAS,CAAC;IACnB,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,IAAI,IAAI,CAAC;IACnB,6DAA6D;IAC7D,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,2BAA2B;IAC3B,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AAItF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAiB3D"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
type Exec = typeof execFileSync;
|
|
3
|
+
export declare function hasPm2(exec?: Exec): boolean;
|
|
4
|
+
/** 与 ccbot 一致:pm2 缺失时自动全局安装;安装失败返回 false,由调用方退前台。 */
|
|
5
|
+
export declare function ensurePm2(exec?: Exec): boolean;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=pm2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm2.d.ts","sourceRoot":"","sources":["../../src/core/pm2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKlD,KAAK,IAAI,GAAG,OAAO,YAAY,CAAC;AAEhC,wBAAgB,MAAM,CAAC,IAAI,GAAE,IAAmB,GAAG,OAAO,CAOzD;AAED,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,IAAI,GAAE,IAAmB,GAAG,OAAO,CAQ5D"}
|
package/dist/index.cjs
CHANGED
|
@@ -175,11 +175,11 @@ function parseEnv(value) {
|
|
|
175
175
|
if (value === void 0 || value === null) return void 0;
|
|
176
176
|
const record = asRecord(value, "agent.env");
|
|
177
177
|
const env = {};
|
|
178
|
-
for (const [key,
|
|
179
|
-
if (typeof
|
|
178
|
+
for (const [key, entry] of Object.entries(record)) {
|
|
179
|
+
if (typeof entry !== "string") {
|
|
180
180
|
throw new ConfigError(`Invalid "agent.env.${key}": expected a string`);
|
|
181
181
|
}
|
|
182
|
-
env[key] =
|
|
182
|
+
env[key] = entry;
|
|
183
183
|
}
|
|
184
184
|
return env;
|
|
185
185
|
}
|
|
@@ -223,7 +223,7 @@ function parseAgent(root, configDir) {
|
|
|
223
223
|
return {
|
|
224
224
|
name: agentName,
|
|
225
225
|
command: optionalString(agentRaw.command, "agent.command"),
|
|
226
|
-
args: Array.isArray(argsRaw) ? argsRaw.map((
|
|
226
|
+
args: Array.isArray(argsRaw) ? argsRaw.map((entry) => String(entry)) : void 0,
|
|
227
227
|
cwd,
|
|
228
228
|
model: optionalString(agentRaw.model, "agent.model") ?? null,
|
|
229
229
|
env: parseEnv(agentRaw.env)
|
|
@@ -360,6 +360,9 @@ var acp = __toESM(require("@agentclientprotocol/sdk"), 1);
|
|
|
360
360
|
// src/agents/types.ts
|
|
361
361
|
var EMPTY_USAGE = { used: 0, size: 0, cost: null };
|
|
362
362
|
|
|
363
|
+
// src/version.ts
|
|
364
|
+
var VBOT_VERSION = "0.1.3";
|
|
365
|
+
|
|
363
366
|
// src/agents/acp.ts
|
|
364
367
|
var AgentAbortError = class extends Error {
|
|
365
368
|
constructor() {
|
|
@@ -376,6 +379,14 @@ var AgentStartError = class extends Error {
|
|
|
376
379
|
stderr;
|
|
377
380
|
};
|
|
378
381
|
var STDERR_LIMIT = 4e3;
|
|
382
|
+
function flattenSelectOptions(options) {
|
|
383
|
+
return options.flatMap(
|
|
384
|
+
(entry) => "group" in entry ? entry.options.map((option) => ({ value: option.value, label: option.name })) : [{ value: entry.value, label: entry.name }]
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
function isModelOption(option) {
|
|
388
|
+
return option.type === "select" && (option.category === "model" || option.id === "model");
|
|
389
|
+
}
|
|
379
390
|
var AcpAgent = class {
|
|
380
391
|
constructor(name, config) {
|
|
381
392
|
this.name = name;
|
|
@@ -405,6 +416,14 @@ var AcpAgent = class {
|
|
|
405
416
|
sessionId() {
|
|
406
417
|
return this.session;
|
|
407
418
|
}
|
|
419
|
+
currentModel() {
|
|
420
|
+
const option = this.configOptions.find(isModelOption);
|
|
421
|
+
if (!option || option.type !== "select") return null;
|
|
422
|
+
const value = String(option.currentValue);
|
|
423
|
+
const options = flattenSelectOptions(option.options);
|
|
424
|
+
const label = options.find((entry) => entry.value === value)?.label ?? value;
|
|
425
|
+
return { value, label, options };
|
|
426
|
+
}
|
|
408
427
|
resetSession() {
|
|
409
428
|
this.session = null;
|
|
410
429
|
}
|
|
@@ -472,7 +491,7 @@ var AcpAgent = class {
|
|
|
472
491
|
const init = await this.ctx.request(acp.methods.agent.initialize, {
|
|
473
492
|
protocolVersion: 1,
|
|
474
493
|
clientCapabilities: {},
|
|
475
|
-
clientInfo: { name: "vbot", version:
|
|
494
|
+
clientInfo: { name: "vbot", version: VBOT_VERSION }
|
|
476
495
|
});
|
|
477
496
|
this.initCaps = init.agentCapabilities;
|
|
478
497
|
} catch (error) {
|
|
@@ -559,7 +578,7 @@ var AcpAgent = class {
|
|
|
559
578
|
);
|
|
560
579
|
pending.catch(() => void 0);
|
|
561
580
|
const response = await Promise.race([pending, aborted]);
|
|
562
|
-
await new Promise((
|
|
581
|
+
await new Promise((resolve3) => setImmediate(resolve3));
|
|
563
582
|
if (response.stopReason === "cancelled" || request.signal.aborted) {
|
|
564
583
|
throw new AgentAbortError();
|
|
565
584
|
}
|
|
@@ -591,15 +610,14 @@ var AcpAgent = class {
|
|
|
591
610
|
this.pendingModel = model;
|
|
592
611
|
return true;
|
|
593
612
|
}
|
|
594
|
-
const option = this.configOptions.find(
|
|
595
|
-
(entry2) => entry2.type === "select" && (entry2.id === "model" || entry2.category === "model")
|
|
596
|
-
);
|
|
613
|
+
const option = this.configOptions.find(isModelOption);
|
|
597
614
|
if (!option) return false;
|
|
598
|
-
await this.ctx.request(acp.methods.agent.session.setConfigOption, {
|
|
615
|
+
const response = await this.ctx.request(acp.methods.agent.session.setConfigOption, {
|
|
599
616
|
sessionId: this.session,
|
|
600
617
|
configId: option.id,
|
|
601
618
|
value: model
|
|
602
619
|
});
|
|
620
|
+
if (response?.configOptions?.length) this.configOptions = response.configOptions;
|
|
603
621
|
this.pendingModel = null;
|
|
604
622
|
return true;
|
|
605
623
|
}
|
|
@@ -618,8 +636,8 @@ var AcpAgent = class {
|
|
|
618
636
|
} catch {
|
|
619
637
|
}
|
|
620
638
|
if (!child || child.exitCode !== null) return;
|
|
621
|
-
const exited = new Promise((
|
|
622
|
-
child.once("exit", () =>
|
|
639
|
+
const exited = new Promise((resolve3) => {
|
|
640
|
+
child.once("exit", () => resolve3());
|
|
623
641
|
});
|
|
624
642
|
child.kill("SIGTERM");
|
|
625
643
|
const timer = setTimeout(() => child.kill("SIGKILL"), 3e3);
|
|
@@ -735,21 +753,29 @@ var BotQueue = class {
|
|
|
735
753
|
}
|
|
736
754
|
};
|
|
737
755
|
|
|
738
|
-
// src/version.ts
|
|
739
|
-
var VBOT_VERSION = "0.1.1";
|
|
740
|
-
|
|
741
756
|
// src/core/dispatcher.ts
|
|
742
|
-
var
|
|
743
|
-
|
|
744
|
-
/
|
|
745
|
-
/
|
|
746
|
-
/
|
|
747
|
-
/
|
|
748
|
-
/
|
|
749
|
-
/
|
|
750
|
-
/
|
|
751
|
-
|
|
752
|
-
|
|
757
|
+
var import_node_os2 = require("os");
|
|
758
|
+
var HELP_ROWS = [
|
|
759
|
+
["/new", "Start a new session"],
|
|
760
|
+
["/stop", "Abort the current request"],
|
|
761
|
+
["/status", "Show agent, session and queue status"],
|
|
762
|
+
["/agent [name]", "Show or switch agent backend"],
|
|
763
|
+
["/model [name]", "Show or switch model"],
|
|
764
|
+
["/cost", "Show context usage and cost"],
|
|
765
|
+
["/version", "Show vbot version"],
|
|
766
|
+
["/help", "Show this help"]
|
|
767
|
+
];
|
|
768
|
+
var HELP_FOOTER = "Other /commands are sent to the agent as prompts.";
|
|
769
|
+
var NEW_BUSY_TEXT = "Cannot reset the session while a request is running. Use /stop first.";
|
|
770
|
+
var MODEL_BUSY_TEXT = "Cannot switch model while a request is running. Use /stop first.";
|
|
771
|
+
var HELP_TEXT = [
|
|
772
|
+
table(
|
|
773
|
+
["Command", "Description"],
|
|
774
|
+
HELP_ROWS.map(([command, description]) => [command, description])
|
|
775
|
+
),
|
|
776
|
+
"",
|
|
777
|
+
HELP_FOOTER
|
|
778
|
+
].join("\n");
|
|
753
779
|
function createDispatcher(runtime) {
|
|
754
780
|
return (text, reply) => {
|
|
755
781
|
const send = (message) => {
|
|
@@ -763,11 +789,57 @@ function createDispatcher(runtime) {
|
|
|
763
789
|
});
|
|
764
790
|
};
|
|
765
791
|
}
|
|
792
|
+
function escapeCell(value) {
|
|
793
|
+
return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
794
|
+
}
|
|
795
|
+
function table(headers, rows) {
|
|
796
|
+
const head = `| ${headers.map(escapeCell).join(" | ")} |`;
|
|
797
|
+
const separator = `| ${headers.map(() => "---").join(" | ")} |`;
|
|
798
|
+
const body = rows.map((row) => `| ${row.map(escapeCell).join(" | ")} |`);
|
|
799
|
+
return [head, separator, ...body].join("\n");
|
|
800
|
+
}
|
|
801
|
+
function formatNumber(value) {
|
|
802
|
+
if (!Number.isFinite(value)) return String(value);
|
|
803
|
+
const negative = value < 0;
|
|
804
|
+
const digits = Math.abs(Math.trunc(value)).toString();
|
|
805
|
+
let out = "";
|
|
806
|
+
for (let i = 0; i < digits.length; i += 1) {
|
|
807
|
+
if (i > 0 && (digits.length - i) % 3 === 0) out += ",";
|
|
808
|
+
out += digits[i];
|
|
809
|
+
}
|
|
810
|
+
return negative ? "-" + out : out;
|
|
811
|
+
}
|
|
812
|
+
function percentOf(used, size) {
|
|
813
|
+
if (size <= 0) return null;
|
|
814
|
+
return `${(used / size * 100).toFixed(1)}%`;
|
|
815
|
+
}
|
|
816
|
+
function usageText(runtime) {
|
|
817
|
+
const { used, size } = runtime.state().usage;
|
|
818
|
+
if (size <= 0) return "not reported";
|
|
819
|
+
const base = `${formatNumber(used)} / ${formatNumber(size)}`;
|
|
820
|
+
const percent = percentOf(used, size);
|
|
821
|
+
return percent ? `${base} (${percent})` : base;
|
|
822
|
+
}
|
|
823
|
+
function compactPath(path) {
|
|
824
|
+
const home = (0, import_node_os2.homedir)();
|
|
825
|
+
if (!home) return path;
|
|
826
|
+
if (path === home) return "~";
|
|
827
|
+
const prefix = home + "/";
|
|
828
|
+
if (path.startsWith(prefix)) return "~" + path.slice(home.length);
|
|
829
|
+
return path;
|
|
830
|
+
}
|
|
831
|
+
function modelText(runtime) {
|
|
832
|
+
const current = runtime.agent().currentModel();
|
|
833
|
+
if (current) return current.label;
|
|
834
|
+
const configured = runtime.config().agent.model;
|
|
835
|
+
if (configured) return `${configured} (configured, not applied yet)`;
|
|
836
|
+
return "unknown (session not started)";
|
|
837
|
+
}
|
|
766
838
|
function handleSlashCommand(runtime, text, send) {
|
|
767
839
|
const [rawCommand, ...args] = text.split(/\s+/);
|
|
768
840
|
switch (rawCommand.toLowerCase()) {
|
|
769
841
|
case "/new":
|
|
770
|
-
handleNew(runtime, send);
|
|
842
|
+
void handleNew(runtime, send);
|
|
771
843
|
return null;
|
|
772
844
|
case "/stop":
|
|
773
845
|
handleStop(runtime, send);
|
|
@@ -779,7 +851,7 @@ function handleSlashCommand(runtime, text, send) {
|
|
|
779
851
|
handleAgent(runtime, args, send);
|
|
780
852
|
return null;
|
|
781
853
|
case "/model":
|
|
782
|
-
handleModel(runtime, args, send);
|
|
854
|
+
void handleModel(runtime, args, send);
|
|
783
855
|
return null;
|
|
784
856
|
case "/cost":
|
|
785
857
|
send(costText(runtime));
|
|
@@ -794,12 +866,18 @@ function handleSlashCommand(runtime, text, send) {
|
|
|
794
866
|
return text.slice(1);
|
|
795
867
|
}
|
|
796
868
|
}
|
|
797
|
-
function handleNew(runtime, send) {
|
|
798
|
-
runtime.
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
runtime.
|
|
869
|
+
async function handleNew(runtime, send) {
|
|
870
|
+
if (runtime.queue().status().busy) {
|
|
871
|
+
send(NEW_BUSY_TEXT);
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
await runtime.serialize(async () => {
|
|
875
|
+
runtime.agent().resetSession();
|
|
876
|
+
const state = runtime.state();
|
|
877
|
+
state.acpSessionId = null;
|
|
878
|
+
state.usage = { used: 0, size: 0, cost: null };
|
|
879
|
+
runtime.saveState();
|
|
880
|
+
});
|
|
803
881
|
send("Session reset. Starting a new conversation.");
|
|
804
882
|
}
|
|
805
883
|
function handleStop(runtime, send) {
|
|
@@ -815,12 +893,18 @@ function handleStop(runtime, send) {
|
|
|
815
893
|
}
|
|
816
894
|
function handleAgent(runtime, args, send) {
|
|
817
895
|
const name = args.join(" ").trim();
|
|
896
|
+
const current = runtime.config().agent.name;
|
|
818
897
|
if (!name) {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
898
|
+
send(
|
|
899
|
+
table(
|
|
900
|
+
["Agent", "Backend", ""],
|
|
901
|
+
AGENT_NAMES.map((entry) => [
|
|
902
|
+
entry,
|
|
903
|
+
AGENTS[entry].label,
|
|
904
|
+
entry === current ? "\u2190 current" : ""
|
|
905
|
+
])
|
|
906
|
+
)
|
|
907
|
+
);
|
|
824
908
|
return;
|
|
825
909
|
}
|
|
826
910
|
if (!isAgentName(name)) {
|
|
@@ -836,56 +920,95 @@ ${list}`);
|
|
|
836
920
|
(error) => send(`Error: ${error instanceof Error ? error.message : String(error)}`)
|
|
837
921
|
);
|
|
838
922
|
}
|
|
839
|
-
function handleModel(runtime, args, send) {
|
|
923
|
+
async function handleModel(runtime, args, send) {
|
|
840
924
|
const model = args.join(" ").trim();
|
|
841
925
|
if (!model) {
|
|
842
|
-
send(
|
|
926
|
+
send(modelReport(runtime));
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
if (runtime.queue().status().busy) {
|
|
930
|
+
send(MODEL_BUSY_TEXT);
|
|
843
931
|
return;
|
|
844
932
|
}
|
|
845
933
|
const config = runtime.config();
|
|
846
934
|
const hadSession = runtime.agent().sessionId() !== null;
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
}
|
|
935
|
+
const supported = await runtime.serialize(async () => {
|
|
936
|
+
const accepted = await runtime.agent().setModel(model);
|
|
937
|
+
config.agent.model = model;
|
|
938
|
+
runtime.saveConfig();
|
|
939
|
+
return accepted;
|
|
940
|
+
});
|
|
941
|
+
const applied = runtime.agent().currentModel()?.label ?? model;
|
|
942
|
+
if (!supported) {
|
|
856
943
|
send(
|
|
857
|
-
|
|
944
|
+
`Model saved: ${model}. This agent does not expose a runtime model option; it will be used on the next session if supported.`
|
|
858
945
|
);
|
|
859
|
-
|
|
860
|
-
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
send(
|
|
949
|
+
hadSession ? `Model switched to: ${applied}` : `Model set to: ${applied}. It will apply when the session starts.`
|
|
861
950
|
);
|
|
862
951
|
}
|
|
952
|
+
function modelReport(runtime) {
|
|
953
|
+
const current = runtime.agent().currentModel();
|
|
954
|
+
if (!current) {
|
|
955
|
+
const configured = runtime.config().agent.model;
|
|
956
|
+
const hint = configured ? `Configured: ${configured}
|
|
957
|
+
|
|
958
|
+
The agent has not reported a model yet; it becomes visible after the first message.` : "This agent does not expose a runtime model option, or the session has not started.";
|
|
959
|
+
return `Current: unknown
|
|
960
|
+
|
|
961
|
+
${hint}`;
|
|
962
|
+
}
|
|
963
|
+
const lines = [`Current: ${current.label}`];
|
|
964
|
+
if (current.options.length > 0) {
|
|
965
|
+
lines.push(
|
|
966
|
+
"",
|
|
967
|
+
table(
|
|
968
|
+
["Model", ""],
|
|
969
|
+
current.options.map((option) => [
|
|
970
|
+
option.label,
|
|
971
|
+
option.value === current.value ? "\u2190 current" : ""
|
|
972
|
+
])
|
|
973
|
+
)
|
|
974
|
+
);
|
|
975
|
+
}
|
|
976
|
+
lines.push("", "Switch: /model <name>");
|
|
977
|
+
return lines.join("\n");
|
|
978
|
+
}
|
|
863
979
|
function statusText(runtime) {
|
|
864
980
|
const config = runtime.config();
|
|
865
981
|
const agent = runtime.agent();
|
|
866
982
|
const state = runtime.state();
|
|
867
983
|
const queue = runtime.queue().status();
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
984
|
+
const { used, size } = state.usage;
|
|
985
|
+
const summary = [
|
|
986
|
+
`**${config.agent.name}**`,
|
|
987
|
+
queue.busy ? "busy" : "idle",
|
|
988
|
+
size > 0 ? `${formatNumber(used)} / ${formatNumber(size)}` : null
|
|
989
|
+
].filter(Boolean).join(" \xB7 ");
|
|
990
|
+
const rows = [
|
|
991
|
+
["Agent", `${config.agent.name} (${AGENTS[config.agent.name].label})`],
|
|
992
|
+
["Session", agent.sessionId() ?? "none"],
|
|
993
|
+
["Work dir", compactPath(config.agent.cwd)],
|
|
994
|
+
["Model", modelText(runtime)],
|
|
995
|
+
["Status", queue.busy ? "busy" : "idle"],
|
|
996
|
+
["Queue", String(queue.queued)],
|
|
997
|
+
["Usage", usageText(runtime)],
|
|
998
|
+
["Capabilities", capabilitiesText(agent.capabilities())]
|
|
877
999
|
];
|
|
878
|
-
return
|
|
1000
|
+
return [summary, "", table(["Field", "Value"], rows)].join("\n");
|
|
879
1001
|
}
|
|
880
1002
|
function costText(runtime) {
|
|
881
1003
|
const usage = runtime.state().usage;
|
|
882
|
-
const
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
1004
|
+
const cost = usage.cost ? `${usage.cost.amount} ${usage.cost.currency}` : "not reported by this agent";
|
|
1005
|
+
return table(
|
|
1006
|
+
["Field", "Value"],
|
|
1007
|
+
[
|
|
1008
|
+
["Context", usageText(runtime)],
|
|
1009
|
+
["Cost", cost]
|
|
1010
|
+
]
|
|
1011
|
+
);
|
|
889
1012
|
}
|
|
890
1013
|
function capabilitiesText(caps) {
|
|
891
1014
|
const enabled = [
|
|
@@ -904,10 +1027,10 @@ var import_node_path4 = require("path");
|
|
|
904
1027
|
// src/core/state.ts
|
|
905
1028
|
var import_node_crypto = require("crypto");
|
|
906
1029
|
var import_node_fs3 = require("fs");
|
|
907
|
-
var
|
|
1030
|
+
var import_node_os3 = require("os");
|
|
908
1031
|
var import_node_path3 = require("path");
|
|
909
1032
|
function vbotHome() {
|
|
910
|
-
return process.env.VBOT_HOME?.trim() || (0, import_node_path3.join)((0,
|
|
1033
|
+
return process.env.VBOT_HOME?.trim() || (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".vbot");
|
|
911
1034
|
}
|
|
912
1035
|
function stateDir() {
|
|
913
1036
|
return (0, import_node_path3.join)(vbotHome(), "state");
|
|
@@ -1074,10 +1197,10 @@ var VicvicWire = class {
|
|
|
1074
1197
|
if (!socket || socket.readyState !== import_ws.default.OPEN) {
|
|
1075
1198
|
throw new Error("Bot connection is not open");
|
|
1076
1199
|
}
|
|
1077
|
-
await new Promise((
|
|
1200
|
+
await new Promise((resolve3, reject) => {
|
|
1078
1201
|
socket.send(JSON.stringify({ type: "reply", msgUid, text }), (error) => {
|
|
1079
1202
|
if (error) reject(error);
|
|
1080
|
-
else
|
|
1203
|
+
else resolve3();
|
|
1081
1204
|
});
|
|
1082
1205
|
});
|
|
1083
1206
|
}
|
|
@@ -1201,9 +1324,6 @@ function splitMessage(text, max = MAX_MESSAGE_CHARS) {
|
|
|
1201
1324
|
return chunks;
|
|
1202
1325
|
}
|
|
1203
1326
|
|
|
1204
|
-
// src/server.ts
|
|
1205
|
-
var import_node_path5 = require("path");
|
|
1206
|
-
|
|
1207
1327
|
// src/core/gate.ts
|
|
1208
1328
|
function createGate() {
|
|
1209
1329
|
let tail = Promise.resolve();
|
|
@@ -1284,13 +1404,17 @@ async function startBot(configPath) {
|
|
|
1284
1404
|
saveConfig: () => saveConfig(config, configPath)
|
|
1285
1405
|
};
|
|
1286
1406
|
holder.queue = new BotQueue((item, signal) => gate(() => processPrompt(ctx, item, signal)));
|
|
1287
|
-
const runtime = createRuntime(
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
switching
|
|
1292
|
-
|
|
1293
|
-
|
|
1407
|
+
const runtime = createRuntime(
|
|
1408
|
+
ctx,
|
|
1409
|
+
(task) => gate(task),
|
|
1410
|
+
(name) => {
|
|
1411
|
+
if (switching) return Promise.reject(new Error("Agent switch already in progress."));
|
|
1412
|
+
switching = true;
|
|
1413
|
+
return gate(() => switchAgent(ctx, name)).finally(() => {
|
|
1414
|
+
switching = false;
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
);
|
|
1294
1418
|
const dispatch = createDispatcher(runtime);
|
|
1295
1419
|
let notifySignal = () => void 0;
|
|
1296
1420
|
const wire = new VicvicWire({
|
|
@@ -1351,7 +1475,7 @@ async function runBot(configPath) {
|
|
|
1351
1475
|
const bot = await startBot(configPath);
|
|
1352
1476
|
await bot.finished;
|
|
1353
1477
|
}
|
|
1354
|
-
function createRuntime(ctx, switchAgent2) {
|
|
1478
|
+
function createRuntime(ctx, gate, switchAgent2) {
|
|
1355
1479
|
return {
|
|
1356
1480
|
config: () => ctx.config,
|
|
1357
1481
|
agent: () => ctx.getAgent(),
|
|
@@ -1359,6 +1483,7 @@ function createRuntime(ctx, switchAgent2) {
|
|
|
1359
1483
|
state: () => ctx.state,
|
|
1360
1484
|
saveState: () => ctx.saveState(),
|
|
1361
1485
|
saveConfig: () => ctx.saveConfig(),
|
|
1486
|
+
serialize: (task) => gate(task),
|
|
1362
1487
|
switchAgent: switchAgent2
|
|
1363
1488
|
};
|
|
1364
1489
|
}
|
|
@@ -1410,19 +1535,6 @@ ${error.stderr}`);
|
|
|
1410
1535
|
console.error("[server] agent run failed:", error);
|
|
1411
1536
|
replySafe(reply, `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
1412
1537
|
}
|
|
1413
|
-
var entry = process.argv[1] ?? "";
|
|
1414
|
-
if (/(^|[\\/])server\.(js|cjs|ts)$/.test(entry)) {
|
|
1415
|
-
const configPath = process.argv[2];
|
|
1416
|
-
if (!configPath) {
|
|
1417
|
-
console.error("Usage: server.js <config-path>");
|
|
1418
|
-
process.exit(1);
|
|
1419
|
-
}
|
|
1420
|
-
runBot((0, import_node_path5.resolve)(configPath)).catch((error) => {
|
|
1421
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
1422
|
-
const expected = error instanceof ConfigError || error instanceof LockError;
|
|
1423
|
-
process.exit(expected ? 2 : 1);
|
|
1424
|
-
});
|
|
1425
|
-
}
|
|
1426
1538
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1427
1539
|
0 && (module.exports = {
|
|
1428
1540
|
AGENTS,
|