zencode-cli 0.2.2 → 0.2.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/dist/bin/zencode.js +72 -11
- package/dist/bin/zencode.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/zencode.js
CHANGED
|
@@ -56,6 +56,7 @@ var init_client = __esm({
|
|
|
56
56
|
params.tools = tools;
|
|
57
57
|
params.tool_choice = "auto";
|
|
58
58
|
}
|
|
59
|
+
params.stream_options = { include_usage: true };
|
|
59
60
|
const abortController = new AbortController();
|
|
60
61
|
this.activeAbortController = abortController;
|
|
61
62
|
try {
|
|
@@ -67,7 +68,16 @@ var init_client = __esm({
|
|
|
67
68
|
let reasoningStarted = false;
|
|
68
69
|
let reasoningEnded = false;
|
|
69
70
|
const toolCallMap = /* @__PURE__ */ new Map();
|
|
71
|
+
let usageInfo = null;
|
|
70
72
|
for await (const chunk of stream) {
|
|
73
|
+
const chunkUsage = chunk.usage;
|
|
74
|
+
if (chunkUsage && chunkUsage.total_tokens) {
|
|
75
|
+
usageInfo = {
|
|
76
|
+
prompt_tokens: chunkUsage.prompt_tokens ?? 0,
|
|
77
|
+
completion_tokens: chunkUsage.completion_tokens ?? 0,
|
|
78
|
+
total_tokens: chunkUsage.total_tokens
|
|
79
|
+
};
|
|
80
|
+
}
|
|
71
81
|
const choice = chunk.choices[0];
|
|
72
82
|
if (!choice) continue;
|
|
73
83
|
const delta = choice.delta;
|
|
@@ -140,6 +150,9 @@ var init_client = __esm({
|
|
|
140
150
|
if (toolCalls.length > 0) {
|
|
141
151
|
assistantMessage.tool_calls = toolCalls;
|
|
142
152
|
}
|
|
153
|
+
if (usageInfo) {
|
|
154
|
+
assistantMessage.usage = usageInfo;
|
|
155
|
+
}
|
|
143
156
|
callbacks.onFinish?.(assistantMessage);
|
|
144
157
|
return assistantMessage;
|
|
145
158
|
} catch (error) {
|
|
@@ -193,6 +206,13 @@ var init_client = __esm({
|
|
|
193
206
|
}
|
|
194
207
|
}));
|
|
195
208
|
}
|
|
209
|
+
if (response.usage) {
|
|
210
|
+
result.usage = {
|
|
211
|
+
prompt_tokens: response.usage.prompt_tokens,
|
|
212
|
+
completion_tokens: response.usage.completion_tokens,
|
|
213
|
+
total_tokens: response.usage.total_tokens
|
|
214
|
+
};
|
|
215
|
+
}
|
|
196
216
|
return result;
|
|
197
217
|
}
|
|
198
218
|
get modelName() {
|
|
@@ -1600,7 +1620,8 @@ var init_sub_agent = __esm({
|
|
|
1600
1620
|
allowedTools;
|
|
1601
1621
|
maxTurns;
|
|
1602
1622
|
timeoutMs;
|
|
1603
|
-
|
|
1623
|
+
tracker;
|
|
1624
|
+
constructor(client, registry, config, task, allowedTools = ["read-file", "glob", "grep"], maxTurns = 10, timeoutMs = DEFAULT_TIMEOUT_MS, tracker) {
|
|
1604
1625
|
this.client = client;
|
|
1605
1626
|
this.registry = registry;
|
|
1606
1627
|
this.config = config;
|
|
@@ -1608,6 +1629,7 @@ var init_sub_agent = __esm({
|
|
|
1608
1629
|
this.allowedTools = allowedTools.filter((t) => t !== "spawn-agents" && t !== "todo");
|
|
1609
1630
|
this.maxTurns = Math.min(maxTurns, 15);
|
|
1610
1631
|
this.timeoutMs = timeoutMs;
|
|
1632
|
+
this.tracker = tracker;
|
|
1611
1633
|
}
|
|
1612
1634
|
async run() {
|
|
1613
1635
|
return Promise.race([
|
|
@@ -1637,6 +1659,9 @@ var init_sub_agent = __esm({
|
|
|
1637
1659
|
conversation.getMessages(),
|
|
1638
1660
|
tools.length > 0 ? tools : void 0
|
|
1639
1661
|
);
|
|
1662
|
+
if (assistantMsg.usage && this.tracker) {
|
|
1663
|
+
this.tracker.addTokens(assistantMsg.usage.total_tokens);
|
|
1664
|
+
}
|
|
1640
1665
|
conversation.addAssistantMessage(assistantMsg);
|
|
1641
1666
|
if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {
|
|
1642
1667
|
lastContent = assistantMsg.content || "";
|
|
@@ -1760,7 +1785,7 @@ function createSpawnAgentsTool(client, registry, config, tracker) {
|
|
|
1760
1785
|
if (tools.length === 0) {
|
|
1761
1786
|
tools = DEFAULT_TOOLS.filter((t) => autoTools.includes(t));
|
|
1762
1787
|
}
|
|
1763
|
-
return new SubAgent(client, registry, config, task.description, tools, maxTurns);
|
|
1788
|
+
return new SubAgent(client, registry, config, task.description, tools, maxTurns, void 0, tracker);
|
|
1764
1789
|
});
|
|
1765
1790
|
const wrappedRuns = agents.map(
|
|
1766
1791
|
(agent) => agent.run().then(
|
|
@@ -1929,11 +1954,13 @@ var init_runner = __esm({
|
|
|
1929
1954
|
registry;
|
|
1930
1955
|
config;
|
|
1931
1956
|
agentConfig;
|
|
1932
|
-
|
|
1957
|
+
tracker;
|
|
1958
|
+
constructor(client, registry, config, agentConfig, tracker) {
|
|
1933
1959
|
this.client = client;
|
|
1934
1960
|
this.registry = registry;
|
|
1935
1961
|
this.config = config;
|
|
1936
1962
|
this.agentConfig = agentConfig;
|
|
1963
|
+
this.tracker = tracker;
|
|
1937
1964
|
}
|
|
1938
1965
|
/**
|
|
1939
1966
|
* 执行子 Agent 任务
|
|
@@ -1974,6 +2001,9 @@ ${context}`;
|
|
|
1974
2001
|
tools.length > 0 ? tools : void 0,
|
|
1975
2002
|
callbacks
|
|
1976
2003
|
);
|
|
2004
|
+
if (assistantMsg.usage && this.tracker) {
|
|
2005
|
+
this.tracker.addTokens(assistantMsg.usage.total_tokens);
|
|
2006
|
+
}
|
|
1977
2007
|
conversation.addAssistantMessage(assistantMsg);
|
|
1978
2008
|
if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {
|
|
1979
2009
|
lastContent = assistantMsg.content || "";
|
|
@@ -2058,7 +2088,7 @@ ${context}`;
|
|
|
2058
2088
|
});
|
|
2059
2089
|
|
|
2060
2090
|
// src/tools/dispatch.ts
|
|
2061
|
-
function createDispatchTool(defaultClient, toolRegistry, config, agentRegistry, callbacks) {
|
|
2091
|
+
function createDispatchTool(defaultClient, toolRegistry, config, agentRegistry, tracker, callbacks) {
|
|
2062
2092
|
return {
|
|
2063
2093
|
name: "dispatch",
|
|
2064
2094
|
description: "\u8C03\u5EA6\u5B50 Agent \u6267\u884C\u4E13\u95E8\u4EFB\u52A1\u3002\u5B50 Agent \u6709\u72EC\u7ACB\u5BF9\u8BDD\u548C\u4E13\u5C5E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF0C\u9002\u7528\u4E8E\u9700\u8981\u4E13\u4E1A\u89D2\u8272\u7684\u573A\u666F\u3002",
|
|
@@ -2100,11 +2130,14 @@ function createDispatchTool(defaultClient, toolRegistry, config, agentRegistry,
|
|
|
2100
2130
|
maxTokens: config.max_tokens
|
|
2101
2131
|
});
|
|
2102
2132
|
}
|
|
2103
|
-
const runner = new SubAgentRunner(client, toolRegistry, config, agentConfig);
|
|
2133
|
+
const runner = new SubAgentRunner(client, toolRegistry, config, agentConfig, tracker);
|
|
2134
|
+
tracker?.start([`${agentName}: ${task.slice(0, 60)}`]);
|
|
2104
2135
|
try {
|
|
2105
2136
|
const result = await runner.execute(task, context, callbacks?.() ?? {});
|
|
2137
|
+
tracker?.finish();
|
|
2106
2138
|
return { content: result || "\uFF08\u5B50 Agent \u6267\u884C\u5B8C\u6210\uFF0C\u65E0\u8F93\u51FA\uFF09" };
|
|
2107
2139
|
} catch (err) {
|
|
2140
|
+
tracker?.finish();
|
|
2108
2141
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2109
2142
|
return { content: `\u5B50 Agent \u6267\u884C\u9519\u8BEF\uFF1A${msg}` };
|
|
2110
2143
|
}
|
|
@@ -2407,7 +2440,8 @@ var init_sub_agent_tracker = __esm({
|
|
|
2407
2440
|
total: descriptions.length,
|
|
2408
2441
|
completed: 0,
|
|
2409
2442
|
failed: 0,
|
|
2410
|
-
descriptions
|
|
2443
|
+
descriptions,
|
|
2444
|
+
tokens: 0
|
|
2411
2445
|
};
|
|
2412
2446
|
this.notify();
|
|
2413
2447
|
}
|
|
@@ -2421,6 +2455,11 @@ var init_sub_agent_tracker = __esm({
|
|
|
2421
2455
|
this.progress = { ...this.progress, failed: this.progress.failed + 1 };
|
|
2422
2456
|
this.notify();
|
|
2423
2457
|
}
|
|
2458
|
+
addTokens(count) {
|
|
2459
|
+
if (!this.progress) return;
|
|
2460
|
+
this.progress = { ...this.progress, tokens: this.progress.tokens + count };
|
|
2461
|
+
this.notify();
|
|
2462
|
+
}
|
|
2424
2463
|
finish() {
|
|
2425
2464
|
this.progress = null;
|
|
2426
2465
|
this.notify();
|
|
@@ -2712,9 +2751,21 @@ function getToolParamSummary(name, params) {
|
|
|
2712
2751
|
case "glob":
|
|
2713
2752
|
case "grep":
|
|
2714
2753
|
return String(params["pattern"] || "");
|
|
2754
|
+
case "spawn-agents": {
|
|
2755
|
+
const tasks = params["tasks"];
|
|
2756
|
+
if (!tasks || tasks.length === 0) return "";
|
|
2757
|
+
return `${tasks.length} tasks: ${tasks.map((t) => t.description || "?").join(" | ").slice(0, 100)}`;
|
|
2758
|
+
}
|
|
2759
|
+
case "dispatch":
|
|
2760
|
+
return `${params["agent"] || "?"}: ${String(params["task"] || "").slice(0, 80)}`;
|
|
2715
2761
|
default:
|
|
2716
2762
|
const keys = Object.keys(params);
|
|
2717
|
-
|
|
2763
|
+
if (keys.length === 0) return "";
|
|
2764
|
+
const val = params[keys[0]];
|
|
2765
|
+
if (val === null || val === void 0) return "";
|
|
2766
|
+
if (typeof val === "string") return val.slice(0, 60);
|
|
2767
|
+
if (typeof val === "number" || typeof val === "boolean") return String(val);
|
|
2768
|
+
return JSON.stringify(val).slice(0, 60);
|
|
2718
2769
|
}
|
|
2719
2770
|
}
|
|
2720
2771
|
function truncateContent(text, maxLines) {
|
|
@@ -2972,6 +3023,11 @@ var init_InputArea = __esm({
|
|
|
2972
3023
|
// src/cli/tui/components/StatusBar.tsx
|
|
2973
3024
|
import { Box as Box5, Text as Text4 } from "ink";
|
|
2974
3025
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3026
|
+
function formatTokens(n) {
|
|
3027
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
3028
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
3029
|
+
return String(n);
|
|
3030
|
+
}
|
|
2975
3031
|
function StatusBar({ isRunning, modelName, todoPlan, subAgentProgress }) {
|
|
2976
3032
|
const todoProgress = todoPlan ? `${todoPlan.items.filter((i) => i.status === "completed").length}/${todoPlan.items.length}` : null;
|
|
2977
3033
|
return /* @__PURE__ */ jsxs4(Box5, { marginTop: 1, children: [
|
|
@@ -2985,16 +3041,21 @@ function StatusBar({ isRunning, modelName, todoPlan, subAgentProgress }) {
|
|
|
2985
3041
|
subAgentProgress && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2986
3042
|
/* @__PURE__ */ jsx5(Text4, { color: "#ebdbb2", children: " \u2502 " }),
|
|
2987
3043
|
/* @__PURE__ */ jsxs4(Text4, { color: "#b8bb26", children: [
|
|
2988
|
-
"
|
|
3044
|
+
"Agents: ",
|
|
2989
3045
|
subAgentProgress.completed + subAgentProgress.failed,
|
|
2990
3046
|
"/",
|
|
2991
3047
|
subAgentProgress.total
|
|
3048
|
+
] }),
|
|
3049
|
+
/* @__PURE__ */ jsx5(Text4, { color: "#ebdbb2", children: " \u2502 " }),
|
|
3050
|
+
/* @__PURE__ */ jsxs4(Text4, { color: "#83a598", children: [
|
|
3051
|
+
"tokens: ",
|
|
3052
|
+
formatTokens(subAgentProgress.tokens)
|
|
2992
3053
|
] })
|
|
2993
3054
|
] }),
|
|
2994
3055
|
todoProgress && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
2995
3056
|
/* @__PURE__ */ jsx5(Text4, { color: "#ebdbb2", children: " \u2502 " }),
|
|
2996
3057
|
/* @__PURE__ */ jsxs4(Text4, { color: "#fabd2f", children: [
|
|
2997
|
-
"
|
|
3058
|
+
"Plan: ",
|
|
2998
3059
|
todoProgress
|
|
2999
3060
|
] })
|
|
3000
3061
|
] })
|
|
@@ -3687,7 +3748,7 @@ async function startTui(options) {
|
|
|
3687
3748
|
if (config.features.todo === "on") {
|
|
3688
3749
|
registry.register(createTodoTool(todoStore));
|
|
3689
3750
|
}
|
|
3690
|
-
registry.register(createDispatchTool(client, registry, config, agentRegistry));
|
|
3751
|
+
registry.register(createDispatchTool(client, registry, config, agentRegistry, subAgentTracker));
|
|
3691
3752
|
const agent = new Agent(client, registry, config, systemPrompt);
|
|
3692
3753
|
const { waitUntilExit } = render(
|
|
3693
3754
|
/* @__PURE__ */ jsx10(
|
|
@@ -4234,7 +4295,7 @@ async function runOnce(prompt, config) {
|
|
|
4234
4295
|
}
|
|
4235
4296
|
function createCli() {
|
|
4236
4297
|
const program2 = new Command();
|
|
4237
|
-
program2.name("zencode").description("\u6781\u7B80 CLI AI \u7F16\u7A0B\u5DE5\u5177").version("0.2.
|
|
4298
|
+
program2.name("zencode").description("\u6781\u7B80 CLI AI \u7F16\u7A0B\u5DE5\u5177").version("0.2.3").option("-m, --model <model>", "\u6307\u5B9A\u6A21\u578B\u540D\u79F0").option("-k, --api-key <key>", "API \u5BC6\u94A5").option("-u, --base-url <url>", "API \u57FA\u7840 URL").option("--simple", "\u4F7F\u7528\u7B80\u5355 REPL \u6A21\u5F0F\uFF08\u975E\u5168\u5C4F TUI\uFF09").argument("[prompt...]", "\u76F4\u63A5\u6267\u884C\u7684\u63D0\u793A\u8BCD\uFF08\u975E\u4EA4\u4E92\u5F0F\uFF09").action(async (promptParts, opts) => {
|
|
4238
4299
|
const config = loadConfig(opts);
|
|
4239
4300
|
if (!config.api_key) {
|
|
4240
4301
|
printError("\u672A\u8BBE\u7F6E API \u5BC6\u94A5\u3002\u8BF7\u901A\u8FC7\u4EE5\u4E0B\u65B9\u5F0F\u4E4B\u4E00\u8BBE\u7F6E\uFF1A");
|