jinzd-ai-cli 0.4.185 → 0.4.187
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/{batch-ILD2EPEO.js → batch-UTP6NYVX.js} +2 -2
- package/dist/{chunk-ZO4LKUDM.js → chunk-43T4MY5B.js} +1 -1
- package/dist/{chunk-GSRXKHZ7.js → chunk-4SZ6X47A.js} +1 -1
- package/dist/{chunk-5LK7H45B.js → chunk-IQ7JE43O.js} +1450 -1321
- package/dist/{chunk-A5VODFAK.js → chunk-L5L5B7HD.js} +1 -1
- package/dist/{chunk-GH32XE5K.js → chunk-MVK25WZW.js} +1 -1
- package/dist/{chunk-GOS4DWW5.js → chunk-Q6BSUIDV.js} +3 -3
- package/dist/{chunk-PMZCQAJL.js → chunk-SOWBY545.js} +1 -1
- package/dist/{chunk-FHZ2LKM5.js → chunk-UAJKGLRV.js} +1 -1
- package/dist/{chunk-U7P5A3MJ.js → chunk-ZTBUTA24.js} +2 -2
- package/dist/{ci-7YWXFKGE.js → ci-2WFKSG2J.js} +3 -3
- package/dist/{constants-RJDN7GOH.js → constants-XEL5347E.js} +1 -1
- package/dist/{doctor-cli-X6MOE3YE.js → doctor-cli-MYJFAWKV.js} +5 -5
- package/dist/electron-server.js +1342 -1127
- package/dist/{hub-SFMWUEUW.js → hub-CHE7JDIH.js} +1 -1
- package/dist/index.js +478 -582
- package/dist/{run-tests-YOP7AKRA.js → run-tests-NWRKAVFS.js} +1 -1
- package/dist/{run-tests-37RHYYD4.js → run-tests-Z7IGVS2W.js} +2 -2
- package/dist/{server-H3KIFOLK.js → server-25WVH5YX.js} +4 -4
- package/dist/{server-UT6PLLZC.js → server-2B5JDVJS.js} +204 -256
- package/dist/{task-orchestrator-2FOUTUSP.js → task-orchestrator-DC7NGBQA.js} +4 -4
- package/dist/{usage-5KBD4UBB.js → usage-ZVKFH7BM.js} +2 -2
- package/package.json +1 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ToolRegistry
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q6BSUIDV.js";
|
|
5
5
|
import "./chunk-HDSKW7Q3.js";
|
|
6
6
|
import "./chunk-ZWVIDFGY.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-4SZ6X47A.js";
|
|
8
8
|
import {
|
|
9
9
|
runTool
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-MVK25WZW.js";
|
|
11
11
|
import {
|
|
12
12
|
getDangerLevel,
|
|
13
13
|
schemaToJsonSchema
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import "./chunk-TZQHYZKT.js";
|
|
16
16
|
import {
|
|
17
17
|
VERSION
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SOWBY545.js";
|
|
19
19
|
import "./chunk-4BKXL7SM.js";
|
|
20
20
|
import "./chunk-MM3F43H6.js";
|
|
21
21
|
import "./chunk-KHYD3WXE.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
loadDevState,
|
|
20
20
|
persistToolRound,
|
|
21
21
|
setupProxy
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZTBUTA24.js";
|
|
23
23
|
import {
|
|
24
24
|
ToolExecutor,
|
|
25
25
|
ToolRegistry,
|
|
@@ -37,10 +37,10 @@ import {
|
|
|
37
37
|
spawnAgentContext,
|
|
38
38
|
truncateOutput,
|
|
39
39
|
undoStack
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-Q6BSUIDV.js";
|
|
41
41
|
import "./chunk-HDSKW7Q3.js";
|
|
42
42
|
import "./chunk-ZWVIDFGY.js";
|
|
43
|
-
import "./chunk-
|
|
43
|
+
import "./chunk-4SZ6X47A.js";
|
|
44
44
|
import {
|
|
45
45
|
SessionManager,
|
|
46
46
|
getContentText
|
|
@@ -50,39 +50,28 @@ import {
|
|
|
50
50
|
formatCost
|
|
51
51
|
} from "./chunk-V37XOYOE.js";
|
|
52
52
|
import {
|
|
53
|
-
BudgetWarner,
|
|
54
53
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
55
|
-
ContextPressureMonitor,
|
|
56
|
-
EmptyResponseGuard,
|
|
57
|
-
FreeRoundTracker,
|
|
58
|
-
HALLUCINATION_CORRECTION_MESSAGE,
|
|
59
54
|
ProviderRegistry,
|
|
60
55
|
TEE_FINAL_USER_NUDGE,
|
|
61
56
|
TOOL_CALL_REMINDER,
|
|
62
|
-
accumulateUsage,
|
|
63
57
|
buildRoundBudgetHint,
|
|
64
|
-
buildRoundsExhaustedPrompt,
|
|
65
|
-
buildUserStopMessage,
|
|
66
58
|
consumeToolCallStream,
|
|
67
59
|
detectMetaNarration,
|
|
68
60
|
detectPseudoToolCalls,
|
|
69
|
-
detectsHallucinatedFileOp,
|
|
70
|
-
extractBashCommands,
|
|
71
|
-
hadPreviousWriteToolCalls,
|
|
72
61
|
looksLikeDocumentBody,
|
|
62
|
+
runAgentLoop,
|
|
73
63
|
stripPseudoToolCalls,
|
|
74
|
-
stripToolCallReminder
|
|
75
|
-
|
|
76
|
-
} from "./chunk-5LK7H45B.js";
|
|
64
|
+
stripToolCallReminder
|
|
65
|
+
} from "./chunk-IQ7JE43O.js";
|
|
77
66
|
import {
|
|
78
67
|
runTool
|
|
79
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-MVK25WZW.js";
|
|
80
69
|
import {
|
|
81
70
|
getDangerLevel
|
|
82
71
|
} from "./chunk-HIU2SH4V.js";
|
|
83
72
|
import {
|
|
84
73
|
ConfigManager
|
|
85
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-UAJKGLRV.js";
|
|
86
75
|
import "./chunk-TZQHYZKT.js";
|
|
87
76
|
import {
|
|
88
77
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -102,7 +91,7 @@ import {
|
|
|
102
91
|
SKILLS_DIR_NAME,
|
|
103
92
|
VERSION,
|
|
104
93
|
buildUserIdentityPrompt
|
|
105
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-SOWBY545.js";
|
|
106
95
|
import {
|
|
107
96
|
formatGitContextForPrompt,
|
|
108
97
|
getGitContext,
|
|
@@ -1007,7 +996,6 @@ var SessionHandler = class _SessionHandler {
|
|
|
1007
996
|
async handleChatWithTools(provider, messages, toolDefs, mcpBudgetNote) {
|
|
1008
997
|
const session = this.sessions.current;
|
|
1009
998
|
const apiMessages = [...messages];
|
|
1010
|
-
const extraMessages = [];
|
|
1011
999
|
const maxToolRounds = this.config.get("maxToolRounds") ?? DEFAULT_MAX_TOOL_ROUNDS;
|
|
1012
1000
|
const autoPauseIntervalRaw = this.config.get("autoPauseInterval");
|
|
1013
1001
|
const autoPauseInterval = typeof autoPauseIntervalRaw === "number" ? autoPauseIntervalRaw : 50;
|
|
@@ -1018,37 +1006,113 @@ var SessionHandler = class _SessionHandler {
|
|
|
1018
1006
|
${mcpBudgetNote}` : "");
|
|
1019
1007
|
const systemPromptVolatile = toolVolatile;
|
|
1020
1008
|
const modelParams = this.getModelParams();
|
|
1021
|
-
const
|
|
1009
|
+
const usage = { inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0 };
|
|
1022
1010
|
const supportsStreamingTools = typeof provider.chatWithToolsStream === "function";
|
|
1023
|
-
const roundToolHistory = [];
|
|
1024
|
-
const budgetWarner = new BudgetWarner(maxToolRounds);
|
|
1025
|
-
const emptyGuard = new EmptyResponseGuard();
|
|
1026
|
-
const ctxMonitor = new ContextPressureMonitor();
|
|
1027
|
-
const freeRounds = new FreeRoundTracker();
|
|
1028
1011
|
const ac = new AbortController();
|
|
1029
1012
|
this.abortController = ac;
|
|
1030
1013
|
try {
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
this.
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1014
|
+
const loopResult = await runAgentLoop({
|
|
1015
|
+
maxToolRounds,
|
|
1016
|
+
autoPauseInterval,
|
|
1017
|
+
planMode: this.planMode,
|
|
1018
|
+
providerId: this.currentProvider,
|
|
1019
|
+
toolDefs,
|
|
1020
|
+
signal: ac.signal,
|
|
1021
|
+
usage,
|
|
1022
|
+
callModel: async (_round, extraMessages) => {
|
|
1023
|
+
const chatRequest = {
|
|
1024
|
+
messages: apiMessages,
|
|
1025
|
+
model: this.currentModel,
|
|
1026
|
+
systemPrompt,
|
|
1027
|
+
systemPromptVolatile,
|
|
1028
|
+
stream: false,
|
|
1029
|
+
temperature: modelParams.temperature,
|
|
1030
|
+
maxTokens: modelParams.maxTokens,
|
|
1031
|
+
timeout: modelParams.timeout,
|
|
1032
|
+
thinking: modelParams.thinking,
|
|
1033
|
+
thinkingBudget: modelParams.thinkingBudget,
|
|
1034
|
+
signal: ac.signal,
|
|
1035
|
+
...extraMessages.length > 0 ? { _extraMessages: extraMessages } : {}
|
|
1036
|
+
};
|
|
1037
|
+
try {
|
|
1038
|
+
if (supportsStreamingTools) {
|
|
1039
|
+
const streamGen = provider.chatWithToolsStream(chatRequest, toolDefs);
|
|
1040
|
+
return await this.consumeToolStream(streamGen, ac);
|
|
1041
|
+
}
|
|
1042
|
+
const result = await provider.chatWithTools(chatRequest, toolDefs);
|
|
1043
|
+
return result;
|
|
1044
|
+
} catch (providerErr) {
|
|
1045
|
+
const errMsg = providerErr instanceof Error ? providerErr.message : String(providerErr);
|
|
1046
|
+
const isCtxLengthError = /maximum context length|context_length_exceeded|context window|too many tokens|reduce the length of the messages/i.test(errMsg);
|
|
1047
|
+
if (isCtxLengthError) {
|
|
1048
|
+
this.send({
|
|
1049
|
+
type: "response_done",
|
|
1050
|
+
content: `\u26A0 Context length exceeded \u2014 the conversation is too long for this model.
|
|
1051
|
+
|
|
1052
|
+
Details: ${errMsg.split("\n")[0]}
|
|
1053
|
+
|
|
1054
|
+
**Recovery options**:
|
|
1055
|
+
1. Run \`/compact\` to summarize old messages and free context
|
|
1056
|
+
2. Run \`/clear\` to start a fresh session
|
|
1057
|
+
3. Run \`/model\` to switch to a model with a larger context window`,
|
|
1058
|
+
usage
|
|
1059
|
+
});
|
|
1060
|
+
return { stopLoop: true };
|
|
1061
|
+
}
|
|
1062
|
+
throw providerErr;
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
1065
|
+
callSummary: async (summaryExtra) => {
|
|
1066
|
+
const summaryResult = await provider.chatWithTools(
|
|
1067
|
+
{
|
|
1068
|
+
messages: apiMessages,
|
|
1069
|
+
model: this.currentModel,
|
|
1070
|
+
systemPrompt,
|
|
1071
|
+
systemPromptVolatile,
|
|
1072
|
+
stream: false,
|
|
1073
|
+
temperature: modelParams.temperature,
|
|
1074
|
+
maxTokens: modelParams.maxTokens,
|
|
1075
|
+
timeout: modelParams.timeout,
|
|
1076
|
+
_extraMessages: summaryExtra
|
|
1077
|
+
},
|
|
1078
|
+
[]
|
|
1079
|
+
);
|
|
1080
|
+
return "content" in summaryResult ? { content: summaryResult.content, usage: summaryResult.usage } : { usage: summaryResult.usage };
|
|
1081
|
+
},
|
|
1082
|
+
executeTools: async (toolCalls) => {
|
|
1083
|
+
googleSearchContext.configManager = this.config;
|
|
1084
|
+
spawnAgentContext.provider = provider;
|
|
1085
|
+
spawnAgentContext.model = this.currentModel;
|
|
1086
|
+
spawnAgentContext.systemPrompt = systemPromptVolatile ? `${systemPrompt}
|
|
1087
|
+
|
|
1088
|
+
---
|
|
1089
|
+
|
|
1090
|
+
${systemPromptVolatile}` : systemPrompt;
|
|
1091
|
+
spawnAgentContext.modelParams = modelParams;
|
|
1092
|
+
spawnAgentContext.configManager = this.config;
|
|
1093
|
+
ToolExecutor.currentMessageIndex = this.sessions.current?.messages.length ?? 0;
|
|
1094
|
+
return this.toolExecutor.executeAll(toolCalls);
|
|
1095
|
+
},
|
|
1096
|
+
buildToolResultMessages: (toolCalls, results, reasoningContent) => provider.buildToolResultMessages(toolCalls, results, reasoningContent),
|
|
1097
|
+
getContextWindow: () => this.getContextWindowSize(),
|
|
1098
|
+
estimateRequestTokens: (extraMessages) => this.estimateRequestTokens(systemPrompt, extraMessages),
|
|
1099
|
+
pollInterjection: () => {
|
|
1100
|
+
if (!this.userInterjection) return null;
|
|
1043
1101
|
const msg = this.userInterjection;
|
|
1044
1102
|
this.userInterjection = null;
|
|
1045
1103
|
this.send({ type: "info", message: `\u26A1 Interjection: "${msg}"` });
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1104
|
+
return msg;
|
|
1105
|
+
},
|
|
1106
|
+
onRoundStart: (round, total) => {
|
|
1107
|
+
this.toolExecutor.setRoundInfo(round + 1, total);
|
|
1108
|
+
this.send({ type: "round_progress", current: round + 1, total });
|
|
1109
|
+
},
|
|
1110
|
+
onBudgetWarning: (warning) => {
|
|
1111
|
+
if (warning.displayMessage) {
|
|
1112
|
+
this.send({ type: "info", message: warning.displayMessage });
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
1115
|
+
onContextPressure: (pressure, ctxWindow) => {
|
|
1052
1116
|
if (pressure.action === "abort") {
|
|
1053
1117
|
this.send({
|
|
1054
1118
|
type: "response_done",
|
|
@@ -1060,191 +1124,48 @@ Too much tool output accumulated this turn. Your work so far is preserved.
|
|
|
1060
1124
|
1. Run \`/compact\` to shrink history, then ask the AI to continue
|
|
1061
1125
|
2. Run \`/clear\` to start fresh
|
|
1062
1126
|
3. Switch to a larger-context model`,
|
|
1063
|
-
usage
|
|
1127
|
+
usage
|
|
1064
1128
|
});
|
|
1065
|
-
|
|
1066
|
-
session.addTokenUsage(roundUsage);
|
|
1067
|
-
return;
|
|
1068
|
-
} else if (pressure.action === "warn") {
|
|
1129
|
+
} else {
|
|
1069
1130
|
this.send({
|
|
1070
1131
|
type: "info",
|
|
1071
1132
|
message: `\u26A0 Context at ${Math.round(pressure.ratio * 100)}% \u2014 asking AI to wrap up`
|
|
1072
1133
|
});
|
|
1073
|
-
extraMessages.push({ role: "user", content: pressure.injectMessage });
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
const chatRequest = {
|
|
1077
|
-
messages: apiMessages,
|
|
1078
|
-
model: this.currentModel,
|
|
1079
|
-
systemPrompt,
|
|
1080
|
-
systemPromptVolatile,
|
|
1081
|
-
stream: false,
|
|
1082
|
-
temperature: modelParams.temperature,
|
|
1083
|
-
maxTokens: modelParams.maxTokens,
|
|
1084
|
-
timeout: modelParams.timeout,
|
|
1085
|
-
thinking: modelParams.thinking,
|
|
1086
|
-
thinkingBudget: modelParams.thinkingBudget,
|
|
1087
|
-
signal: ac.signal,
|
|
1088
|
-
...extraMessages.length > 0 ? { _extraMessages: extraMessages } : {}
|
|
1089
|
-
};
|
|
1090
|
-
let result;
|
|
1091
|
-
try {
|
|
1092
|
-
if (supportsStreamingTools) {
|
|
1093
|
-
const streamGen = provider.chatWithToolsStream(chatRequest, toolDefs);
|
|
1094
|
-
result = await this.consumeToolStream(streamGen, ac);
|
|
1095
|
-
} else {
|
|
1096
|
-
result = await provider.chatWithTools(chatRequest, toolDefs);
|
|
1097
1134
|
}
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
content: `\u26A0 Context length exceeded \u2014 the conversation is too long for this model.
|
|
1105
|
-
|
|
1106
|
-
Details: ${errMsg.split("\n")[0]}
|
|
1107
|
-
|
|
1108
|
-
**Recovery options**:
|
|
1109
|
-
1. Run \`/compact\` to summarize old messages and free context
|
|
1110
|
-
2. Run \`/clear\` to start a fresh session
|
|
1111
|
-
3. Run \`/model\` to switch to a model with a larger context window`,
|
|
1112
|
-
usage: roundUsage
|
|
1113
|
-
});
|
|
1114
|
-
this.addWebSessionUsage(roundUsage);
|
|
1115
|
-
session.addTokenUsage(roundUsage);
|
|
1116
|
-
return;
|
|
1117
|
-
}
|
|
1118
|
-
throw providerErr;
|
|
1119
|
-
}
|
|
1120
|
-
if (ac.signal.aborted) break;
|
|
1121
|
-
accumulateUsage(roundUsage, result.usage);
|
|
1122
|
-
const hasToolCalls = !!(result.toolCalls && result.toolCalls.length > 0);
|
|
1123
|
-
const contentBlank = !result.content || result.content.trim() === "";
|
|
1124
|
-
if (!hasToolCalls && contentBlank) {
|
|
1125
|
-
const decision = emptyGuard.onEmpty(round < maxToolRounds - 1, result.finishReason);
|
|
1135
|
+
},
|
|
1136
|
+
onHallucinationRetry: ({ phantomPaths }) => {
|
|
1137
|
+
const detail = phantomPaths.length > 0 ? ` (phantom files: ${phantomPaths.join(", ")})` : "";
|
|
1138
|
+
this.send({ type: "info", message: `\u26A0 Hallucinated completion detected, forcing retry...${detail}` });
|
|
1139
|
+
},
|
|
1140
|
+
onEmptyResponse: (decision) => {
|
|
1126
1141
|
if (decision.action === "nudge") {
|
|
1127
1142
|
this.send({ type: "info", message: decision.displayMessage });
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
type: "response_done",
|
|
1133
|
-
content: `${decision.displayMessage}
|
|
1143
|
+
} else {
|
|
1144
|
+
this.send({
|
|
1145
|
+
type: "response_done",
|
|
1146
|
+
content: `${decision.displayMessage}
|
|
1134
1147
|
|
|
1135
1148
|
${decision.hint}
|
|
1136
1149
|
Try: /compact to reduce context, /clear to reset, or switch to a larger-context model.`,
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
emptyGuard.onNonEmpty();
|
|
1144
|
-
if (result.content && !result.toolCalls) {
|
|
1145
|
-
const hasWriteTools = toolDefs.some((t) => t.name === "write_file" || t.name === "edit_file");
|
|
1146
|
-
const alreadyWrote = hadPreviousWriteToolCalls(extraMessages);
|
|
1147
|
-
const bashRanThisTurn = extractBashCommands(extraMessages).length > 0;
|
|
1148
|
-
if (hasWriteTools && !alreadyWrote && !bashRanThisTurn && detectsHallucinatedFileOp(result.content) && round < maxToolRounds - 1) {
|
|
1149
|
-
this.send({ type: "info", message: "\u26A0 Hallucinated completion detected, forcing retry..." });
|
|
1150
|
-
const reasoningField = result.reasoningContent ? { reasoning_content: result.reasoningContent } : this.currentProvider === "deepseek" ? { reasoning_content: "" } : {};
|
|
1151
|
-
extraMessages.push(
|
|
1152
|
-
{ role: "assistant", content: result.content, ...reasoningField },
|
|
1153
|
-
{ role: "user", content: HALLUCINATION_CORRECTION_MESSAGE }
|
|
1154
|
-
);
|
|
1155
|
-
continue;
|
|
1156
|
-
}
|
|
1157
|
-
this.send({ type: "response_done", content: result.content, usage: roundUsage });
|
|
1150
|
+
usage
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
},
|
|
1154
|
+
onFinalContent: (content, { reasoningContent }) => {
|
|
1155
|
+
this.send({ type: "response_done", content, usage });
|
|
1158
1156
|
session.addMessage({
|
|
1159
1157
|
role: "assistant",
|
|
1160
|
-
content
|
|
1158
|
+
content,
|
|
1161
1159
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1162
|
-
...
|
|
1160
|
+
...reasoningContent ? { reasoningContent } : {}
|
|
1163
1161
|
});
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
tools: result.toolCalls.map((tc) => tc.name)
|
|
1172
|
-
});
|
|
1173
|
-
for (const tc of result.toolCalls) {
|
|
1174
|
-
if (tc.name.startsWith("mcp__")) this.usedMcpToolNames.add(tc.name);
|
|
1175
|
-
}
|
|
1176
|
-
googleSearchContext.configManager = this.config;
|
|
1177
|
-
spawnAgentContext.provider = provider;
|
|
1178
|
-
spawnAgentContext.model = this.currentModel;
|
|
1179
|
-
spawnAgentContext.systemPrompt = systemPromptVolatile ? `${systemPrompt}
|
|
1180
|
-
|
|
1181
|
-
---
|
|
1182
|
-
|
|
1183
|
-
${systemPromptVolatile}` : systemPrompt;
|
|
1184
|
-
spawnAgentContext.modelParams = modelParams;
|
|
1185
|
-
spawnAgentContext.configManager = this.config;
|
|
1186
|
-
ToolExecutor.currentMessageIndex = this.sessions.current?.messages.length ?? 0;
|
|
1187
|
-
const saveLastResponseCall = result.toolCalls.find((tc) => tc.name === "save_last_response");
|
|
1188
|
-
const saveLastResponsePath = saveLastResponseCall ? String(saveLastResponseCall.arguments["path"] ?? "") : "";
|
|
1189
|
-
if (saveLastResponseCall && saveLastResponsePath) {
|
|
1190
|
-
const teeResult = await this.runSaveLastResponseTee(
|
|
1191
|
-
provider,
|
|
1192
|
-
saveLastResponseCall,
|
|
1193
|
-
saveLastResponsePath,
|
|
1194
|
-
apiMessages,
|
|
1195
|
-
extraMessages,
|
|
1196
|
-
systemPrompt,
|
|
1197
|
-
systemPromptVolatile,
|
|
1198
|
-
modelParams,
|
|
1199
|
-
ac,
|
|
1200
|
-
roundUsage
|
|
1201
|
-
);
|
|
1202
|
-
const teeToolResults = result.toolCalls.map((tc) => {
|
|
1203
|
-
if (tc.id === saveLastResponseCall.id) {
|
|
1204
|
-
return {
|
|
1205
|
-
callId: tc.id,
|
|
1206
|
-
content: teeResult.summary,
|
|
1207
|
-
isError: teeResult.isError
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
return {
|
|
1211
|
-
callId: tc.id,
|
|
1212
|
-
content: "[skipped: file already saved by tee streaming]",
|
|
1213
|
-
isError: false
|
|
1214
|
-
};
|
|
1215
|
-
});
|
|
1216
|
-
const reasoningContent2 = result.reasoningContent;
|
|
1217
|
-
const newMsgs2 = provider.buildToolResultMessages(result.toolCalls, teeToolResults, reasoningContent2);
|
|
1218
|
-
extraMessages.push(...newMsgs2);
|
|
1219
|
-
persistToolRound(session, result.toolCalls, teeToolResults, {
|
|
1220
|
-
assistantContent: teeResult.content,
|
|
1221
|
-
reasoningContent: reasoningContent2
|
|
1222
|
-
});
|
|
1223
|
-
freeRounds.apply(result.toolCalls.map((tc) => tc.name));
|
|
1224
|
-
continue;
|
|
1225
|
-
}
|
|
1226
|
-
const toolResults = await this.toolExecutor.executeAll(result.toolCalls);
|
|
1227
|
-
const reasoningContent = result.reasoningContent;
|
|
1228
|
-
const newMsgs = provider.buildToolResultMessages(result.toolCalls, toolResults, reasoningContent);
|
|
1229
|
-
extraMessages.push(...newMsgs);
|
|
1230
|
-
persistToolRound(session, result.toolCalls, toolResults, {
|
|
1231
|
-
assistantContent: result.content,
|
|
1232
|
-
reasoningContent
|
|
1233
|
-
});
|
|
1234
|
-
if (freeRounds.apply(result.toolCalls.map((tc) => tc.name))) {
|
|
1235
|
-
round--;
|
|
1236
|
-
}
|
|
1237
|
-
if (this.userInterjection) {
|
|
1238
|
-
const msg = this.userInterjection;
|
|
1239
|
-
this.userInterjection = null;
|
|
1240
|
-
this.send({ type: "info", message: `\u26A1 Interjection: "${msg}"` });
|
|
1241
|
-
extraMessages.push({ role: "user", content: msg });
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
const effectiveRound = round + 1;
|
|
1245
|
-
const remaining = maxToolRounds - effectiveRound;
|
|
1246
|
-
if (autoPauseInterval > 0 && effectiveRound > 0 && effectiveRound % autoPauseInterval === 0 && remaining > 0 && !ac.signal.aborted) {
|
|
1247
|
-
const toolSummary = summarizeRecentTools(roundToolHistory, autoPauseInterval);
|
|
1162
|
+
},
|
|
1163
|
+
persistRound: (toolCalls, results, info) => {
|
|
1164
|
+
persistToolRound(session, toolCalls, results, info);
|
|
1165
|
+
},
|
|
1166
|
+
// Track MCP tool usage for next-turn budget prioritization (C1)
|
|
1167
|
+
onMcpToolUsed: (name) => this.usedMcpToolNames.add(name),
|
|
1168
|
+
requestAutoPause: async ({ effectiveRound, maxToolRounds: totalRounds, toolSummary }) => {
|
|
1248
1169
|
const requestId = `pause_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1249
1170
|
const pauseResp = await new Promise((resolve3) => {
|
|
1250
1171
|
this.pendingAutoPause.set(requestId, resolve3);
|
|
@@ -1252,58 +1173,85 @@ ${systemPromptVolatile}` : systemPrompt;
|
|
|
1252
1173
|
type: "auto_pause_request",
|
|
1253
1174
|
requestId,
|
|
1254
1175
|
currentRound: effectiveRound,
|
|
1255
|
-
totalRounds
|
|
1176
|
+
totalRounds,
|
|
1256
1177
|
toolSummary
|
|
1257
1178
|
});
|
|
1258
1179
|
});
|
|
1259
|
-
if (ac.signal.aborted) break;
|
|
1260
1180
|
if (pauseResp.action === "stop") {
|
|
1261
|
-
this.send({ type: "info", message: `\u23F8 Stopped by user at ${effectiveRound}/${
|
|
1262
|
-
extraMessages.push({ role: "user", content: buildUserStopMessage(effectiveRound, maxToolRounds) });
|
|
1263
|
-
break;
|
|
1181
|
+
this.send({ type: "info", message: `\u23F8 Stopped by user at ${effectiveRound}/${totalRounds}` });
|
|
1264
1182
|
} else if (pauseResp.action === "redirect" && pauseResp.message) {
|
|
1265
1183
|
this.send({ type: "info", message: `\u26A1 Redirect: "${pauseResp.message}"` });
|
|
1266
|
-
extraMessages.push({ role: "user", content: pauseResp.message });
|
|
1267
1184
|
}
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1185
|
+
return pauseResp;
|
|
1186
|
+
},
|
|
1187
|
+
onRoundsExhausted: (summaryContent) => {
|
|
1188
|
+
if (summaryContent !== null) {
|
|
1189
|
+
this.send({
|
|
1190
|
+
type: "response_done",
|
|
1191
|
+
content: `\u26A0 Reached maximum tool call rounds (${maxToolRounds}).
|
|
1192
|
+
|
|
1193
|
+
${summaryContent}`,
|
|
1194
|
+
usage
|
|
1195
|
+
});
|
|
1196
|
+
session.addMessage({ role: "assistant", content: summaryContent, timestamp: /* @__PURE__ */ new Date() });
|
|
1197
|
+
} else {
|
|
1198
|
+
this.send({
|
|
1199
|
+
type: "error",
|
|
1200
|
+
message: `Reached maximum tool call rounds (${maxToolRounds}). You can continue by asking the AI to proceed.`
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
// ─── save_last_response tee-streaming(v0.4.102+)─────────────────
|
|
1205
|
+
// AI 在 Web 模式下调用 save_last_response 时,复刻 REPL 的 tee 流式路径:
|
|
1206
|
+
// 发起一次新的 chatStream → 实时通过 WS 推送文本 + 同步写盘 → 注入合成
|
|
1207
|
+
// 工具结果。否则该工具会落到默认 executor,读到空的 lastResponseStore
|
|
1208
|
+
// 直接报错;用户被迫退到 write_file,又因 tool_call arguments 截断
|
|
1209
|
+
// (~2KB) 只能写出片段,再用 edit_file 反复 insert 才能补全(v0.4.101 报告)。
|
|
1210
|
+
// 与 REPL 不同:Web 端 tee 成功后继续 agentic 循环(返回 'continue'),
|
|
1211
|
+
// 让模型基于工具结果给出最终文本。
|
|
1212
|
+
runSaveLastResponseTee: async ({ toolCalls, call, saveToFile, extraMessages, reasoningContent }) => {
|
|
1213
|
+
const teeResult = await this.runSaveLastResponseTee(
|
|
1214
|
+
provider,
|
|
1215
|
+
call,
|
|
1216
|
+
saveToFile,
|
|
1217
|
+
apiMessages,
|
|
1218
|
+
extraMessages,
|
|
1279
1219
|
systemPrompt,
|
|
1280
1220
|
systemPromptVolatile,
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1221
|
+
modelParams,
|
|
1222
|
+
ac,
|
|
1223
|
+
usage
|
|
1224
|
+
);
|
|
1225
|
+
const teeToolResults = toolCalls.map((tc) => {
|
|
1226
|
+
if (tc.id === call.id) {
|
|
1227
|
+
return {
|
|
1228
|
+
callId: tc.id,
|
|
1229
|
+
content: teeResult.summary,
|
|
1230
|
+
isError: teeResult.isError
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
return {
|
|
1234
|
+
callId: tc.id,
|
|
1235
|
+
content: "[skipped: file already saved by tee streaming]",
|
|
1236
|
+
isError: false
|
|
1237
|
+
};
|
|
1238
|
+
});
|
|
1239
|
+
const newMsgs = provider.buildToolResultMessages(toolCalls, teeToolResults, reasoningContent);
|
|
1240
|
+
extraMessages.push(...newMsgs);
|
|
1241
|
+
persistToolRound(session, toolCalls, teeToolResults, {
|
|
1242
|
+
assistantContent: teeResult.content,
|
|
1243
|
+
reasoningContent
|
|
1296
1244
|
});
|
|
1297
|
-
|
|
1245
|
+
return "continue";
|
|
1298
1246
|
}
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1247
|
+
});
|
|
1248
|
+
if (loopResult.reason !== "tee-stop") {
|
|
1249
|
+
this.addWebSessionUsage(usage);
|
|
1250
|
+
session.addTokenUsage(usage);
|
|
1251
|
+
}
|
|
1252
|
+
if (loopResult.reason === "aborted") {
|
|
1253
|
+
this.send({ type: "info", message: "[interrupted]" });
|
|
1304
1254
|
}
|
|
1305
|
-
this.addWebSessionUsage(roundUsage);
|
|
1306
|
-
session.addTokenUsage(roundUsage);
|
|
1307
1255
|
} catch (err) {
|
|
1308
1256
|
if (err.name === "AbortError") {
|
|
1309
1257
|
this.send({ type: "info", message: "[interrupted]" });
|
|
@@ -2489,7 +2437,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2489
2437
|
case "test": {
|
|
2490
2438
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2491
2439
|
try {
|
|
2492
|
-
const { executeTests } = await import("./run-tests-
|
|
2440
|
+
const { executeTests } = await import("./run-tests-Z7IGVS2W.js");
|
|
2493
2441
|
const argStr = args.join(" ").trim();
|
|
2494
2442
|
let testArgs = {};
|
|
2495
2443
|
if (argStr) {
|
|
@@ -3,20 +3,20 @@ import {
|
|
|
3
3
|
ToolRegistry,
|
|
4
4
|
googleSearchContext,
|
|
5
5
|
truncateOutput
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-Q6BSUIDV.js";
|
|
7
7
|
import "./chunk-HDSKW7Q3.js";
|
|
8
8
|
import "./chunk-ZWVIDFGY.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-4SZ6X47A.js";
|
|
10
10
|
import {
|
|
11
11
|
runTool
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MVK25WZW.js";
|
|
13
13
|
import {
|
|
14
14
|
getDangerLevel
|
|
15
15
|
} from "./chunk-HIU2SH4V.js";
|
|
16
16
|
import "./chunk-TZQHYZKT.js";
|
|
17
17
|
import {
|
|
18
18
|
SUBAGENT_ALLOWED_TOOLS
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-SOWBY545.js";
|
|
20
20
|
import "./chunk-4BKXL7SM.js";
|
|
21
21
|
import "./chunk-MM3F43H6.js";
|
|
22
22
|
import "./chunk-KHYD3WXE.js";
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
} from "./chunk-V37XOYOE.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigManager
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-UAJKGLRV.js";
|
|
12
12
|
import "./chunk-TZQHYZKT.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-SOWBY545.js";
|
|
14
14
|
import "./chunk-PDX44BCA.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/usage.ts
|