deepseeker-code 1.0.49 → 1.0.50
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 +4 -3
- package/dist/cli.mjs +839 -271
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -161,7 +161,8 @@ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
|
|
|
161
161
|
cmdStatus: "\u67E5\u770B\u5F53\u524D\u6A21\u578B/\u4F1A\u8BDD/\u6A21\u5F0F",
|
|
162
162
|
cmdPlan: "\u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814\u2192\u5BA1\u6279\u2192\u5B9E\u73B0\uFF09",
|
|
163
163
|
cmdAuto: "\u5207\u6362\u81EA\u52A8\u6A21\u5F0F\uFF08\u6587\u4EF6\u7F16\u8F91\u5206\u7C7B\u5668\u81EA\u52A8\u653E\u884C\uFF0C\u9AD8\u5371\u8F6C\u4EBA\u5DE5\uFF09",
|
|
164
|
-
cmdModel: "\u5207\u6362\u6A21\u578B\uFF1A/model
|
|
164
|
+
cmdModel: "\u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF09\uFF1A/model <\u6A21\u578Bid>\uFF0C\u65E0\u53C2\u67E5\u770B\u5F53\u524D\u6A21\u578B",
|
|
165
|
+
cmdSwitch: "\u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668\uFF08\u2191\u2193 \u9009\u62E9\uFF09",
|
|
165
166
|
cmdThinking: "\u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF1A/thinking <off|high|max>",
|
|
166
167
|
cmdLang: "\u5207\u6362\u754C\u9762\u8BED\u8A00\uFF1A/lang <zh|en>",
|
|
167
168
|
cmdOutputStyle: "\u5207\u6362\u8F93\u51FA\u98CE\u683C\uFF1A/output-style <name|off>",
|
|
@@ -185,6 +186,12 @@ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
|
|
|
185
186
|
forkEmpty: "\uFF08\u5F53\u524D\u4F1A\u8BDD\u6682\u65E0\u53EF\u5206\u53C9\u7684\u68C0\u67E5\u70B9\uFF09",
|
|
186
187
|
forkDone: (id, roundNo) => `\u5DF2\u4ECE\u7B2C ${roundNo} \u8F6E\u5206\u53C9 \u2192 \u65B0\u4F1A\u8BDD ${id}\uFF08\u5DF2\u8F7D\u5165\uFF0C\u540E\u7EED\u5BF9\u8BDD\u5199\u5165\u65B0\u4F1A\u8BDD\uFF0C\u539F\u4F1A\u8BDD\u4E0D\u53D8\uFF09`,
|
|
187
188
|
forkFailed: (e) => `\u5206\u53C9\u5931\u8D25\uFF1A${e}`,
|
|
189
|
+
modelUsage: (current) => `\u5F53\u524D\u6A21\u578B\uFF1A${current || "\u9ED8\u8BA4\uFF08DEEP_SEEK_MODEL\uFF09"}
|
|
190
|
+
\u7528\u6CD5\uFF1A/model <\u6A21\u578Bid> \u76F4\u8F93\u5207\u6362\uFF0C\u6216 /switch \u5F39\u51FA\u5019\u9009\u9009\u62E9\u5668`,
|
|
191
|
+
modelPickerTitle: (current) => `\u{1F9E0} \u9009\u62E9\u6A21\u578B\uFF08\u5F53\u524D\uFF1A${current || "\u9ED8\u8BA4"}\uFF09`,
|
|
192
|
+
modelPickerPrompt: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u5207\u6362 \xB7 Esc \u53D6\u6D88\uFF08\u5176\u5B83\u6A21\u578B\uFF1A/model <\u6A21\u578Bid>\uFF09",
|
|
193
|
+
modelCurrentTag: "\u5F53\u524D",
|
|
194
|
+
modelSwitched: (m) => `\u6A21\u578B\u5DF2\u5207\u6362\uFF1A${m}\uFF08\u4E0B\u6B21\u56DE\u590D\u751F\u6548\uFF0C\u91CD\u542F\u540E\u4FDD\u6301\uFF09`,
|
|
188
195
|
relTime: (iso) => {
|
|
189
196
|
const t = Date.parse(iso);
|
|
190
197
|
if (!t) return "";
|
|
@@ -216,7 +223,8 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
|
|
|
216
223
|
helpText: (model2, thinking, locale2) => [
|
|
217
224
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
218
225
|
"/plan \u2014 \u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814 \u2192 \u65B9\u6848\u5BA1\u6279 \u2192 \u5B9E\u73B0\uFF09",
|
|
219
|
-
`/model
|
|
226
|
+
`/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${model2}\uFF09`,
|
|
227
|
+
"/switch \u2014 \u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668",
|
|
220
228
|
`/thinking [off|high|max] \u2014 \u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF08\u5F53\u524D ${thinking}\uFF09`,
|
|
221
229
|
`/lang [zh|en] \u2014 \u5207\u6362\u754C\u9762\u8BED\u8A00\uFF08\u5F53\u524D ${locale2}\uFF09`,
|
|
222
230
|
"/sessions \u2014 \u9009\u62E9\u5E76\u8F7D\u5165\u5386\u53F2\u4F1A\u8BDD\uFF08\u7EED\u63A5\u5BF9\u8BDD\uFF09",
|
|
@@ -301,7 +309,8 @@ ${dim} Run npm i -g deepseeker-code@latest to update${reset}
|
|
|
301
309
|
cmdStatus: "Show current model/session/mode",
|
|
302
310
|
cmdPlan: "Toggle plan mode (read-only research \u2192 review \u2192 implement)",
|
|
303
311
|
cmdAuto: "Toggle auto mode (classifier auto-approves file edits, escalates risky)",
|
|
304
|
-
cmdModel: "Switch model: /model <
|
|
312
|
+
cmdModel: "Switch model (direct): /model <model-id>; no arg shows current",
|
|
313
|
+
cmdSwitch: "Open the model picker (\u2191\u2193 to pick)",
|
|
305
314
|
cmdThinking: "Switch thinking level: /thinking <off|high|max>",
|
|
306
315
|
cmdLang: "Switch interface language: /lang <zh|en>",
|
|
307
316
|
cmdOutputStyle: "Switch output style: /output-style <name|off>",
|
|
@@ -325,6 +334,12 @@ ${dim} Run npm i -g deepseeker-code@latest to update${reset}
|
|
|
325
334
|
forkEmpty: "(no checkpoints to fork from in this session)",
|
|
326
335
|
forkDone: (id, roundNo) => `Forked from round ${roundNo} \u2192 new session ${id} (loaded; new messages go to the fork, source untouched)`,
|
|
327
336
|
forkFailed: (e) => `Fork failed: ${e}`,
|
|
337
|
+
modelUsage: (current) => `Current model: ${current || "default (DEEP_SEEK_MODEL)"}
|
|
338
|
+
Usage: /model <model-id> to switch directly, or /switch for the picker`,
|
|
339
|
+
modelPickerTitle: (current) => `\u{1F9E0} Pick a model (current: ${current || "default"})`,
|
|
340
|
+
modelPickerPrompt: "\u2191\u2193 pick \xB7 Enter switch \xB7 Esc cancel (any other model: /model <id>)",
|
|
341
|
+
modelCurrentTag: "current",
|
|
342
|
+
modelSwitched: (m) => `Model switched: ${m} (takes effect on next reply, persists across restarts)`,
|
|
328
343
|
relTime: (iso) => {
|
|
329
344
|
const t = Date.parse(iso);
|
|
330
345
|
if (!t) return "";
|
|
@@ -356,7 +371,8 @@ DeepSeeker-Code will read, edit, and execute files here.`,
|
|
|
356
371
|
helpText: (model2, thinking, locale2) => [
|
|
357
372
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
358
373
|
"/plan \u2014 Toggle plan mode (read-only research \u2192 review \u2192 implement)",
|
|
359
|
-
`/model
|
|
374
|
+
`/model <model-id> \u2014 Switch model (direct input; current ${model2})`,
|
|
375
|
+
"/switch \u2014 Open the model picker",
|
|
360
376
|
`/thinking [off|high|max] \u2014 Switch thinking level (current ${thinking})`,
|
|
361
377
|
`/lang [zh|en] \u2014 Switch interface language (current ${locale2})`,
|
|
362
378
|
"/sessions \u2014 Pick a past session to resume",
|
|
@@ -381,7 +397,7 @@ DeepSeeker-Code will read, edit, and execute files here.`,
|
|
|
381
397
|
S = new Proxy({}, {
|
|
382
398
|
get: (_t, k) => typeof k === "string" ? STRINGS[locale][k] : void 0
|
|
383
399
|
});
|
|
384
|
-
LOCAL_COMMAND_NAMES = ["help", "status", "plan", "auto", "model", "thinking", "lang", "output-style", "sessions", "fork", "usage", "context", "permissions", "mcp", "hooks", "trust", "debug", "clear", "exit"];
|
|
400
|
+
LOCAL_COMMAND_NAMES = ["help", "status", "plan", "auto", "model", "switch", "thinking", "lang", "output-style", "sessions", "fork", "usage", "context", "permissions", "mcp", "hooks", "trust", "debug", "clear", "exit"];
|
|
385
401
|
}
|
|
386
402
|
});
|
|
387
403
|
|
|
@@ -690,7 +706,7 @@ ${body}`) return;
|
|
|
690
706
|
// src/prefs.ts
|
|
691
707
|
import path4 from "path";
|
|
692
708
|
import fs2 from "fs/promises";
|
|
693
|
-
var PREFS_FILE, readPrefs, readLocale, writePrefs, writeLocale;
|
|
709
|
+
var PREFS_FILE, readPrefs, readModelPref, readLocale, writePrefs, writeLocale;
|
|
694
710
|
var init_prefs = __esm({
|
|
695
711
|
"src/prefs.ts"() {
|
|
696
712
|
"use strict";
|
|
@@ -701,6 +717,10 @@ var init_prefs = __esm({
|
|
|
701
717
|
const p = await readJSONFile(PREFS_FILE);
|
|
702
718
|
return p && typeof p === "object" ? p : {};
|
|
703
719
|
};
|
|
720
|
+
readModelPref = async () => {
|
|
721
|
+
const { model: model2 } = await readPrefs();
|
|
722
|
+
return typeof model2 === "string" && model2.trim() ? model2.trim() : null;
|
|
723
|
+
};
|
|
704
724
|
readLocale = async () => {
|
|
705
725
|
const { locale: locale2 } = await readPrefs();
|
|
706
726
|
return locale2 === "zh" || locale2 === "en" ? locale2 : null;
|
|
@@ -792,8 +812,9 @@ var init_client = __esm({
|
|
|
792
812
|
baseURL: process.env.DEEP_SEEK_API_URL || "https://api.deepseek.com",
|
|
793
813
|
apiKey: process.env.DEEP_SEEK_API_KEY,
|
|
794
814
|
// ★ 瞬态错误自动指数退避重试(SDK 内置:408/409/429/500/502/503/504 + 连接错误),
|
|
795
|
-
//
|
|
796
|
-
//
|
|
815
|
+
// 覆盖非流式 helper(summarize / classifyRisk)。★ 流式对话不在此列:stream.ts 按
|
|
816
|
+
// maxRetries: 0 关掉 SDK 层,瞬态重试单层归 streamInference 应用层(Retry-After 感知 +
|
|
817
|
+
// text.reset/abort/超长降级语义,SDK 层不具备)——两层同开会把 429 放大成 5×3=15 次请求。
|
|
797
818
|
maxRetries: 4,
|
|
798
819
|
timeout: 12e4
|
|
799
820
|
// 单次请求 120s 兜底(长上下文 / 长生成场景)
|
|
@@ -808,18 +829,37 @@ var init_client = __esm({
|
|
|
808
829
|
});
|
|
809
830
|
|
|
810
831
|
// ../core/src/llm/providers/deepseek/stream.ts
|
|
811
|
-
var STREAM_IDLE_TIMEOUT_MS, streamChat;
|
|
832
|
+
var STREAM_IDLE_TIMEOUT_MS, stripHistoricalReasoning, streamChat;
|
|
812
833
|
var init_stream = __esm({
|
|
813
834
|
"../core/src/llm/providers/deepseek/stream.ts"() {
|
|
814
835
|
"use strict";
|
|
815
836
|
init_client();
|
|
816
837
|
STREAM_IDLE_TIMEOUT_MS = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
838
|
+
stripHistoricalReasoning = (messages) => {
|
|
839
|
+
if (process.env.DEEP_SEEK_REASONING_PASSTHROUGH === "1") return messages;
|
|
840
|
+
let lastNonSystem = null;
|
|
841
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
842
|
+
if (messages[i]?.role !== "system") {
|
|
843
|
+
lastNonSystem = messages[i];
|
|
844
|
+
break;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
if (lastNonSystem?.role === "assistant") return messages;
|
|
848
|
+
return messages.map((m) => {
|
|
849
|
+
const wire = m;
|
|
850
|
+
if (wire?.role !== "assistant" || typeof wire.reasoning_content !== "string") return m;
|
|
851
|
+
const copy = { ...wire };
|
|
852
|
+
delete copy.reasoning_content;
|
|
853
|
+
return copy;
|
|
854
|
+
});
|
|
855
|
+
};
|
|
817
856
|
streamChat = async function* (messages, tools, opts) {
|
|
818
857
|
const level = opts.thinkingLevel;
|
|
819
858
|
const thinkingType = (level === void 0 ? MODEL_THINKING_ENABLED : level !== "off") ? "enabled" : "disabled";
|
|
820
859
|
const effort = level === "max" ? "max" : level === "high" ? "high" : level === "off" ? "high" : MODEL_REASONING_EFFORT;
|
|
821
860
|
const requestBody = {
|
|
822
|
-
messages,
|
|
861
|
+
messages: stripHistoricalReasoning(messages),
|
|
862
|
+
// ★ 出口剥离历史思考记录(见函数注释;默认开)
|
|
823
863
|
model: opts.model ?? MODEL_NAME,
|
|
824
864
|
// per-agent 覆盖(声明式子 Agent);缺省回退全局
|
|
825
865
|
tool_choice: "auto",
|
|
@@ -836,7 +876,8 @@ var init_stream = __esm({
|
|
|
836
876
|
const extSignal = opts.signal;
|
|
837
877
|
const combinedSignal = extSignal ? AbortSignal.any([idleAc.signal, extSignal]) : idleAc.signal;
|
|
838
878
|
const stream = await model.chat.completions.create(requestBody, {
|
|
839
|
-
signal: combinedSignal
|
|
879
|
+
signal: combinedSignal,
|
|
880
|
+
maxRetries: 0
|
|
840
881
|
});
|
|
841
882
|
const reader = stream[Symbol.asyncIterator]();
|
|
842
883
|
try {
|
|
@@ -903,7 +944,8 @@ var init_deepseek = __esm({
|
|
|
903
944
|
summarize = async (messages, tools, opts) => {
|
|
904
945
|
try {
|
|
905
946
|
const requestBody = {
|
|
906
|
-
messages,
|
|
947
|
+
messages: stripHistoricalReasoning(messages),
|
|
948
|
+
// ★ 出口剥离历史思考记录(压缩输入全价计费,省得最实)
|
|
907
949
|
model: AUX_MODEL_NAME,
|
|
908
950
|
tool_choice: "auto",
|
|
909
951
|
tools,
|
|
@@ -980,11 +1022,22 @@ var init_deepseek = __esm({
|
|
|
980
1022
|
}
|
|
981
1023
|
});
|
|
982
1024
|
|
|
1025
|
+
// ../core/src/llm/createModel.ts
|
|
1026
|
+
var SELECTABLE_MODELS;
|
|
1027
|
+
var init_createModel = __esm({
|
|
1028
|
+
"../core/src/llm/createModel.ts"() {
|
|
1029
|
+
"use strict";
|
|
1030
|
+
init_client();
|
|
1031
|
+
SELECTABLE_MODELS = ["deepseek-v4-flash", "deepseek-v4-pro", "deepseek-v4-flash-vision-exp"];
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
|
|
983
1035
|
// ../core/src/session/contentParts.ts
|
|
984
|
-
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, isVisionEnabled, estimateImageTokens, toWireUserContent, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
1036
|
+
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, modelSupportsVision, isVisionEnabled, estimateImageTokens, toWireUserContent, toIngestContents, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
985
1037
|
var init_contentParts = __esm({
|
|
986
1038
|
"../core/src/session/contentParts.ts"() {
|
|
987
1039
|
"use strict";
|
|
1040
|
+
init_createModel();
|
|
988
1041
|
MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
989
1042
|
msgText = (content) => {
|
|
990
1043
|
if (typeof content === "string") return content;
|
|
@@ -998,9 +1051,13 @@ var init_contentParts = __esm({
|
|
|
998
1051
|
return content.filter((p) => p?.type === "image_url" && typeof p?.image_url?.url === "string").map((p) => p.image_url.url);
|
|
999
1052
|
};
|
|
1000
1053
|
hasImagePart = (content) => imageUrlsOf(content).length > 0;
|
|
1001
|
-
|
|
1054
|
+
modelSupportsVision = (modelId) => /vision|vlm|(^|[-_.])vl([-_.0-9]|$)/i.test(modelId || "");
|
|
1055
|
+
isVisionEnabled = (modelId) => {
|
|
1002
1056
|
const v = process.env.DEEP_SEEK_VISION;
|
|
1003
|
-
|
|
1057
|
+
if (v === "1" || v === "true") return true;
|
|
1058
|
+
if (v === "0" || v === "false") return false;
|
|
1059
|
+
const effective = typeof modelId === "string" && modelId.trim() ? modelId.trim() : MODEL_NAME;
|
|
1060
|
+
return modelSupportsVision(effective);
|
|
1004
1061
|
};
|
|
1005
1062
|
estimateImageTokens = () => {
|
|
1006
1063
|
const n = Number(process.env.DEEP_SEEK_IMAGE_TOKENS);
|
|
@@ -1039,6 +1096,22 @@ ${footer.join("\n")}` : text;
|
|
|
1039
1096
|
];
|
|
1040
1097
|
return parts;
|
|
1041
1098
|
};
|
|
1099
|
+
toIngestContents = (text, attachments, modelId) => {
|
|
1100
|
+
const archive = toWireUserContent(text, attachments);
|
|
1101
|
+
if (!Array.isArray(attachments) || attachments.length === 0) return { wire: archive, archive };
|
|
1102
|
+
if (isVisionEnabled(modelId)) return { wire: archive, archive };
|
|
1103
|
+
const names = attachments.map((a) => a?.name || "image").join("\u3001");
|
|
1104
|
+
const paths = attachments.map((a) => typeof a?.path === "string" && a.path ? ` ${a?.name || "image"} \u2192 ${a.path}` : "").filter(Boolean);
|
|
1105
|
+
const relay = paths.length ? `\u56FE\u7247\u5DF2\u5B58\u5DE5\u4F5C\u533A\uFF1A
|
|
1106
|
+
${paths.join("\n")}
|
|
1107
|
+
\u82E5\u5DF2\u914D\u7F6E\u56FE\u50CF\u8BC6\u522B MCP \u5DE5\u5177\uFF0C\u53EF\u8BFB\u53D6\u4E0A\u8FF0\u8DEF\u5F84\u7406\u89E3\u56FE\u7247\u5185\u5BB9\u3002` : "\u82E5\u6D88\u606F\u4E2D\u5305\u542B\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84\u4E14\u5DF2\u914D\u7F6E\u56FE\u50CF\u8BC6\u522B MCP \u5DE5\u5177\uFF0C\u53EF\u8BFB\u53D6\u8BE5\u8DEF\u5F84\u7406\u89E3\u56FE\u7247\u3002";
|
|
1108
|
+
return {
|
|
1109
|
+
wire: `${text}
|
|
1110
|
+
|
|
1111
|
+
\u{1F5BC} \u6536\u5230\u56FE\u7247\u9644\u4EF6\uFF08${names}\uFF09\uFF1A\u5F53\u524D\u6A21\u578B\u65E0\u89C6\u89C9\u80FD\u529B\uFF0C\u65E0\u6CD5\u76F4\u63A5\u67E5\u770B\u56FE\u7247\u5185\u5BB9\uFF08\u53EF\u5207\u6362 vision \u6A21\u578B\u6216\u8BBE DEEP_SEEK_VISION=1 \u5F3A\u5F00\uFF09\uFF1B${relay}`,
|
|
1112
|
+
archive
|
|
1113
|
+
};
|
|
1114
|
+
};
|
|
1042
1115
|
replaceImageParts = (m, note) => {
|
|
1043
1116
|
if (!m || !Array.isArray(m.content)) return m;
|
|
1044
1117
|
let touched = false;
|
|
@@ -1719,7 +1792,7 @@ var init_shellExecutor = __esm({
|
|
|
1719
1792
|
};
|
|
1720
1793
|
executeHookCommand = (input) => {
|
|
1721
1794
|
return new Promise((resolve) => {
|
|
1722
|
-
const
|
|
1795
|
+
const timeoutMs2 = Math.min(input.timeoutMs ?? DEFAULT_TIMEOUT_MS, HARD_TIMEOUT_CAP_MS);
|
|
1723
1796
|
const childEnv = {};
|
|
1724
1797
|
for (const k of ENV_WHITELIST) {
|
|
1725
1798
|
const v = process.env[k];
|
|
@@ -1755,7 +1828,7 @@ var init_shellExecutor = __esm({
|
|
|
1755
1828
|
const timer = setTimeout(() => {
|
|
1756
1829
|
timedOut = true;
|
|
1757
1830
|
void killTree(child);
|
|
1758
|
-
},
|
|
1831
|
+
}, timeoutMs2);
|
|
1759
1832
|
child.stdout?.on("data", (d) => {
|
|
1760
1833
|
if (stdout.length < MAX_OUTPUT) stdout += d.toString();
|
|
1761
1834
|
});
|
|
@@ -1787,7 +1860,7 @@ var init_shellExecutor = __esm({
|
|
|
1787
1860
|
});
|
|
1788
1861
|
|
|
1789
1862
|
// ../core/src/hooks/registry.ts
|
|
1790
|
-
var rules, matches,
|
|
1863
|
+
var rules, matches, DECLARATIVE_RULE, replaceDeclarativeHooks, listHooks, isPlainObject, dispatch, runPreHooks, HOOK_RESULT_MAX, truncateForHook, runPostHooks;
|
|
1791
1864
|
var init_registry = __esm({
|
|
1792
1865
|
"../core/src/hooks/registry.ts"() {
|
|
1793
1866
|
"use strict";
|
|
@@ -1796,7 +1869,12 @@ var init_registry = __esm({
|
|
|
1796
1869
|
init_config();
|
|
1797
1870
|
rules = [];
|
|
1798
1871
|
matches = (matcher, toolName) => {
|
|
1799
|
-
if (typeof matcher === "string")
|
|
1872
|
+
if (typeof matcher === "string") {
|
|
1873
|
+
if (matcher === "*") return true;
|
|
1874
|
+
if (matcher === "mcp_call") return toolName.startsWith("mcp__");
|
|
1875
|
+
if (matcher.endsWith("*")) return toolName.startsWith(matcher.slice(0, -1));
|
|
1876
|
+
return matcher === toolName;
|
|
1877
|
+
}
|
|
1800
1878
|
if (matcher instanceof RegExp) return matcher.test(toolName);
|
|
1801
1879
|
try {
|
|
1802
1880
|
return matcher(toolName);
|
|
@@ -1804,8 +1882,15 @@ var init_registry = __esm({
|
|
|
1804
1882
|
return false;
|
|
1805
1883
|
}
|
|
1806
1884
|
};
|
|
1807
|
-
|
|
1808
|
-
|
|
1885
|
+
DECLARATIVE_RULE = Symbol("dsc.hook.declarative");
|
|
1886
|
+
replaceDeclarativeHooks = (rs) => {
|
|
1887
|
+
for (let i = rules.length - 1; i >= 0; i--) {
|
|
1888
|
+
if (rules[i][DECLARATIVE_RULE]) rules.splice(i, 1);
|
|
1889
|
+
}
|
|
1890
|
+
for (const r of rs) {
|
|
1891
|
+
r[DECLARATIVE_RULE] = true;
|
|
1892
|
+
rules.push(r);
|
|
1893
|
+
}
|
|
1809
1894
|
};
|
|
1810
1895
|
listHooks = () => {
|
|
1811
1896
|
const strMatcher = (m) => {
|
|
@@ -1923,15 +2008,14 @@ function stripAnsi(text) {
|
|
|
1923
2008
|
}
|
|
1924
2009
|
function microcompactTextContent(raw) {
|
|
1925
2010
|
let s = stripAnsi(raw || "");
|
|
1926
|
-
s = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
1927
2011
|
s = relativizeWorkspacePathsInText(s);
|
|
1928
|
-
s = s.replace(/\n{3,}/g, "\n\n").
|
|
2012
|
+
s = s.replace(/\n{3,}/g, "\n\n").trim();
|
|
1929
2013
|
return s;
|
|
1930
2014
|
}
|
|
1931
2015
|
function isAsyncGenerator(x) {
|
|
1932
2016
|
return x != null && typeof x[Symbol.asyncIterator] === "function";
|
|
1933
2017
|
}
|
|
1934
|
-
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, compactSlotNarrative,
|
|
2018
|
+
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, batchSummaryPrompt, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, CHECKPOINT_MAX_CHARS, SLOT_PLACEHOLDER, CHECKPOINT_FORMAT, checkpointRules, checkpointPrompt, checkpointDirectPrompt, assembleSlot, parseSlotNarrativeState, synthesizeSlotNarrative, synthesizeSlotNarrativeFromBatch, compactSlotNarrative, splitIntoBatches, compactBatches, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, ensureFitsWindow, collectToolResult;
|
|
1935
2019
|
var init_truncate = __esm({
|
|
1936
2020
|
"../core/src/agent/truncate.ts"() {
|
|
1937
2021
|
"use strict";
|
|
@@ -2003,10 +2087,11 @@ var init_truncate = __esm({
|
|
|
2003
2087
|
|
|
2004
2088
|
${tail}`;
|
|
2005
2089
|
};
|
|
2006
|
-
|
|
2090
|
+
batchSummaryPrompt = (tailContext) => "\u6982\u62EC\u4EE5\u4E0A\u5BF9\u8BDD\u4E0E\u5DE5\u5177\u8C03\u7528\uFF0C\u6309\u300C\u5B8C\u6210\u4E86\u4EC0\u4E48 \u2192 \u6B63\u5728\u505A\u4EC0\u4E48 \u2192 \u4E0B\u4E00\u6B65/\u53D7\u963B\u300D\u7684\u987A\u5E8F\u5199\u6210\u4E00\u6BB5\u3002\u5FC5\u987B\u539F\u6837\u4FDD\u7559\u5173\u952E\u5B9E\u4F53\u540D\uFF08\u6587\u4EF6\u8DEF\u5F84\u3001\u51FD\u6570/\u7C7B\u540D\u3001\u62A5\u9519\u5173\u952E\u8BCD\uFF09\u4EE5\u4FBF\u540E\u7EED\u68C0\u7D22\uFF1B" + (tailContext ? "\u8FD9\u6279\u6458\u8981\u7D27\u90BB\u672A\u538B\u7F29\u7684\u4FDD\u7559\u533A\uFF0C\u8BF7\u989D\u5916\u5199\u660E\u5176\u4E2D\u5BF9\u7D27\u968F\u5176\u540E\u7684\u8FD1\u671F\u5DE5\u4F5C\u6709\u7528\u7684\u80CC\u666F\uFF08\u5DF2\u786E\u8BA4\u7684\u7EA6\u675F\u3001\u6570\u636E\u3001\u7ED3\u8BBA\uFF09\u3002" : "") + '\u5BF9\u8BB0\u4E0D\u51C6\u7684\u7EC6\u8282\u4E0D\u8981\u81C6\u6D4B\uFF0C\u6807\u6CE8"(\u7EC6\u8282\u5DF2\u5F52\u6863)"\u5373\u53EF\u3002\u4E0D\u8981\u8C03\u7528\u5DE5\u5177\u3002';
|
|
2091
|
+
compactBatch = async (batch, signal, tailContext) => {
|
|
2007
2092
|
const resp = await chatWithModelWithSummary(
|
|
2008
2093
|
// ★ 辅助模型是 text-only:送前把 image part 降级为占位符——base64 绝不能进摘要批(烧钱且无意义)
|
|
2009
|
-
[...batch.map(degradeImagesForAux), { role: "user", content:
|
|
2094
|
+
[...batch.map(degradeImagesForAux), { role: "user", content: batchSummaryPrompt(tailContext) }],
|
|
2010
2095
|
[],
|
|
2011
2096
|
{ signal }
|
|
2012
2097
|
);
|
|
@@ -2026,6 +2111,8 @@ ${tail}`;
|
|
|
2026
2111
|
const push = (raw) => {
|
|
2027
2112
|
const s = raw.trim();
|
|
2028
2113
|
if (!s || s.length < 3 || s.length > 60 || seen.has(s)) return;
|
|
2114
|
+
const lastSeg = s.split(/[\\/]/).pop() ?? "";
|
|
2115
|
+
if (/^[\d.]+$/.test(lastSeg)) return;
|
|
2029
2116
|
seen.add(s);
|
|
2030
2117
|
found.push(s);
|
|
2031
2118
|
};
|
|
@@ -2054,8 +2141,8 @@ ${tail}`;
|
|
|
2054
2141
|
merged.push(e);
|
|
2055
2142
|
if (merged.length >= ARCHIVE_INDEX_MAX_ENTRIES) break;
|
|
2056
2143
|
}
|
|
2057
|
-
const newNotes = notes ? `${notes}
|
|
2058
|
-
${noteLine}` : noteLine;
|
|
2144
|
+
const newNotes = noteLine ? notes ? `${notes}
|
|
2145
|
+
${noteLine}` : noteLine : notes;
|
|
2059
2146
|
return [
|
|
2060
2147
|
"\u27E6DSC:ARCHIVE-INDEX\u27E7 \u7CBE\u786E\u7EC6\u8282\u53EF\u7528 recall \u5DE5\u5177\u68C0\u7D22\u672C\u4F1A\u8BDD\u5168\u91CF\u5386\u53F2\uFF1B\u4EE5\u4E0B\u4E3A\u5F52\u6863\u5B9E\u4F53\u7D22\u5F15\uFF08\u68C0\u7D22\u5173\u952E\u8BCD\u7EBF\u7D22\uFF09\uFF1A",
|
|
2061
2148
|
merged.join(" | "),
|
|
@@ -2063,17 +2150,57 @@ ${noteLine}` : noteLine;
|
|
|
2063
2150
|
newNotes
|
|
2064
2151
|
].join("\n");
|
|
2065
2152
|
};
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2153
|
+
CHECKPOINT_MAX_CHARS = 800;
|
|
2154
|
+
SLOT_PLACEHOLDER = "SYSTEM_ROLLING_SUMMARY_SLOT";
|
|
2155
|
+
CHECKPOINT_FORMAT = '\u4E25\u683C\u6309\u4EE5\u4E0B\u683C\u5F0F\u8F93\u51FA\uFF1A\n\n## \u76EE\u6807\n[\u7528\u6237\u8981\u5B8C\u6210\u4EC0\u4E48\uFF1B\u591A\u4EFB\u52A1\u5206\u6BB5\u5217\u51FA]\n## \u7EA6\u675F\u4E0E\u504F\u597D\n- [\u7528\u6237\u660E\u793A\u7684\u7EA6\u675F\u3001\u504F\u597D\u4E0E\u6280\u672F\u8981\u6C42\uFF1B\u65E0\u5219\u5199"(\u65E0)"]\n## \u8FDB\u5EA6\n### \u5DF2\u5B8C\u6210\n- [x] [\u5DF2\u5B8C\u6210\u7684\u4E8B\u9879]\n### \u8FDB\u884C\u4E2D\n- [ ] [\u8FDB\u884C\u4E2D\u7684\u4E8B\u9879\u53CA\u5176\u6700\u65B0\u72B6\u6001]\n### \u53D7\u963B\n- [\u5361\u70B9\uFF1B\u65E0\u5219\u5199"(\u65E0)"]\n## \u5173\u952E\u51B3\u7B56\n- **[\u51B3\u7B56]**: [\u7B80\u8981\u7406\u7531]\n## \u4E0B\u4E00\u6B65\n1. [\u6309\u987A\u5E8F\u5217\u51FA\u63A5\u4E0B\u6765\u8BE5\u505A\u4EC0\u4E48]\n## \u5173\u952E\u4E0A\u4E0B\u6587\n- [\u7EED\u63A5\u6240\u9700\u7684\u6570\u636E\u3001\u7ED3\u8BBA\u4E0E\u53C2\u7167\uFF1B\u65E0\u5219\u5199"(\u65E0)"]\n\n';
|
|
2156
|
+
checkpointRules = (hasPrevious, isRaw = false) => "\u89C4\u5219\uFF1A" + (hasPrevious ? `\u4FDD\u7559\u65E2\u6709\u68C0\u67E5\u70B9\u4E0E\u65B0\u5F52\u6863${isRaw ? "\u539F\u6587" : "\u884C"}\u4E2D\u7684\u5168\u90E8\u6709\u6548\u4FE1\u606F\uFF0C\u53EA\u6574\u7406\u3001\u4E0D\u6539\u5199\u4E8B\u5B9E\uFF1B\u5DF2\u5B8C\u6210\u4E8B\u9879\u79FB\u5165"\u5DF2\u5B8C\u6210"\uFF0C\u8FDB\u884C\u4E2D\u4E8B\u9879\u5237\u65B0\u5230\u6700\u65B0\u72B6\u6001\uFF1B\u88AB\u53D6\u4EE3\u7684\u8FC7\u671F\u7EC6\u8282\u53EF\u5220\u9664\uFF08\u7EC6\u8282\u53EF\u7ECF recall \u68C0\u7D22\uFF0C\u65E0\u9700\u604B\u6218\uFF09\uFF1B` : '\u5BF9\u8BB0\u4E0D\u51C6\u7684\u7EC6\u8282\u4E0D\u8981\u81C6\u6D4B\uFF0C\u6807\u6CE8"(\u7EC6\u8282\u5DF2\u5F52\u6863)"\u5373\u53EF\uFF08\u7EC6\u8282\u53EF\u7ECF recall \u68C0\u7D22\uFF09\uFF1B') + "\u539F\u6837\u4FDD\u7559\u6587\u4EF6\u8DEF\u5F84\u3001\u51FD\u6570/\u7C7B\u540D\u3001\u62A5\u9519\u5173\u952E\u8BCD\u7B49\u5B9E\u4F53\u540D\uFF1B\u5168\u6587\u4E0D\u8D85\u8FC7 " + CHECKPOINT_MAX_CHARS + " \u5B57\uFF1B\u76F4\u63A5\u8F93\u51FA\u68C0\u67E5\u70B9\uFF0C\u4E0D\u8981\u4EFB\u4F55\u89E3\u91CA\u3002";
|
|
2157
|
+
checkpointPrompt = (hasPrevious) => (hasPrevious ? "\u4EE5\u4E0A\u662F\u672C\u4F1A\u8BDD\u7684\u5F52\u6863\u6863\u6848\uFF1A\u27E6DSC:ARCHIVE-INDEX\u27E7 \u5B9E\u4F53\u7D22\u5F15\uFF08\u68C0\u7D22\u7EBF\u7D22\uFF0C\u4E0D\u8981\u6539\u52A8\u5176\u5185\u5BB9\uFF09\u4E0E \u27E6DSC:ARCHIVE-NOTES\u27E7 \u65E2\u6709\u68C0\u67E5\u70B9\u3002\u8BF7\u628A\u65E2\u6709\u68C0\u67E5\u70B9\u4E0E\u7528\u6237\u6D88\u606F\u4E2D\u7684\u672C\u8F6E\u65B0\u5F52\u6863\u6458\u8981\u884C\u5408\u5E76\u6539\u5199\u4E3A\u4E00\u4EFD\u65B0\u7684\u7ED3\u6784\u5316\u68C0\u67E5\u70B9\uFF0C\u4F9B\u540E\u7EED\u6A21\u578B\u7EED\u63A5\u5DE5\u4F5C\u3002" : "\u7528\u6237\u6D88\u606F\u662F\u672C\u4F1A\u8BDD\u672C\u8F6E\u5F52\u6863\u51FA\u7684\u6458\u8981\u884C\u3002\u8BF7\u628A\u5B83\u4EEC\u6574\u7406\u4E3A\u4E00\u4EFD\u7ED3\u6784\u5316\u68C0\u67E5\u70B9\uFF0C\u4F9B\u540E\u7EED\u6A21\u578B\u7EED\u63A5\u5DE5\u4F5C\uFF08\u5B9E\u4F53\u7D22\u5F15\u7531\u7CFB\u7EDF\u53E6\u884C\u786E\u5B9A\u6027\u7EF4\u62A4\uFF0C\u65E0\u9700\u4F60\u8F93\u51FA\uFF09\u3002") + CHECKPOINT_FORMAT + checkpointRules(hasPrevious);
|
|
2158
|
+
checkpointDirectPrompt = (hasPrevious) => (hasPrevious ? "system \u6D88\u606F\u662F\u672C\u4F1A\u8BDD\u7684\u5F52\u6863\u6863\u6848\uFF1A\u27E6DSC:ARCHIVE-INDEX\u27E7 \u5B9E\u4F53\u7D22\u5F15\uFF08\u68C0\u7D22\u7EBF\u7D22\uFF0C\u4E0D\u8981\u6539\u52A8\u5176\u5185\u5BB9\uFF09\u4E0E \u27E6DSC:ARCHIVE-NOTES\u27E7 \u65E2\u6709\u68C0\u67E5\u70B9\uFF1B\u5176\u540E\u7684\u5BF9\u8BDD\u6D88\u606F\u662F\u672C\u8F6E\u65B0\u5F52\u6863\u7684\u4F1A\u8BDD\u539F\u6587\uFF08\u672A\u7ECF\u884C\u5F0F\u538B\u7F29\uFF09\u3002\u8BF7\u628A\u65E2\u6709\u68C0\u67E5\u70B9\u4E0E\u8FD9\u4E9B\u539F\u6587\u5408\u5E76\u6539\u5199\u4E3A\u4E00\u4EFD\u65B0\u7684\u7ED3\u6784\u5316\u68C0\u67E5\u70B9\uFF0C\u4F9B\u540E\u7EED\u6A21\u578B\u7EED\u63A5\u5DE5\u4F5C\u3002" : "\u672C\u8F6E\u5F52\u6863\u51FA\u7684\u4F1A\u8BDD\u539F\u6587\u4EE5\u5BF9\u8BDD\u6D88\u606F\u5F62\u5F0F\u9644\u540E\uFF08\u672A\u7ECF\u884C\u5F0F\u538B\u7F29\uFF09\u3002\u8BF7\u628A\u5B83\u4EEC\u6574\u7406\u4E3A\u4E00\u4EFD\u7ED3\u6784\u5316\u68C0\u67E5\u70B9\uFF0C\u4F9B\u540E\u7EED\u6A21\u578B\u7EED\u63A5\u5DE5\u4F5C\uFF08\u5B9E\u4F53\u7D22\u5F15\u7531\u7CFB\u7EDF\u53E6\u884C\u786E\u5B9A\u6027\u7EF4\u62A4\uFF0C\u65E0\u9700\u4F60\u8F93\u51FA\uFF09\u3002") + "\u8FD9\u6279\u539F\u6587\u7D27\u90BB\u672A\u538B\u7F29\u7684\u4FDD\u7559\u533A\uFF0C\u8BF7\u989D\u5916\u5199\u660E\u5176\u4E2D\u5BF9\u7D27\u968F\u5176\u540E\u7684\u8FD1\u671F\u5DE5\u4F5C\u6709\u7528\u7684\u80CC\u666F\uFF08\u5DF2\u786E\u8BA4\u7684\u7EA6\u675F\u3001\u6570\u636E\u3001\u7ED3\u8BBA\uFF09\u3002" + CHECKPOINT_FORMAT + checkpointRules(hasPrevious, true);
|
|
2159
|
+
assembleSlot = (index, newNotes) => [
|
|
2160
|
+
"\u27E6DSC:ARCHIVE-INDEX\u27E7 \u7CBE\u786E\u7EC6\u8282\u53EF\u7528 recall \u5DE5\u5177\u68C0\u7D22\u672C\u4F1A\u8BDD\u5168\u91CF\u5386\u53F2\uFF1B\u4EE5\u4E0B\u4E3A\u5F52\u6863\u5B9E\u4F53\u7D22\u5F15\uFF08\u68C0\u7D22\u5173\u952E\u8BCD\u7EBF\u7D22\uFF09\uFF1A",
|
|
2161
|
+
index.join(" | "),
|
|
2162
|
+
"\u27E6DSC:ARCHIVE-NOTES\u27E7",
|
|
2163
|
+
newNotes
|
|
2164
|
+
].join("\n");
|
|
2165
|
+
parseSlotNarrativeState = (slotContent) => {
|
|
2166
|
+
const { index, notes } = parseSummarySlot(slotContent);
|
|
2167
|
+
const trimmedNotes = notes.trim();
|
|
2168
|
+
const hasPrevious = trimmedNotes.length > 0 && trimmedNotes !== SLOT_PLACEHOLDER;
|
|
2169
|
+
return { index, hasPrevious };
|
|
2170
|
+
};
|
|
2171
|
+
synthesizeSlotNarrative = async (slotContent, newLines, signal) => {
|
|
2172
|
+
const { index, hasPrevious } = parseSlotNarrativeState(slotContent);
|
|
2173
|
+
const lines = newLines.trim();
|
|
2174
|
+
const resp = await chatWithModelWithSummary(
|
|
2175
|
+
[
|
|
2176
|
+
{ role: "system", content: slotContent },
|
|
2177
|
+
{ role: "user", content: `${lines ? `\u672C\u8F6E\u65B0\u5F52\u6863\u7684\u6458\u8981\u884C\uFF1A
|
|
2178
|
+
${lines}
|
|
2179
|
+
|
|
2180
|
+
` : ""}${checkpointPrompt(hasPrevious)}` }
|
|
2181
|
+
],
|
|
2182
|
+
[],
|
|
2183
|
+
{ signal }
|
|
2184
|
+
);
|
|
2185
|
+
const newNotes = (resp.choices[0].message.content || "").trim();
|
|
2186
|
+
return assembleSlot(index, newNotes);
|
|
2187
|
+
};
|
|
2188
|
+
synthesizeSlotNarrativeFromBatch = async (slotContent, batch, signal) => {
|
|
2189
|
+
const { index, hasPrevious } = parseSlotNarrativeState(slotContent);
|
|
2190
|
+
const resp = await chatWithModelWithSummary(
|
|
2191
|
+
[
|
|
2192
|
+
{ role: "system", content: slotContent },
|
|
2193
|
+
...batch.map(degradeImagesForAux),
|
|
2194
|
+
{ role: "user", content: checkpointDirectPrompt(hasPrevious) }
|
|
2195
|
+
],
|
|
2196
|
+
[],
|
|
2197
|
+
{ signal }
|
|
2198
|
+
);
|
|
2199
|
+
const newNotes = (resp.choices[0].message.content || "").trim();
|
|
2200
|
+
return assembleSlot(index, newNotes);
|
|
2075
2201
|
};
|
|
2076
|
-
|
|
2202
|
+
compactSlotNarrative = async (slotContent, _modelWindow, signal) => synthesizeSlotNarrative(slotContent, "", signal);
|
|
2203
|
+
splitIntoBatches = (toCompact) => {
|
|
2077
2204
|
const MAX_BATCH_TOKENS = 16e3;
|
|
2078
2205
|
const units = groupUnits(toCompact);
|
|
2079
2206
|
const batches = [];
|
|
@@ -2090,7 +2217,10 @@ ${noteLine}` : noteLine;
|
|
|
2090
2217
|
batchTokens += size;
|
|
2091
2218
|
}
|
|
2092
2219
|
if (batch.length > 0) batches.push(batch);
|
|
2093
|
-
|
|
2220
|
+
return batches;
|
|
2221
|
+
};
|
|
2222
|
+
compactBatches = async (batches, signal) => {
|
|
2223
|
+
const lines = await Promise.all(batches.map((b, i) => compactBatch(b, signal, i === batches.length - 1)));
|
|
2094
2224
|
return lines.join("\n");
|
|
2095
2225
|
};
|
|
2096
2226
|
ensureSummarySlot = (messageArr) => {
|
|
@@ -2098,13 +2228,14 @@ ${noteLine}` : noteLine;
|
|
|
2098
2228
|
messageArr.unshift({ role: "system", content: "SYSTEM_META_CONTEXT_START" });
|
|
2099
2229
|
}
|
|
2100
2230
|
if (messageArr.length < 2 || messageArr[1]?.role !== "system") {
|
|
2101
|
-
messageArr.splice(1, 0, { role: "system", content:
|
|
2231
|
+
messageArr.splice(1, 0, { role: "system", content: SLOT_PLACEHOLDER });
|
|
2102
2232
|
}
|
|
2103
2233
|
};
|
|
2104
2234
|
SUMMARY_SELF_COMPACT_THRESHOLD = 2e3;
|
|
2105
2235
|
ensureFitsWindow = async (event) => {
|
|
2106
2236
|
const correctionRatio = event.correctionRatio ?? 1.4;
|
|
2107
|
-
const
|
|
2237
|
+
const toolsTokens = event.toolsTokens ?? 0;
|
|
2238
|
+
const estReal = (arr) => estimateTokens(arr) * correctionRatio + toolsTokens;
|
|
2108
2239
|
const hitRate = event.lastRealPromptTokens && event.lastCachedTokens != null && event.lastRealPromptTokens > 0 ? event.lastCachedTokens / event.lastRealPromptTokens : null;
|
|
2109
2240
|
const cacheFactor = hitRate == null ? 1 : Math.min(1.1, Math.max(0.9, 0.9 + hitRate * 0.2));
|
|
2110
2241
|
const effectiveRatio = Math.min(event.compactRatio * cacheFactor, 0.82);
|
|
@@ -2126,8 +2257,9 @@ ${noteLine}` : noteLine;
|
|
|
2126
2257
|
const { toCompact, keepRecent } = splitUntils(active, keep);
|
|
2127
2258
|
try {
|
|
2128
2259
|
if (toCompact.length > 0) {
|
|
2129
|
-
|
|
2130
|
-
|
|
2260
|
+
summaryMsg.content = mergeSummarySlot(summaryMsg?.content || "", "", extractArchiveEntities(toCompact));
|
|
2261
|
+
const batches = splitIntoBatches(toCompact);
|
|
2262
|
+
summaryMsg.content = batches.length === 1 ? await synthesizeSlotNarrativeFromBatch(summaryMsg.content, batches[0], event.signal) : await synthesizeSlotNarrative(summaryMsg.content, await compactBatches(batches, event.signal), event.signal);
|
|
2131
2263
|
if (estimateTokens([summaryMsg]) > SUMMARY_SELF_COMPACT_THRESHOLD) {
|
|
2132
2264
|
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal);
|
|
2133
2265
|
}
|
|
@@ -2263,12 +2395,12 @@ ${noteLine}` : noteLine;
|
|
|
2263
2395
|
}
|
|
2264
2396
|
return full;
|
|
2265
2397
|
}
|
|
2266
|
-
const
|
|
2398
|
+
const timeoutMs2 = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
2267
2399
|
let timer;
|
|
2268
2400
|
const raced = await Promise.race([
|
|
2269
2401
|
Promise.resolve(ret).then((v) => ({ kind: "ok", value: typeof v === "string" ? v : JSON.stringify(v) })),
|
|
2270
2402
|
new Promise((resolve) => {
|
|
2271
|
-
timer = setTimeout(() => resolve({ kind: "timeout" }),
|
|
2403
|
+
timer = setTimeout(() => resolve({ kind: "timeout" }), timeoutMs2);
|
|
2272
2404
|
}),
|
|
2273
2405
|
...signal ? [new Promise((resolve) => {
|
|
2274
2406
|
signal.addEventListener("abort", () => resolve({ kind: "abort" }), { once: true });
|
|
@@ -2276,7 +2408,7 @@ ${noteLine}` : noteLine;
|
|
|
2276
2408
|
]);
|
|
2277
2409
|
if (timer) clearTimeout(timer);
|
|
2278
2410
|
if (raced.kind === "timeout") {
|
|
2279
|
-
return `[\u23F3 \u5DE5\u5177\u6267\u884C\u8D85\u65F6\uFF08${Math.round(
|
|
2411
|
+
return `[\u23F3 \u5DE5\u5177\u6267\u884C\u8D85\u65F6\uFF08${Math.round(timeoutMs2 / 1e3)}s \u672A\u8FD4\u56DE\uFF09\uFF0C\u5DF2\u7194\u65AD\u8DF3\u8FC7\u3002\u8BE5\u5DE5\u5177\u53EF\u80FD hang \u6216\u4E0D\u54CD\u5E94\u4E2D\u6B62\u4FE1\u53F7\u3002]`;
|
|
2280
2412
|
}
|
|
2281
2413
|
if (raced.kind === "abort") {
|
|
2282
2414
|
throw new Error("aborted");
|
|
@@ -4038,19 +4170,19 @@ var init_httpExecutor = __esm({
|
|
|
4038
4170
|
};
|
|
4039
4171
|
executeHttpHook = async (input) => {
|
|
4040
4172
|
const method = (input.method || "POST").toUpperCase();
|
|
4041
|
-
const
|
|
4173
|
+
const timeoutMs2 = input.timeoutMs ?? 3e4;
|
|
4042
4174
|
try {
|
|
4043
4175
|
const res = await fetch(input.url, {
|
|
4044
4176
|
method,
|
|
4045
4177
|
headers: { "content-type": "application/json", ...input.headers ?? {} },
|
|
4046
4178
|
body: input.body !== void 0 ? JSON.stringify(input.body) : void 0,
|
|
4047
|
-
signal: AbortSignal.timeout(
|
|
4179
|
+
signal: AbortSignal.timeout(timeoutMs2)
|
|
4048
4180
|
});
|
|
4049
4181
|
const text = await res.text();
|
|
4050
4182
|
return { ok: true, status: res.status, responseBody: truncateBody(text) };
|
|
4051
4183
|
} catch (e) {
|
|
4052
4184
|
const name = e?.name ?? "";
|
|
4053
|
-
if (name === "TimeoutError") return { ok: false, status: 0, responseBody: "", error: `\u8BF7\u6C42\u8D85\u65F6\uFF08>${
|
|
4185
|
+
if (name === "TimeoutError") return { ok: false, status: 0, responseBody: "", error: `\u8BF7\u6C42\u8D85\u65F6\uFF08>${timeoutMs2}ms\uFF09` };
|
|
4054
4186
|
if (name === "AbortError") return { ok: false, status: 0, responseBody: "", error: "\u8BF7\u6C42\u88AB\u4E2D\u6B62" };
|
|
4055
4187
|
return { ok: false, status: 0, responseBody: "", error: e?.message ?? String(e) };
|
|
4056
4188
|
}
|
|
@@ -4351,7 +4483,7 @@ var init_registry3 = __esm({
|
|
|
4351
4483
|
getSkillCatalog = () => {
|
|
4352
4484
|
const all = listSkills();
|
|
4353
4485
|
if (all.length === 0) return "";
|
|
4354
|
-
return all.map((s) => `- ${s.name}\uFF1A${s.description}${s.triggers.length ? `\uFF08\u89E6\u53D1\uFF1A${s.triggers.join("\u3001 ")}\uFF09` : ""}`).join("\n");
|
|
4486
|
+
return all.slice().sort((a, b) => a.name.localeCompare(b.name)).map((s) => `- ${s.name}\uFF1A${s.description}${s.triggers.length ? `\uFF08\u89E6\u53D1\uFF1A${s.triggers.join("\u3001 ")}\uFF09` : ""}`).join("\n");
|
|
4355
4487
|
};
|
|
4356
4488
|
}
|
|
4357
4489
|
});
|
|
@@ -4391,7 +4523,7 @@ var init_registry4 = __esm({
|
|
|
4391
4523
|
getAgentCatalog = () => {
|
|
4392
4524
|
const all = listAgents();
|
|
4393
4525
|
if (all.length === 0) return "";
|
|
4394
|
-
return all.map((a) => `- ${a.name}\uFF1A${a.description}${a.role ? `\uFF08\u89D2\u8272\uFF1A${a.role}\uFF09` : ""}`).join("\n");
|
|
4526
|
+
return all.slice().sort((a, b) => a.name.localeCompare(b.name)).map((a) => `- ${a.name}\uFF1A${a.description}${a.role ? `\uFF08\u89D2\u8272\uFF1A${a.role}\uFF09` : ""}`).join("\n");
|
|
4395
4527
|
};
|
|
4396
4528
|
}
|
|
4397
4529
|
});
|
|
@@ -4593,6 +4725,7 @@ var init_systemInjections = __esm({
|
|
|
4593
4725
|
type: t.type,
|
|
4594
4726
|
function: { name: t.function.name, description: t.function.description, parameters: t.function.parameters }
|
|
4595
4727
|
}));
|
|
4728
|
+
const toolsTokens = Math.round(JSON.stringify(cleanedToolSchemas).length / 4);
|
|
4596
4729
|
ensureSummarySlot(message);
|
|
4597
4730
|
const LOCALE_HINTS = {
|
|
4598
4731
|
zh: "\u59CB\u7EC8\u7528\u4E2D\u6587\u8F93\u51FA\u6240\u6709\u9762\u5411\u7528\u6237\u7684\u5185\u5BB9\uFF1A\u4F60\u7684\u56DE\u590D\u3001\u4E2D\u95F4\u53D9\u8FF0\u3001todo \u4EFB\u52A1\u9879\u6807\u9898\u3001\u901A\u8FC7 exit_plan_mode \u63D0\u4EA4\u7684\u65B9\u6848\u6587\u672C\u3001\u4EE3\u7801\u6CE8\u91CA\u4E0E\u63D0\u4EA4\u4FE1\u606F\u3002\u4EE3\u7801\u6807\u8BC6\u7B26\u4FDD\u6301\u539F\u6837\uFF1B\u5DE5\u5177\u7ED3\u679C\u4E0E\u7CFB\u7EDF\u6307\u4EE4\u53EF\u80FD\u5939\u6742\u5176\u4ED6\u8BED\u8A00\u2014\u2014\u5FC5\u8981\u65F6\u7167\u5F15\u539F\u6587\uFF0C\u4F46\u4F60\u81EA\u5DF1\u7684\u53D9\u8FF0\u4E0E\u89E3\u91CA\u4E00\u5F8B\u7528\u4E2D\u6587\u3002",
|
|
@@ -4616,7 +4749,7 @@ var init_systemInjections = __esm({
|
|
|
4616
4749
|
injectAgentCatalog(message);
|
|
4617
4750
|
injectProjectGuide(message);
|
|
4618
4751
|
injectMemory(message);
|
|
4619
|
-
return { rawTools, cleanedToolSchemas };
|
|
4752
|
+
return { rawTools, cleanedToolSchemas, toolsTokens };
|
|
4620
4753
|
};
|
|
4621
4754
|
}
|
|
4622
4755
|
});
|
|
@@ -4633,14 +4766,14 @@ var init_agent = __esm({
|
|
|
4633
4766
|
type: "function",
|
|
4634
4767
|
function: {
|
|
4635
4768
|
name: "spawn_agent",
|
|
4636
|
-
description: "\
|
|
4769
|
+
description: "\u6D3E\u751F\u62E5\u6709\u72EC\u7ACB\u6267\u884C\u73AF\u5883\u7684\u5B50 agent \u5904\u7406\u9694\u79BB\u5B50\u4EFB\u52A1\uFF0C\u5B8C\u6210\u540E\u81EA\u52A8\u6C47\u62A5\u6539\u52A8\u70B9\u4E0E\u7ED3\u8BBA\u3002name \u53EF\u6307\u5B9A\u58F0\u660E\u5F0F\u5B50 Agent\uFF08\u89C1\u7CFB\u7EDF\u63D0\u793A\u8BCD\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\uFF0C\u5957\u7528\u5176\u7CFB\u7EDF\u8BCD/\u5DE5\u5177\u767D\u540D\u5355/model\uFF09\uFF1B\u7F3A\u7701\u8D70\u901A\u7528\u6A21\u677F\u3002\u7EED\u8DD1\uFF1A\u4F20 resume_session_id\uFF08\u6B64\u524D\u8FD4\u56DE\u7684 agent_id\uFF09\u590D\u7528\u8BE5\u5B50 Agent \u5B8C\u6574\u5386\u53F2\u8BB0\u5FC6\uFF0C\u9002\u5408\u8FFD\u95EE/\u7EE7\u7EED\u672A\u5B8C\u4EFB\u52A1\u3002",
|
|
4637
4770
|
parameters: {
|
|
4638
4771
|
type: "object",
|
|
4639
4772
|
properties: {
|
|
4640
|
-
task: { type: "string", description: "\
|
|
4641
|
-
name: { type: "string", description: "\u58F0\u660E\u5F0F\u5B50 Agent \u540D\
|
|
4642
|
-
role: { type: "string", description: "\
|
|
4643
|
-
resume_session_id: { type: "string", description: "\u7EED\u8DD1\u65E2\u6709\u5B50 Agent\uFF1A\u4F20\u6B64\u524D
|
|
4773
|
+
task: { type: "string", description: "\u5B50 agent \u7684\u5177\u4F53\u4EFB\u52A1\uFF08\u5982 '\u7F16\u5199 Button \u7EC4\u4EF6\u7684\u5355\u5143\u6D4B\u8BD5'\uFF09\uFF1B\u7EED\u8DD1\u65F6\u4E3A\u65B0\u6307\u4EE4" },
|
|
4774
|
+
name: { type: "string", description: "\u58F0\u660E\u5F0F\u5B50 Agent \u540D\uFF08\u987B\u4E0E\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\u4E00\u81F4\uFF09\uFF1B\u7F3A\u7701\u901A\u7528\u5B50 agent" },
|
|
4775
|
+
role: { type: "string", description: "\u89D2\u8272/\u4E13\u957F\u8865\u5145\uFF08\u53EF\u9009\uFF09\uFF1B\u58F0\u660E\u5F0F agent \u81EA\u5E26 role \u65F6\u4F5C\u8865\u5145" },
|
|
4776
|
+
resume_session_id: { type: "string", description: "\u7EED\u8DD1\u65E2\u6709\u5B50 Agent\uFF1A\u4F20\u6B64\u524D\u8FD4\u56DE\u7684 agent_id\uFF08\u6062\u590D\u5176\u78C1\u76D8\u5386\u53F2\u4E0E\u8BB0\u5FC6\uFF09\u3002\u6CE8\u610F\u5B50 Agent \u72B6\u6001\u4E0D\u968F\u4E3B\u4F1A\u8BDD fork \u56DE\u6EDA\u3002\u7F3A\u7701\u65B0\u5EFA" }
|
|
4644
4777
|
},
|
|
4645
4778
|
required: ["task"]
|
|
4646
4779
|
},
|
|
@@ -4907,13 +5040,9 @@ var init_workflow = __esm({
|
|
|
4907
5040
|
function: {
|
|
4908
5041
|
name: "run_workflow",
|
|
4909
5042
|
description: [
|
|
4910
|
-
"\u591A\u5B50 agent \
|
|
4911
|
-
|
|
4912
|
-
"\
|
|
4913
|
-
"\u2022 pipeline\uFF1A\u6B65\u9AA4\u4E32\u884C\uFF0C\u9636\u6BB5 N \u81EA\u52A8\u63A5\u6536\u9636\u6BB5 N-1 \u7684\u4EA7\u51FA\u4F5C\u4E3A\u8F93\u5165\u4E0A\u4E0B\u6587\uFF0C\u9010\u7EA7\u7CBE\u70BC\u3002\u9002\u5408\u5206\u9636\u6BB5\u52A0\u5DE5\uFF08\u5982\uFF1A\u9636\u6BB51 \u62BD\u53D6\u8981\u70B9 \u2192 \u9636\u6BB52 \u5F52\u7C7B \u2192 \u9636\u6BB53 \u6C47\u603B\u7ED3\u8BBA\uFF09\u3002",
|
|
4914
|
-
"\u6BCF\u4E2A\u6B65\u9AA4\u53EF\u6307\u5B9A name \u5957\u7528\u58F0\u660E\u5F0F\u5B50 Agent\uFF08\u89C1\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\uFF09\u3001role \u8865\u5145\u89D2\u8272\u3001key \u4F5C\u4E3A\u7ED3\u679C\u6807\u7B7E\u3002",
|
|
4915
|
-
'\u5E76\u884C\u5199\u5B89\u5168\uFF1Aparallel \u6A21\u5F0F\u9ED8\u8BA4\u5171\u4EAB\u5DE5\u4F5C\u533A\uFF08\u5E76\u884C\u6539\u540C\u4E00\u6279\u6587\u4EF6\u4F1A\u51B2\u7A81\uFF0C\u5EFA\u8BAE\u4EC5\u7528\u4E8E\u8BFB/\u5206\u6790\uFF09\u3002\u8BBE isolation="worktree" \u540E\uFF0C\u6BCF\u4E2A\u6B65\u9AA4\u5728\u72EC\u7ACB git worktree \u91CC\u6267\u884C\uFF0C\u4E92\u4E0D\u6C61\u67D3\u2014\u2014\u7ED3\u675F\u540E\u6536\u5272\u5404 worktree \u7684 diff \u4F9B\u5408\u5E76\uFF0C\u5B9E\u73B0\u5B89\u5168\u7684\u5E76\u884C\u8FC1\u79FB/\u6539\u9020\u3002',
|
|
4916
|
-
"\u4E0E spawn_agent \u7684\u5173\u7CFB\uFF1Aspawn_agent = \u4E32\u884C\u6D3E\u751F\u5355\u4E2A\uFF1Brun_workflow = \u5E76\u884C/\u6D41\u6C34\u7EBF\u7F16\u6392\u591A\u4E2A\u3002\u4EFB\u52A1\u53EF\u5206\u89E3\u3001\u5F7C\u6B64\u72EC\u7ACB\u6216\u5448\u6D41\u6C34\u7EBF\u65F6\u7528\u672C\u5DE5\u5177\uFF0C\u5426\u5219\u7528 spawn_agent\u3002"
|
|
5043
|
+
"\u591A\u5B50 agent \u7F16\u6392\uFF1A\u628A\u53EF\u5206\u89E3\u7684\u5927\u4EFB\u52A1\u6D3E\u7ED9\u591A\u4E2A\u72EC\u7ACB\u5B50 agent\u3002parallel\uFF08\u9ED8\u8BA4\uFF09=\u5404\u6B65\u9AA4\u5E76\u53D1\u6267\u884C\u3001\u7ED3\u679C\u6309\u5E8F\u805A\u5408\uFF0C\u9002\u5408\u4E92\u76F8\u72EC\u7ACB\u7684\u53EA\u8BFB/\u5206\u6790\u4EFB\u52A1\uFF1Bpipeline=\u6B65\u9AA4\u4E32\u884C\uFF0C\u524D\u9636\u6BB5\u4EA7\u51FA\u81EA\u52A8\u4F5C\u4E3A\u540E\u9636\u6BB5\u8F93\u5165\uFF0C\u9002\u5408\u5206\u9636\u6BB5\u52A0\u5DE5\uFF08\u62BD\u53D6\u2192\u5F52\u7C7B\u2192\u6C47\u603B\uFF09\u3002",
|
|
5044
|
+
'\u6B65\u9AA4\u53EF\u7528 name \u5957\u7528\u58F0\u660E\u5F0F\u5B50 Agent\uFF08\u89C1\u3010\u53EF\u7528\u5B50 Agent \u76EE\u5F55\u3011\uFF09\u3001key \u4F5C\u7ED3\u679C\u6807\u7B7E\u3002parallel \u9ED8\u8BA4\u5171\u4EAB\u5DE5\u4F5C\u533A\uFF0C\u4EC5\u9002\u5408\u5E76\u884C\u8BFB/\u5206\u6790\uFF1B\u5E76\u884C\u5199/\u8FC1\u79FB\u7528 isolation="worktree"\uFF08\u6BCF\u6B65\u72EC\u7ACB git worktree\uFF0C\u7ED3\u675F\u540E\u6536\u5272\u5404\u6B65 diff\uFF09\u3002',
|
|
5045
|
+
"\u4E0E spawn_agent \u7684\u5206\u5DE5\uFF1A\u5355\u4EFB\u52A1\u4E32\u884C\u59D4\u6D3E\u7528 spawn_agent\uFF1B\u4EFB\u52A1\u53EF\u5206\u89E3\u3001\u591A\u5206\u652F\u6216\u6D41\u6C34\u7EBF\u5F0F\u65F6\u7528\u672C\u5DE5\u5177\u3002"
|
|
4917
5046
|
].join("\n"),
|
|
4918
5047
|
parameters: {
|
|
4919
5048
|
type: "object",
|
|
@@ -4921,18 +5050,18 @@ var init_workflow = __esm({
|
|
|
4921
5050
|
mode: {
|
|
4922
5051
|
type: "string",
|
|
4923
5052
|
enum: ["parallel", "pipeline"],
|
|
4924
|
-
description: "
|
|
5053
|
+
description: "parallel=\u5E76\u53D1\u6247\u51FA\uFF08\u9ED8\u8BA4\uFF0C\u6B65\u9AA4\u4E92\u4E0D\u4F9D\u8D56\uFF09\uFF1Bpipeline=\u4E32\u884C\u6D41\u6C34\u7EBF\uFF08\u524D\u9636\u6BB5\u4EA7\u51FA\u4F5C\u540E\u9636\u6BB5\u8F93\u5165\uFF09\u3002"
|
|
4925
5054
|
},
|
|
4926
5055
|
steps: {
|
|
4927
5056
|
type: "array",
|
|
4928
|
-
description: "\
|
|
5057
|
+
description: "\u6B65\u9AA4\u5217\u8868\uFF08parallel=\u6BCF\u4E2A\u662F\u72EC\u7ACB\u5B50 agent \u4EFB\u52A1\uFF1Bpipeline=\u6309\u5E8F\u5404\u9636\u6BB5\uFF09\u3002",
|
|
4929
5058
|
items: {
|
|
4930
5059
|
type: "object",
|
|
4931
5060
|
properties: {
|
|
4932
|
-
task: { type: "string", description: "\
|
|
4933
|
-
name: { type: "string", description: "\u58F0\u660E\u5F0F\u5B50 Agent \u540D\
|
|
4934
|
-
role: { type: "string", description: "\u89D2\u8272
|
|
4935
|
-
key: { type: "string", description: "\u7ED3\u679C\u6807\u7B7E\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\
|
|
5061
|
+
task: { type: "string", description: "\u5B50 agent \u4EFB\u52A1\u63CF\u8FF0\uFF08parallel \u987B\u81EA\u5305\u542B\uFF1Bpipeline \u53EA\u5199\u672C\u9636\u6BB5\u804C\u8D23\uFF09" },
|
|
5062
|
+
name: { type: "string", description: "\u58F0\u660E\u5F0F\u5B50 Agent \u540D\uFF08\u53EF\u9009\uFF0C\u5957\u7528\u5176\u7CFB\u7EDF\u8BCD/\u5DE5\u5177\u767D\u540D\u5355/model\uFF09" },
|
|
5063
|
+
role: { type: "string", description: "\u89D2\u8272\u8865\u5145\uFF08\u53EF\u9009\uFF09" },
|
|
5064
|
+
key: { type: "string", description: "\u7ED3\u679C\u6807\u7B7E\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u53D6\u4EFB\u52A1\u9996\u53E5\uFF09" }
|
|
4936
5065
|
},
|
|
4937
5066
|
required: ["task"]
|
|
4938
5067
|
},
|
|
@@ -4940,12 +5069,12 @@ var init_workflow = __esm({
|
|
|
4940
5069
|
},
|
|
4941
5070
|
concurrency: {
|
|
4942
5071
|
type: "number",
|
|
4943
|
-
description: "parallel \
|
|
5072
|
+
description: "parallel \u6700\u5927\u5E76\u53D1\u6570\uFF08\u9ED8\u8BA4 4\uFF0C\u53D7\u5168\u5C40\u4E0A\u9650\u7EA6\u675F\uFF1B1=\u4E32\u884C\uFF09\u3002"
|
|
4944
5073
|
},
|
|
4945
5074
|
isolation: {
|
|
4946
5075
|
type: "string",
|
|
4947
5076
|
enum: ["none", "worktree"],
|
|
4948
|
-
description: "
|
|
5077
|
+
description: "none=\u5171\u4EAB\u5DE5\u4F5C\u533A\uFF08\u9ED8\u8BA4\uFF0C\u53EA\u8BFB/\u5206\u6790\uFF09\uFF1Bworktree=\u6BCF\u6B65\u72EC\u7ACB git worktree\uFF08\u5E76\u884C\u5199/\u8FC1\u79FB\uFF09\u3002\u4EC5 parallel \u652F\u6301\u3002"
|
|
4949
5078
|
}
|
|
4950
5079
|
},
|
|
4951
5080
|
required: ["steps"]
|
|
@@ -5602,23 +5731,23 @@ ${treeResult}`;
|
|
|
5602
5731
|
type: "function",
|
|
5603
5732
|
function: {
|
|
5604
5733
|
name: "edit_file",
|
|
5605
|
-
description: "\
|
|
5734
|
+
description: "\u5BF9\u6587\u4EF6\u505A\u5C40\u90E8\u7CBE\u51C6\u4FEE\u6539\u3002\u2605 \u540C\u4E00\u6587\u4EF6\u591A\u5904\u8981\u6539\u65F6\u4E00\u6B21\u4F20 edits \u6570\u7EC4\u5168\u90E8\u5B8C\u6210\uFF08\u6309\u5E8F\u5E94\u7528\u3001\u6574\u4F53\u539F\u5B50\uFF1A\u4EFB\u4E00\u5904\u5931\u8D25\u5168\u90E8\u4E0D\u5199\u5165\uFF09\uFF0C\u52FF\u9010\u5904\u591A\u6B21\u8C03\u7528\u3002old_str \u987B\u4E0E\u6587\u4EF6\u539F\u6587\u9010\u5B57\u7B26\u4E00\u81F4\uFF1A\u53BB\u6389 read_file \u8FD4\u56DE\u7684\u300C<\u884C\u53F7>: \u300D\u524D\u7F00\uFF0C\u4FDD\u7559\u539F\u7F29\u8FDB\uFF08Tab/\u7A7A\u683C\uFF09\u4E0E\u884C\u5C3E\u7A7A\u767D\u3002\u9ED8\u8BA4\u987B\u5168\u6587\u552F\u4E00\uFF1Breplace_all=true \u66FF\u6362\u5168\u90E8\u5339\u914D\uFF08\u6279\u91CF\u91CD\u547D\u540D/\u7EDF\u4E00\u6539\u5199\uFF09\u3002",
|
|
5606
5735
|
parameters: {
|
|
5607
5736
|
type: "object",
|
|
5608
5737
|
properties: {
|
|
5609
|
-
path: { type: "string", description: "\
|
|
5610
|
-
old_str: { type: "string", description: "\
|
|
5611
|
-
new_str: { type: "string", description: "\
|
|
5612
|
-
replace_all: { type: "boolean", description: "\
|
|
5738
|
+
path: { type: "string", description: "\u76EE\u6807\u6587\u4EF6\u8DEF\u5F84" },
|
|
5739
|
+
old_str: { type: "string", description: "\u73B0\u6709\u65E7\u4EE3\u7801\u5757\uFF08\u5355\u5904\u4FEE\u6539\u7528\uFF1B\u591A\u5904\u6539\u7528 edits\uFF09" },
|
|
5740
|
+
new_str: { type: "string", description: "\u66FF\u6362\u540E\u7684\u65B0\u4EE3\u7801\u5757\uFF08\u5355\u5904\u4FEE\u6539\u7528\uFF09" },
|
|
5741
|
+
replace_all: { type: "boolean", description: "\u66FF\u6362\u5168\u6587\u6240\u6709\u5339\u914D\uFF08\u9ED8\u8BA4 false \u4EC5\u552F\u4E00\u5339\u914D\uFF09\u3002\u9876\u5C42\u4EC5\u4F5C\u7528\u5355\u6761 old_str/new_str\uFF1Bedits \u5185\u6BCF\u6761\u53EF\u72EC\u7ACB\u8BBE\u7F6E" },
|
|
5613
5742
|
edits: {
|
|
5614
5743
|
type: "array",
|
|
5615
|
-
description: "\u2605 \u540C\
|
|
5744
|
+
description: "\u2605 \u540C\u6587\u4EF6\u591A\u5904\u4FEE\u6539\u9996\u9009\uFF1A\u4E00\u6B21\u6309\u5E8F\u5B8C\u6210\u5168\u90E8\u66FF\u6362\u3002\u7B2C N \u6761 old_str \u57FA\u4E8E\u524D N-1 \u6761\u5E94\u7528\u540E\u7684\u5185\u5BB9\u6784\u9020\uFF1B\u4EFB\u4E00\u6761\u672A\u547D\u4E2D\u5219\u6574\u7EC4\u4E0D\u5199\u5165\uFF08\u539F\u5B50\uFF09\uFF0C\u4FEE\u6B63\u540E\u6574\u7EC4\u91CD\u8BD5",
|
|
5616
5745
|
items: {
|
|
5617
5746
|
type: "object",
|
|
5618
5747
|
properties: {
|
|
5619
|
-
old_str: { type: "string", description: "\
|
|
5620
|
-
new_str: { type: "string", description: "\
|
|
5621
|
-
replace_all: { type: "boolean", description: "\
|
|
5748
|
+
old_str: { type: "string", description: "\u73B0\u6709\u65E7\u4EE3\u7801\u5757" },
|
|
5749
|
+
new_str: { type: "string", description: "\u65B0\u4EE3\u7801\u5757" },
|
|
5750
|
+
replace_all: { type: "boolean", description: "\u66FF\u6362\u5168\u90E8\u5339\u914D\uFF08\u9ED8\u8BA4 false\uFF09" }
|
|
5622
5751
|
},
|
|
5623
5752
|
required: ["old_str", "new_str"]
|
|
5624
5753
|
}
|
|
@@ -5784,7 +5913,7 @@ ${summaries.join("\n")}`;
|
|
|
5784
5913
|
type: "function",
|
|
5785
5914
|
function: {
|
|
5786
5915
|
name: "write_file",
|
|
5787
|
-
description: "\u5C06\u5B8C\u6574\u5185\u5BB9\u5168\u91CF\u5199\u5165\u6307\u5B9A\u6587\u4EF6\uFF08\u8986\u76D6\uFF09\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u5219\u65B0\u5EFA\uFF08\u542B\u7236\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u5219\u6574\u4F53\u8986\u76D6\u3002\u2605 \u4EC5\u7528\u4E8E\u3010\u65B0\u5EFA\u6587\u4EF6\u3011\u6216\u3010\u5F7B\u5E95\u91CD\u5199\u6574\u4E2A\u6587\u4EF6\u3011\
|
|
5916
|
+
description: "\u5C06\u5B8C\u6574\u5185\u5BB9\u5168\u91CF\u5199\u5165\u6307\u5B9A\u6587\u4EF6\uFF08\u8986\u76D6\uFF09\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u5219\u65B0\u5EFA\uFF08\u542B\u7236\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u5219\u6574\u4F53\u8986\u76D6\u3002\u2605 \u4EC5\u7528\u4E8E\u3010\u65B0\u5EFA\u6587\u4EF6\u3011\u6216\u3010\u5F7B\u5E95\u91CD\u5199\u6574\u4E2A\u6587\u4EF6\u3011\uFF1B\u4FEE\u6539\u65E2\u6709\u6587\u4EF6\u4E00\u5F8B\u6539\u7528 edit_file\uFF08\u5C40\u90E8\u7CBE\u51C6\u66FF\u6362\u3001\u6700\u5C0F diff\uFF09\u3002",
|
|
5788
5917
|
parameters: {
|
|
5789
5918
|
type: "object",
|
|
5790
5919
|
properties: {
|
|
@@ -5970,14 +6099,14 @@ var init_search = __esm({
|
|
|
5970
6099
|
type: "function",
|
|
5971
6100
|
function: {
|
|
5972
6101
|
name: "search_grep",
|
|
5973
|
-
description: "\u5728\u5DE5\u4F5C\u533A\
|
|
6102
|
+
description: "\u5728\u5DE5\u4F5C\u533A\u6587\u4EF6\u4E2D\u68C0\u7D22\u5339\u914D\u7684\u4EE3\u7801\u884C\uFF0C\u6BCF\u4E2A\u547D\u4E2D\u9ED8\u8BA4\u5E26\u524D\u540E\u5404 2 \u884C\u4E0A\u4E0B\u6587\uFF08\u53EF\u76F4\u63A5\u5224\u65AD\u7528\u6CD5\uFF1B\u6784\u9020 edit_file \u7684 old_str \u524D\u53EF\u7528 context \u8C03\u5927\u4E00\u6B21\u62FF\u8DB3\uFF09\u3002\u9ED8\u8BA4\u5B57\u9762\u91CF\u5339\u914D\uFF0C\u6B63\u5219\u4F20 is_regex=true\u3002\u2605 \u591A\u5173\u952E\u8BCD\u7528 is_regex=true \u4EE5 | \u5408\u5E76\uFF08\u5982 'uploadVisible|uploadTip'\uFF09\u4E00\u6B21\u67E5\u5B8C\uFF0C\u52FF\u9010\u8BCD\u591A\u6B21\u8C03\u7528\u3002path \u53EF\u9650\u5B9A\u76EE\u5F55\u6216\u6587\u4EF6\uFF08\u5355\u5927\u6587\u4EF6\u591A\u5904\u5B9A\u4F4D\u4F20\u6587\u4EF6\u8DEF\u5F84\u6700\u9AD8\u6548\uFF09\u3002\u591A\u6839\u5DE5\u4F5C\u533A\uFF1Apath \u53EF\u4F20\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u5982 'frontend'\uFF09\u3001\u7EDD\u5BF9\u8DEF\u5F84\u6216 ../\u5144\u5F1F\u76EE\u5F55\u3002\u2605 \u7528\u6237\u6307\u660E\u4E86\u9879\u76EE\u65F6\u52A1\u5FC5\u628A\u8BE5\u9879\u76EE\u4F5C\u4E3A path \u4F20\u5165\u2014\u2014\u7F3A\u7701\u53EA\u641C\u6D3B\u52A8\u6839\uFF0C\u5E38\u4E0E\u610F\u56FE\u4E0D\u7B26\u3002",
|
|
5974
6103
|
parameters: {
|
|
5975
6104
|
type: "object",
|
|
5976
6105
|
properties: {
|
|
5977
|
-
query: { type: "string", description: "\u68C0\u7D22\
|
|
5978
|
-
is_regex: { type: "boolean", description: "
|
|
5979
|
-
path: { type: "string", description: "\u9650\u5B9A\u641C\u7D22\u7684\u76EE\u5F55\u6216\
|
|
5980
|
-
context: { type: "number", description: "\u6BCF\
|
|
6106
|
+
query: { type: "string", description: "\u68C0\u7D22\u8BCD\u3002\u9ED8\u8BA4\u5B57\u9762\u91CF\uFF08\u5982 'function runAgent'\uFF09\uFF1Bis_regex=true \u65F6\u6309\u6B63\u5219\uFF08\u591A\u5173\u952E\u8BCD\u7528 | \u5408\u5E76\uFF09" },
|
|
6107
|
+
is_regex: { type: "boolean", description: "query \u6309\u6B63\u5219\u89E3\u6790\uFF08\u9ED8\u8BA4 false\uFF0C\u5B57\u9762\u91CF\u81EA\u52A8\u8F6C\u4E49\u7279\u6B8A\u5B57\u7B26\uFF09" },
|
|
6108
|
+
path: { type: "string", description: "\u9650\u5B9A\u641C\u7D22\u7684\u76EE\u5F55\u6216\u6587\u4EF6\uFF08\u53EF\u9009\uFF09\u3002\u4F20\u6587\u4EF6=\u8BE5\u6587\u4EF6\u5185\u68C0\u7D22\uFF08\u5927\u6587\u4EF6\u591A\u5904\u5B9A\u4F4D\u9996\u9009\uFF09\u3002\u9ED8\u8BA4\u6D3B\u52A8\u6839\uFF1B\u591A\u6839\u4E0B\u53EF\u4F20\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u5982 'frontend'\uFF09/\u7EDD\u5BF9\u8DEF\u5F84/../\u5144\u5F1F\u76EE\u5F55\u3002\u7528\u6237\u63D0\u5230\u5177\u4F53\u9879\u76EE\u65F6\u5FC5\u586B\u3002" },
|
|
6109
|
+
context: { type: "number", description: "\u6BCF\u547D\u4E2D\u9644\u5E26\u4E0A\u4E0B\u6587\u884C\u6570\uFF080-10\uFF0C\u9ED8\u8BA4 2\uFF09\u3002\u8981\u62FF\u8DB3\u5B8C\u6574\u4EE3\u7801\u4F5C old_str \u65F6\u8C03\u5927\uFF08\u5982 5-8\uFF09" }
|
|
5981
6110
|
},
|
|
5982
6111
|
required: ["query"]
|
|
5983
6112
|
},
|
|
@@ -6121,7 +6250,7 @@ ${content}`;
|
|
|
6121
6250
|
|
|
6122
6251
|
// ../core/src/tool/registry/command.ts
|
|
6123
6252
|
import { spawn as spawn4 } from "child_process";
|
|
6124
|
-
var EXIT_SENTINEL, EXIT_SENTINEL_RE, RUN_COMMAND_MAX_CHARS, commandTools;
|
|
6253
|
+
var EXIT_SENTINEL, EXIT_SENTINEL_RE, AUTO_BG_NOTICE, AUTO_BG_SENTINEL_RE, RUN_COMMAND_MAX_CHARS, commandTools;
|
|
6125
6254
|
var init_command = __esm({
|
|
6126
6255
|
"../core/src/tool/registry/command.ts"() {
|
|
6127
6256
|
"use strict";
|
|
@@ -6132,6 +6261,8 @@ var init_command = __esm({
|
|
|
6132
6261
|
EXIT_SENTINEL = (code) => `
|
|
6133
6262
|
\u27E6DSC_EXIT:${code}\u27E7`;
|
|
6134
6263
|
EXIT_SENTINEL_RE = /⟦DSC_EXIT:(-?\d+)⟧/g;
|
|
6264
|
+
AUTO_BG_NOTICE = "\u27E6DSC_BG\u27E7";
|
|
6265
|
+
AUTO_BG_SENTINEL_RE = /⟦DSC_BG⟧\s*$/;
|
|
6135
6266
|
RUN_COMMAND_MAX_CHARS = 2e4;
|
|
6136
6267
|
commandTools = [
|
|
6137
6268
|
{
|
|
@@ -6156,8 +6287,13 @@ var init_command = __esm({
|
|
|
6156
6287
|
// 💡 我们将在 execute 内部真正落地这个长度限制
|
|
6157
6288
|
verifyResult: (rawOutput) => {
|
|
6158
6289
|
const matches2 = [...rawOutput.matchAll(EXIT_SENTINEL_RE)];
|
|
6159
|
-
const
|
|
6290
|
+
const last = matches2[matches2.length - 1];
|
|
6291
|
+
const code = last ? parseInt(last[1], 10) : null;
|
|
6160
6292
|
if (code === 0) return { status: "success" /* SUCCESS */ };
|
|
6293
|
+
if (code === null) {
|
|
6294
|
+
if (AUTO_BG_SENTINEL_RE.test(rawOutput.trimEnd())) return { status: "success" /* SUCCESS */ };
|
|
6295
|
+
return { status: "failed" /* FAILED */, summary: "\u8F93\u51FA\u4E2D\u7F3A\u5C11\u9000\u51FA\u7801\u54E8\u5175\u2014\u2014\u8FDB\u7A0B\u88AB\u5F3A\u5236\u7EC8\u6B62\u6216\u8F93\u51FA\u4E0D\u5B8C\u6574\uFF0C\u7ED3\u679C\u4E0D\u53EF\u4FE1\uFF0C\u6309\u5931\u8D25\u5904\u7406\u3002" };
|
|
6296
|
+
}
|
|
6161
6297
|
const hint = code === 9009 ? "\uFF08Windows\uFF1A\u547D\u4EE4\u672A\u88AB\u8BC6\u522B\u2014\u2014\u547D\u4EE4\u4E0D\u5B58\u5728\u6216 PATH \u7F3A\u5931\uFF09" : code === 127 ? "\uFF08\u547D\u4EE4\u672A\u627E\u5230\u2014\u2014\u68C0\u67E5\u547D\u4EE4\u540D/PATH\uFF09" : code === 255 ? "\uFF08255 \u5E38\u89C1\u4E8E Unix \u547D\u4EE4\u5728\u975E POSIX shell \u4E0B\u7F3A\u5931\uFF0C\u6216\u8FDB\u7A0B\u663E\u5F0F exit(-1/255)\u3001\u8FDE\u63A5\u5931\u8D25\uFF09" : code === 4294967295 || code === -1 ? "\uFF08\u8FDB\u7A0B\u9000\u51FA\u7801 -1/\u672A\u6355\u83B7\u5F02\u5E38\u88AB\u6740\uFF09" : "";
|
|
6162
6298
|
return { status: "failed" /* FAILED */, summary: `\u547D\u4EE4\u9000\u51FA\u7801\u975E\u96F6\uFF1A${code}${hint}` };
|
|
6163
6299
|
},
|
|
@@ -6346,6 +6482,7 @@ ${tail}`,
|
|
|
6346
6482
|
\u23F3 [\u81EA\u52A8\u8F6C\u540E\u53F0]\uFF1A\u547D\u4EE4 [${args.command}] ${why}\uFF0C\u5DF2\u81EA\u52A8\u8F6C\u4E3A\u540E\u53F0\u4EFB\u52A1\uFF08\u524D\u53F0\u6D41\u5F0F\u7ED3\u675F\uFF0C\u672A\u6D88\u8D39\u7684\u5269\u4F59\u8F93\u51FA\u5DF2\u5E76\u5165\u540E\u53F0\u7F13\u51B2\uFF09\u3002
|
|
6347
6483
|
task_id: ${taskId}
|
|
6348
6484
|
\u26A0\uFE0F \u8FDB\u7A0B\u4ECD\u5728\u8FD0\u884C\uFF0C\u9000\u51FA\u7801\u672A\u77E5\uFF08\u4E0D\u5224\u5B9A\u6210\u529F/\u5931\u8D25\uFF09\u2014\u2014\u7528 get_background_output(task_id="${taskId}", wait_seconds=\u2026) \u7B49\u5F85/\u67E5\u770B\u7ED3\u679C\uFF1B\u82E5\u786E\u8BA4\u65E0\u9700\u7EE7\u7EED\uFF0C\u7528 stop_background_task(task_id="${taskId}") \u7EC8\u6B62\u3002
|
|
6485
|
+
${AUTO_BG_NOTICE}
|
|
6349
6486
|
`;
|
|
6350
6487
|
} else if (overLimit) {
|
|
6351
6488
|
yield EXIT_SENTINEL(-1);
|
|
@@ -7267,9 +7404,9 @@ var init_http = __esm({
|
|
|
7267
7404
|
function: {
|
|
7268
7405
|
name: "http_request",
|
|
7269
7406
|
description: [
|
|
7270
|
-
"\u5168\u65B9\u6CD5 HTTP \u5BA2\u6237\u7AEF\
|
|
7271
|
-
"\u4E0E web_fetch \
|
|
7272
|
-
"SSRF\uFF1A\
|
|
7407
|
+
"\u5168\u65B9\u6CD5 HTTP \u5BA2\u6237\u7AEF\uFF1A\u672C\u5730\u524D\u540E\u7AEF\u8054\u8C03\u3001API \u6D4B\u8BD5\u3001\u8C03 REST \u63A5\u53E3\u3002\u8FD4\u56DE\u539F\u59CB\u54CD\u5E94\uFF08\u72B6\u6001\u7801+\u54CD\u5E94\u5934+body \u539F\u6587\uFF0C\u4E0D\u8F6C Markdown\uFF09\u3002",
|
|
7408
|
+
"\u4E0E web_fetch \u533A\u522B\uFF1Aweb_fetch GET \u6293\u7F51\u9875\u8F6C Markdown\uFF08\u67E5\u6587\u6863\u3001\u9ED8\u8BA4\u62E6\u5185\u7F51\uFF09\uFF1B\u672C\u5DE5\u5177\u8C03\u63A5\u53E3\u53D6\u539F\u59CB\u54CD\u5E94\uFF08\u8054\u8C03\u3001\u9ED8\u8BA4\u653E\u884C localhost/\u5185\u7F51\uFF09\u3002",
|
|
7409
|
+
"SSRF\uFF1A\u59CB\u7EC8\u62E6\u4E91\u5143\u6570\u636E\u7AEF\u70B9 169.254.169.254\uFF1B\u4EC5 http/https\u3002"
|
|
7273
7410
|
].join(" "),
|
|
7274
7411
|
parameters: {
|
|
7275
7412
|
type: "object",
|
|
@@ -7365,7 +7502,7 @@ var init_http = __esm({
|
|
|
7365
7502
|
// ../core/src/tool/registry/typescript.ts
|
|
7366
7503
|
import fs16 from "fs/promises";
|
|
7367
7504
|
import path20 from "path";
|
|
7368
|
-
var MAX_FILE_BYTES, toDisplayPath, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, diagnoseOneFile, typescriptTools;
|
|
7505
|
+
var MAX_FILE_BYTES, toDisplayPath, isLibFile, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, MAX_REF_ENTRIES, REF_SNIPPET_MAX, diagnoseOneFile, typescriptTools;
|
|
7369
7506
|
var init_typescript = __esm({
|
|
7370
7507
|
"../core/src/tool/registry/typescript.ts"() {
|
|
7371
7508
|
"use strict";
|
|
@@ -7379,6 +7516,7 @@ var init_typescript = __esm({
|
|
|
7379
7516
|
if (rel && !rel.startsWith("..") && !path20.isAbsolute(rel)) return rel.replace(/\\/g, "/");
|
|
7380
7517
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
7381
7518
|
};
|
|
7519
|
+
isLibFile = (abs) => /(?:^|\/)node_modules\//.test(abs.replace(/\\/g, "/")) || /\.d\.ts$/i.test(abs);
|
|
7382
7520
|
precheck = async (displayPath, absPath) => {
|
|
7383
7521
|
const readBlock = await assertReadable(absPath, displayPath);
|
|
7384
7522
|
if (readBlock) return readBlock;
|
|
@@ -7392,6 +7530,8 @@ var init_typescript = __esm({
|
|
|
7392
7530
|
};
|
|
7393
7531
|
MAX_DIAG_ENTRIES = 300;
|
|
7394
7532
|
MAX_DIAG_FILES = 20;
|
|
7533
|
+
MAX_REF_ENTRIES = 200;
|
|
7534
|
+
REF_SNIPPET_MAX = 160;
|
|
7395
7535
|
diagnoseOneFile = async (TS, displayPath, checkJs) => {
|
|
7396
7536
|
try {
|
|
7397
7537
|
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
@@ -7446,7 +7586,7 @@ ${body}${tail}` };
|
|
|
7446
7586
|
type: "function",
|
|
7447
7587
|
function: {
|
|
7448
7588
|
name: "get_diagnostics",
|
|
7449
|
-
description: "\u5BF9\u4E00\u4E2A\u6216\u591A\u4E2A TS/JS \u6587\u4EF6\u53D6
|
|
7589
|
+
description: "\u5BF9\u4E00\u4E2A\u6216\u591A\u4E2A TS/JS \u6587\u4EF6\u53D6\u7C7B\u578B+\u8BED\u4E49\u8BCA\u65AD\uFF08\u7C7B\u578B\u9519\u8BEF/\u672A\u7528\u53D8\u91CF/\u4E0D\u53EF\u8FBE\u4EE3\u7801\uFF09\uFF0C\u8F93\u51FA\u884C:\u5217/\u4E25\u91CD\u5EA6/TS \u9519\u8BEF\u7801\uFF0C\u683C\u5F0F\u5BF9\u9F50 tsc\u3002\u2605 \u6539\u5B8C\u591A\u4E2A\u6587\u4EF6\u540E\u9A8C\u8BC1\uFF1A\u4F20 paths \u6570\u7EC4\u4E00\u6B21\u8BCA\u65AD\u5168\u90E8\uFF08\u6700\u591A 20 \u4E2A\uFF09\uFF0C\u52FF\u9010\u6587\u4EF6\u591A\u6B21\u8C03\u7528\u3002\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B.vue SFC \u4E0E\u5176\u4ED6\u8BED\u8A00\u6269\u5C55\u540D\uFF08.java/.py \u7B49\uFF09\u76F4\u63A5\u62D2\u7EDD\u3001\u52FF\u4F20\u5165\u3002\u9879\u76EE\u7EA7\u5168\u91CF\u8BCA\u65AD\u7528 run_command \u8DD1 `tsc --noEmit`\u3002",
|
|
7450
7590
|
parameters: {
|
|
7451
7591
|
type: "object",
|
|
7452
7592
|
properties: {
|
|
@@ -7501,7 +7641,7 @@ ${sections.join("\n\n")}`;
|
|
|
7501
7641
|
type: "function",
|
|
7502
7642
|
function: {
|
|
7503
7643
|
name: "goto_definition",
|
|
7504
|
-
description: "\u8DF3\u8F6C\u5230
|
|
7644
|
+
description: "\u8DF3\u8F6C\u5230 TS/JS \u6587\u4EF6\u67D0\u884C\u67D0\u5217\u7B26\u53F7\u7684\u5B9A\u4E49\u4F4D\u7F6E\uFF0C\u8FD4\u56DE rel/path:line:col\uFF08\u53EF\u591A\u5904\uFF09\u3002\u8DE8\u6587\u4EF6\u8FFD\u8E2A\u51FD\u6570/\u7C7B\u578B/\u53D8\u91CF\u7684\u6765\u6E90\uFF0C\u66FF\u4EE3 grep \u731C\u6D4B\u3002\u843D\u70B9\u5728 node_modules/.d.ts \u65F6\u6807\u6CE8 (declaration/library)\u3002\u884C\u5217 1-based\u3002\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B.vue SFC \u4E0E\u5176\u4ED6\u8BED\u8A00\u6269\u5C55\u540D\u76F4\u63A5\u62D2\u7EDD\u3001\u52FF\u4F20\u5165\u3002",
|
|
7505
7645
|
parameters: {
|
|
7506
7646
|
type: "object",
|
|
7507
7647
|
properties: {
|
|
@@ -7541,7 +7681,7 @@ ${sections.join("\n\n")}`;
|
|
|
7541
7681
|
const lc = posToLineCol(TS, defSf, def.textSpan.start);
|
|
7542
7682
|
loc = `${toDisplayPath(wsRoot, def.fileName)}:${lc.line}:${lc.column}`;
|
|
7543
7683
|
}
|
|
7544
|
-
const isLib =
|
|
7684
|
+
const isLib = isLibFile(def.fileName);
|
|
7545
7685
|
const name = def.name || "(anonymous)";
|
|
7546
7686
|
const kind = def.kind ? ` [${def.kind}]` : "";
|
|
7547
7687
|
return `${name}${kind} \u2192 ${loc}${isLib ? " (declaration/library)" : ""}`;
|
|
@@ -7553,6 +7693,97 @@ ${out.join("\n")}`;
|
|
|
7553
7693
|
}
|
|
7554
7694
|
}
|
|
7555
7695
|
}
|
|
7696
|
+
},
|
|
7697
|
+
{
|
|
7698
|
+
type: "function",
|
|
7699
|
+
function: {
|
|
7700
|
+
name: "find_references",
|
|
7701
|
+
description: "\u67E5\u627E TS/JS \u6587\u4EF6\u67D0\u884C\u67D0\u5217\u7B26\u53F7\u7684\u5168\u9879\u76EE\u5F15\u7528\uFF08\u8C03\u7528/\u5BFC\u5165/\u8BFB\u5199\uFF09\uFF0C\u8F93\u51FA rel/path:line:col + \u8BFB\u5199\u6807\u6CE8 + \u884C\u6458\u5F55\u3002\u7C7B\u578B\u611F\u77E5\uFF1A\u53EA\u8FD4\u56DE\u771F\u5B9E\u7ED1\u5B9A\uFF0C\u4E0D\u542B\u6CE8\u91CA/\u5B57\u7B26\u4E32\u91CC\u7684\u540C\u540D\u8BCD\uFF08grep \u6838\u5FC3\u8BEF\u62A5\u6E90\uFF09\u3002\u7528\u4E8E\u6539\u7B7E\u540D/\u91CD\u547D\u540D\u524D\u7684\u5F71\u54CD\u9762\u6392\u67E5\u3001\u8FFD\u8E2A\u8C03\u7528\u65B9\uFF1B\u4E0E goto_definition \u4E92\u4E3A\u53CD\u5411\u3002\u8986\u76D6\u4EE5 program \u5185\u6587\u4EF6\u4E3A\u754C\uFF08tsconfig include + import \u94FE\uFF09\uFF1B\u5355\u7B26\u53F7\u8D85 200 \u5904\u5F15\u7528\u622A\u65AD\u3002\u884C\u5217 1-based\u3002\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B.vue SFC \u4E0E\u5176\u4ED6\u8BED\u8A00\u6269\u5C55\u540D\u76F4\u63A5\u62D2\u7EDD\u3001\u52FF\u4F20\u5165\u3002",
|
|
7702
|
+
parameters: {
|
|
7703
|
+
type: "object",
|
|
7704
|
+
properties: {
|
|
7705
|
+
path: { type: "string", description: "\u76EE\u6807\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF08\u5982 'src/index.ts'\uFF09" },
|
|
7706
|
+
line: { type: "integer", description: "\u7B26\u53F7\u6240\u5728\u884C\u53F7\uFF081-based\uFF09" },
|
|
7707
|
+
column: { type: "integer", description: "\u7B26\u53F7\u6240\u5728\u5217\u53F7\uFF081-based\uFF09" }
|
|
7708
|
+
},
|
|
7709
|
+
required: ["path", "line", "column"]
|
|
7710
|
+
},
|
|
7711
|
+
safetyLevel: "safe" /* SAFE */,
|
|
7712
|
+
isSync: true,
|
|
7713
|
+
maxOutputCharacters: 48e3,
|
|
7714
|
+
// 200 条引用 × ~160 字符摘录的理论上界之内;中心 truncateToolResult 仍是最终兜底
|
|
7715
|
+
privacyMaskingRules: maskSecretsInContent,
|
|
7716
|
+
validateEnvironment: async () => !!await getTs(),
|
|
7717
|
+
async execute(args, _ctx) {
|
|
7718
|
+
const { path: displayPath, line, column } = args;
|
|
7719
|
+
try {
|
|
7720
|
+
const TS = await getTs();
|
|
7721
|
+
if (!TS) return `\u26A0\uFE0F [\u67E5\u627E\u5F15\u7528\u4E0D\u53EF\u7528]\uFF1Atypescript \u6A21\u5757\u672A\u52A0\u8F7D\uFF08VSCode \u6269\u5C55\u5185\u53EF\u7528\uFF1BCLI \u73AF\u5883\u672A\u5FC5\u5B89\u88C5 typescript\uFF09\u3002`;
|
|
7722
|
+
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
7723
|
+
const block = await precheck(displayPath, absPath);
|
|
7724
|
+
if (block) return block;
|
|
7725
|
+
const { ls } = await getLanguageService(TS, absPath);
|
|
7726
|
+
const program = ls.getProgram();
|
|
7727
|
+
if (!program) return `\u274C \u65E0\u6CD5\u53D6\u5F97 TS program\uFF08\u5185\u90E8\u9519\u8BEF\uFF09\u3002`;
|
|
7728
|
+
const sf = program.getSourceFile(absPath);
|
|
7729
|
+
if (!sf) return `\u274C \u6587\u4EF6\u672A\u7EB3\u5165 program\uFF1A${displayPath}\uFF08\u53EF\u80FD\u65E0\u5BF9\u5E94 tsconfig \u6216\u89E3\u6790\u5931\u8D25\uFF09\u3002`;
|
|
7730
|
+
const pos = lineColToPos(TS, sf, line, column);
|
|
7731
|
+
const groups = ls.findReferences(absPath, pos);
|
|
7732
|
+
if (!groups || groups.length === 0) {
|
|
7733
|
+
return `No references found at ${displayPath}:${line}:${column}\uFF08\u786E\u8BA4\u5B9A\u4F4D\u5728\u6807\u8BC6\u7B26\u4E0A\uFF0C\u975E\u7A7A\u767D/\u5B57\u9762\u91CF/\u5173\u952E\u5B57\uFF09\u3002`;
|
|
7734
|
+
}
|
|
7735
|
+
const wsRoot = getContainingRoot(absPath);
|
|
7736
|
+
const lineTextCache = /* @__PURE__ */ new Map();
|
|
7737
|
+
const lineSnippet = async (abs, line1) => {
|
|
7738
|
+
let lines = lineTextCache.get(abs);
|
|
7739
|
+
if (!lines) {
|
|
7740
|
+
try {
|
|
7741
|
+
lines = (await fs16.readFile(abs, "utf-8")).split(/\r?\n/);
|
|
7742
|
+
} catch {
|
|
7743
|
+
lines = [];
|
|
7744
|
+
}
|
|
7745
|
+
lineTextCache.set(abs, lines);
|
|
7746
|
+
}
|
|
7747
|
+
const text = (lines[line1 - 1] ?? "").trim();
|
|
7748
|
+
if (!text) return "";
|
|
7749
|
+
return " " + (text.length > REF_SNIPPET_MAX ? text.slice(0, REF_SNIPPET_MAX) + "\u2026" : text);
|
|
7750
|
+
};
|
|
7751
|
+
const sections = [];
|
|
7752
|
+
let shown = 0, overflow = 0;
|
|
7753
|
+
for (const g of groups) {
|
|
7754
|
+
const defSf = program.getSourceFile(g.definition.fileName);
|
|
7755
|
+
let defLoc = toDisplayPath(wsRoot, g.definition.fileName);
|
|
7756
|
+
if (defSf && g.definition.textSpan) {
|
|
7757
|
+
const lc = posToLineCol(TS, defSf, g.definition.textSpan.start);
|
|
7758
|
+
defLoc = `${defLoc}:${lc.line}:${lc.column}`;
|
|
7759
|
+
}
|
|
7760
|
+
const defLib = isLibFile(g.definition.fileName) ? " (declaration/library)" : "";
|
|
7761
|
+
const defName = (g.definition.name || "(anonymous)").replace(/\s+/g, " ");
|
|
7762
|
+
const header = `${defName}${g.definition.kind ? ` [${g.definition.kind}]` : ""} \u2014 ${g.references.length} \u5904\u5F15\u7528\uFF08\u58F0\u660E ${defLoc}\uFF09${defLib}`;
|
|
7763
|
+
const bodyLines = [];
|
|
7764
|
+
for (const r of g.references) {
|
|
7765
|
+
if (shown >= MAX_REF_ENTRIES) {
|
|
7766
|
+
overflow++;
|
|
7767
|
+
continue;
|
|
7768
|
+
}
|
|
7769
|
+
shown++;
|
|
7770
|
+
const refSf = program.getSourceFile(r.fileName);
|
|
7771
|
+
const lc = refSf ? posToLineCol(TS, refSf, r.textSpan.start) : { line: 0, column: 0 };
|
|
7772
|
+
const tag = r.isDefinition ? "[def]" : r.isWriteAccess ? "(write)" : "(read)";
|
|
7773
|
+
const snippet = r.isDefinition ? "" : await lineSnippet(r.fileName, lc.line);
|
|
7774
|
+
bodyLines.push(` ${toDisplayPath(wsRoot, r.fileName)}:${lc.line}:${lc.column} ${tag}${snippet}`);
|
|
7775
|
+
}
|
|
7776
|
+
sections.push([header, ...bodyLines].join("\n"));
|
|
7777
|
+
}
|
|
7778
|
+
const tail = overflow > 0 ? `
|
|
7779
|
+
\u2026(\u53E6\u6709 ${overflow} \u5904\u5F15\u7528\u672A\u663E\u793A\uFF1B\u7B26\u53F7\u8FC7\u70ED\u53EF\u6539\u7528 grep \u6309\u8C03\u7528\u540D\u626B\u63CF\uFF0C\u6216\u5206\u6587\u4EF6\u7F29\u5C0F\u8303\u56F4)\u2026` : "";
|
|
7780
|
+
return `[References: ${displayPath}:${line}:${column}]
|
|
7781
|
+
${sections.join("\n")}${tail}`;
|
|
7782
|
+
} catch (e) {
|
|
7783
|
+
return `\u274C \u67E5\u627E\u5F15\u7528\u5931\u8D25 [${displayPath}:${line}:${column}]: ${e?.message ?? e}`;
|
|
7784
|
+
}
|
|
7785
|
+
}
|
|
7786
|
+
}
|
|
7556
7787
|
}
|
|
7557
7788
|
];
|
|
7558
7789
|
}
|
|
@@ -8528,10 +8759,9 @@ var init_ask = __esm({
|
|
|
8528
8759
|
function: {
|
|
8529
8760
|
name: "ask_question",
|
|
8530
8761
|
description: [
|
|
8531
|
-
"\u5411\u7528\u6237\u63D0\u51FA\
|
|
8532
|
-
"
|
|
8533
|
-
"\
|
|
8534
|
-
"\u6CE8\u610F\uFF1A\u4EC5\u5728\u4EA4\u4E92\u5F0F\u73AF\u5883\u53EF\u7528\uFF1B\u82E5\u7ED3\u679C\u63D0\u793A\u300C\u4E0D\u652F\u6301\u300D\uFF0C\u6539\u7528\u7EAF\u6587\u672C\u5411\u7528\u6237\u63D0\u95EE\u3002"
|
|
8762
|
+
"\u5411\u7528\u6237\u63D0\u51FA\u591A\u9009\u95EE\u9898\u5E76\u7B49\u5F85\u4F5C\u7B54\uFF1A\u6280\u672F\u65B9\u6848\u4E8C\u9009\u4E00\u3001\u8DEF\u5F84\u53D6\u820D\u3001\u8303\u56F4\u786E\u8BA4\u7B49\u9700\u7528\u6237\u62CD\u677F\u7684\u51B3\u7B56\u6216\u6B67\u4E49\u6F84\u6E05\u2014\u2014\u52FF\u7528\u4E8E\u80FD\u4ECE\u4EE3\u7801/\u4E0A\u4E0B\u6587\u81EA\u884C\u786E\u5B9A\u7684\u95EE\u9898\u3002",
|
|
8763
|
+
"2-4 \u4E2A\u9009\u9879\uFF08label + \u53EF\u9009 description\uFF09\uFF1BmultiSelect=true \u591A\u9009\uFF08\u9ED8\u8BA4\u5355\u9009\uFF09\u3002\u7528\u6237\u53D6\u6D88\u8FD4\u56DE\u7A7A\u9009\u62E9\uFF08\u6539\u7528\u9ED8\u8BA4\u6216\u91CD\u65B0\u63D0\u95EE\uFF09\u3002",
|
|
8764
|
+
"\u4EC5\u4EA4\u4E92\u5F0F\u73AF\u5883\u53EF\u7528\uFF1B\u7ED3\u679C\u63D0\u793A\u300C\u4E0D\u652F\u6301\u300D\u65F6\u6539\u7528\u7EAF\u6587\u672C\u63D0\u95EE\u3002"
|
|
8535
8765
|
].join("\n"),
|
|
8536
8766
|
parameters: {
|
|
8537
8767
|
type: "object",
|
|
@@ -8974,30 +9204,30 @@ ${body.trim()}
|
|
|
8974
9204
|
type: "function",
|
|
8975
9205
|
function: {
|
|
8976
9206
|
name: "memory_save",
|
|
8977
|
-
description: "\u4FDD\u5B58\u4E00\u6761\u6301\u4E45\u8BB0\u5FC6\uFF08\u8DE8\u4F1A\u8BDD\u4FDD\u7559\uFF09\
|
|
9207
|
+
description: "\u4FDD\u5B58\u4E00\u6761\u6301\u4E45\u8BB0\u5FC6\uFF08\u8DE8\u4F1A\u8BDD\u4FDD\u7559\uFF09\uFF1A\u975E\u663E\u7136\u7684\u4E8B\u5B9E\u3001\u7528\u6237\u504F\u597D\u3001\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\u3001\u9879\u76EE\u7EA6\u675F\u3001\u5916\u90E8\u8D44\u6E90\u6307\u9488\u2014\u2014\u300C\u4E0D\u5E94\u6BCF\u6B21\u91CD\u65B0\u53D1\u73B0\u300D\u300C\u4EE3\u7801/git \u4E0D\u4F1A\u76F4\u63A5\u544A\u8BC9\u4F60\u300D\u7684\u4FE1\u606F\u3002\u52FF\u5B58\u4F1A\u8BDD\u5185\u5373\u629B\u7684\u4E34\u65F6\u4FE1\u606F\u3002\u4FDD\u5B58\u540E\u8BB0\u5FC6\u7D22\u5F15\u81EA\u52A8\u66F4\u65B0\uFF1B\u540C\u540D\u8BB0\u5FC6\u88AB\u8986\u76D6\u3002",
|
|
8978
9208
|
parameters: {
|
|
8979
9209
|
type: "object",
|
|
8980
9210
|
properties: {
|
|
8981
9211
|
name: {
|
|
8982
9212
|
type: "string",
|
|
8983
|
-
description: "\
|
|
9213
|
+
description: "\u552F\u4E00\u952E\uFF0C\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF08\u63CF\u8FF0\u6027 kebab-case\uFF0C\u5982 user-prefers-arrow-fns\uFF09"
|
|
8984
9214
|
},
|
|
8985
9215
|
description: {
|
|
8986
9216
|
type: "string",
|
|
8987
|
-
description: "\u4E00\u53E5\u8BDD\u6982\u62EC\
|
|
9217
|
+
description: "\u4E00\u53E5\u8BDD\u6982\u62EC\uFF08\u6CE8\u5165\u7D22\u5F15\u4F9B\u65E5\u540E\u5224\u65AD\u662F\u5426\u53EC\u56DE\uFF09\u3002\u52FF\u6362\u884C"
|
|
8988
9218
|
},
|
|
8989
9219
|
body: {
|
|
8990
9220
|
type: "string",
|
|
8991
|
-
description: "\u8BB0\u5FC6\u6B63\u6587\
|
|
9221
|
+
description: "\u8BB0\u5FC6\u6B63\u6587\uFF0C\u53EF\u591A\u884C\uFF0C\u4E0A\u9650 64KB"
|
|
8992
9222
|
},
|
|
8993
9223
|
type: {
|
|
8994
9224
|
type: "string",
|
|
8995
9225
|
enum: ["user", "feedback", "project", "reference"],
|
|
8996
|
-
description: "user=\u7528\u6237\u753B\u50CF/\u504F\u597D\uFF1Bfeedback=\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\uFF08\u542B\u539F\u56E0\u4E0E\u505A\u6CD5\uFF09\uFF1Bproject=\u9879\u76EE\u76EE\u6807/\u7EA6\u675F\uFF1Breference=\u5916\u90E8\u8D44\u6E90\u6307\u9488\
|
|
9226
|
+
description: "user=\u7528\u6237\u753B\u50CF/\u504F\u597D\uFF1Bfeedback=\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\uFF08\u542B\u539F\u56E0\u4E0E\u505A\u6CD5\uFF09\uFF1Bproject=\u9879\u76EE\u76EE\u6807/\u7EA6\u675F\uFF1Breference=\u5916\u90E8\u8D44\u6E90\u6307\u9488\u3002\u9ED8\u8BA4 reference"
|
|
8997
9227
|
},
|
|
8998
9228
|
project: {
|
|
8999
9229
|
type: "boolean",
|
|
9000
|
-
description: "
|
|
9230
|
+
description: "true=\u5199\u5165\u9879\u76EE .deepseeker-code/memory\uFF08\u53EF\u63D0\u4EA4 git \u5171\u4EAB\uFF09\uFF1B\u9ED8\u8BA4 false\uFF08\u5168\u5C40\uFF0C\u4EC5\u672C\u673A\uFF09"
|
|
9001
9231
|
}
|
|
9002
9232
|
},
|
|
9003
9233
|
required: ["name", "description", "body"]
|
|
@@ -9150,7 +9380,7 @@ var init_recall = __esm({
|
|
|
9150
9380
|
type: "function",
|
|
9151
9381
|
function: {
|
|
9152
9382
|
name: "recall",
|
|
9153
|
-
description: "\u68C0\u7D22\u3010\u672C\u4F1A\u8BDD\u3011\u5168\u91CF\u5386\u53F2\
|
|
9383
|
+
description: "\u68C0\u7D22\u3010\u672C\u4F1A\u8BDD\u3011\u5168\u91CF\u5386\u53F2\uFF08\u542B\u5DF2\u88AB\u538B\u7F29\u5F52\u6863\u7684\u539F\u59CB\u6D88\u606F\u4E0E\u5DE5\u5177\u7ED3\u679C\uFF09\u3002\u65F6\u673A\uFF1A\u6EDA\u52A8\u6458\u8981\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u7EC6\u8282\u65F6\uFF08\u5F52\u6863\u524D\u7684\u6587\u4EF6\u5185\u5BB9/\u62A5\u9519\u539F\u6587/\u7528\u6237\u65E9\u524D\u8981\u6C42\uFF09\u2014\u2014\u5148\u68C0\u7D22\uFF0C\u4E0D\u8981\u51ED\u6458\u8981\u81C6\u6D4B\uFF0C\u4E5F\u4E0D\u8981\u91CD\u8DD1\u5DE5\u5177\u3002query \u7528\u5177\u4F53\u5B9E\u4F53\u8BCD\uFF1A\u62A5\u9519\u5173\u952E\u8BCD\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u51FD\u6570/\u7B26\u53F7\u540D\uFF08\u4F18\u5148\u53D6\u6458\u8981\u5B9E\u4F53\u7D22\u5F15 \u27E6DSC:ARCHIVE-INDEX\u27E7 \u91CC\u51FA\u73B0\u8FC7\u7684\uFF09\uFF1B\u5FCC\u7528\u5DE5\u5177\u540D\u6216\u6CDB\u8BCD\uFF08\u4EE3\u7801/\u6587\u4EF6/\u95EE\u9898\uFF09\u3002\u672A\u547D\u4E2D\u5C31\u6362\u66F4\u5177\u4F53\u7684\u8BCD\uFF0C\u6216 is_regex=true \u7528 | \u5408\u5E76\u591A\u5019\u9009\u8BCD\uFF0C\u901A\u5E38 1-2 \u6B21\u5185\u547D\u4E2D\u3002\u8FD4\u56DE\u6309\u65F6\u95F4\u65E7\u2192\u65B0\uFF1B\u6587\u4EF6\u7C7B\u7ED3\u679C\u9644\u5B9E\u65F6\u6821\u9A8C\uFF1A\u26A0\uFE0F \u5DF2\u4FEE\u6539/\u5DF2\u4E0D\u5B58\u5728\u5FC5\u987B\u91CD\u65B0 read_file \u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539\uFF0C\u2713 \u672A\u53D8\u53EF\u76F4\u63A5\u5F15\u7528\u3002\u66FE\u88AB\u622A\u65AD\u7684\u7ED3\u679C\u4F1A\u6807\u6CE8 with_full \u53D6\u5B58\u6863\u5168\u6587\u3002\u6458\u8981\u5DF2\u591F\u65F6\u52FF\u8C03\u7528\uFF08\u7701 token\uFF09\u3002",
|
|
9154
9384
|
parameters: {
|
|
9155
9385
|
type: "object",
|
|
9156
9386
|
properties: {
|
|
@@ -9630,7 +9860,8 @@ async function runBackgroundTool(gen, lockKey, toolName, signal) {
|
|
|
9630
9860
|
if (lockKey && !acquireLock(lockKey)) {
|
|
9631
9861
|
try {
|
|
9632
9862
|
await gen.return(void 0);
|
|
9633
|
-
} catch {
|
|
9863
|
+
} catch (e) {
|
|
9864
|
+
console.warn("\u26A0\uFE0F \u5173\u95ED\u672A\u6D88\u8D39\u7684\u540E\u53F0 generator \u5931\u8D25:", e instanceof Error ? e.message : e);
|
|
9634
9865
|
}
|
|
9635
9866
|
return `\u{1F512} [\u4E92\u65A5\u9501\u963B\u585E]\uFF1A\u9501 [${lockKey}] \u5DF2\u88AB\u5360\u7528\uFF0C[${toolName}] \u672A\u542F\u52A8\u3002`;
|
|
9636
9867
|
}
|
|
@@ -9681,7 +9912,7 @@ var init_backgroundTool = __esm({
|
|
|
9681
9912
|
|
|
9682
9913
|
// ../core/src/tool/autoPermission.ts
|
|
9683
9914
|
import path30 from "path";
|
|
9684
|
-
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9915
|
+
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, PKG_MGR, SCRIPT_RUNNER_HEADS, SCRIPT_RUNNER_READONLY, isScriptRunnerCommand, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9685
9916
|
var init_autoPermission = __esm({
|
|
9686
9917
|
"../core/src/tool/autoPermission.ts"() {
|
|
9687
9918
|
"use strict";
|
|
@@ -9788,12 +10019,25 @@ var init_autoPermission = __esm({
|
|
|
9788
10019
|
// —— 版本号 ——
|
|
9789
10020
|
/^(node|npm|pnpm|npx|git|tsc|python|python3)\s+(-v|-V|--version)\b/,
|
|
9790
10021
|
// —— 验证类(跑项目代码但不改源码)——
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
10022
|
+
// ★ npm/pnpm/npx/yarn 系「跑脚本」命令已整类移出免审清单(isScriptRunnerCommand 单独治理,见下方):
|
|
10023
|
+
// package.json scripts 是仓库作者的任意代码、npx 未装包时还会从 registry 拉取执行——
|
|
10024
|
+
// hasShellMetachars 检查的是命令串本身,拦不到脚本内容(恶意 repo 投毒面)。
|
|
10025
|
+
// 改走「首次人工确认 + allow-always 按精确命令串记住」路径(toolExecution 的 scriptRunnerBlocked 门)。
|
|
9795
10026
|
/^tsc --noEmit\b/
|
|
9796
10027
|
];
|
|
10028
|
+
PKG_MGR = String.raw`\s*([^\s"'\`]*[\\/])?(npx|npm|pnpm|yarn|corepack)(\.cmd|\.exe|\.ps1|\.bat)?\b`;
|
|
10029
|
+
SCRIPT_RUNNER_HEADS = [
|
|
10030
|
+
new RegExp(`^${PKG_MGR}`, "i")
|
|
10031
|
+
];
|
|
10032
|
+
SCRIPT_RUNNER_READONLY = [
|
|
10033
|
+
new RegExp(`^${PKG_MGR}\\s+(-v|-V|--version)\\b`, "i")
|
|
10034
|
+
];
|
|
10035
|
+
isScriptRunnerCommand = (cmd) => {
|
|
10036
|
+
const c = (cmd || "").trim();
|
|
10037
|
+
if (!c || hasShellMetachars(c)) return false;
|
|
10038
|
+
if (SCRIPT_RUNNER_READONLY.some((re) => re.test(c))) return false;
|
|
10039
|
+
return SCRIPT_RUNNER_HEADS.some((re) => re.test(c));
|
|
10040
|
+
};
|
|
9797
10041
|
hasWriteModifier = (cmd) => {
|
|
9798
10042
|
if (!cmd) return false;
|
|
9799
10043
|
if (/^sed\b/.test(cmd) && /(^|\s)-i\b/.test(cmd)) return true;
|
|
@@ -9950,7 +10194,7 @@ var init_toolExecution = __esm({
|
|
|
9950
10194
|
preHooksAdvanced = true;
|
|
9951
10195
|
let veto;
|
|
9952
10196
|
try {
|
|
9953
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10197
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
9954
10198
|
} catch (e) {
|
|
9955
10199
|
veto = { deny: true, reason: `\u274C [Pre-hook \u5F02\u5E38]\uFF1A${e?.message ?? e}\u3002\u51FA\u4E8E\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD [${calledName}] \u7684\u6267\u884C\u3002` };
|
|
9956
10200
|
}
|
|
@@ -9982,7 +10226,20 @@ var init_toolExecution = __esm({
|
|
|
9982
10226
|
} catch {
|
|
9983
10227
|
perm = null;
|
|
9984
10228
|
}
|
|
9985
|
-
|
|
10229
|
+
const cmdIsScriptRunner = (calledName === "run_command" || calledName === "run_in_background") && isScriptRunnerCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "");
|
|
10230
|
+
const argCwd = typeof calledArgs?.cwd === "string" ? calledArgs.cwd.trim() : "";
|
|
10231
|
+
const samePath = (a, b) => {
|
|
10232
|
+
try {
|
|
10233
|
+
const ra = path31.resolve(a), rb = path31.resolve(b);
|
|
10234
|
+
return process.platform === "win32" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;
|
|
10235
|
+
} catch {
|
|
10236
|
+
return false;
|
|
10237
|
+
}
|
|
10238
|
+
};
|
|
10239
|
+
const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd);
|
|
10240
|
+
const scriptRunnerBlocked = cmdIsScriptRunner && (perm === null || scriptRunnerCwdDrift);
|
|
10241
|
+
if (scriptRunnerCwdDrift) needApproval = true;
|
|
10242
|
+
if (perm === null && needApproval && !denied && !scriptRunnerBlocked && calledName === "run_command" && isReadOnlyCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
9986
10243
|
needApproval = false;
|
|
9987
10244
|
}
|
|
9988
10245
|
if ((calledName === "run_command" || calledName === "run_in_background") && matchCommandDeny(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
@@ -9995,7 +10252,7 @@ var init_toolExecution = __esm({
|
|
|
9995
10252
|
denied = true;
|
|
9996
10253
|
result = `\u{1F512} [\u4E92\u65A5\u9501\u963B\u585E]\uFF1A\u5DF2\u6709\u540E\u53F0\u4EFB\u52A1\u6301\u6709\u9501 [${lockKey}]\uFF0C[${calledName}] \u8C03\u7528\u88AB\u8DF3\u8FC7\u3002`;
|
|
9997
10254
|
}
|
|
9998
|
-
if (needApproval && !denied) {
|
|
10255
|
+
if (needApproval && !denied && !scriptRunnerBlocked) {
|
|
9999
10256
|
const auto = await runAutoCheck(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx, permissionMode === "auto");
|
|
10000
10257
|
if (auto === "allow") {
|
|
10001
10258
|
needApproval = false;
|
|
@@ -10030,7 +10287,7 @@ var init_toolExecution = __esm({
|
|
|
10030
10287
|
if (!denied && !preHooksAdvanced) {
|
|
10031
10288
|
let veto;
|
|
10032
10289
|
try {
|
|
10033
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10290
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
10034
10291
|
} catch (e) {
|
|
10035
10292
|
veto = { deny: true, reason: `\u274C [Pre-hook \u5F02\u5E38]\uFF1A${e?.message ?? e}\u3002\u51FA\u4E8E\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD [${calledName}] \u7684\u6267\u884C\u3002` };
|
|
10036
10293
|
}
|
|
@@ -10072,7 +10329,7 @@ ${result}`;
|
|
|
10072
10329
|
events({ sessionId, eventType: "tool.failed", metadata: { depth, decisionSource: llmDecisionSource, durationMs: performance.now() - startTime, round, tools_id: toolCall.id, toolName: calledName, toolSource: "builtin", ok: false, attempt: round }, payload: { output: result } });
|
|
10073
10330
|
}
|
|
10074
10331
|
try {
|
|
10075
|
-
const post = await runPostHooks(calledName, calledArgs, result, toolCtx);
|
|
10332
|
+
const post = await runPostHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, result, toolCtx);
|
|
10076
10333
|
postHookOverride = post?.resultOverride;
|
|
10077
10334
|
} catch (e) {
|
|
10078
10335
|
console.warn(`\u26A0\uFE0F post-hook [${calledName}] \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09:`, e?.message ?? e);
|
|
@@ -10232,7 +10489,8 @@ var init_toolScheduling = __esm({
|
|
|
10232
10489
|
});
|
|
10233
10490
|
|
|
10234
10491
|
// ../core/src/agent/streamInference.ts
|
|
10235
|
-
|
|
10492
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
10493
|
+
var sha1short, RETRY_BACKOFF_CAP_MS, extractRetryAfterMs, withNudgeTail, streamInference;
|
|
10236
10494
|
var init_streamInference = __esm({
|
|
10237
10495
|
"../core/src/agent/streamInference.ts"() {
|
|
10238
10496
|
"use strict";
|
|
@@ -10241,6 +10499,32 @@ var init_streamInference = __esm({
|
|
|
10241
10499
|
init_transcript();
|
|
10242
10500
|
init_contextCore();
|
|
10243
10501
|
init_contentParts();
|
|
10502
|
+
sha1short = (s) => createHash2("sha1").update(s).digest("hex").slice(0, 10);
|
|
10503
|
+
RETRY_BACKOFF_CAP_MS = 3e4;
|
|
10504
|
+
extractRetryAfterMs = (e) => {
|
|
10505
|
+
try {
|
|
10506
|
+
const h = e?.headers;
|
|
10507
|
+
if (!h) return null;
|
|
10508
|
+
const get = (k) => typeof h.get === "function" ? h.get(k) ?? void 0 : h[k] ?? h[k.toLowerCase()];
|
|
10509
|
+
const ms = get("retry-after-ms");
|
|
10510
|
+
if (ms != null) {
|
|
10511
|
+
const n = Number(ms);
|
|
10512
|
+
if (Number.isFinite(n) && n >= 0) return n;
|
|
10513
|
+
}
|
|
10514
|
+
const sec = get("retry-after");
|
|
10515
|
+
if (sec != null) {
|
|
10516
|
+
const n = Number(sec);
|
|
10517
|
+
if (Number.isFinite(n) && n >= 0) return n * 1e3;
|
|
10518
|
+
}
|
|
10519
|
+
} catch {
|
|
10520
|
+
}
|
|
10521
|
+
return null;
|
|
10522
|
+
};
|
|
10523
|
+
withNudgeTail = (base, nudge) => {
|
|
10524
|
+
if (!nudge) return base;
|
|
10525
|
+
const lastRole = base[base.length - 1]?.role;
|
|
10526
|
+
return [...base, lastRole === "assistant" ? { ...nudge, role: "user" } : nudge];
|
|
10527
|
+
};
|
|
10244
10528
|
streamInference = async function* (ctx) {
|
|
10245
10529
|
const {
|
|
10246
10530
|
message,
|
|
@@ -10258,16 +10542,24 @@ var init_streamInference = __esm({
|
|
|
10258
10542
|
events,
|
|
10259
10543
|
keepRecentUnits,
|
|
10260
10544
|
compactRatio,
|
|
10261
|
-
modelWindow
|
|
10545
|
+
modelWindow,
|
|
10546
|
+
toolsTokens = 0
|
|
10262
10547
|
} = ctx;
|
|
10263
|
-
let inferenceMessages =
|
|
10548
|
+
let inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10264
10549
|
let assistantMessage = { role: "assistant", content: null };
|
|
10265
10550
|
try {
|
|
10551
|
+
const prefixFingerprint = {
|
|
10552
|
+
toolsHash: sha1short(JSON.stringify(cleanedToolSchemas)),
|
|
10553
|
+
sysHash: sha1short(String(message[0]?.content ?? "")),
|
|
10554
|
+
sumHash: sha1short(String(message[1]?.content ?? "")),
|
|
10555
|
+
msgCount: message.length
|
|
10556
|
+
};
|
|
10266
10557
|
events({
|
|
10267
10558
|
sessionId,
|
|
10268
10559
|
eventType: "llm.request",
|
|
10269
|
-
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
10270
|
-
|
|
10560
|
+
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, ...prefixFingerprint },
|
|
10561
|
+
// ★ P2 口径:估算加上工具 schema 常数项(与 API 真实 prompt_tokens 同口径,trace 里 est/real 才可比)
|
|
10562
|
+
usage: { prompt_tokens: estimateTokens(inferenceMessages) + toolsTokens },
|
|
10271
10563
|
payload: { input: msgText(message[message.length - 1].content) }
|
|
10272
10564
|
// ★ 多模态:trace 只记文本视图
|
|
10273
10565
|
});
|
|
@@ -10277,7 +10569,7 @@ var init_streamInference = __esm({
|
|
|
10277
10569
|
const toolCallsBuf = /* @__PURE__ */ new Map();
|
|
10278
10570
|
let lastUsage;
|
|
10279
10571
|
const MAX_STREAM_RETRIES = 2;
|
|
10280
|
-
const MAX_API_RETRIES =
|
|
10572
|
+
const MAX_API_RETRIES = 3;
|
|
10281
10573
|
let apiRetries = 0;
|
|
10282
10574
|
let compactedThisRound = false;
|
|
10283
10575
|
for (let streamAttempt = 0; ; streamAttempt++) {
|
|
@@ -10337,10 +10629,15 @@ var init_streamInference = __esm({
|
|
|
10337
10629
|
}
|
|
10338
10630
|
if (activeProvider.isTransientError(streamErr) && apiRetries < MAX_API_RETRIES && !signal?.aborted) {
|
|
10339
10631
|
apiRetries++;
|
|
10340
|
-
const
|
|
10632
|
+
const retryAfterMs = extractRetryAfterMs(streamErr);
|
|
10633
|
+
const backoffMs = Math.min(
|
|
10634
|
+
Math.max(1e3 * Math.pow(2, apiRetries - 1), retryAfterMs ?? 0),
|
|
10635
|
+
RETRY_BACKOFF_CAP_MS
|
|
10636
|
+
);
|
|
10341
10637
|
if (!noOutputYet) yield { type: "text.reset" };
|
|
10342
10638
|
const statusHint = streamErr?.status ? `${streamErr.status} ` : "";
|
|
10343
|
-
|
|
10639
|
+
const raHint = retryAfterMs != null ? `\uFF0C\u9075 Retry-After=${retryAfterMs}ms` : "";
|
|
10640
|
+
console.warn(`\u26A0\uFE0F API \u77AC\u65F6\u9519\u8BEF\uFF08${statusHint}${streamErr instanceof Error ? streamErr.message : String(streamErr)}\uFF09\uFF0C${backoffMs}ms \u540E\u7B2C ${apiRetries}/${MAX_API_RETRIES} \u6B21\u91CD\u8BD5${raHint}...`);
|
|
10344
10641
|
await new Promise((resolve, reject) => {
|
|
10345
10642
|
const t = setTimeout(resolve, backoffMs);
|
|
10346
10643
|
signal?.addEventListener("abort", () => {
|
|
@@ -10364,9 +10661,10 @@ var init_streamInference = __esm({
|
|
|
10364
10661
|
modelWindow,
|
|
10365
10662
|
events,
|
|
10366
10663
|
depth,
|
|
10367
|
-
signal
|
|
10664
|
+
signal,
|
|
10665
|
+
toolsTokens
|
|
10368
10666
|
});
|
|
10369
|
-
inferenceMessages =
|
|
10667
|
+
inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10370
10668
|
compactedThisRound = true;
|
|
10371
10669
|
contentBuf = "";
|
|
10372
10670
|
reasoningBuf = "";
|
|
@@ -10447,12 +10745,12 @@ var init_agentNudges = __esm({
|
|
|
10447
10745
|
GREP_REPEAT_THRESHOLD = 2;
|
|
10448
10746
|
REPEAT_NUDGE_MAX = 3;
|
|
10449
10747
|
PHANTOM_TEXT = "\u4F60\u7684\u4E0A\u4E00\u6761\u56DE\u590D\u6CA1\u6709\u4EFB\u4F55\u5185\u5BB9\u3001\u4E5F\u6CA1\u6709\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\uFF0C\u4F46\u4EFB\u52A1\u5C1A\u672A\u5B8C\u6210\u3002\u8BF7\u7EE7\u7EED\u63A8\u8FDB\uFF08\u8C03\u7528\u5DE5\u5177\u6216\u7ED9\u51FA\u5B9E\u8D28\u56DE\u7B54\uFF09\uFF1B\u82E5\u786E\u5B9E\u53D7\u963B\u3001\u9700\u8981\u7528\u6237\u51B3\u7B56\uFF0C\u7528 ask_question \u8BF4\u660E\u5177\u4F53\u963B\u585E\u70B9\u3002\u4E0D\u8981\u8FD4\u56DE\u7A7A\u56DE\u590D\u3002";
|
|
10450
|
-
EARLY_FINAL_TEXT = (round) => `\u4F60\u4EC5
|
|
10748
|
+
EARLY_FINAL_TEXT = (round) => `\u4F60\u4EC5 ${round} \u8F6E\u5C31\u51C6\u5907\u6536\u5C3E\uFF0C\u4E14\u56DE\u7B54\u4E2D\u6CA1\u6709\u660E\u786E\u7684\u5B8C\u6210\u58F0\u660E\u3002\u8BF7\u81EA\u68C0\uFF1A\u82E5\u7528\u6237\u8F93\u5165\u672C\u5C31\u65E0\u9700\u5DE5\u5177\uFF08\u5BD2\u6684/\u95F2\u804A/\u7EAF\u95EE\u7B54\uFF09\u3001\u6216\u4F60\u5728\u7B49\u7528\u6237\u6F84\u6E05\u51B3\u7B56\uFF0C\u76F4\u63A5\u6B63\u5E38\u56DE\u5E94\u5373\u53EF\uFF0C\u5FFD\u7565\u672C\u81EA\u68C0\u3001\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u81EA\u68C0\u8BF4\u660E\uFF1B\u82E5\u786E\u6709\u4EFB\u52A1\u672A\u843D\u5730\uFF08\u6240\u9700\u4FE1\u606F\u672A\u83B7\u53D6\u9F50 / \u8BE5\u6539\u7684\u6587\u4EF6\u672A\u6539\u5B8C / \u672A\u9A8C\u8BC1\uFF09\uFF0C\u7ACB\u5373\u7EE7\u7EED\u8C03\u7528\u5DE5\u5177\u63A8\u8FDB\uFF0C\u4E0D\u8981\u8349\u7387\u603B\u7ED3\u6536\u5C3E\uFF1B\u82E5\u786E\u5DF2\u5168\u90E8\u5B8C\u6210\uFF0C\u8BF7\u660E\u786E\u56DE\u590D\u300C\u5DF2\u5B8C\u6210\u300D\u5E76\u7B80\u8FF0\u6210\u679C\u3002`;
|
|
10451
10749
|
TOOL_DIGEST_TEXT = "\u4F60\u521A\u6267\u884C\u5B8C\u5DE5\u5177\u62FF\u5230\u7ED3\u679C\uFF0C\u5374\u672A\u57FA\u4E8E\u8BE5\u7ED3\u679C\u7ED9\u51FA\u5B9E\u8D28\u56DE\u5E94\u5C31\u51C6\u5907\u6536\u5C3E\u3002\u8BF7\u7ED3\u5408\u5DE5\u5177\u8FD4\u56DE\u7ED3\u679C\u7EE7\u7EED\u63A8\u8FDB\uFF1B\u82E5\u7ED3\u679C\u8868\u660E\u4EFB\u52A1\u5C1A\u672A\u5B8C\u6210\uFF08\u5982\u4ECD\u5728\u7F16\u8BD1/\u8FD0\u884C\u3001\u9700\u7EE7\u7EED\u8F6E\u8BE2\uFF09\uFF0C\u7ACB\u5373\u91C7\u53D6\u4E0B\u4E00\u6B65\u884C\u52A8\uFF0C\u4E0D\u8981\u7A7A\u624B\u6536\u5C3E\u3002\u82E5\u786E\u5DF2\u5168\u90E8\u5B8C\u6210\uFF0C\u8BF7\u660E\u786E\u56DE\u590D\u300C\u5DF2\u5B8C\u6210\u300D\u5E76\u7B80\u8FF0\u6210\u679C\u3002";
|
|
10452
10750
|
NUDGE_TEXT = (round) => `\u4F60\u5DF2\u6267\u884C\u7EA6 ${round} \u8F6E\u5DE5\u5177\u8C03\u7528\u3002\u8BF7\u81EA\u8BC4\uFF1A\u82E5\u4EFB\u52A1\u5DF2\u53EF\u5B8C\u6210\uFF0C\u7ACB\u5373\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\u3001\u4E0D\u518D\u8C03\u7528\u5DE5\u5177\uFF1B\u82E5\u786E\u9700\u66F4\u591A\u6B65\u9AA4\uFF0C\u7EE7\u7EED\uFF0C\u4F46\u786E\u4FDD\u6BCF\u6B65\u90FD\u5728\u5B9E\u8D28\u63A8\u8FDB\u4EFB\u52A1\u3001\u4E0D\u91CD\u590D\u68C0\u7D22\u3002`;
|
|
10453
|
-
COMPLEX_VERBS =
|
|
10454
|
-
COMPLEX_OBJECTS =
|
|
10455
|
-
COMPLEX_MARKERS = /多个文件|多文件|整体|全套|端到端|从零|重新设计|一整套|跨[^,。\s]{1,6}
|
|
10751
|
+
COMPLEX_VERBS = /实现|新增|添加|重构|改造|迁移|重写|拆分|升级|开发|编写|构建|集成|支持|完善|implement|refactor|migrate|rewrite|rebuild|restructure|split|upgrade|integrate|develop/i;
|
|
10752
|
+
COMPLEX_OBJECTS = /功能|模块|系统|架构|流程|机制|组件|服务|页面|接口|能力|特性|面板|feature|module|system|architecture|pipeline|component|service|page|api\b|interface|panel|workflow|endpoint/i;
|
|
10753
|
+
COMPLEX_MARKERS = /多个文件|多文件|整体|全套|端到端|从零|重新设计|一整套|跨[^,。\s]{1,6}|multiple files|multi-file|end-to-end|from scratch|across\s+\S+/i;
|
|
10456
10754
|
QUERY_LEAD = /^(请)?\s*(解释|说明|查(一下|询)?|搜索|搜一下|怎么看|如何(用|使用|配置|启动)|怎么用|为什么|是什么|帮我看看|分析一下|检查|review|对比|评价)/i;
|
|
10457
10755
|
looksComplex = (text) => {
|
|
10458
10756
|
const t = (text || "").trim();
|
|
@@ -10480,7 +10778,7 @@ var init_agentNudges = __esm({
|
|
|
10480
10778
|
return s;
|
|
10481
10779
|
};
|
|
10482
10780
|
normQuery = (q) => String(q ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
10483
|
-
REPEAT_READ_TEXT = (p, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u8BFB\u53D6\u300C${p}\u300D\u2014\u2014\u8BE5\u6587\u4EF6\u5185\u5BB9\u4F60\u65E9\u5DF2\u62E5\u6709\uFF0C\u65E0\u9700\u6574\u6587\u4EF6\u91CD\u8BFB\u3002\u5982\u9700\u67D0\u5904\u7EC6\u8282\u8BF7\u56DE\u770B\u4E4B\u524D\u7684\u5DE5\u5177\u7ED3\u679C\uFF1B\u82E5\u8BE5\u6587\u4EF6\u521A\u88AB\u6539\u52A8\u3001\u786E\u9700\u786E\u8BA4\uFF0C\u53EA\u8BFB\u6539\u52A8\u9644\u8FD1\u51E0\u884C\u5373\u53EF\uFF0C\u4E0D\u8981\u6574\u6587\u4EF6\u91CD\u8BFB\u3002`;
|
|
10781
|
+
REPEAT_READ_TEXT = (p, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u8BFB\u53D6\u300C${p}\u300D\u2014\u2014\u8BE5\u6587\u4EF6\u5185\u5BB9\u4F60\u65E9\u5DF2\u62E5\u6709\uFF0C\u65E0\u9700\u6574\u6587\u4EF6\u91CD\u8BFB\u3002\u5982\u9700\u67D0\u5904\u7EC6\u8282\u8BF7\u56DE\u770B\u4E4B\u524D\u7684\u5DE5\u5177\u7ED3\u679C\uFF08\u65E9\u524D\u8BFB\u53D6\u53EF\u80FD\u5DF2\u88AB\u5F52\u6863\uFF0C\u53EF\u7528 recall \u5DE5\u5177\u68C0\u7D22\u53D6\u56DE\u539F\u6587\uFF09\uFF1B\u82E5\u8BE5\u6587\u4EF6\u521A\u88AB\u6539\u52A8\u3001\u786E\u9700\u786E\u8BA4\uFF0C\u53EA\u8BFB\u6539\u52A8\u9644\u8FD1\u51E0\u884C\u5373\u53EF\uFF0C\u4E0D\u8981\u6574\u6587\u4EF6\u91CD\u8BFB\u3002`;
|
|
10484
10782
|
REPEAT_GREP_TEXT = (q, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u68C0\u7D22\u300C${q}\u300D\u2014\u2014\u4E4B\u524D\u7684\u7ED3\u679C\u4F60\u5DF2\u62E5\u6709\u3002\u8BF7\u6539\u7528 read_file \u8BFB\u5B8C\u6574\u76EE\u6807\u6587\u4EF6\u7406\u89E3\u4E0A\u4E0B\u6587\uFF0C\u6216\u7F29\u5C0F/\u8C03\u6574\u68C0\u7D22\u8303\u56F4\uFF0C\u4E0D\u8981\u91CD\u590D\u540C\u4E00\u68C0\u7D22\u3002`;
|
|
10485
10783
|
createNudgeScheduler = (opts = {}) => {
|
|
10486
10784
|
const firstPrompt = opts.firstPrompt ?? "";
|
|
@@ -10548,7 +10846,7 @@ ${TOOL_DIGEST_TEXT}` };
|
|
|
10548
10846
|
${PHANTOM_TEXT}` };
|
|
10549
10847
|
return true;
|
|
10550
10848
|
}
|
|
10551
|
-
if (!noEarlyFinal && text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
10849
|
+
if (!noEarlyFinal && (lastToolCallRound > 0 || looksComplex(firstPrompt)) && text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
10552
10850
|
earlyFinalNudges++;
|
|
10553
10851
|
earlyFinalPending = { role: "system", content: `${EARLY_FINAL_FENCE}
|
|
10554
10852
|
${EARLY_FINAL_TEXT(round)}` };
|
|
@@ -10608,10 +10906,11 @@ ${REPEAT_GREP_TEXT(q, n)}` };
|
|
|
10608
10906
|
// ../core/src/agent/runAgent.ts
|
|
10609
10907
|
async function* runAgent(message, options) {
|
|
10610
10908
|
const sessionId = options.sessionId;
|
|
10909
|
+
const runId = createUUID();
|
|
10611
10910
|
const rawEvents = options.events;
|
|
10612
10911
|
const events = async (base) => {
|
|
10613
10912
|
try {
|
|
10614
|
-
await rawEvents(base);
|
|
10913
|
+
await rawEvents({ ...base, metadata: { ...base.metadata, runId } });
|
|
10615
10914
|
} catch (e) {
|
|
10616
10915
|
console.warn("\u26A0\uFE0F \u57CB\u70B9\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u63A8\u7406\uFF09:", e instanceof Error ? e.message : e);
|
|
10617
10916
|
}
|
|
@@ -10623,7 +10922,7 @@ async function* runAgent(message, options) {
|
|
|
10623
10922
|
const keepRecentUnits = options.keepRecentUnits;
|
|
10624
10923
|
const compactRatio = options.compactRatio;
|
|
10625
10924
|
const parentSystemPrompt = options.parentSystemPrompt;
|
|
10626
|
-
const { rawTools, cleanedToolSchemas } = await prepareToolsAndInjections(message, options, events);
|
|
10925
|
+
const { rawTools, cleanedToolSchemas, toolsTokens } = await prepareToolsAndInjections(message, options, events);
|
|
10627
10926
|
let round = 0;
|
|
10628
10927
|
let lastContent = "";
|
|
10629
10928
|
let stopReason = "normal";
|
|
@@ -10642,7 +10941,6 @@ async function* runAgent(message, options) {
|
|
|
10642
10941
|
let lastRealPromptTokens = persistedCalib.lastRealPromptTokens;
|
|
10643
10942
|
let lastCachedTokens = persistedCalib.lastCachedTokens;
|
|
10644
10943
|
const breaker = createRepeatBreaker({ sessionId, depth, llmDecisionSource, startTime, events });
|
|
10645
|
-
const runId = createUUID();
|
|
10646
10944
|
let usageSum;
|
|
10647
10945
|
const addUsage = (u) => {
|
|
10648
10946
|
if (!u) return;
|
|
@@ -10703,7 +11001,8 @@ async function* runAgent(message, options) {
|
|
|
10703
11001
|
signal,
|
|
10704
11002
|
correctionRatio: calibRatio,
|
|
10705
11003
|
lastRealPromptTokens,
|
|
10706
|
-
lastCachedTokens
|
|
11004
|
+
lastCachedTokens,
|
|
11005
|
+
toolsTokens
|
|
10707
11006
|
}
|
|
10708
11007
|
);
|
|
10709
11008
|
} catch (e) {
|
|
@@ -10735,7 +11034,8 @@ async function* runAgent(message, options) {
|
|
|
10735
11034
|
events,
|
|
10736
11035
|
keepRecentUnits,
|
|
10737
11036
|
compactRatio,
|
|
10738
|
-
modelWindow
|
|
11037
|
+
modelWindow,
|
|
11038
|
+
toolsTokens
|
|
10739
11039
|
});
|
|
10740
11040
|
if (infResult.kind === "aborted") {
|
|
10741
11041
|
yield { type: "final", text: infResult.partialText || lastContent || "\uFF08\u5DF2\u4E2D\u6B62\uFF09" };
|
|
@@ -10747,7 +11047,7 @@ async function* runAgent(message, options) {
|
|
|
10747
11047
|
return;
|
|
10748
11048
|
}
|
|
10749
11049
|
if (infResult.usage?.prompt_tokens) {
|
|
10750
|
-
const estAtInfer = estimateTokens(message);
|
|
11050
|
+
const estAtInfer = estimateTokens(message) + toolsTokens;
|
|
10751
11051
|
if (estAtInfer > 1e3) {
|
|
10752
11052
|
const observed = infResult.usage.prompt_tokens / estAtInfer;
|
|
10753
11053
|
calibRatio = calibRatio * 0.6 + observed * 0.4;
|
|
@@ -10837,11 +11137,13 @@ async function* runAgent(message, options) {
|
|
|
10837
11137
|
try {
|
|
10838
11138
|
const reason = signal?.aborted ? "aborted" : stopReason;
|
|
10839
11139
|
await dispatch("Stop", { sessionId, cwd, lastText: lastContent || "", reason });
|
|
10840
|
-
} catch {
|
|
11140
|
+
} catch (e) {
|
|
11141
|
+
console.warn("\u26A0\uFE0F Stop hook \u5916\u5C42\u515C\u5E95\uFF08dispatch \u5185\u90E8\u5BB9\u9519\u5931\u6548\uFF0C\u5C5E\u5F02\u5E38\u4FE1\u53F7\uFF09:", e instanceof Error ? e.message : e);
|
|
10841
11142
|
}
|
|
10842
11143
|
try {
|
|
10843
11144
|
await updateCalibration(sessionId, { calibRatio, lastRealPromptTokens, lastCachedTokens });
|
|
10844
|
-
} catch {
|
|
11145
|
+
} catch (e) {
|
|
11146
|
+
console.warn("\u26A0\uFE0F \u538B\u7F29\u6821\u51C6\u72B6\u6001\u843D\u76D8\u5931\u8D25\uFF08\u4E0B run \u6821\u51C6\u91CD\u96F6\uFF0C\u7F13\u5B58\u611F\u77E5\u538B\u7F29\u9000\u5316\u56DE\u7F3A\u7701 1.4\uFF09:", e instanceof Error ? e.message : e);
|
|
10845
11147
|
}
|
|
10846
11148
|
}
|
|
10847
11149
|
}
|
|
@@ -10984,9 +11286,9 @@ var init_content = __esm({
|
|
|
10984
11286
|
return replaceImageParts(mm, "[\u5386\u53F2\u56FE\u7247\u5DF2\u6298\u53E0\uFF1A\u539F\u56FE\u4ECD\u5728\u4F1A\u8BDD\u5F52\u6863\u4E2D\uFF0C\u5982\u9700\u518D\u6B21\u67E5\u770B\u8BF7\u91CD\u65B0\u63D0\u4F9B\u8BE5\u56FE\u7247]");
|
|
10985
11287
|
});
|
|
10986
11288
|
};
|
|
10987
|
-
NO_VISION_IMAGE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\
|
|
10988
|
-
enforceVisionGate = (msgs) => isVisionEnabled() ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
10989
|
-
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt) => {
|
|
11289
|
+
NO_VISION_IMAGE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\u6A21\u578B\u65E0\u89C6\u89C9\u80FD\u529B\uFF0C\u770B\u4E0D\u5230\u8BE5\u56FE\uFF1B\u539F\u56FE\u4FDD\u7559\u5728\u4F1A\u8BDD\u5F52\u6863\u4E2D\uFF0C\u5982\u9700\u5206\u6790\u8BF7\u8BA9\u7528\u6237\u91CD\u65B0\u63D0\u4F9B\u6216\u5207\u6362 vision \u6A21\u578B]";
|
|
11290
|
+
enforceVisionGate = (msgs, modelId) => isVisionEnabled(modelId) ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
11291
|
+
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt, modelId) => {
|
|
10990
11292
|
const lines = await readTranscriptLines(sessionId);
|
|
10991
11293
|
const store = await getRollingState(sessionId);
|
|
10992
11294
|
const eventAware = appConfig.transcriptEvents || lines.some(isEventLine);
|
|
@@ -11005,12 +11307,12 @@ var init_content = __esm({
|
|
|
11005
11307
|
const messageAll = all.slice(archivedMessageCount);
|
|
11006
11308
|
if (messageAll.length === 0) {
|
|
11007
11309
|
result.push(currentUserMsg);
|
|
11008
|
-
return enforceVisionGate(result);
|
|
11310
|
+
return enforceVisionGate(result, modelId);
|
|
11009
11311
|
}
|
|
11010
11312
|
const repair = repairOrphanToolCalls(messageAll, recovery.interruption.kind === "crashed");
|
|
11011
11313
|
result.push(...decayOldToolResults(repair.msgs));
|
|
11012
11314
|
result.push(currentUserMsg);
|
|
11013
|
-
return enforceVisionGate(result);
|
|
11315
|
+
return enforceVisionGate(result, modelId);
|
|
11014
11316
|
};
|
|
11015
11317
|
}
|
|
11016
11318
|
});
|
|
@@ -11171,7 +11473,7 @@ var init_subagent = __esm({
|
|
|
11171
11473
|
console.log(`${resuming ? "\u{1F501} \u7EED\u8DD1" : "\u{1F423} \u6D3E\u751F"}\u5B50 Agent [\u6DF1\u5EA6: ${ctx.depth + 1}/${MAX_AGENT_DEPTH}][${subSessionId}]${manifest ? ` \u58F0\u660E\u5F0F=${manifest.name}` : ""} \u4EFB\u52A1: "${task.slice(0, 50)}..."`);
|
|
11172
11474
|
activeSubagents.add(subSessionId);
|
|
11173
11475
|
try {
|
|
11174
|
-
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem);
|
|
11476
|
+
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem, manifest?.model);
|
|
11175
11477
|
await appendMessage({ sessionId: subSessionId, role: "user", content: task });
|
|
11176
11478
|
let subResult = "";
|
|
11177
11479
|
let hasFinalResult = false;
|
|
@@ -11348,7 +11650,7 @@ var init_loader4 = __esm({
|
|
|
11348
11650
|
console.warn(`\u26A0\uFE0F [hooks] ${where} \u975E\u5DE5\u5177\u4E8B\u4EF6\u4E0D\u652F\u6301 matcher\uFF0C\u5DF2\u5FFD\u7565`);
|
|
11349
11651
|
}
|
|
11350
11652
|
const matcher = TOOL_EVENTS.has(event) && typeof raw.matcher === "string" ? raw.matcher : void 0;
|
|
11351
|
-
const
|
|
11653
|
+
const timeoutMs2 = typeof raw.timeoutMs === "number" && raw.timeoutMs > 0 ? raw.timeoutMs : void 0;
|
|
11352
11654
|
let denyOnNonZero = typeof raw.denyOnNonZero === "boolean" ? raw.denyOnNonZero : void 0;
|
|
11353
11655
|
if (denyOnNonZero === true && !INTERCEPTABLE_EVENTS.has(event)) {
|
|
11354
11656
|
console.warn(`\u26A0\uFE0F [hooks] ${where} \u975E\u62E6\u622A\u4E8B\u4EF6\uFF0CdenyOnNonZero \u4E0D\u751F\u6548\uFF08\u4EC5 PreToolUse/UserPromptSubmit \u53EF\u62E6\u622A\uFF09\uFF0C\u5DF2\u5FFD\u7565`);
|
|
@@ -11376,7 +11678,7 @@ var init_loader4 = __esm({
|
|
|
11376
11678
|
text: type === "prompt" && typeof raw.text === "string" ? raw.text : void 0,
|
|
11377
11679
|
task: type === "agent" && typeof raw.task === "string" ? raw.task : void 0,
|
|
11378
11680
|
matcher,
|
|
11379
|
-
timeoutMs,
|
|
11681
|
+
timeoutMs: timeoutMs2,
|
|
11380
11682
|
denyOnNonZero,
|
|
11381
11683
|
onError,
|
|
11382
11684
|
requireApproval: raw.requireApproval === true ? true : void 0
|
|
@@ -11419,7 +11721,7 @@ var init_loader4 = __esm({
|
|
|
11419
11721
|
};
|
|
11420
11722
|
compileRule2 = (event, raw) => {
|
|
11421
11723
|
const denyOnNonZero = raw.denyOnNonZero ?? event === "PreToolUse";
|
|
11422
|
-
const
|
|
11724
|
+
const timeoutMs2 = raw.timeoutMs ?? DEFAULT_TIMEOUT_BY_EVENT[event];
|
|
11423
11725
|
const base = { event, matcher: raw.matcher, source: "config", onError: raw.onError };
|
|
11424
11726
|
if (raw.type === "prompt") {
|
|
11425
11727
|
const text = raw.text;
|
|
@@ -11464,7 +11766,7 @@ var init_loader4 = __esm({
|
|
|
11464
11766
|
headers: raw.headers,
|
|
11465
11767
|
body: ctx,
|
|
11466
11768
|
// 整个 hook 上下文 JSON 化发出(含 sessionId/toolName/args/prompt 等)
|
|
11467
|
-
timeoutMs
|
|
11769
|
+
timeoutMs: timeoutMs2
|
|
11468
11770
|
});
|
|
11469
11771
|
if (!res.ok) {
|
|
11470
11772
|
return denyOnNonZero ? { deny: true, reason: `hook http \u8BF7\u6C42\u5931\u8D25\uFF1A${res.error}` } : { deny: false };
|
|
@@ -11498,11 +11800,11 @@ var init_loader4 = __esm({
|
|
|
11498
11800
|
command,
|
|
11499
11801
|
cwd: ctx?.cwd,
|
|
11500
11802
|
env: ctx?.env,
|
|
11501
|
-
timeoutMs,
|
|
11803
|
+
timeoutMs: timeoutMs2,
|
|
11502
11804
|
stdinPayload: ctx
|
|
11503
11805
|
});
|
|
11504
11806
|
if (res.timedOut) {
|
|
11505
|
-
return denyOnNonZero ? { deny: true, reason: `hook \u6267\u884C\u8D85\u65F6\uFF08>${
|
|
11807
|
+
return denyOnNonZero ? { deny: true, reason: `hook \u6267\u884C\u8D85\u65F6\uFF08>${timeoutMs2}ms\uFF09` } : { deny: false };
|
|
11506
11808
|
}
|
|
11507
11809
|
if (denyOnNonZero && res.exitCode !== 0) {
|
|
11508
11810
|
const detail = res.stderr ? `\uFF1A${res.stderr.slice(0, 200)}` : "";
|
|
@@ -11524,9 +11826,7 @@ var init_loader4 = __esm({
|
|
|
11524
11826
|
if (!list || list.length === 0) continue;
|
|
11525
11827
|
for (const raw of list) compiled.push(compileRule2(event, raw));
|
|
11526
11828
|
}
|
|
11527
|
-
|
|
11528
|
-
registerHooks(compiled);
|
|
11529
|
-
}
|
|
11829
|
+
replaceDeclarativeHooks(compiled);
|
|
11530
11830
|
return compiled.length;
|
|
11531
11831
|
};
|
|
11532
11832
|
initHooks = async (includeProject) => {
|
|
@@ -12103,14 +12403,6 @@ var init_runner = __esm({
|
|
|
12103
12403
|
}
|
|
12104
12404
|
});
|
|
12105
12405
|
|
|
12106
|
-
// ../core/src/llm/createModel.ts
|
|
12107
|
-
var init_createModel = __esm({
|
|
12108
|
-
"../core/src/llm/createModel.ts"() {
|
|
12109
|
-
"use strict";
|
|
12110
|
-
init_client();
|
|
12111
|
-
}
|
|
12112
|
-
});
|
|
12113
|
-
|
|
12114
12406
|
// ../core/src/observability/store.ts
|
|
12115
12407
|
import path39 from "path";
|
|
12116
12408
|
import fs37 from "fs/promises";
|
|
@@ -12427,11 +12719,12 @@ var init_systemPrompt = __esm({
|
|
|
12427
12719
|
- \u88AB\u95EE"\u4F60\u662F\u8C01"\u65F6\u636E\u5B9E\u56DE\u7B54\uFF1A\u4F60\u662F ${p.displayName}\u3002\u5207\u52FF\u81EA\u79F0 ChatGPT\u3001GPT \u6216\u4EFB\u4F55\u5176\u4ED6\u516C\u53F8\u7684\u5927\u6A21\u578B/AI \u4EA7\u54C1\u3002
|
|
12428
12720
|
|
|
12429
12721
|
\u3010\u56DE\u7B54\u51C6\u5219 / \u5B8C\u6210\u5224\u5B9A\u3011
|
|
12430
|
-
- \u4EFB\u52A1\u5B8C\u6210\u540E\u76F4\u63A5\u7528\u81EA\u7136\u8BED\u8A00\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u5DE5\u5177\u3002
|
|
12431
|
-
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
- **\
|
|
12722
|
+
- \u4EFB\u52A1\u5B8C\u6210\u540E\u76F4\u63A5\u7528\u81EA\u7136\u8BED\u8A00\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u5DE5\u5177\u3002**\u5B8C\u6210\u5224\u636E = \u7528\u6237\u7684\u6BCF\u4E2A\u5B50\u76EE\u6807\u90FD\u6709\u843D\u5730\u4EA7\u7269**\uFF08\u6240\u9700\u4FE1\u606F\u5DF2\u5230\u624B / \u8BE5\u6539\u7684\u6587\u4EF6\u5DF2\u6539\u5B8C / \u5DF2\u9A8C\u8BC1\u901A\u8FC7\uFF09\uFF0C\u800C\u975E"\u8C03\u7528\u8FC7\u5DE5\u5177"\u3002\u6BCF\u8F6E\u5DE5\u5177\u8FD4\u56DE\u540E\u5BF9\u7167\u539F\u59CB\u8BF7\u6C42\u4E0E todo \u6E05\u5355\uFF08\u82E5\u6709\uFF09\u9010\u9879\u6838\u5BF9\uFF1A\u8FD8\u6709\u672A\u843D\u5730\u9879\u5C31\u7EE7\u7EED\u63A8\u8FDB\uFF0C\u4E0D\u8981\u62FF\u90E8\u5206\u68C0\u7D22/\u8BFB\u53D6\u7ED3\u679C\u603B\u7ED3\u6536\u5C3E\u3002\u590D\u6742\u4EFB\u52A1\u7528 todo_write \u62C6\u89E3\u5E76\u9010\u9879\u52FE\u9009\uFF0C\u6BCF\u8F6E\u5BF9\u7167\u6E05\u5355\u6838\u5BF9\u8FDB\u5EA6\u3002
|
|
12723
|
+
- \u5DE5\u5177**\u6267\u884C\u5931\u8D25\u6216\u88AB\u7528\u6237\u62D2\u7EDD**\u65F6\uFF0C\u8BFB\u8FD4\u56DE\u7ED3\u679C\u5B9A\u4F4D\u539F\u56E0\uFF0C\u4FEE\u6B63\u53C2\u6570\u6216\u6362\u7B49\u6548\u65B9\u6848\u7EE7\u7EED\uFF0C\u4E0D\u8981\u9053\u6B49\u4E00\u4E24\u53E5\u5C31\u505C\u4E0B\uFF1B\u786E\u5B9E\u53D7\u963B\u9700\u8981\u7528\u6237\u51B3\u7B56\u65F6\uFF0C\u7528 ask_question \u8BF4\u660E**\u5177\u4F53**\u963B\u585E\u70B9\u3002**\u4E25\u7981**\u5728\u672A\u771F\u6B63\u6267\u884C\u6216\u672A\u9A8C\u8BC1\u7684\u60C5\u51B5\u4E0B\u58F0\u79F0"\u5DF2\u5B8C\u6210/\u5DF2\u4FEE\u6539/\u5DF2\u4FEE\u590D"\u2014\u2014\u6539\u52A8\u82E5\u53EF\u9A8C\u8BC1\uFF08\u91CD\u8BFB\u786E\u8BA4\u3001\u8DD1\u6D4B\u8BD5\u3001\u7C7B\u578B\u68C0\u67E5\uFF09\uFF0C\u5148\u9A8C\u8BC1\u518D\u6536\u5C3E\u3002
|
|
12724
|
+
|
|
12725
|
+
\u3010\u56DE\u7B54\u5F62\u5F0F\u3011
|
|
12726
|
+
- **\u5148\u7ED3\u8BBA\u540E\u7EC6\u8282**\uFF1A\u5148\u76F4\u63A5\u56DE\u7B54\u6216\u6C47\u62A5\u7ED3\u679C\uFF0C\u518D\u5C55\u5F00\u5FC5\u8981\u7684\u89E3\u91CA\uFF1B\u6536\u5C3E\u603B\u7ED3\u7B80\u77ED\uFF08\u51E0\u884C\u4EE5\u5185\uFF09\uFF0C\u4E0D\u9010\u6587\u4EF6\u6D41\u6C34\u8D26\u3002
|
|
12727
|
+
- **\u4E0D\u56DE\u8D34\u5927\u6BB5\u4EE3\u7801**\uFF1A\u6539\u52A8\u5185\u5BB9\u7528\u6237\u5728\u7F16\u8F91\u5668/diff \u91CC\u770B\u5F97\u5230\uFF0C\u6B63\u6587\u53EA\u9700\u4E00\u53E5\u8BDD\u8BF4\u660E\u6539\u4E86\u4EC0\u4E48\u3001\u4E3A\u4EC0\u4E48\uFF0C\u6216\u5F15\u7528\u5173\u952E\u51E0\u884C\u3002
|
|
12435
12728
|
|
|
12436
12729
|
\u3010\u5DE5\u5177\u4F7F\u7528\u51C6\u5219\u3011
|
|
12437
12730
|
- \u4FEE\u6539\u6587\u4EF6**\u53EA\u80FD**\u7528 edit_file / create_file / write_file\u3002**\u4E25\u7981**\u7528 run_command \u901A\u8FC7 python/node/sed/awk/perl \u7B49\u811A\u672C\u8BFB\u5199\u6216\u4FEE\u6539\u6587\u4EF6\u2014\u2014\u811A\u672C\u8F6C\u4E49\u6781\u6613\u51FA\u9519\u3001\u6BCF\u6761\u547D\u4EE4\u90FD\u8981\u7528\u6237\u5BA1\u6279\u3001\u6548\u7387\u6781\u4F4E\uFF0C\u662F\u88AB\u660E\u786E\u7981\u6B62\u7684\u9000\u8DEF\u3002
|
|
@@ -12532,18 +12825,29 @@ ${lines.join("\n")}
|
|
|
12532
12825
|
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path41.basename(activeReal) || activeReal} = IDE \u5934\u90E8\u6240\u793A\u6839\uFF09\u3002\u5F53\u7528\u6237\u5728\u5BF9\u8BDD\u4E2D\u6307\u660E\u4E86\u67D0\u4E2A\u9879\u76EE\uFF08\u5982\u300C\u5728 A \u9879\u76EE\u300D\u300C\u6539\u524D\u7AEF\u7684 xxx\u300D\u300C\u641C\u540E\u7AEF\u300D\uFF09\uFF0C\u8BE5\u8F6E\u6240\u6709\u5E26 path \u53C2\u6570\u7684\u5DE5\u5177\u8C03\u7528\uFF08read_file / edit_file / search_grep / glob / list_dir / read_xlsx / read_docx \u7B49\uFF09\u5FC5\u987B\u628A\u5BF9\u5E94\u9879\u76EE\u6839\u4F5C\u4E3A path \u4F20\u5165\uFF08\u7EDD\u5BF9\u8DEF\u5F84\u3001../<\u5144\u5F1F\u76EE\u5F55>\u3001\u6216\u9879\u76EE\u76EE\u5F55\u540D\uFF09\uFF0C\u5426\u5219\u53EA\u4F1A\u8BFB\u5199/\u641C\u7D22\u9ED8\u8BA4\u6839\uFF0C\u4E0E\u7528\u6237\u610F\u56FE\u4E0D\u7B26\u3002
|
|
12533
12826
|
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path41.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
|
|
12534
12827
|
}
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12828
|
+
const osName = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
12829
|
+
const now = /* @__PURE__ */ new Date();
|
|
12830
|
+
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
12831
|
+
const shellNote = process.platform === "win32" ? "\u7ECF shell \u6267\u884C\uFF08\u4F18\u5148 Git Bash\uFF0CPOSIX \u8BED\u4E49\uFF1B\u7F3A\u7701\u56DE\u9000 cmd.exe\uFF09" : "\u7ECF POSIX shell\uFF08sh\uFF09\u6267\u884C";
|
|
12832
|
+
const envLines = [
|
|
12833
|
+
...roots.length > 1 ? [] : [`- \u5DE5\u4F5C\u533A\u6839\uFF08\u5DE5\u5177\u76F8\u5BF9\u8DEF\u5F84\u7684\u57FA\u51C6\uFF09: ${getActiveWorkspaceRoot()}`],
|
|
12834
|
+
`- \u64CD\u4F5C\u7CFB\u7EDF: ${osName}\uFF08${process.platform}\uFF09`,
|
|
12835
|
+
`- \u547D\u4EE4\u6267\u884C: ${shellNote}`,
|
|
12836
|
+
`- \u4ECA\u5929: ${today}`
|
|
12837
|
+
];
|
|
12838
|
+
sysPrompt = sysPrompt + `
|
|
12539
12839
|
|
|
12540
|
-
\
|
|
12541
|
-
|
|
12840
|
+
\u3010\u73AF\u5883\u3011
|
|
12841
|
+
${envLines.join("\n")}`;
|
|
12842
|
+
let replyText = "";
|
|
12843
|
+
const { wire: userContent, archive: archiveContent } = toIngestContents(inbound.content, inbound.attachments, opts?.model);
|
|
12542
12844
|
try {
|
|
12543
12845
|
const fullMessages = await buildContextMessages(
|
|
12544
12846
|
sessionId,
|
|
12545
12847
|
{ role: "user", content: userContent },
|
|
12546
|
-
sysPrompt
|
|
12848
|
+
sysPrompt,
|
|
12849
|
+
opts?.model
|
|
12850
|
+
// ★ vision 自动判定与实际请求模型(opts.model ?? MODEL_NAME)同源
|
|
12547
12851
|
);
|
|
12548
12852
|
await emitTrace({
|
|
12549
12853
|
sessionId,
|
|
@@ -12555,7 +12859,7 @@ ${lines.join("\n")}
|
|
|
12555
12859
|
});
|
|
12556
12860
|
void sweepStaleAtomicTmp().catch(() => {
|
|
12557
12861
|
});
|
|
12558
|
-
await appendMessage({ sessionId, role: "user", content:
|
|
12862
|
+
await appendMessage({ sessionId, role: "user", content: archiveContent });
|
|
12559
12863
|
let streamedAnyText = false;
|
|
12560
12864
|
const onUIEvent = opts?.onUIEvent ?? ((evt) => sseWrite?.(evt));
|
|
12561
12865
|
const requestApproval2 = opts?.requestApproval ?? createWebRequestApproval((evt) => sseWrite?.(evt), abortSignal);
|
|
@@ -12744,6 +13048,75 @@ var init_fork = __esm({
|
|
|
12744
13048
|
}
|
|
12745
13049
|
});
|
|
12746
13050
|
|
|
13051
|
+
// ../core/src/commands/bashDirect.ts
|
|
13052
|
+
import { exec } from "node:child_process";
|
|
13053
|
+
var OUTPUT_MAX_CHARS, timeoutMs, truncateOutput, decodeBuffer, runBashDirect, formatBashEntry, recordBashEntry;
|
|
13054
|
+
var init_bashDirect = __esm({
|
|
13055
|
+
"../core/src/commands/bashDirect.ts"() {
|
|
13056
|
+
"use strict";
|
|
13057
|
+
init_transcript();
|
|
13058
|
+
init_guard();
|
|
13059
|
+
OUTPUT_MAX_CHARS = 4e3;
|
|
13060
|
+
timeoutMs = () => {
|
|
13061
|
+
const n = Number(process.env.DEEP_SEEK_BANG_TIMEOUT_MS);
|
|
13062
|
+
return Number.isFinite(n) && n > 0 ? n : 6e4;
|
|
13063
|
+
};
|
|
13064
|
+
truncateOutput = (s) => {
|
|
13065
|
+
if (s.length <= OUTPUT_MAX_CHARS) return s;
|
|
13066
|
+
const half = Math.floor(OUTPUT_MAX_CHARS / 2);
|
|
13067
|
+
return `${s.slice(0, half)}
|
|
13068
|
+
\u2026\uFF08\u4E2D\u6BB5\u7701\u7565 ${s.length - OUTPUT_MAX_CHARS} \u5B57\u7B26\uFF09\u2026
|
|
13069
|
+
${s.slice(-half)}`;
|
|
13070
|
+
};
|
|
13071
|
+
decodeBuffer = (buf) => {
|
|
13072
|
+
const utf8 = buf.toString("utf8");
|
|
13073
|
+
if (!utf8.includes("\uFFFD")) return utf8;
|
|
13074
|
+
try {
|
|
13075
|
+
return new TextDecoder("gbk").decode(buf);
|
|
13076
|
+
} catch {
|
|
13077
|
+
return utf8;
|
|
13078
|
+
}
|
|
13079
|
+
};
|
|
13080
|
+
runBashDirect = (cmd, cwd, signal) => new Promise((resolve) => {
|
|
13081
|
+
let settled = false;
|
|
13082
|
+
const finish = (r) => {
|
|
13083
|
+
if (!settled) {
|
|
13084
|
+
settled = true;
|
|
13085
|
+
resolve(r);
|
|
13086
|
+
}
|
|
13087
|
+
};
|
|
13088
|
+
const start = Date.now();
|
|
13089
|
+
const child = exec(cmd, { cwd, timeout: timeoutMs(), maxBuffer: 4 * 1024 * 1024, windowsHide: true, env: scrubCommandEnv(), encoding: "buffer" }, (err, stdout, stderr) => {
|
|
13090
|
+
const durationMs = Date.now() - start;
|
|
13091
|
+
const out = stdout;
|
|
13092
|
+
const errBuf = stderr;
|
|
13093
|
+
const timedOut = err != null && err.killed === true && signal?.aborted !== true;
|
|
13094
|
+
const combined = errBuf.length ? (out.length ? `${decodeBuffer(out)}
|
|
13095
|
+
` : "") + decodeBuffer(errBuf) : decodeBuffer(out);
|
|
13096
|
+
const exitCode = err == null ? 0 : typeof err.code === "number" ? err.code : null;
|
|
13097
|
+
finish({ ok: err == null, output: truncateOutput(combined ?? ""), exitCode, timedOut, durationMs });
|
|
13098
|
+
});
|
|
13099
|
+
if (signal) {
|
|
13100
|
+
const onAbort = () => {
|
|
13101
|
+
try {
|
|
13102
|
+
child.kill();
|
|
13103
|
+
} catch {
|
|
13104
|
+
}
|
|
13105
|
+
};
|
|
13106
|
+
if (signal.aborted) onAbort();
|
|
13107
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13108
|
+
}
|
|
13109
|
+
});
|
|
13110
|
+
formatBashEntry = (cmd, r) => `!bash $ ${cmd}
|
|
13111
|
+
` + (r.timedOut ? `[\u8D85\u65F6\u4E2D\u6B62\uFF08>${Math.round(r.durationMs / 1e3)}s\uFF09]
|
|
13112
|
+
` : "") + (r.exitCode != null && r.exitCode !== 0 ? `[\u9000\u51FA\u7801 ${r.exitCode}]
|
|
13113
|
+
` : "") + (r.output.trim() || "(\u65E0\u8F93\u51FA)");
|
|
13114
|
+
recordBashEntry = async (sessionId, text) => {
|
|
13115
|
+
await appendMessage({ sessionId, role: "user", content: text });
|
|
13116
|
+
};
|
|
13117
|
+
}
|
|
13118
|
+
});
|
|
13119
|
+
|
|
12747
13120
|
// src/cliHost.ts
|
|
12748
13121
|
var createCliRequestApproval, createCliRequestQuestion;
|
|
12749
13122
|
var init_cliHost = __esm({
|
|
@@ -12938,9 +13311,12 @@ var init_useChatState = __esm({
|
|
|
12938
13311
|
init_fork();
|
|
12939
13312
|
init_inbox();
|
|
12940
13313
|
init_contextCore();
|
|
13314
|
+
init_bashDirect();
|
|
13315
|
+
init_guard();
|
|
12941
13316
|
init_createModel();
|
|
12942
13317
|
init_tool();
|
|
12943
13318
|
init_cliHost();
|
|
13319
|
+
init_prefs();
|
|
12944
13320
|
init_strings();
|
|
12945
13321
|
init_util();
|
|
12946
13322
|
init_replay2();
|
|
@@ -12962,6 +13338,7 @@ var init_useChatState = __esm({
|
|
|
12962
13338
|
const [pendingPlan, setPendingPlan] = useState(null);
|
|
12963
13339
|
const [pendingSessions, setPendingSessions] = useState(null);
|
|
12964
13340
|
const [pendingFork, setPendingFork] = useState(null);
|
|
13341
|
+
const [pendingModel, setPendingModel] = useState(null);
|
|
12965
13342
|
const nextId = useRef(1);
|
|
12966
13343
|
const assistantStreamingId = useRef(null);
|
|
12967
13344
|
const thinkingStreamingId = useRef(null);
|
|
@@ -13333,6 +13710,22 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13333
13710
|
if (turnGenRef.current === myGen) setBusy(false);
|
|
13334
13711
|
}
|
|
13335
13712
|
}, [busy, initialSessionId, pushUser, pushInfo, runOnce, runPlanStage, takeEnterPlanRequest, takeProposedPlan, approveAndImplement]);
|
|
13713
|
+
const runBangCommand = useCallback(async (raw) => {
|
|
13714
|
+
const cmd = raw.replace(/^!/, "").trim();
|
|
13715
|
+
if (!cmd) {
|
|
13716
|
+
pushInfo("\u7528\u6CD5\uFF1A!<shell \u547D\u4EE4>\uFF08\u5982 !git status\uFF09\uFF1B\u8F93\u51FA\u4F1A\u5E26\u5165\u4E0B\u8F6E\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u3002");
|
|
13717
|
+
return;
|
|
13718
|
+
}
|
|
13719
|
+
pushUser(raw);
|
|
13720
|
+
if (sessionIdRef.current == null) {
|
|
13721
|
+
sessionIdRef.current = await getOrCreateSessionId(initialSessionId ?? void 0);
|
|
13722
|
+
}
|
|
13723
|
+
const r = await runBashDirect(cmd, getActiveWorkspaceRoot());
|
|
13724
|
+
const head = r.timedOut ? `\u23F1 \u8D85\u65F6\u4E2D\u6B62` : r.ok ? `\u2705 \u9000\u51FA\u7801 0` : r.exitCode != null ? `\u274C \u9000\u51FA\u7801 ${r.exitCode}` : `\u274C \u5DF2\u4E2D\u6B62`;
|
|
13725
|
+
pushInfo(`${head} \xB7 ${Math.round(r.durationMs / 100) / 10}s
|
|
13726
|
+
${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
|
|
13727
|
+
await recordBashEntry(sessionIdRef.current, formatBashEntry(cmd, r));
|
|
13728
|
+
}, [initialSessionId, pushUser, pushInfo]);
|
|
13336
13729
|
const abortCurrent = useCallback(() => {
|
|
13337
13730
|
const ac = currentAcRef.current;
|
|
13338
13731
|
if (!ac) return;
|
|
@@ -13416,7 +13809,21 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13416
13809
|
}, [pushInfo, loadSession]);
|
|
13417
13810
|
const setModelOverride = useCallback((m) => {
|
|
13418
13811
|
modelRef.current = m;
|
|
13812
|
+
void writePrefs({ model: m });
|
|
13813
|
+
}, []);
|
|
13814
|
+
const resolveModel = useCallback((model2) => {
|
|
13815
|
+
setPendingModel((prev) => {
|
|
13816
|
+
prev?.resolve(model2);
|
|
13817
|
+
return null;
|
|
13818
|
+
});
|
|
13419
13819
|
}, []);
|
|
13820
|
+
const openModelPicker = useCallback(async () => {
|
|
13821
|
+
const picked = await new Promise((resolve) => setPendingModel({ models: SELECTABLE_MODELS, resolve }));
|
|
13822
|
+
if (picked) {
|
|
13823
|
+
setModelOverride(picked);
|
|
13824
|
+
pushInfo(S.modelSwitched(picked));
|
|
13825
|
+
}
|
|
13826
|
+
}, [pushInfo, setModelOverride]);
|
|
13420
13827
|
const setPlanMode = useCallback((on) => {
|
|
13421
13828
|
planModeRef.current = on;
|
|
13422
13829
|
}, []);
|
|
@@ -13444,6 +13851,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13444
13851
|
pendingPlan,
|
|
13445
13852
|
pendingSessions,
|
|
13446
13853
|
pendingFork,
|
|
13854
|
+
pendingModel,
|
|
13447
13855
|
sessionIdRef,
|
|
13448
13856
|
// 动作
|
|
13449
13857
|
submit,
|
|
@@ -13452,6 +13860,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13452
13860
|
pushUser,
|
|
13453
13861
|
pushInfo,
|
|
13454
13862
|
pushEvent,
|
|
13863
|
+
runBangCommand,
|
|
13455
13864
|
askApproval,
|
|
13456
13865
|
resolveApproval,
|
|
13457
13866
|
resolveQuestion,
|
|
@@ -13472,7 +13881,9 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13472
13881
|
resolveSession,
|
|
13473
13882
|
loadSession,
|
|
13474
13883
|
openForkPicker,
|
|
13475
|
-
resolveFork
|
|
13884
|
+
resolveFork,
|
|
13885
|
+
openModelPicker,
|
|
13886
|
+
resolveModel
|
|
13476
13887
|
};
|
|
13477
13888
|
};
|
|
13478
13889
|
}
|
|
@@ -13561,7 +13972,7 @@ var init_StreamingCursor = __esm({
|
|
|
13561
13972
|
// src/components/MessageBlock.tsx
|
|
13562
13973
|
import { Box, Text as Text3 } from "ink";
|
|
13563
13974
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
13564
|
-
var UsageFooter, listPrefix, AssistantLine, MessageBlock;
|
|
13975
|
+
var UsageFooter, listPrefix, AssistantLine, isFenceMark, isMdRow, isMdSep, mdCells, parseBlocks, fitCell, tableWidths, buildVLines, AssistantVLine, MessageBlock;
|
|
13565
13976
|
var init_MessageBlock = __esm({
|
|
13566
13977
|
"src/components/MessageBlock.tsx"() {
|
|
13567
13978
|
"use strict";
|
|
@@ -13600,6 +14011,94 @@ var init_MessageBlock = __esm({
|
|
|
13600
14011
|
}
|
|
13601
14012
|
return /* @__PURE__ */ jsx3(RichText, { text: line });
|
|
13602
14013
|
};
|
|
14014
|
+
isFenceMark = (l) => /^\s*```/.test(l);
|
|
14015
|
+
isMdRow = (l) => l.includes("|");
|
|
14016
|
+
isMdSep = (l) => /^[ \t|:-]+$/.test(l) && l.includes("-") && l.includes("|");
|
|
14017
|
+
mdCells = (l) => l.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim());
|
|
14018
|
+
parseBlocks = (text) => {
|
|
14019
|
+
const src = String(text || "").split("\n");
|
|
14020
|
+
const blocks = [];
|
|
14021
|
+
let i = 0;
|
|
14022
|
+
while (i < src.length) {
|
|
14023
|
+
if (isFenceMark(src[i])) {
|
|
14024
|
+
const body = [];
|
|
14025
|
+
i++;
|
|
14026
|
+
while (i < src.length && !isFenceMark(src[i])) body.push(src[i++]);
|
|
14027
|
+
if (i < src.length) i++;
|
|
14028
|
+
blocks.push({ kind: "fence", lines: body });
|
|
14029
|
+
continue;
|
|
14030
|
+
}
|
|
14031
|
+
if (isMdRow(src[i]) && i + 1 < src.length && isMdSep(src[i + 1])) {
|
|
14032
|
+
const header = mdCells(src[i]);
|
|
14033
|
+
const rows = [];
|
|
14034
|
+
i += 2;
|
|
14035
|
+
while (i < src.length && isMdRow(src[i])) rows.push(mdCells(src[i++]));
|
|
14036
|
+
blocks.push({ kind: "table", header, rows });
|
|
14037
|
+
continue;
|
|
14038
|
+
}
|
|
14039
|
+
blocks.push({ kind: "line", text: src[i++] });
|
|
14040
|
+
}
|
|
14041
|
+
return blocks;
|
|
14042
|
+
};
|
|
14043
|
+
fitCell = (s, w) => {
|
|
14044
|
+
if (strWidth(s) <= w) return s + " ".repeat(w - strWidth(s));
|
|
14045
|
+
let out = "";
|
|
14046
|
+
let width = 0;
|
|
14047
|
+
const limit = Math.max(1, w - 1);
|
|
14048
|
+
for (const ch of s) {
|
|
14049
|
+
const cw = strWidth(ch);
|
|
14050
|
+
if (width + cw > limit) break;
|
|
14051
|
+
out += ch;
|
|
14052
|
+
width += cw;
|
|
14053
|
+
}
|
|
14054
|
+
return out + "\u2026";
|
|
14055
|
+
};
|
|
14056
|
+
tableWidths = (header, rows, contentW) => {
|
|
14057
|
+
const n = Math.max(1, header.length);
|
|
14058
|
+
const w = Array.from({ length: n }, (_, c) => {
|
|
14059
|
+
let m = strWidth(header[c] ?? "");
|
|
14060
|
+
for (const r of rows) m = Math.max(m, strWidth(r[c] ?? ""));
|
|
14061
|
+
return Math.min(m, 30);
|
|
14062
|
+
});
|
|
14063
|
+
const total = () => w.reduce((a, b) => a + b, 0) + 2 * (n - 1);
|
|
14064
|
+
while (total() > contentW && Math.max(...w) > 1) {
|
|
14065
|
+
const maxW = Math.max(...w);
|
|
14066
|
+
w[w.indexOf(maxW)] = maxW - 1;
|
|
14067
|
+
}
|
|
14068
|
+
return w;
|
|
14069
|
+
};
|
|
14070
|
+
buildVLines = (text, contentW) => {
|
|
14071
|
+
const out = [];
|
|
14072
|
+
for (const b of parseBlocks(text)) {
|
|
14073
|
+
if (b.kind === "line") {
|
|
14074
|
+
for (const l of wrapText(b.text, contentW)) out.push({ k: "text", s: l });
|
|
14075
|
+
} else if (b.kind === "fence") {
|
|
14076
|
+
for (const l of b.lines) out.push({ k: "code", s: l });
|
|
14077
|
+
} else {
|
|
14078
|
+
const w = tableWidths(b.header, b.rows, contentW);
|
|
14079
|
+
out.push({ k: "thead", cells: b.header, w }, { k: "tsep", w });
|
|
14080
|
+
for (const r of b.rows) out.push({ k: "trow", cells: r, w });
|
|
14081
|
+
}
|
|
14082
|
+
}
|
|
14083
|
+
return out.length ? out : [{ k: "text", s: "" }];
|
|
14084
|
+
};
|
|
14085
|
+
AssistantVLine = ({ v }) => {
|
|
14086
|
+
switch (v.k) {
|
|
14087
|
+
case "text":
|
|
14088
|
+
return /* @__PURE__ */ jsx3(AssistantLine, { line: v.s });
|
|
14089
|
+
case "code":
|
|
14090
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
14091
|
+
/* @__PURE__ */ jsx3(Text3, { color: THEME.divider, children: "\u2502 " }),
|
|
14092
|
+
/* @__PURE__ */ jsx3(Text3, { color: THEME.gray, children: v.s.length ? v.s : " " })
|
|
14093
|
+
] });
|
|
14094
|
+
case "thead":
|
|
14095
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "row", children: v.w.map((cw, i) => /* @__PURE__ */ jsx3(Box, { width: cw + 2, flexShrink: 0, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "#ffffff", children: fitCell(v.cells[i] ?? "", cw) }) }, i)) });
|
|
14096
|
+
case "tsep":
|
|
14097
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "row", children: v.w.map((cw, i) => /* @__PURE__ */ jsx3(Box, { width: cw + 2, flexShrink: 0, children: /* @__PURE__ */ jsx3(Text3, { color: THEME.divider, children: "\u2500".repeat(cw) }) }, i)) });
|
|
14098
|
+
case "trow":
|
|
14099
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "row", children: v.w.map((cw, i) => /* @__PURE__ */ jsx3(Box, { width: cw + 2, flexShrink: 0, children: /* @__PURE__ */ jsx3(Text3, { color: THEME.body, children: fitCell(v.cells[i] ?? "", cw) }) }, i)) });
|
|
14100
|
+
}
|
|
14101
|
+
};
|
|
13603
14102
|
MessageBlock = ({ row, wrapW, streamTail }) => {
|
|
13604
14103
|
if (row.kind === "meta") {
|
|
13605
14104
|
if (/^第 \d+ 轮$/.test(row.text)) {
|
|
@@ -13616,15 +14115,15 @@ var init_MessageBlock = __esm({
|
|
|
13616
14115
|
] }) });
|
|
13617
14116
|
}
|
|
13618
14117
|
if (row.kind === "info") {
|
|
13619
|
-
const
|
|
13620
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14118
|
+
const lines = wrapText(row.text, Math.max(8, wrapW));
|
|
14119
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsxs(Text3, { color: THEME.coralMuted, children: [
|
|
13621
14120
|
j === 0 ? "\u203A " : " ",
|
|
13622
14121
|
line
|
|
13623
14122
|
] }, j)) });
|
|
13624
14123
|
}
|
|
13625
14124
|
if (row.kind === "user") {
|
|
13626
|
-
const
|
|
13627
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14125
|
+
const lines = wrapText(row.text, Math.max(8, wrapW - 2));
|
|
14126
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsx3(Text3, { children: j === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13628
14127
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.coralBright, bold: true, children: "> " }),
|
|
13629
14128
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.white, children: line })
|
|
13630
14129
|
] }) : /* @__PURE__ */ jsxs(Text3, { color: THEME.white, children: [
|
|
@@ -13633,19 +14132,19 @@ var init_MessageBlock = __esm({
|
|
|
13633
14132
|
] }) }, j)) });
|
|
13634
14133
|
}
|
|
13635
14134
|
if (row.kind === "system") {
|
|
13636
|
-
const
|
|
13637
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14135
|
+
const lines = wrapText(row.text, Math.max(8, wrapW - 2));
|
|
14136
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsxs(Text3, { color: THEME.warn, children: [
|
|
13638
14137
|
j === 0 ? "! " : " ",
|
|
13639
14138
|
line
|
|
13640
14139
|
] }, j)) });
|
|
13641
14140
|
}
|
|
13642
14141
|
const contentW = Math.max(8, wrapW - 2);
|
|
13643
|
-
const allLines =
|
|
13644
|
-
let
|
|
14142
|
+
const allLines = buildVLines(row.text, contentW);
|
|
14143
|
+
let vlines = allLines;
|
|
13645
14144
|
let folded = 0;
|
|
13646
14145
|
if (row.streaming && streamTail && allLines.length > streamTail) {
|
|
13647
14146
|
folded = allLines.length - streamTail;
|
|
13648
|
-
|
|
14147
|
+
vlines = allLines.slice(folded);
|
|
13649
14148
|
}
|
|
13650
14149
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: [
|
|
13651
14150
|
folded > 0 ? /* @__PURE__ */ jsxs(Text3, { color: THEME.grayDim, children: [
|
|
@@ -13653,11 +14152,11 @@ var init_MessageBlock = __esm({
|
|
|
13653
14152
|
folded,
|
|
13654
14153
|
" \u884C\u2026"
|
|
13655
14154
|
] }) : null,
|
|
13656
|
-
|
|
13657
|
-
const isLast = j ===
|
|
14155
|
+
vlines.map((v, j) => {
|
|
14156
|
+
const isLast = j === vlines.length - 1;
|
|
13658
14157
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
13659
14158
|
/* @__PURE__ */ jsx3(Text3, { bold: true, color: THEME.coralBright, children: j === 0 ? "\u25CF " : " " }),
|
|
13660
|
-
/* @__PURE__ */ jsx3(
|
|
14159
|
+
/* @__PURE__ */ jsx3(AssistantVLine, { v }),
|
|
13661
14160
|
isLast && row.streaming ? /* @__PURE__ */ jsx3(StreamingCursor, {}) : null
|
|
13662
14161
|
] }, j);
|
|
13663
14162
|
}),
|
|
@@ -14281,9 +14780,44 @@ var init_ForkPicker = __esm({
|
|
|
14281
14780
|
}
|
|
14282
14781
|
});
|
|
14283
14782
|
|
|
14284
|
-
// src/components/
|
|
14783
|
+
// src/components/ModelPicker.tsx
|
|
14285
14784
|
import { Box as Box12, Text as Text14 } from "ink";
|
|
14286
14785
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
14786
|
+
var PAGE_SIZE3, ModelPicker;
|
|
14787
|
+
var init_ModelPicker = __esm({
|
|
14788
|
+
"src/components/ModelPicker.tsx"() {
|
|
14789
|
+
"use strict";
|
|
14790
|
+
init_theme();
|
|
14791
|
+
init_strings();
|
|
14792
|
+
init_util();
|
|
14793
|
+
PAGE_SIZE3 = 8;
|
|
14794
|
+
ModelPicker = ({ models, currentModel, selectedIndex, wrapW }) => {
|
|
14795
|
+
const start = Math.floor(Math.max(0, selectedIndex) / PAGE_SIZE3) * PAGE_SIZE3;
|
|
14796
|
+
const visible = models.slice(start, start + PAGE_SIZE3);
|
|
14797
|
+
const contentW = Math.max(24, wrapW);
|
|
14798
|
+
const metaSample = " \xB7 \uFF08\u5F53\u524D\uFF09";
|
|
14799
|
+
const modelW = Math.max(12, contentW - strWidth(metaSample) - 4);
|
|
14800
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: THEME.blue, paddingX: 1, paddingY: 1, marginTop: 1, children: [
|
|
14801
|
+
/* @__PURE__ */ jsx14(Text14, { color: THEME.blue, bold: true, children: S.modelPickerTitle(currentModel) }),
|
|
14802
|
+
/* @__PURE__ */ jsx14(Text14, { color: THEME.grayDim, children: S.modelPickerPrompt }),
|
|
14803
|
+
/* @__PURE__ */ jsx14(Box12, { flexDirection: "column", marginTop: 0.5, children: visible.map((m, i) => {
|
|
14804
|
+
const idx = start + i;
|
|
14805
|
+
const active = idx === selectedIndex;
|
|
14806
|
+
const current = m === currentModel;
|
|
14807
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
|
|
14808
|
+
/* @__PURE__ */ jsx14(Text14, { color: active ? THEME.coralBright : void 0, bold: true, children: active ? "\u203A " : " " }),
|
|
14809
|
+
/* @__PURE__ */ jsx14(Text14, { color: active ? THEME.white : THEME.gray, bold: active, children: `${current ? "\u25CF " : " "}${truncateMiddle(m, modelW)}` }),
|
|
14810
|
+
current ? /* @__PURE__ */ jsx14(Text14, { color: THEME.grayDim, children: ` \xB7 ${S.modelCurrentTag}` }) : null
|
|
14811
|
+
] }, m);
|
|
14812
|
+
}) })
|
|
14813
|
+
] });
|
|
14814
|
+
};
|
|
14815
|
+
}
|
|
14816
|
+
});
|
|
14817
|
+
|
|
14818
|
+
// src/components/SlashMenu.tsx
|
|
14819
|
+
import { Box as Box13, Text as Text15 } from "ink";
|
|
14820
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
14287
14821
|
var MAX_ROWS, SlashMenu;
|
|
14288
14822
|
var init_SlashMenu = __esm({
|
|
14289
14823
|
"src/components/SlashMenu.tsx"() {
|
|
@@ -14295,22 +14829,22 @@ var init_SlashMenu = __esm({
|
|
|
14295
14829
|
const visible = entries.slice(start, start + MAX_ROWS);
|
|
14296
14830
|
const cmdW = Math.min(22, Math.max(8, ...visible.map((e) => e.name.length)) + 1);
|
|
14297
14831
|
const descMax = Math.max(12, cols - cmdW - 6);
|
|
14298
|
-
return /* @__PURE__ */
|
|
14832
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: THEME.coral, paddingX: 1, paddingY: 0, marginTop: 1, children: [
|
|
14299
14833
|
visible.map((e, i) => {
|
|
14300
14834
|
const active = i + start === selectedIndex;
|
|
14301
14835
|
const desc = e.description.length > descMax ? `${e.description.slice(0, descMax - 1)}\u2026` : e.description;
|
|
14302
14836
|
const gap = Math.max(1, cmdW - e.name.length);
|
|
14303
|
-
return /* @__PURE__ */
|
|
14304
|
-
/* @__PURE__ */
|
|
14305
|
-
/* @__PURE__ */
|
|
14837
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", children: [
|
|
14838
|
+
/* @__PURE__ */ jsx15(Text15, { color: active ? THEME.coralBright : void 0, bold: true, children: active ? "\u276F " : " " }),
|
|
14839
|
+
/* @__PURE__ */ jsxs13(Text15, { color: active ? THEME.white : THEME.gray, bold: active, children: [
|
|
14306
14840
|
"/",
|
|
14307
14841
|
e.name
|
|
14308
14842
|
] }),
|
|
14309
|
-
/* @__PURE__ */
|
|
14310
|
-
/* @__PURE__ */
|
|
14843
|
+
/* @__PURE__ */ jsx15(Text15, { color: THEME.grayDim, children: " ".repeat(gap) }),
|
|
14844
|
+
/* @__PURE__ */ jsx15(Text15, { color: active ? THEME.gray : THEME.grayDim, children: desc })
|
|
14311
14845
|
] }, e.name);
|
|
14312
14846
|
}),
|
|
14313
|
-
entries.length > MAX_ROWS ? /* @__PURE__ */
|
|
14847
|
+
entries.length > MAX_ROWS ? /* @__PURE__ */ jsxs13(Text15, { color: THEME.coralMuted, children: [
|
|
14314
14848
|
"\u2191\u2193 \u6EDA\u52A8 \xB7 ",
|
|
14315
14849
|
selectedIndex + 1,
|
|
14316
14850
|
"/",
|
|
@@ -14323,8 +14857,8 @@ var init_SlashMenu = __esm({
|
|
|
14323
14857
|
});
|
|
14324
14858
|
|
|
14325
14859
|
// src/components/StatusStrip.tsx
|
|
14326
|
-
import { Box as
|
|
14327
|
-
import { jsx as
|
|
14860
|
+
import { Box as Box14, Text as Text16 } from "ink";
|
|
14861
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
14328
14862
|
var StatusStrip;
|
|
14329
14863
|
var init_StatusStrip = __esm({
|
|
14330
14864
|
"src/components/StatusStrip.tsx"() {
|
|
@@ -14341,18 +14875,18 @@ var init_StatusStrip = __esm({
|
|
|
14341
14875
|
`state: ${stateText}`,
|
|
14342
14876
|
sessionShort ? `session: ${sessionShort}` : ""
|
|
14343
14877
|
].filter(Boolean);
|
|
14344
|
-
return /* @__PURE__ */
|
|
14345
|
-
/* @__PURE__ */
|
|
14346
|
-
/* @__PURE__ */
|
|
14347
|
-
/* @__PURE__ */
|
|
14878
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexShrink: 0, children: [
|
|
14879
|
+
/* @__PURE__ */ jsx16(Text16, { color: THEME.coralMuted, children: customLine && customLine.trim() ? customLine : bits.join(" \xB7 ") }),
|
|
14880
|
+
/* @__PURE__ */ jsx16(Text16, { color: stateColor, children: "" }),
|
|
14881
|
+
/* @__PURE__ */ jsx16(Text16, { color: THEME.grayDim, children: S.cmdHint })
|
|
14348
14882
|
] });
|
|
14349
14883
|
};
|
|
14350
14884
|
}
|
|
14351
14885
|
});
|
|
14352
14886
|
|
|
14353
14887
|
// src/components/TopPanel.tsx
|
|
14354
|
-
import { Box as
|
|
14355
|
-
import { jsx as
|
|
14888
|
+
import { Box as Box15, Text as Text17 } from "ink";
|
|
14889
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
14356
14890
|
var ROBOT, INNER_H, TopPanel;
|
|
14357
14891
|
var init_TopPanel = __esm({
|
|
14358
14892
|
"src/components/TopPanel.tsx"() {
|
|
@@ -14372,36 +14906,36 @@ var init_TopPanel = __esm({
|
|
|
14372
14906
|
const leftW = Math.floor(innerW * 0.33);
|
|
14373
14907
|
const rightW = innerW - leftW - 1;
|
|
14374
14908
|
const ruleLen = Math.max(8, rightW - 2);
|
|
14375
|
-
const VDivider = /* @__PURE__ */
|
|
14376
|
-
return /* @__PURE__ */
|
|
14377
|
-
/* @__PURE__ */
|
|
14378
|
-
/* @__PURE__ */
|
|
14379
|
-
/* @__PURE__ */
|
|
14380
|
-
/* @__PURE__ */
|
|
14381
|
-
/* @__PURE__ */
|
|
14382
|
-
/* @__PURE__ */
|
|
14909
|
+
const VDivider = /* @__PURE__ */ jsx17(Box15, { flexDirection: "column", width: 1, flexShrink: 0, children: Array.from({ length: INNER_H }).map((_, i) => /* @__PURE__ */ jsx17(Text17, { color: THEME.coral, children: "\u2502" }, i)) });
|
|
14910
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: panelW, marginBottom: 1, children: [
|
|
14911
|
+
/* @__PURE__ */ jsxs15(Text17, { children: [
|
|
14912
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "* Welcome to " }),
|
|
14913
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.white, children: "deep" }),
|
|
14914
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.coralBright, children: "Seek" }),
|
|
14915
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.white, children: "Code" }),
|
|
14916
|
+
/* @__PURE__ */ jsxs15(Text17, { color: THEME.coralMuted, children: [
|
|
14383
14917
|
" ",
|
|
14384
14918
|
VERSION
|
|
14385
14919
|
] })
|
|
14386
14920
|
] }),
|
|
14387
|
-
/* @__PURE__ */
|
|
14388
|
-
/* @__PURE__ */
|
|
14389
|
-
/* @__PURE__ */
|
|
14390
|
-
/* @__PURE__ */
|
|
14391
|
-
ROBOT.map((l, i) => /* @__PURE__ */
|
|
14392
|
-
/* @__PURE__ */
|
|
14393
|
-
/* @__PURE__ */
|
|
14921
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: cwd }),
|
|
14922
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "row", borderStyle: "round", borderColor: THEME.coral, marginTop: 1, paddingX: 0, paddingY: 0, children: [
|
|
14923
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: leftW, height: INNER_H, alignItems: "center", justifyContent: "center", children: [
|
|
14924
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, bold: true, children: "Welcome back!" }),
|
|
14925
|
+
ROBOT.map((l, i) => /* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, children: l }, i)),
|
|
14926
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "Ctrl+C \u9000\u51FA \xB7 Esc \u4E2D\u6B62" }),
|
|
14927
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "\u8F93\u5165 / \u67E5\u770B\u547D\u4EE4" })
|
|
14394
14928
|
] }),
|
|
14395
14929
|
VDivider,
|
|
14396
|
-
/* @__PURE__ */
|
|
14397
|
-
/* @__PURE__ */
|
|
14398
|
-
/* @__PURE__ */
|
|
14399
|
-
/* @__PURE__ */
|
|
14930
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: rightW, height: INNER_H, justifyContent: "space-between", paddingX: 1, children: [
|
|
14931
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
14932
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "Tips for getting started" }),
|
|
14933
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, children: "\u8F93\u5165\u9700\u6C42\u5F00\u59CB\uFF0C\u8F93\u5165 / \u5524\u51FA\u547D\u4EE4\u3002" })
|
|
14400
14934
|
] }),
|
|
14401
|
-
/* @__PURE__ */
|
|
14402
|
-
/* @__PURE__ */
|
|
14403
|
-
/* @__PURE__ */
|
|
14404
|
-
/* @__PURE__ */
|
|
14935
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "\u2500".repeat(ruleLen) }),
|
|
14936
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
14937
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "What's new" }),
|
|
14938
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, children: "\u5DF2\u5BF9\u63A5\u672C\u5730 Tool Call \u667A\u80FD\u51FD\u6570\u8C03\u7528\u3002" })
|
|
14405
14939
|
] })
|
|
14406
14940
|
] })
|
|
14407
14941
|
] })
|
|
@@ -14552,9 +15086,9 @@ __export(App_exports, {
|
|
|
14552
15086
|
App: () => App
|
|
14553
15087
|
});
|
|
14554
15088
|
import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState4 } from "react";
|
|
14555
|
-
import { Box as
|
|
14556
|
-
import { Fragment as Fragment3, jsx as
|
|
14557
|
-
var
|
|
15089
|
+
import { Box as Box16, Static, Text as Text18, useApp, useInput as useInput2, useStdout } from "ink";
|
|
15090
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
15091
|
+
var CWD2, RowView, isDynamicRow, App;
|
|
14558
15092
|
var init_App = __esm({
|
|
14559
15093
|
"src/App.tsx"() {
|
|
14560
15094
|
"use strict";
|
|
@@ -14579,24 +15113,24 @@ var init_App = __esm({
|
|
|
14579
15113
|
init_PlanEditor();
|
|
14580
15114
|
init_SessionPicker();
|
|
14581
15115
|
init_ForkPicker();
|
|
15116
|
+
init_ModelPicker();
|
|
14582
15117
|
init_SlashMenu();
|
|
14583
15118
|
init_MultilineInput();
|
|
14584
15119
|
init_StatusStrip();
|
|
14585
15120
|
init_TopPanel();
|
|
14586
15121
|
init_inspect();
|
|
14587
|
-
KNOWN_MODELS = ["deepseek-v4", "deepseek-v4-flash"];
|
|
14588
15122
|
CWD2 = process.cwd();
|
|
14589
15123
|
RowView = ({ row, wrapW, streamTail, showThinking }) => {
|
|
14590
|
-
if (row.kind === "todos") return /* @__PURE__ */
|
|
14591
|
-
if (row.kind === "tool") return /* @__PURE__ */
|
|
14592
|
-
if (row.kind === "thinking") return /* @__PURE__ */
|
|
15124
|
+
if (row.kind === "todos") return /* @__PURE__ */ jsx18(TodosPanel, { todos: row.todos, wrapW });
|
|
15125
|
+
if (row.kind === "tool") return /* @__PURE__ */ jsx18(ToolCard, { toolName: row.toolName, args: row.args, result: row.result, ok: row.ok, status: row.status, progress: row.progress, wrapW });
|
|
15126
|
+
if (row.kind === "thinking") return /* @__PURE__ */ jsx18(ThinkingBlock, { streaming: row.streaming ?? false, startedAt: row.startedAt, durationMs: row.durationMs, tokens: row.tokens, text: row.text, expanded: showThinking, wrapW });
|
|
14593
15127
|
if (row.kind === "user") {
|
|
14594
|
-
return /* @__PURE__ */
|
|
14595
|
-
/* @__PURE__ */
|
|
14596
|
-
/* @__PURE__ */
|
|
15128
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginTop: 1, children: [
|
|
15129
|
+
/* @__PURE__ */ jsx18(Text18, { color: THEME.grayDim, children: "\u2500".repeat(Math.max(8, wrapW)) }),
|
|
15130
|
+
/* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail })
|
|
14597
15131
|
] });
|
|
14598
15132
|
}
|
|
14599
|
-
return /* @__PURE__ */
|
|
15133
|
+
return /* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail });
|
|
14600
15134
|
};
|
|
14601
15135
|
isDynamicRow = (r) => r.kind === "assistant" && !!r.streaming || r.kind === "thinking" && !!r.streaming || r.kind === "tool" && r.status === "running" || r.kind === "todos" && !!r.active;
|
|
14602
15136
|
App = ({ resumeSessionId, initialPlanMode, initialAutoMode, initialIncludeProject, engineReady }) => {
|
|
@@ -14672,6 +15206,15 @@ var init_App = __esm({
|
|
|
14672
15206
|
await refreshStatusLineRef.current();
|
|
14673
15207
|
})();
|
|
14674
15208
|
}, []);
|
|
15209
|
+
useEffect4(() => {
|
|
15210
|
+
void (async () => {
|
|
15211
|
+
const saved = await readModelPref();
|
|
15212
|
+
if (saved) {
|
|
15213
|
+
state.setModelOverride(saved);
|
|
15214
|
+
setModelDisplay(saved);
|
|
15215
|
+
}
|
|
15216
|
+
})();
|
|
15217
|
+
}, []);
|
|
14675
15218
|
useEffect4(() => {
|
|
14676
15219
|
void refreshStatusLineRef.current();
|
|
14677
15220
|
}, [state.busy, state.aborting, modelDisplay]);
|
|
@@ -14698,6 +15241,8 @@ var init_App = __esm({
|
|
|
14698
15241
|
return S.cmdAuto;
|
|
14699
15242
|
case "model":
|
|
14700
15243
|
return S.cmdModel;
|
|
15244
|
+
case "switch":
|
|
15245
|
+
return S.cmdSwitch;
|
|
14701
15246
|
case "thinking":
|
|
14702
15247
|
return S.cmdThinking;
|
|
14703
15248
|
case "lang":
|
|
@@ -14740,17 +15285,23 @@ var init_App = __esm({
|
|
|
14740
15285
|
const q = input.slice(1).toLowerCase();
|
|
14741
15286
|
return menuEntries.filter((c) => c.name.toLowerCase().startsWith(q));
|
|
14742
15287
|
}, [input, menuEntries]);
|
|
14743
|
-
const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null;
|
|
15288
|
+
const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null || state.pendingModel != null;
|
|
14744
15289
|
const slashVisible = !menuActive && input.startsWith("/") && filteredCommands.length > 0;
|
|
14745
15290
|
const inputActive = !menuActive;
|
|
14746
15291
|
useEffect4(() => {
|
|
14747
15292
|
setSelectIdx(0);
|
|
14748
15293
|
setPlanEditing(false);
|
|
14749
|
-
}, [state.pendingApproval, state.pendingQuestion, state.pendingPlan, state.pendingSessions, state.pendingFork, slashVisible, filteredCommands.length]);
|
|
15294
|
+
}, [state.pendingApproval, state.pendingQuestion, state.pendingPlan, state.pendingSessions, state.pendingFork, state.pendingModel, slashVisible, filteredCommands.length]);
|
|
14750
15295
|
useEffect4(() => {
|
|
14751
15296
|
setQCursor(0);
|
|
14752
15297
|
setQChecked(/* @__PURE__ */ new Set());
|
|
14753
15298
|
}, [state.pendingQuestion]);
|
|
15299
|
+
useEffect4(() => {
|
|
15300
|
+
if (state.pendingModel) {
|
|
15301
|
+
const idx = state.pendingModel.models.indexOf(modelDisplay);
|
|
15302
|
+
setSelectIdx(idx >= 0 ? idx : 0);
|
|
15303
|
+
}
|
|
15304
|
+
}, [state.pendingModel]);
|
|
14754
15305
|
const runLocalSlash = async (text) => {
|
|
14755
15306
|
const [cmd, ...rest] = text.trim().split(/\s+/);
|
|
14756
15307
|
const arg = rest.join(" ");
|
|
@@ -14827,13 +15378,15 @@ ${list}
|
|
|
14827
15378
|
}
|
|
14828
15379
|
case "/model":
|
|
14829
15380
|
if (!arg) {
|
|
14830
|
-
state.pushInfo(
|
|
14831
|
-
\u53EF\u9009\uFF1A${KNOWN_MODELS.join("\u3001")} \u6216\u4EFB\u610F\u6A21\u578B id\u3002`);
|
|
15381
|
+
state.pushInfo(S.modelUsage(modelDisplay));
|
|
14832
15382
|
return true;
|
|
14833
15383
|
}
|
|
14834
15384
|
state.setModelOverride(arg);
|
|
14835
15385
|
setModelDisplay(arg);
|
|
14836
|
-
state.pushInfo(
|
|
15386
|
+
state.pushInfo(S.modelSwitched(arg));
|
|
15387
|
+
return true;
|
|
15388
|
+
case "/switch":
|
|
15389
|
+
void state.openModelPicker();
|
|
14837
15390
|
return true;
|
|
14838
15391
|
case "/thinking": {
|
|
14839
15392
|
const lvl = arg.toLowerCase();
|
|
@@ -14922,7 +15475,7 @@ ${listText}`);
|
|
|
14922
15475
|
const v = inputRef.current.trim();
|
|
14923
15476
|
if (!v) return;
|
|
14924
15477
|
if (busyRef.current) {
|
|
14925
|
-
if (!v.startsWith("/") && state.queueInput(v)) {
|
|
15478
|
+
if (!v.startsWith("/") && !v.startsWith("!") && state.queueInput(v)) {
|
|
14926
15479
|
setInput("");
|
|
14927
15480
|
setCursor(0);
|
|
14928
15481
|
} else {
|
|
@@ -14932,6 +15485,10 @@ ${listText}`);
|
|
|
14932
15485
|
}
|
|
14933
15486
|
setInput("");
|
|
14934
15487
|
setCursor(0);
|
|
15488
|
+
if (v.startsWith("!")) {
|
|
15489
|
+
await state.runBangCommand(v);
|
|
15490
|
+
return;
|
|
15491
|
+
}
|
|
14935
15492
|
if (v.startsWith("/")) {
|
|
14936
15493
|
await executeSlash(v);
|
|
14937
15494
|
return;
|
|
@@ -15020,6 +15577,16 @@ ${listText}`);
|
|
|
15020
15577
|
} else if (key.escape || key.ctrl && ch === "g") state.resolveFork(null);
|
|
15021
15578
|
return;
|
|
15022
15579
|
}
|
|
15580
|
+
if (state.pendingModel) {
|
|
15581
|
+
const list = state.pendingModel.models;
|
|
15582
|
+
if (key.upArrow) setSelectIdx((i) => (i - 1 + list.length) % list.length);
|
|
15583
|
+
else if (key.downArrow) setSelectIdx((i) => (i + 1) % list.length);
|
|
15584
|
+
else if (key.return) {
|
|
15585
|
+
const sel = list[Math.min(selectIdxRef.current, list.length - 1)];
|
|
15586
|
+
state.resolveModel(sel ?? null);
|
|
15587
|
+
} else if (key.escape || key.ctrl && ch === "g") state.resolveModel(null);
|
|
15588
|
+
return;
|
|
15589
|
+
}
|
|
15023
15590
|
if (key.ctrl && ch === "t") {
|
|
15024
15591
|
state.toggleShowThinking();
|
|
15025
15592
|
return;
|
|
@@ -15060,19 +15627,19 @@ ${listText}`);
|
|
|
15060
15627
|
}
|
|
15061
15628
|
});
|
|
15062
15629
|
const sessionShort = state.sessionIdRef.current ? truncateMiddle(state.sessionIdRef.current, 12) : "";
|
|
15063
|
-
return /* @__PURE__ */
|
|
15064
|
-
/* @__PURE__ */
|
|
15065
|
-
/* @__PURE__ */
|
|
15066
|
-
menuActive ? null : /* @__PURE__ */
|
|
15067
|
-
dynamicRows.map((row) => /* @__PURE__ */
|
|
15068
|
-
state.busy ? /* @__PURE__ */
|
|
15630
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
|
|
15631
|
+
/* @__PURE__ */ jsx18(Static, { items: staticItems, children: (item) => item.kind === "__header" ? /* @__PURE__ */ jsx18(TopPanel, { cwd: CWD2, cols }, "header") : /* @__PURE__ */ jsx18(RowView, { row: item, wrapW, streamTail, showThinking: state.showThinkingText }, item.id) }),
|
|
15632
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
|
|
15633
|
+
menuActive ? null : /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, children: [
|
|
15634
|
+
dynamicRows.map((row) => /* @__PURE__ */ jsx18(RowView, { row, wrapW, streamTail, showThinking: state.showThinkingText }, row.id)),
|
|
15635
|
+
state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */ jsxs16(Text18, { color: THEME.coralBright, children: [
|
|
15069
15636
|
"\u25CF ",
|
|
15070
15637
|
S.generating
|
|
15071
15638
|
] }) }) : null
|
|
15072
15639
|
] }),
|
|
15073
|
-
/* @__PURE__ */
|
|
15074
|
-
state.pendingApproval ? /* @__PURE__ */
|
|
15075
|
-
state.pendingQuestion ? /* @__PURE__ */
|
|
15640
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, flexShrink: 0, children: [
|
|
15641
|
+
state.pendingApproval ? /* @__PURE__ */ jsx18(ApprovalModal, { toolName: state.pendingApproval.toolName, detail: state.pendingApproval.detail, selectedIndex: selectIdx, wrapW }) : null,
|
|
15642
|
+
state.pendingQuestion ? /* @__PURE__ */ jsx18(
|
|
15076
15643
|
QuestionModal,
|
|
15077
15644
|
{
|
|
15078
15645
|
question: state.pendingQuestion.req.question,
|
|
@@ -15083,7 +15650,7 @@ ${listText}`);
|
|
|
15083
15650
|
wrapW
|
|
15084
15651
|
}
|
|
15085
15652
|
) : null,
|
|
15086
|
-
state.pendingPlan ? planEditing ? /* @__PURE__ */
|
|
15653
|
+
state.pendingPlan ? planEditing ? /* @__PURE__ */ jsx18(
|
|
15087
15654
|
PlanEditor,
|
|
15088
15655
|
{
|
|
15089
15656
|
value: planDraft,
|
|
@@ -15094,15 +15661,16 @@ ${listText}`);
|
|
|
15094
15661
|
},
|
|
15095
15662
|
onSubmit: confirmPlanEdit
|
|
15096
15663
|
}
|
|
15097
|
-
) : /* @__PURE__ */
|
|
15098
|
-
state.pendingSessions ? /* @__PURE__ */
|
|
15099
|
-
state.pendingFork ? /* @__PURE__ */
|
|
15100
|
-
|
|
15664
|
+
) : /* @__PURE__ */ jsx18(PlanModal, { selectedIndex: selectIdx }) : null,
|
|
15665
|
+
state.pendingSessions ? /* @__PURE__ */ jsx18(SessionPicker, { sessions: state.pendingSessions.sessions, selectedIndex: selectIdx, wrapW }) : null,
|
|
15666
|
+
state.pendingFork ? /* @__PURE__ */ jsx18(ForkPicker, { anchors: state.pendingFork.anchors, selectedIndex: selectIdx, wrapW }) : null,
|
|
15667
|
+
state.pendingModel ? /* @__PURE__ */ jsx18(ModelPicker, { models: state.pendingModel.models, currentModel: modelDisplay, selectedIndex: selectIdx, wrapW }) : null,
|
|
15668
|
+
slashVisible ? /* @__PURE__ */ jsx18(SlashMenu, { entries: filteredCommands, selectedIndex: selectIdx, cols }) : null
|
|
15101
15669
|
] }),
|
|
15102
|
-
/* @__PURE__ */
|
|
15670
|
+
/* @__PURE__ */ jsx18(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1, flexShrink: 0, children: (() => {
|
|
15103
15671
|
const planOn = state.getPlanMode();
|
|
15104
15672
|
const autoOn = !planOn && state.getAutoMode();
|
|
15105
|
-
const inputEl = /* @__PURE__ */
|
|
15673
|
+
const inputEl = /* @__PURE__ */ jsx18(
|
|
15106
15674
|
MultilineInput,
|
|
15107
15675
|
{
|
|
15108
15676
|
value: input,
|
|
@@ -15120,17 +15688,17 @@ ${listText}`);
|
|
|
15120
15688
|
}
|
|
15121
15689
|
);
|
|
15122
15690
|
if (planOn || autoOn) {
|
|
15123
|
-
return /* @__PURE__ */
|
|
15124
|
-
/* @__PURE__ */
|
|
15691
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: planOn ? THEME.thinking : THEME.warn, paddingX: 1, children: [
|
|
15692
|
+
/* @__PURE__ */ jsx18(Text18, { color: planOn ? THEME.thinking : THEME.warn, children: planOn ? S.inputBadgePlan : S.inputBadgeAuto }),
|
|
15125
15693
|
inputEl
|
|
15126
15694
|
] });
|
|
15127
15695
|
}
|
|
15128
|
-
return /* @__PURE__ */
|
|
15129
|
-
/* @__PURE__ */
|
|
15696
|
+
return /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
15697
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, color: THEME.gray, children: dimRule(cols) }),
|
|
15130
15698
|
inputEl
|
|
15131
15699
|
] });
|
|
15132
15700
|
})() }),
|
|
15133
|
-
/* @__PURE__ */
|
|
15701
|
+
/* @__PURE__ */ jsx18(Box16, { paddingX: 1, marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(StatusStrip, { model: modelDisplay, busy: state.busy, aborting: state.aborting, planMode: state.getPlanMode(), autoMode: state.getAutoMode(), sessionShort, cols, customLine: statusLineText }) })
|
|
15134
15702
|
] })
|
|
15135
15703
|
] });
|
|
15136
15704
|
};
|
|
@@ -15190,7 +15758,7 @@ import { render } from "ink";
|
|
|
15190
15758
|
import os5 from "os";
|
|
15191
15759
|
import path42 from "path";
|
|
15192
15760
|
import { emitKeypressEvents } from "node:readline";
|
|
15193
|
-
import { jsx as
|
|
15761
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
15194
15762
|
var parseArgs = (argv) => {
|
|
15195
15763
|
const out = {};
|
|
15196
15764
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -15340,7 +15908,7 @@ var main = async () => {
|
|
|
15340
15908
|
resumeId = await getMostRecentSessionId2() ?? void 0;
|
|
15341
15909
|
}
|
|
15342
15910
|
const { waitUntilExit } = render(
|
|
15343
|
-
/* @__PURE__ */
|
|
15911
|
+
/* @__PURE__ */ jsx19(App2, { resumeSessionId: resumeId, initialPlanMode: args.plan, initialAutoMode: args.auto, initialIncludeProject: includeProject, engineReady }),
|
|
15344
15912
|
// exitOnCtrlC:false:Ctrl+C 交由 App useInput 处理(统一退出/中止语义);
|
|
15345
15913
|
// patchConsole:false:避免 console 劫持与全屏重绘叠加闪屏。
|
|
15346
15914
|
{ exitOnCtrlC: false, patchConsole: false }
|