deepseeker-code 1.0.48 → 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 +857 -276
- 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
|
|
|
@@ -666,7 +682,7 @@ ${body}`;
|
|
|
666
682
|
const oldBody = next?.index !== void 0 ? after.slice(0, next.index) : after;
|
|
667
683
|
if (oldBody === `
|
|
668
684
|
${body}`) return;
|
|
669
|
-
console.warn(`\u26A0\uFE0F ${fence} \u5DF2\u9501\u5B9A\
|
|
685
|
+
console.warn(`\u26A0\uFE0F ${fence} \u5DF2\u9501\u5B9A\uFF08run \u5185\u4E0D\u53D8\u4EE5\u4FDD\u524D\u7F00\u7F13\u5B58\uFF09\uFF0C\u5185\u5BB9\u53D8\u5316\u5C06\u4E8E\u4E0B\u8F6E\u91CD\u5EFA message[0] \u65F6\u751F\u6548\u3002`);
|
|
670
686
|
};
|
|
671
687
|
decodeProcessOutput = (buf) => {
|
|
672
688
|
const utf8 = buf.toString("utf8");
|
|
@@ -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"]
|
|
@@ -5068,7 +5197,7 @@ var init_workflow = __esm({
|
|
|
5068
5197
|
// ../core/src/tool/tsHost.ts
|
|
5069
5198
|
import fsSync3 from "fs";
|
|
5070
5199
|
import path15 from "path";
|
|
5071
|
-
var _ts, _tsTried, getTs, buildDefaultOptions, findTsConfigBounded, resolveTsConfig, createProjectHost, lsCache, getLanguageService, realpathNative, posToLineCol, lineColToPos;
|
|
5200
|
+
var _ts, _tsTried, getTs, buildDefaultOptions, findTsConfigBounded, resolveTsConfig, createProjectHost, lsCache, getLanguageService, realpathNative, posToLineCol, SUPPORTED_SOURCE_EXTS, checkSupportedSourceExt, lineColToPos;
|
|
5072
5201
|
var init_tsHost = __esm({
|
|
5073
5202
|
"../core/src/tool/tsHost.ts"() {
|
|
5074
5203
|
"use strict";
|
|
@@ -5214,6 +5343,12 @@ var init_tsHost = __esm({
|
|
|
5214
5343
|
const { line, character } = ts.getLineAndCharacterOfPosition(sf, pos);
|
|
5215
5344
|
return { line: line + 1, column: character + 1 };
|
|
5216
5345
|
};
|
|
5346
|
+
SUPPORTED_SOURCE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
5347
|
+
checkSupportedSourceExt = (displayPath) => {
|
|
5348
|
+
const ext = path15.extname(displayPath).toLowerCase();
|
|
5349
|
+
if (SUPPORTED_SOURCE_EXTS.has(ext)) return null;
|
|
5350
|
+
return `\u274C [\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301]\uFF1A[${displayPath}] \u7684\u6269\u5C55\u540D ${ext || "(\u65E0)"} \u4E0D\u5728 TS \u5F15\u64CE\u652F\u6301\u8303\u56F4\uFF08\u4EC5 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF09\u3002\u8BF7\u6539\u7528 read_file/grep \u67E5\u770B\u5185\u5BB9\uFF1B\u7F16\u8BD1/\u7C7B\u578B\u7C7B\u9A8C\u8BC1\u7528 run_command \u8DD1\u5BF9\u5E94\u8BED\u8A00\u5DE5\u5177\u94FE\uFF08\u5982 mvn compile / tsc --noEmit\uFF09\u3002`;
|
|
5351
|
+
};
|
|
5217
5352
|
lineColToPos = (ts, sf, line1, col1) => ts.getPositionOfLineAndCharacter(sf, Math.max(0, line1 - 1), Math.max(0, col1 - 1));
|
|
5218
5353
|
}
|
|
5219
5354
|
});
|
|
@@ -5596,23 +5731,23 @@ ${treeResult}`;
|
|
|
5596
5731
|
type: "function",
|
|
5597
5732
|
function: {
|
|
5598
5733
|
name: "edit_file",
|
|
5599
|
-
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",
|
|
5600
5735
|
parameters: {
|
|
5601
5736
|
type: "object",
|
|
5602
5737
|
properties: {
|
|
5603
|
-
path: { type: "string", description: "\
|
|
5604
|
-
old_str: { type: "string", description: "\
|
|
5605
|
-
new_str: { type: "string", description: "\
|
|
5606
|
-
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" },
|
|
5607
5742
|
edits: {
|
|
5608
5743
|
type: "array",
|
|
5609
|
-
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",
|
|
5610
5745
|
items: {
|
|
5611
5746
|
type: "object",
|
|
5612
5747
|
properties: {
|
|
5613
|
-
old_str: { type: "string", description: "\
|
|
5614
|
-
new_str: { type: "string", description: "\
|
|
5615
|
-
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" }
|
|
5616
5751
|
},
|
|
5617
5752
|
required: ["old_str", "new_str"]
|
|
5618
5753
|
}
|
|
@@ -5778,7 +5913,7 @@ ${summaries.join("\n")}`;
|
|
|
5778
5913
|
type: "function",
|
|
5779
5914
|
function: {
|
|
5780
5915
|
name: "write_file",
|
|
5781
|
-
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",
|
|
5782
5917
|
parameters: {
|
|
5783
5918
|
type: "object",
|
|
5784
5919
|
properties: {
|
|
@@ -5816,7 +5951,7 @@ ${summaries.join("\n")}`;
|
|
|
5816
5951
|
type: "function",
|
|
5817
5952
|
function: {
|
|
5818
5953
|
name: "view_symbol_outline",
|
|
5819
|
-
description: "\u901A\u8FC7\u62BD\u8C61\u8BED\u6CD5\u6811(AST)\u5FEB\u901F\u63D0\u53D6\u6307\u5B9A\u6587\u4EF6\u4E2D\u7684\u7B26\u53F7\u5927\u7EB2\uFF08\u7C7B\u3001\u63A5\u53E3\u3001\u51FD\u6570\u540D\u3001\u5BFC\u51FA\u9879\u3001\u5165\u53C2\u7B7E\u540D\u7B49\uFF09\u3002\u9002\u5408\u5728\u4E0D\u8BFB\u53D6\u51E0\u5343\u884C\u5177\u4F53\u4EE3\u7801\u7684\u524D\u63D0\u4E0B\uFF0C\u5B8F\u89C2\u4E86\u89E3\u6587\u4EF6\u67B6\u6784\u3002",
|
|
5954
|
+
description: "\u901A\u8FC7\u62BD\u8C61\u8BED\u6CD5\u6811(AST)\u5FEB\u901F\u63D0\u53D6\u6307\u5B9A TS/JS \u6E90\u6587\u4EF6\u4E2D\u7684\u7B26\u53F7\u5927\u7EB2\uFF08\u7C7B\u3001\u63A5\u53E3\u3001\u51FD\u6570\u540D\u3001\u5BFC\u51FA\u9879\u3001\u5165\u53C2\u7B7E\u540D\u7B49\uFF09\u3002\u9002\u5408\u5728\u4E0D\u8BFB\u53D6\u51E0\u5343\u884C\u5177\u4F53\u4EE3\u7801\u7684\u524D\u63D0\u4E0B\uFF0C\u5B8F\u89C2\u4E86\u89E3\u6587\u4EF6\u67B6\u6784\u3002\u4EC5\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B\u5176\u4ED6\u7C7B\u578B\u6587\u4EF6\uFF08.java/.vue/.py \u7B49\uFF09\u76F4\u63A5\u62D2\u7EDD\uFF0C\u8BF7\u6539\u7528 read_file\u3002",
|
|
5820
5955
|
parameters: {
|
|
5821
5956
|
type: "object",
|
|
5822
5957
|
properties: {
|
|
@@ -5832,6 +5967,8 @@ ${summaries.join("\n")}`;
|
|
|
5832
5967
|
const absPath = resolveReadablePath(args.path);
|
|
5833
5968
|
const readBlock = await assertReadable(absPath, args.path);
|
|
5834
5969
|
if (readBlock) return readBlock;
|
|
5970
|
+
const extBlock = checkSupportedSourceExt(args.path);
|
|
5971
|
+
if (extBlock) return extBlock;
|
|
5835
5972
|
const statForSize = await fs12.stat(absPath);
|
|
5836
5973
|
if (statForSize.size > 1024 * 1024) {
|
|
5837
5974
|
return `\u26A0\uFE0F [\u6587\u4EF6\u8FC7\u5927]\uFF1A[${args.path}] \u7EA6 ${Math.round(statForSize.size / 1024)}KB\uFF0C\u8D85\u8FC7\u7B26\u53F7\u5927\u7EB2\u5206\u6790\u7684 1MB \u4E0A\u9650\uFF08\u9632\u5168\u91CF readFile + AST \u9A7B\u7559\u5403\u5185\u5B58\uFF09\u3002\u8BF7\u6539\u7528 read_file \u5206\u7247\u67E5\u770B\uFF0C\u6216\u7F29\u5C0F\u76EE\u6807\u6587\u4EF6\u3002`;
|
|
@@ -5962,14 +6099,14 @@ var init_search = __esm({
|
|
|
5962
6099
|
type: "function",
|
|
5963
6100
|
function: {
|
|
5964
6101
|
name: "search_grep",
|
|
5965
|
-
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",
|
|
5966
6103
|
parameters: {
|
|
5967
6104
|
type: "object",
|
|
5968
6105
|
properties: {
|
|
5969
|
-
query: { type: "string", description: "\u68C0\u7D22\
|
|
5970
|
-
is_regex: { type: "boolean", description: "
|
|
5971
|
-
path: { type: "string", description: "\u9650\u5B9A\u641C\u7D22\u7684\u76EE\u5F55\u6216\
|
|
5972
|
-
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" }
|
|
5973
6110
|
},
|
|
5974
6111
|
required: ["query"]
|
|
5975
6112
|
},
|
|
@@ -6113,7 +6250,7 @@ ${content}`;
|
|
|
6113
6250
|
|
|
6114
6251
|
// ../core/src/tool/registry/command.ts
|
|
6115
6252
|
import { spawn as spawn4 } from "child_process";
|
|
6116
|
-
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;
|
|
6117
6254
|
var init_command = __esm({
|
|
6118
6255
|
"../core/src/tool/registry/command.ts"() {
|
|
6119
6256
|
"use strict";
|
|
@@ -6124,6 +6261,8 @@ var init_command = __esm({
|
|
|
6124
6261
|
EXIT_SENTINEL = (code) => `
|
|
6125
6262
|
\u27E6DSC_EXIT:${code}\u27E7`;
|
|
6126
6263
|
EXIT_SENTINEL_RE = /⟦DSC_EXIT:(-?\d+)⟧/g;
|
|
6264
|
+
AUTO_BG_NOTICE = "\u27E6DSC_BG\u27E7";
|
|
6265
|
+
AUTO_BG_SENTINEL_RE = /⟦DSC_BG⟧\s*$/;
|
|
6127
6266
|
RUN_COMMAND_MAX_CHARS = 2e4;
|
|
6128
6267
|
commandTools = [
|
|
6129
6268
|
{
|
|
@@ -6148,8 +6287,13 @@ var init_command = __esm({
|
|
|
6148
6287
|
// 💡 我们将在 execute 内部真正落地这个长度限制
|
|
6149
6288
|
verifyResult: (rawOutput) => {
|
|
6150
6289
|
const matches2 = [...rawOutput.matchAll(EXIT_SENTINEL_RE)];
|
|
6151
|
-
const
|
|
6290
|
+
const last = matches2[matches2.length - 1];
|
|
6291
|
+
const code = last ? parseInt(last[1], 10) : null;
|
|
6152
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
|
+
}
|
|
6153
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" : "";
|
|
6154
6298
|
return { status: "failed" /* FAILED */, summary: `\u547D\u4EE4\u9000\u51FA\u7801\u975E\u96F6\uFF1A${code}${hint}` };
|
|
6155
6299
|
},
|
|
@@ -6338,6 +6482,7 @@ ${tail}`,
|
|
|
6338
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
|
|
6339
6483
|
task_id: ${taskId}
|
|
6340
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}
|
|
6341
6486
|
`;
|
|
6342
6487
|
} else if (overLimit) {
|
|
6343
6488
|
yield EXIT_SENTINEL(-1);
|
|
@@ -7259,9 +7404,9 @@ var init_http = __esm({
|
|
|
7259
7404
|
function: {
|
|
7260
7405
|
name: "http_request",
|
|
7261
7406
|
description: [
|
|
7262
|
-
"\u5168\u65B9\u6CD5 HTTP \u5BA2\u6237\u7AEF\
|
|
7263
|
-
"\u4E0E web_fetch \
|
|
7264
|
-
"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"
|
|
7265
7410
|
].join(" "),
|
|
7266
7411
|
parameters: {
|
|
7267
7412
|
type: "object",
|
|
@@ -7357,7 +7502,7 @@ var init_http = __esm({
|
|
|
7357
7502
|
// ../core/src/tool/registry/typescript.ts
|
|
7358
7503
|
import fs16 from "fs/promises";
|
|
7359
7504
|
import path20 from "path";
|
|
7360
|
-
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;
|
|
7361
7506
|
var init_typescript = __esm({
|
|
7362
7507
|
"../core/src/tool/registry/typescript.ts"() {
|
|
7363
7508
|
"use strict";
|
|
@@ -7371,9 +7516,12 @@ var init_typescript = __esm({
|
|
|
7371
7516
|
if (rel && !rel.startsWith("..") && !path20.isAbsolute(rel)) return rel.replace(/\\/g, "/");
|
|
7372
7517
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
7373
7518
|
};
|
|
7519
|
+
isLibFile = (abs) => /(?:^|\/)node_modules\//.test(abs.replace(/\\/g, "/")) || /\.d\.ts$/i.test(abs);
|
|
7374
7520
|
precheck = async (displayPath, absPath) => {
|
|
7375
7521
|
const readBlock = await assertReadable(absPath, displayPath);
|
|
7376
7522
|
if (readBlock) return readBlock;
|
|
7523
|
+
const extBlock = checkSupportedSourceExt(displayPath);
|
|
7524
|
+
if (extBlock) return extBlock;
|
|
7377
7525
|
const stat = await fs16.stat(absPath);
|
|
7378
7526
|
if (stat.size > MAX_FILE_BYTES) {
|
|
7379
7527
|
return `\u26A0\uFE0F [\u6587\u4EF6\u8FC7\u5927]\uFF1A[${displayPath}] \u7EA6 ${Math.round(stat.size / 1024)}KB\uFF0C\u8D85\u8FC7 ${MAX_FILE_BYTES / 1024}KB \u4E0A\u9650\uFF08\u9632\u5168\u91CF type-check \u5403\u5185\u5B58\uFF09\u3002`;
|
|
@@ -7382,6 +7530,8 @@ var init_typescript = __esm({
|
|
|
7382
7530
|
};
|
|
7383
7531
|
MAX_DIAG_ENTRIES = 300;
|
|
7384
7532
|
MAX_DIAG_FILES = 20;
|
|
7533
|
+
MAX_REF_ENTRIES = 200;
|
|
7534
|
+
REF_SNIPPET_MAX = 160;
|
|
7385
7535
|
diagnoseOneFile = async (TS, displayPath, checkJs) => {
|
|
7386
7536
|
try {
|
|
7387
7537
|
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
@@ -7436,7 +7586,7 @@ ${body}${tail}` };
|
|
|
7436
7586
|
type: "function",
|
|
7437
7587
|
function: {
|
|
7438
7588
|
name: "get_diagnostics",
|
|
7439
|
-
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",
|
|
7440
7590
|
parameters: {
|
|
7441
7591
|
type: "object",
|
|
7442
7592
|
properties: {
|
|
@@ -7491,7 +7641,7 @@ ${sections.join("\n\n")}`;
|
|
|
7491
7641
|
type: "function",
|
|
7492
7642
|
function: {
|
|
7493
7643
|
name: "goto_definition",
|
|
7494
|
-
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",
|
|
7495
7645
|
parameters: {
|
|
7496
7646
|
type: "object",
|
|
7497
7647
|
properties: {
|
|
@@ -7531,7 +7681,7 @@ ${sections.join("\n\n")}`;
|
|
|
7531
7681
|
const lc = posToLineCol(TS, defSf, def.textSpan.start);
|
|
7532
7682
|
loc = `${toDisplayPath(wsRoot, def.fileName)}:${lc.line}:${lc.column}`;
|
|
7533
7683
|
}
|
|
7534
|
-
const isLib =
|
|
7684
|
+
const isLib = isLibFile(def.fileName);
|
|
7535
7685
|
const name = def.name || "(anonymous)";
|
|
7536
7686
|
const kind = def.kind ? ` [${def.kind}]` : "";
|
|
7537
7687
|
return `${name}${kind} \u2192 ${loc}${isLib ? " (declaration/library)" : ""}`;
|
|
@@ -7543,6 +7693,97 @@ ${out.join("\n")}`;
|
|
|
7543
7693
|
}
|
|
7544
7694
|
}
|
|
7545
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
|
+
}
|
|
7546
7787
|
}
|
|
7547
7788
|
];
|
|
7548
7789
|
}
|
|
@@ -8518,10 +8759,9 @@ var init_ask = __esm({
|
|
|
8518
8759
|
function: {
|
|
8519
8760
|
name: "ask_question",
|
|
8520
8761
|
description: [
|
|
8521
|
-
"\u5411\u7528\u6237\u63D0\u51FA\
|
|
8522
|
-
"
|
|
8523
|
-
"\
|
|
8524
|
-
"\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"
|
|
8525
8765
|
].join("\n"),
|
|
8526
8766
|
parameters: {
|
|
8527
8767
|
type: "object",
|
|
@@ -8964,30 +9204,30 @@ ${body.trim()}
|
|
|
8964
9204
|
type: "function",
|
|
8965
9205
|
function: {
|
|
8966
9206
|
name: "memory_save",
|
|
8967
|
-
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",
|
|
8968
9208
|
parameters: {
|
|
8969
9209
|
type: "object",
|
|
8970
9210
|
properties: {
|
|
8971
9211
|
name: {
|
|
8972
9212
|
type: "string",
|
|
8973
|
-
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"
|
|
8974
9214
|
},
|
|
8975
9215
|
description: {
|
|
8976
9216
|
type: "string",
|
|
8977
|
-
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"
|
|
8978
9218
|
},
|
|
8979
9219
|
body: {
|
|
8980
9220
|
type: "string",
|
|
8981
|
-
description: "\u8BB0\u5FC6\u6B63\u6587\
|
|
9221
|
+
description: "\u8BB0\u5FC6\u6B63\u6587\uFF0C\u53EF\u591A\u884C\uFF0C\u4E0A\u9650 64KB"
|
|
8982
9222
|
},
|
|
8983
9223
|
type: {
|
|
8984
9224
|
type: "string",
|
|
8985
9225
|
enum: ["user", "feedback", "project", "reference"],
|
|
8986
|
-
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"
|
|
8987
9227
|
},
|
|
8988
9228
|
project: {
|
|
8989
9229
|
type: "boolean",
|
|
8990
|
-
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"
|
|
8991
9231
|
}
|
|
8992
9232
|
},
|
|
8993
9233
|
required: ["name", "description", "body"]
|
|
@@ -9140,7 +9380,7 @@ var init_recall = __esm({
|
|
|
9140
9380
|
type: "function",
|
|
9141
9381
|
function: {
|
|
9142
9382
|
name: "recall",
|
|
9143
|
-
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",
|
|
9144
9384
|
parameters: {
|
|
9145
9385
|
type: "object",
|
|
9146
9386
|
properties: {
|
|
@@ -9620,7 +9860,8 @@ async function runBackgroundTool(gen, lockKey, toolName, signal) {
|
|
|
9620
9860
|
if (lockKey && !acquireLock(lockKey)) {
|
|
9621
9861
|
try {
|
|
9622
9862
|
await gen.return(void 0);
|
|
9623
|
-
} 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);
|
|
9624
9865
|
}
|
|
9625
9866
|
return `\u{1F512} [\u4E92\u65A5\u9501\u963B\u585E]\uFF1A\u9501 [${lockKey}] \u5DF2\u88AB\u5360\u7528\uFF0C[${toolName}] \u672A\u542F\u52A8\u3002`;
|
|
9626
9867
|
}
|
|
@@ -9671,7 +9912,7 @@ var init_backgroundTool = __esm({
|
|
|
9671
9912
|
|
|
9672
9913
|
// ../core/src/tool/autoPermission.ts
|
|
9673
9914
|
import path30 from "path";
|
|
9674
|
-
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;
|
|
9675
9916
|
var init_autoPermission = __esm({
|
|
9676
9917
|
"../core/src/tool/autoPermission.ts"() {
|
|
9677
9918
|
"use strict";
|
|
@@ -9778,12 +10019,25 @@ var init_autoPermission = __esm({
|
|
|
9778
10019
|
// —— 版本号 ——
|
|
9779
10020
|
/^(node|npm|pnpm|npx|git|tsc|python|python3)\s+(-v|-V|--version)\b/,
|
|
9780
10021
|
// —— 验证类(跑项目代码但不改源码)——
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
10022
|
+
// ★ npm/pnpm/npx/yarn 系「跑脚本」命令已整类移出免审清单(isScriptRunnerCommand 单独治理,见下方):
|
|
10023
|
+
// package.json scripts 是仓库作者的任意代码、npx 未装包时还会从 registry 拉取执行——
|
|
10024
|
+
// hasShellMetachars 检查的是命令串本身,拦不到脚本内容(恶意 repo 投毒面)。
|
|
10025
|
+
// 改走「首次人工确认 + allow-always 按精确命令串记住」路径(toolExecution 的 scriptRunnerBlocked 门)。
|
|
9785
10026
|
/^tsc --noEmit\b/
|
|
9786
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
|
+
};
|
|
9787
10041
|
hasWriteModifier = (cmd) => {
|
|
9788
10042
|
if (!cmd) return false;
|
|
9789
10043
|
if (/^sed\b/.test(cmd) && /(^|\s)-i\b/.test(cmd)) return true;
|
|
@@ -9940,7 +10194,7 @@ var init_toolExecution = __esm({
|
|
|
9940
10194
|
preHooksAdvanced = true;
|
|
9941
10195
|
let veto;
|
|
9942
10196
|
try {
|
|
9943
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10197
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
9944
10198
|
} catch (e) {
|
|
9945
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` };
|
|
9946
10200
|
}
|
|
@@ -9972,7 +10226,20 @@ var init_toolExecution = __esm({
|
|
|
9972
10226
|
} catch {
|
|
9973
10227
|
perm = null;
|
|
9974
10228
|
}
|
|
9975
|
-
|
|
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 : "")) {
|
|
9976
10243
|
needApproval = false;
|
|
9977
10244
|
}
|
|
9978
10245
|
if ((calledName === "run_command" || calledName === "run_in_background") && matchCommandDeny(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
@@ -9985,7 +10252,7 @@ var init_toolExecution = __esm({
|
|
|
9985
10252
|
denied = true;
|
|
9986
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`;
|
|
9987
10254
|
}
|
|
9988
|
-
if (needApproval && !denied) {
|
|
10255
|
+
if (needApproval && !denied && !scriptRunnerBlocked) {
|
|
9989
10256
|
const auto = await runAutoCheck(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx, permissionMode === "auto");
|
|
9990
10257
|
if (auto === "allow") {
|
|
9991
10258
|
needApproval = false;
|
|
@@ -10020,7 +10287,7 @@ var init_toolExecution = __esm({
|
|
|
10020
10287
|
if (!denied && !preHooksAdvanced) {
|
|
10021
10288
|
let veto;
|
|
10022
10289
|
try {
|
|
10023
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10290
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
10024
10291
|
} catch (e) {
|
|
10025
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` };
|
|
10026
10293
|
}
|
|
@@ -10062,7 +10329,7 @@ ${result}`;
|
|
|
10062
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 } });
|
|
10063
10330
|
}
|
|
10064
10331
|
try {
|
|
10065
|
-
const post = await runPostHooks(calledName, calledArgs, result, toolCtx);
|
|
10332
|
+
const post = await runPostHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, result, toolCtx);
|
|
10066
10333
|
postHookOverride = post?.resultOverride;
|
|
10067
10334
|
} catch (e) {
|
|
10068
10335
|
console.warn(`\u26A0\uFE0F post-hook [${calledName}] \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09:`, e?.message ?? e);
|
|
@@ -10222,7 +10489,8 @@ var init_toolScheduling = __esm({
|
|
|
10222
10489
|
});
|
|
10223
10490
|
|
|
10224
10491
|
// ../core/src/agent/streamInference.ts
|
|
10225
|
-
|
|
10492
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
10493
|
+
var sha1short, RETRY_BACKOFF_CAP_MS, extractRetryAfterMs, withNudgeTail, streamInference;
|
|
10226
10494
|
var init_streamInference = __esm({
|
|
10227
10495
|
"../core/src/agent/streamInference.ts"() {
|
|
10228
10496
|
"use strict";
|
|
@@ -10231,6 +10499,32 @@ var init_streamInference = __esm({
|
|
|
10231
10499
|
init_transcript();
|
|
10232
10500
|
init_contextCore();
|
|
10233
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
|
+
};
|
|
10234
10528
|
streamInference = async function* (ctx) {
|
|
10235
10529
|
const {
|
|
10236
10530
|
message,
|
|
@@ -10248,16 +10542,24 @@ var init_streamInference = __esm({
|
|
|
10248
10542
|
events,
|
|
10249
10543
|
keepRecentUnits,
|
|
10250
10544
|
compactRatio,
|
|
10251
|
-
modelWindow
|
|
10545
|
+
modelWindow,
|
|
10546
|
+
toolsTokens = 0
|
|
10252
10547
|
} = ctx;
|
|
10253
|
-
let inferenceMessages =
|
|
10548
|
+
let inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10254
10549
|
let assistantMessage = { role: "assistant", content: null };
|
|
10255
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
|
+
};
|
|
10256
10557
|
events({
|
|
10257
10558
|
sessionId,
|
|
10258
10559
|
eventType: "llm.request",
|
|
10259
|
-
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
10260
|
-
|
|
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 },
|
|
10261
10563
|
payload: { input: msgText(message[message.length - 1].content) }
|
|
10262
10564
|
// ★ 多模态:trace 只记文本视图
|
|
10263
10565
|
});
|
|
@@ -10267,7 +10569,7 @@ var init_streamInference = __esm({
|
|
|
10267
10569
|
const toolCallsBuf = /* @__PURE__ */ new Map();
|
|
10268
10570
|
let lastUsage;
|
|
10269
10571
|
const MAX_STREAM_RETRIES = 2;
|
|
10270
|
-
const MAX_API_RETRIES =
|
|
10572
|
+
const MAX_API_RETRIES = 3;
|
|
10271
10573
|
let apiRetries = 0;
|
|
10272
10574
|
let compactedThisRound = false;
|
|
10273
10575
|
for (let streamAttempt = 0; ; streamAttempt++) {
|
|
@@ -10327,10 +10629,15 @@ var init_streamInference = __esm({
|
|
|
10327
10629
|
}
|
|
10328
10630
|
if (activeProvider.isTransientError(streamErr) && apiRetries < MAX_API_RETRIES && !signal?.aborted) {
|
|
10329
10631
|
apiRetries++;
|
|
10330
|
-
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
|
+
);
|
|
10331
10637
|
if (!noOutputYet) yield { type: "text.reset" };
|
|
10332
10638
|
const statusHint = streamErr?.status ? `${streamErr.status} ` : "";
|
|
10333
|
-
|
|
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}...`);
|
|
10334
10641
|
await new Promise((resolve, reject) => {
|
|
10335
10642
|
const t = setTimeout(resolve, backoffMs);
|
|
10336
10643
|
signal?.addEventListener("abort", () => {
|
|
@@ -10354,9 +10661,10 @@ var init_streamInference = __esm({
|
|
|
10354
10661
|
modelWindow,
|
|
10355
10662
|
events,
|
|
10356
10663
|
depth,
|
|
10357
|
-
signal
|
|
10664
|
+
signal,
|
|
10665
|
+
toolsTokens
|
|
10358
10666
|
});
|
|
10359
|
-
inferenceMessages =
|
|
10667
|
+
inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10360
10668
|
compactedThisRound = true;
|
|
10361
10669
|
contentBuf = "";
|
|
10362
10670
|
reasoningBuf = "";
|
|
@@ -10437,12 +10745,12 @@ var init_agentNudges = __esm({
|
|
|
10437
10745
|
GREP_REPEAT_THRESHOLD = 2;
|
|
10438
10746
|
REPEAT_NUDGE_MAX = 3;
|
|
10439
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";
|
|
10440
|
-
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`;
|
|
10441
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";
|
|
10442
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`;
|
|
10443
|
-
COMPLEX_VERBS =
|
|
10444
|
-
COMPLEX_OBJECTS =
|
|
10445
|
-
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;
|
|
10446
10754
|
QUERY_LEAD = /^(请)?\s*(解释|说明|查(一下|询)?|搜索|搜一下|怎么看|如何(用|使用|配置|启动)|怎么用|为什么|是什么|帮我看看|分析一下|检查|review|对比|评价)/i;
|
|
10447
10755
|
looksComplex = (text) => {
|
|
10448
10756
|
const t = (text || "").trim();
|
|
@@ -10470,7 +10778,7 @@ var init_agentNudges = __esm({
|
|
|
10470
10778
|
return s;
|
|
10471
10779
|
};
|
|
10472
10780
|
normQuery = (q) => String(q ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
10473
|
-
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`;
|
|
10474
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`;
|
|
10475
10783
|
createNudgeScheduler = (opts = {}) => {
|
|
10476
10784
|
const firstPrompt = opts.firstPrompt ?? "";
|
|
@@ -10538,7 +10846,7 @@ ${TOOL_DIGEST_TEXT}` };
|
|
|
10538
10846
|
${PHANTOM_TEXT}` };
|
|
10539
10847
|
return true;
|
|
10540
10848
|
}
|
|
10541
|
-
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)) {
|
|
10542
10850
|
earlyFinalNudges++;
|
|
10543
10851
|
earlyFinalPending = { role: "system", content: `${EARLY_FINAL_FENCE}
|
|
10544
10852
|
${EARLY_FINAL_TEXT(round)}` };
|
|
@@ -10598,10 +10906,11 @@ ${REPEAT_GREP_TEXT(q, n)}` };
|
|
|
10598
10906
|
// ../core/src/agent/runAgent.ts
|
|
10599
10907
|
async function* runAgent(message, options) {
|
|
10600
10908
|
const sessionId = options.sessionId;
|
|
10909
|
+
const runId = createUUID();
|
|
10601
10910
|
const rawEvents = options.events;
|
|
10602
10911
|
const events = async (base) => {
|
|
10603
10912
|
try {
|
|
10604
|
-
await rawEvents(base);
|
|
10913
|
+
await rawEvents({ ...base, metadata: { ...base.metadata, runId } });
|
|
10605
10914
|
} catch (e) {
|
|
10606
10915
|
console.warn("\u26A0\uFE0F \u57CB\u70B9\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u63A8\u7406\uFF09:", e instanceof Error ? e.message : e);
|
|
10607
10916
|
}
|
|
@@ -10613,7 +10922,7 @@ async function* runAgent(message, options) {
|
|
|
10613
10922
|
const keepRecentUnits = options.keepRecentUnits;
|
|
10614
10923
|
const compactRatio = options.compactRatio;
|
|
10615
10924
|
const parentSystemPrompt = options.parentSystemPrompt;
|
|
10616
|
-
const { rawTools, cleanedToolSchemas } = await prepareToolsAndInjections(message, options, events);
|
|
10925
|
+
const { rawTools, cleanedToolSchemas, toolsTokens } = await prepareToolsAndInjections(message, options, events);
|
|
10617
10926
|
let round = 0;
|
|
10618
10927
|
let lastContent = "";
|
|
10619
10928
|
let stopReason = "normal";
|
|
@@ -10632,7 +10941,6 @@ async function* runAgent(message, options) {
|
|
|
10632
10941
|
let lastRealPromptTokens = persistedCalib.lastRealPromptTokens;
|
|
10633
10942
|
let lastCachedTokens = persistedCalib.lastCachedTokens;
|
|
10634
10943
|
const breaker = createRepeatBreaker({ sessionId, depth, llmDecisionSource, startTime, events });
|
|
10635
|
-
const runId = createUUID();
|
|
10636
10944
|
let usageSum;
|
|
10637
10945
|
const addUsage = (u) => {
|
|
10638
10946
|
if (!u) return;
|
|
@@ -10693,7 +11001,8 @@ async function* runAgent(message, options) {
|
|
|
10693
11001
|
signal,
|
|
10694
11002
|
correctionRatio: calibRatio,
|
|
10695
11003
|
lastRealPromptTokens,
|
|
10696
|
-
lastCachedTokens
|
|
11004
|
+
lastCachedTokens,
|
|
11005
|
+
toolsTokens
|
|
10697
11006
|
}
|
|
10698
11007
|
);
|
|
10699
11008
|
} catch (e) {
|
|
@@ -10725,7 +11034,8 @@ async function* runAgent(message, options) {
|
|
|
10725
11034
|
events,
|
|
10726
11035
|
keepRecentUnits,
|
|
10727
11036
|
compactRatio,
|
|
10728
|
-
modelWindow
|
|
11037
|
+
modelWindow,
|
|
11038
|
+
toolsTokens
|
|
10729
11039
|
});
|
|
10730
11040
|
if (infResult.kind === "aborted") {
|
|
10731
11041
|
yield { type: "final", text: infResult.partialText || lastContent || "\uFF08\u5DF2\u4E2D\u6B62\uFF09" };
|
|
@@ -10737,7 +11047,7 @@ async function* runAgent(message, options) {
|
|
|
10737
11047
|
return;
|
|
10738
11048
|
}
|
|
10739
11049
|
if (infResult.usage?.prompt_tokens) {
|
|
10740
|
-
const estAtInfer = estimateTokens(message);
|
|
11050
|
+
const estAtInfer = estimateTokens(message) + toolsTokens;
|
|
10741
11051
|
if (estAtInfer > 1e3) {
|
|
10742
11052
|
const observed = infResult.usage.prompt_tokens / estAtInfer;
|
|
10743
11053
|
calibRatio = calibRatio * 0.6 + observed * 0.4;
|
|
@@ -10827,11 +11137,13 @@ async function* runAgent(message, options) {
|
|
|
10827
11137
|
try {
|
|
10828
11138
|
const reason = signal?.aborted ? "aborted" : stopReason;
|
|
10829
11139
|
await dispatch("Stop", { sessionId, cwd, lastText: lastContent || "", reason });
|
|
10830
|
-
} 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);
|
|
10831
11142
|
}
|
|
10832
11143
|
try {
|
|
10833
11144
|
await updateCalibration(sessionId, { calibRatio, lastRealPromptTokens, lastCachedTokens });
|
|
10834
|
-
} 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);
|
|
10835
11147
|
}
|
|
10836
11148
|
}
|
|
10837
11149
|
}
|
|
@@ -10974,9 +11286,9 @@ var init_content = __esm({
|
|
|
10974
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]");
|
|
10975
11287
|
});
|
|
10976
11288
|
};
|
|
10977
|
-
NO_VISION_IMAGE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\
|
|
10978
|
-
enforceVisionGate = (msgs) => isVisionEnabled() ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
10979
|
-
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) => {
|
|
10980
11292
|
const lines = await readTranscriptLines(sessionId);
|
|
10981
11293
|
const store = await getRollingState(sessionId);
|
|
10982
11294
|
const eventAware = appConfig.transcriptEvents || lines.some(isEventLine);
|
|
@@ -10995,12 +11307,12 @@ var init_content = __esm({
|
|
|
10995
11307
|
const messageAll = all.slice(archivedMessageCount);
|
|
10996
11308
|
if (messageAll.length === 0) {
|
|
10997
11309
|
result.push(currentUserMsg);
|
|
10998
|
-
return enforceVisionGate(result);
|
|
11310
|
+
return enforceVisionGate(result, modelId);
|
|
10999
11311
|
}
|
|
11000
11312
|
const repair = repairOrphanToolCalls(messageAll, recovery.interruption.kind === "crashed");
|
|
11001
11313
|
result.push(...decayOldToolResults(repair.msgs));
|
|
11002
11314
|
result.push(currentUserMsg);
|
|
11003
|
-
return enforceVisionGate(result);
|
|
11315
|
+
return enforceVisionGate(result, modelId);
|
|
11004
11316
|
};
|
|
11005
11317
|
}
|
|
11006
11318
|
});
|
|
@@ -11161,7 +11473,7 @@ var init_subagent = __esm({
|
|
|
11161
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)}..."`);
|
|
11162
11474
|
activeSubagents.add(subSessionId);
|
|
11163
11475
|
try {
|
|
11164
|
-
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem);
|
|
11476
|
+
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem, manifest?.model);
|
|
11165
11477
|
await appendMessage({ sessionId: subSessionId, role: "user", content: task });
|
|
11166
11478
|
let subResult = "";
|
|
11167
11479
|
let hasFinalResult = false;
|
|
@@ -11338,7 +11650,7 @@ var init_loader4 = __esm({
|
|
|
11338
11650
|
console.warn(`\u26A0\uFE0F [hooks] ${where} \u975E\u5DE5\u5177\u4E8B\u4EF6\u4E0D\u652F\u6301 matcher\uFF0C\u5DF2\u5FFD\u7565`);
|
|
11339
11651
|
}
|
|
11340
11652
|
const matcher = TOOL_EVENTS.has(event) && typeof raw.matcher === "string" ? raw.matcher : void 0;
|
|
11341
|
-
const
|
|
11653
|
+
const timeoutMs2 = typeof raw.timeoutMs === "number" && raw.timeoutMs > 0 ? raw.timeoutMs : void 0;
|
|
11342
11654
|
let denyOnNonZero = typeof raw.denyOnNonZero === "boolean" ? raw.denyOnNonZero : void 0;
|
|
11343
11655
|
if (denyOnNonZero === true && !INTERCEPTABLE_EVENTS.has(event)) {
|
|
11344
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`);
|
|
@@ -11366,7 +11678,7 @@ var init_loader4 = __esm({
|
|
|
11366
11678
|
text: type === "prompt" && typeof raw.text === "string" ? raw.text : void 0,
|
|
11367
11679
|
task: type === "agent" && typeof raw.task === "string" ? raw.task : void 0,
|
|
11368
11680
|
matcher,
|
|
11369
|
-
timeoutMs,
|
|
11681
|
+
timeoutMs: timeoutMs2,
|
|
11370
11682
|
denyOnNonZero,
|
|
11371
11683
|
onError,
|
|
11372
11684
|
requireApproval: raw.requireApproval === true ? true : void 0
|
|
@@ -11374,9 +11686,12 @@ var init_loader4 = __esm({
|
|
|
11374
11686
|
};
|
|
11375
11687
|
parseStdoutDecision = (stdout) => {
|
|
11376
11688
|
const s = (stdout ?? "").trim();
|
|
11377
|
-
if (!s
|
|
11689
|
+
if (!s) return void 0;
|
|
11690
|
+
const match = s.match(/\{[\s\S]*\}$/);
|
|
11691
|
+
if (!match) return void 0;
|
|
11692
|
+
const jsonStr = match[0];
|
|
11378
11693
|
try {
|
|
11379
|
-
const parsed = JSON.parse(
|
|
11694
|
+
const parsed = JSON.parse(jsonStr);
|
|
11380
11695
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return void 0;
|
|
11381
11696
|
const out = {};
|
|
11382
11697
|
if (parsed.deny === true) {
|
|
@@ -11406,7 +11721,7 @@ var init_loader4 = __esm({
|
|
|
11406
11721
|
};
|
|
11407
11722
|
compileRule2 = (event, raw) => {
|
|
11408
11723
|
const denyOnNonZero = raw.denyOnNonZero ?? event === "PreToolUse";
|
|
11409
|
-
const
|
|
11724
|
+
const timeoutMs2 = raw.timeoutMs ?? DEFAULT_TIMEOUT_BY_EVENT[event];
|
|
11410
11725
|
const base = { event, matcher: raw.matcher, source: "config", onError: raw.onError };
|
|
11411
11726
|
if (raw.type === "prompt") {
|
|
11412
11727
|
const text = raw.text;
|
|
@@ -11451,7 +11766,7 @@ var init_loader4 = __esm({
|
|
|
11451
11766
|
headers: raw.headers,
|
|
11452
11767
|
body: ctx,
|
|
11453
11768
|
// 整个 hook 上下文 JSON 化发出(含 sessionId/toolName/args/prompt 等)
|
|
11454
|
-
timeoutMs
|
|
11769
|
+
timeoutMs: timeoutMs2
|
|
11455
11770
|
});
|
|
11456
11771
|
if (!res.ok) {
|
|
11457
11772
|
return denyOnNonZero ? { deny: true, reason: `hook http \u8BF7\u6C42\u5931\u8D25\uFF1A${res.error}` } : { deny: false };
|
|
@@ -11485,11 +11800,11 @@ var init_loader4 = __esm({
|
|
|
11485
11800
|
command,
|
|
11486
11801
|
cwd: ctx?.cwd,
|
|
11487
11802
|
env: ctx?.env,
|
|
11488
|
-
timeoutMs,
|
|
11803
|
+
timeoutMs: timeoutMs2,
|
|
11489
11804
|
stdinPayload: ctx
|
|
11490
11805
|
});
|
|
11491
11806
|
if (res.timedOut) {
|
|
11492
|
-
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 };
|
|
11493
11808
|
}
|
|
11494
11809
|
if (denyOnNonZero && res.exitCode !== 0) {
|
|
11495
11810
|
const detail = res.stderr ? `\uFF1A${res.stderr.slice(0, 200)}` : "";
|
|
@@ -11511,9 +11826,7 @@ var init_loader4 = __esm({
|
|
|
11511
11826
|
if (!list || list.length === 0) continue;
|
|
11512
11827
|
for (const raw of list) compiled.push(compileRule2(event, raw));
|
|
11513
11828
|
}
|
|
11514
|
-
|
|
11515
|
-
registerHooks(compiled);
|
|
11516
|
-
}
|
|
11829
|
+
replaceDeclarativeHooks(compiled);
|
|
11517
11830
|
return compiled.length;
|
|
11518
11831
|
};
|
|
11519
11832
|
initHooks = async (includeProject) => {
|
|
@@ -12090,14 +12403,6 @@ var init_runner = __esm({
|
|
|
12090
12403
|
}
|
|
12091
12404
|
});
|
|
12092
12405
|
|
|
12093
|
-
// ../core/src/llm/createModel.ts
|
|
12094
|
-
var init_createModel = __esm({
|
|
12095
|
-
"../core/src/llm/createModel.ts"() {
|
|
12096
|
-
"use strict";
|
|
12097
|
-
init_client();
|
|
12098
|
-
}
|
|
12099
|
-
});
|
|
12100
|
-
|
|
12101
12406
|
// ../core/src/observability/store.ts
|
|
12102
12407
|
import path39 from "path";
|
|
12103
12408
|
import fs37 from "fs/promises";
|
|
@@ -12414,11 +12719,12 @@ var init_systemPrompt = __esm({
|
|
|
12414
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
|
|
12415
12720
|
|
|
12416
12721
|
\u3010\u56DE\u7B54\u51C6\u5219 / \u5B8C\u6210\u5224\u5B9A\u3011
|
|
12417
|
-
- \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
|
|
12418
|
-
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
- **\
|
|
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
|
|
12422
12728
|
|
|
12423
12729
|
\u3010\u5DE5\u5177\u4F7F\u7528\u51C6\u5219\u3011
|
|
12424
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
|
|
@@ -12519,18 +12825,29 @@ ${lines.join("\n")}
|
|
|
12519
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
|
|
12520
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`;
|
|
12521
12827
|
}
|
|
12522
|
-
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
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 + `
|
|
12526
12839
|
|
|
12527
|
-
\
|
|
12528
|
-
|
|
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);
|
|
12529
12844
|
try {
|
|
12530
12845
|
const fullMessages = await buildContextMessages(
|
|
12531
12846
|
sessionId,
|
|
12532
12847
|
{ role: "user", content: userContent },
|
|
12533
|
-
sysPrompt
|
|
12848
|
+
sysPrompt,
|
|
12849
|
+
opts?.model
|
|
12850
|
+
// ★ vision 自动判定与实际请求模型(opts.model ?? MODEL_NAME)同源
|
|
12534
12851
|
);
|
|
12535
12852
|
await emitTrace({
|
|
12536
12853
|
sessionId,
|
|
@@ -12542,7 +12859,7 @@ ${lines.join("\n")}
|
|
|
12542
12859
|
});
|
|
12543
12860
|
void sweepStaleAtomicTmp().catch(() => {
|
|
12544
12861
|
});
|
|
12545
|
-
await appendMessage({ sessionId, role: "user", content:
|
|
12862
|
+
await appendMessage({ sessionId, role: "user", content: archiveContent });
|
|
12546
12863
|
let streamedAnyText = false;
|
|
12547
12864
|
const onUIEvent = opts?.onUIEvent ?? ((evt) => sseWrite?.(evt));
|
|
12548
12865
|
const requestApproval2 = opts?.requestApproval ?? createWebRequestApproval((evt) => sseWrite?.(evt), abortSignal);
|
|
@@ -12731,6 +13048,75 @@ var init_fork = __esm({
|
|
|
12731
13048
|
}
|
|
12732
13049
|
});
|
|
12733
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
|
+
|
|
12734
13120
|
// src/cliHost.ts
|
|
12735
13121
|
var createCliRequestApproval, createCliRequestQuestion;
|
|
12736
13122
|
var init_cliHost = __esm({
|
|
@@ -12925,9 +13311,12 @@ var init_useChatState = __esm({
|
|
|
12925
13311
|
init_fork();
|
|
12926
13312
|
init_inbox();
|
|
12927
13313
|
init_contextCore();
|
|
13314
|
+
init_bashDirect();
|
|
13315
|
+
init_guard();
|
|
12928
13316
|
init_createModel();
|
|
12929
13317
|
init_tool();
|
|
12930
13318
|
init_cliHost();
|
|
13319
|
+
init_prefs();
|
|
12931
13320
|
init_strings();
|
|
12932
13321
|
init_util();
|
|
12933
13322
|
init_replay2();
|
|
@@ -12949,6 +13338,7 @@ var init_useChatState = __esm({
|
|
|
12949
13338
|
const [pendingPlan, setPendingPlan] = useState(null);
|
|
12950
13339
|
const [pendingSessions, setPendingSessions] = useState(null);
|
|
12951
13340
|
const [pendingFork, setPendingFork] = useState(null);
|
|
13341
|
+
const [pendingModel, setPendingModel] = useState(null);
|
|
12952
13342
|
const nextId = useRef(1);
|
|
12953
13343
|
const assistantStreamingId = useRef(null);
|
|
12954
13344
|
const thinkingStreamingId = useRef(null);
|
|
@@ -13320,6 +13710,22 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13320
13710
|
if (turnGenRef.current === myGen) setBusy(false);
|
|
13321
13711
|
}
|
|
13322
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]);
|
|
13323
13729
|
const abortCurrent = useCallback(() => {
|
|
13324
13730
|
const ac = currentAcRef.current;
|
|
13325
13731
|
if (!ac) return;
|
|
@@ -13403,7 +13809,21 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13403
13809
|
}, [pushInfo, loadSession]);
|
|
13404
13810
|
const setModelOverride = useCallback((m) => {
|
|
13405
13811
|
modelRef.current = m;
|
|
13812
|
+
void writePrefs({ model: m });
|
|
13406
13813
|
}, []);
|
|
13814
|
+
const resolveModel = useCallback((model2) => {
|
|
13815
|
+
setPendingModel((prev) => {
|
|
13816
|
+
prev?.resolve(model2);
|
|
13817
|
+
return null;
|
|
13818
|
+
});
|
|
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]);
|
|
13407
13827
|
const setPlanMode = useCallback((on) => {
|
|
13408
13828
|
planModeRef.current = on;
|
|
13409
13829
|
}, []);
|
|
@@ -13431,6 +13851,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13431
13851
|
pendingPlan,
|
|
13432
13852
|
pendingSessions,
|
|
13433
13853
|
pendingFork,
|
|
13854
|
+
pendingModel,
|
|
13434
13855
|
sessionIdRef,
|
|
13435
13856
|
// 动作
|
|
13436
13857
|
submit,
|
|
@@ -13439,6 +13860,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13439
13860
|
pushUser,
|
|
13440
13861
|
pushInfo,
|
|
13441
13862
|
pushEvent,
|
|
13863
|
+
runBangCommand,
|
|
13442
13864
|
askApproval,
|
|
13443
13865
|
resolveApproval,
|
|
13444
13866
|
resolveQuestion,
|
|
@@ -13459,7 +13881,9 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13459
13881
|
resolveSession,
|
|
13460
13882
|
loadSession,
|
|
13461
13883
|
openForkPicker,
|
|
13462
|
-
resolveFork
|
|
13884
|
+
resolveFork,
|
|
13885
|
+
openModelPicker,
|
|
13886
|
+
resolveModel
|
|
13463
13887
|
};
|
|
13464
13888
|
};
|
|
13465
13889
|
}
|
|
@@ -13548,7 +13972,7 @@ var init_StreamingCursor = __esm({
|
|
|
13548
13972
|
// src/components/MessageBlock.tsx
|
|
13549
13973
|
import { Box, Text as Text3 } from "ink";
|
|
13550
13974
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
13551
|
-
var UsageFooter, listPrefix, AssistantLine, MessageBlock;
|
|
13975
|
+
var UsageFooter, listPrefix, AssistantLine, isFenceMark, isMdRow, isMdSep, mdCells, parseBlocks, fitCell, tableWidths, buildVLines, AssistantVLine, MessageBlock;
|
|
13552
13976
|
var init_MessageBlock = __esm({
|
|
13553
13977
|
"src/components/MessageBlock.tsx"() {
|
|
13554
13978
|
"use strict";
|
|
@@ -13587,6 +14011,94 @@ var init_MessageBlock = __esm({
|
|
|
13587
14011
|
}
|
|
13588
14012
|
return /* @__PURE__ */ jsx3(RichText, { text: line });
|
|
13589
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
|
+
};
|
|
13590
14102
|
MessageBlock = ({ row, wrapW, streamTail }) => {
|
|
13591
14103
|
if (row.kind === "meta") {
|
|
13592
14104
|
if (/^第 \d+ 轮$/.test(row.text)) {
|
|
@@ -13603,15 +14115,15 @@ var init_MessageBlock = __esm({
|
|
|
13603
14115
|
] }) });
|
|
13604
14116
|
}
|
|
13605
14117
|
if (row.kind === "info") {
|
|
13606
|
-
const
|
|
13607
|
-
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: [
|
|
13608
14120
|
j === 0 ? "\u203A " : " ",
|
|
13609
14121
|
line
|
|
13610
14122
|
] }, j)) });
|
|
13611
14123
|
}
|
|
13612
14124
|
if (row.kind === "user") {
|
|
13613
|
-
const
|
|
13614
|
-
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: [
|
|
13615
14127
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.coralBright, bold: true, children: "> " }),
|
|
13616
14128
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.white, children: line })
|
|
13617
14129
|
] }) : /* @__PURE__ */ jsxs(Text3, { color: THEME.white, children: [
|
|
@@ -13620,19 +14132,19 @@ var init_MessageBlock = __esm({
|
|
|
13620
14132
|
] }) }, j)) });
|
|
13621
14133
|
}
|
|
13622
14134
|
if (row.kind === "system") {
|
|
13623
|
-
const
|
|
13624
|
-
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: [
|
|
13625
14137
|
j === 0 ? "! " : " ",
|
|
13626
14138
|
line
|
|
13627
14139
|
] }, j)) });
|
|
13628
14140
|
}
|
|
13629
14141
|
const contentW = Math.max(8, wrapW - 2);
|
|
13630
|
-
const allLines =
|
|
13631
|
-
let
|
|
14142
|
+
const allLines = buildVLines(row.text, contentW);
|
|
14143
|
+
let vlines = allLines;
|
|
13632
14144
|
let folded = 0;
|
|
13633
14145
|
if (row.streaming && streamTail && allLines.length > streamTail) {
|
|
13634
14146
|
folded = allLines.length - streamTail;
|
|
13635
|
-
|
|
14147
|
+
vlines = allLines.slice(folded);
|
|
13636
14148
|
}
|
|
13637
14149
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: [
|
|
13638
14150
|
folded > 0 ? /* @__PURE__ */ jsxs(Text3, { color: THEME.grayDim, children: [
|
|
@@ -13640,11 +14152,11 @@ var init_MessageBlock = __esm({
|
|
|
13640
14152
|
folded,
|
|
13641
14153
|
" \u884C\u2026"
|
|
13642
14154
|
] }) : null,
|
|
13643
|
-
|
|
13644
|
-
const isLast = j ===
|
|
14155
|
+
vlines.map((v, j) => {
|
|
14156
|
+
const isLast = j === vlines.length - 1;
|
|
13645
14157
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
13646
14158
|
/* @__PURE__ */ jsx3(Text3, { bold: true, color: THEME.coralBright, children: j === 0 ? "\u25CF " : " " }),
|
|
13647
|
-
/* @__PURE__ */ jsx3(
|
|
14159
|
+
/* @__PURE__ */ jsx3(AssistantVLine, { v }),
|
|
13648
14160
|
isLast && row.streaming ? /* @__PURE__ */ jsx3(StreamingCursor, {}) : null
|
|
13649
14161
|
] }, j);
|
|
13650
14162
|
}),
|
|
@@ -14268,9 +14780,44 @@ var init_ForkPicker = __esm({
|
|
|
14268
14780
|
}
|
|
14269
14781
|
});
|
|
14270
14782
|
|
|
14271
|
-
// src/components/
|
|
14783
|
+
// src/components/ModelPicker.tsx
|
|
14272
14784
|
import { Box as Box12, Text as Text14 } from "ink";
|
|
14273
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";
|
|
14274
14821
|
var MAX_ROWS, SlashMenu;
|
|
14275
14822
|
var init_SlashMenu = __esm({
|
|
14276
14823
|
"src/components/SlashMenu.tsx"() {
|
|
@@ -14282,22 +14829,22 @@ var init_SlashMenu = __esm({
|
|
|
14282
14829
|
const visible = entries.slice(start, start + MAX_ROWS);
|
|
14283
14830
|
const cmdW = Math.min(22, Math.max(8, ...visible.map((e) => e.name.length)) + 1);
|
|
14284
14831
|
const descMax = Math.max(12, cols - cmdW - 6);
|
|
14285
|
-
return /* @__PURE__ */
|
|
14832
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: THEME.coral, paddingX: 1, paddingY: 0, marginTop: 1, children: [
|
|
14286
14833
|
visible.map((e, i) => {
|
|
14287
14834
|
const active = i + start === selectedIndex;
|
|
14288
14835
|
const desc = e.description.length > descMax ? `${e.description.slice(0, descMax - 1)}\u2026` : e.description;
|
|
14289
14836
|
const gap = Math.max(1, cmdW - e.name.length);
|
|
14290
|
-
return /* @__PURE__ */
|
|
14291
|
-
/* @__PURE__ */
|
|
14292
|
-
/* @__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: [
|
|
14293
14840
|
"/",
|
|
14294
14841
|
e.name
|
|
14295
14842
|
] }),
|
|
14296
|
-
/* @__PURE__ */
|
|
14297
|
-
/* @__PURE__ */
|
|
14843
|
+
/* @__PURE__ */ jsx15(Text15, { color: THEME.grayDim, children: " ".repeat(gap) }),
|
|
14844
|
+
/* @__PURE__ */ jsx15(Text15, { color: active ? THEME.gray : THEME.grayDim, children: desc })
|
|
14298
14845
|
] }, e.name);
|
|
14299
14846
|
}),
|
|
14300
|
-
entries.length > MAX_ROWS ? /* @__PURE__ */
|
|
14847
|
+
entries.length > MAX_ROWS ? /* @__PURE__ */ jsxs13(Text15, { color: THEME.coralMuted, children: [
|
|
14301
14848
|
"\u2191\u2193 \u6EDA\u52A8 \xB7 ",
|
|
14302
14849
|
selectedIndex + 1,
|
|
14303
14850
|
"/",
|
|
@@ -14310,8 +14857,8 @@ var init_SlashMenu = __esm({
|
|
|
14310
14857
|
});
|
|
14311
14858
|
|
|
14312
14859
|
// src/components/StatusStrip.tsx
|
|
14313
|
-
import { Box as
|
|
14314
|
-
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";
|
|
14315
14862
|
var StatusStrip;
|
|
14316
14863
|
var init_StatusStrip = __esm({
|
|
14317
14864
|
"src/components/StatusStrip.tsx"() {
|
|
@@ -14328,18 +14875,18 @@ var init_StatusStrip = __esm({
|
|
|
14328
14875
|
`state: ${stateText}`,
|
|
14329
14876
|
sessionShort ? `session: ${sessionShort}` : ""
|
|
14330
14877
|
].filter(Boolean);
|
|
14331
|
-
return /* @__PURE__ */
|
|
14332
|
-
/* @__PURE__ */
|
|
14333
|
-
/* @__PURE__ */
|
|
14334
|
-
/* @__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 })
|
|
14335
14882
|
] });
|
|
14336
14883
|
};
|
|
14337
14884
|
}
|
|
14338
14885
|
});
|
|
14339
14886
|
|
|
14340
14887
|
// src/components/TopPanel.tsx
|
|
14341
|
-
import { Box as
|
|
14342
|
-
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";
|
|
14343
14890
|
var ROBOT, INNER_H, TopPanel;
|
|
14344
14891
|
var init_TopPanel = __esm({
|
|
14345
14892
|
"src/components/TopPanel.tsx"() {
|
|
@@ -14359,36 +14906,36 @@ var init_TopPanel = __esm({
|
|
|
14359
14906
|
const leftW = Math.floor(innerW * 0.33);
|
|
14360
14907
|
const rightW = innerW - leftW - 1;
|
|
14361
14908
|
const ruleLen = Math.max(8, rightW - 2);
|
|
14362
|
-
const VDivider = /* @__PURE__ */
|
|
14363
|
-
return /* @__PURE__ */
|
|
14364
|
-
/* @__PURE__ */
|
|
14365
|
-
/* @__PURE__ */
|
|
14366
|
-
/* @__PURE__ */
|
|
14367
|
-
/* @__PURE__ */
|
|
14368
|
-
/* @__PURE__ */
|
|
14369
|
-
/* @__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: [
|
|
14370
14917
|
" ",
|
|
14371
14918
|
VERSION
|
|
14372
14919
|
] })
|
|
14373
14920
|
] }),
|
|
14374
|
-
/* @__PURE__ */
|
|
14375
|
-
/* @__PURE__ */
|
|
14376
|
-
/* @__PURE__ */
|
|
14377
|
-
/* @__PURE__ */
|
|
14378
|
-
ROBOT.map((l, i) => /* @__PURE__ */
|
|
14379
|
-
/* @__PURE__ */
|
|
14380
|
-
/* @__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" })
|
|
14381
14928
|
] }),
|
|
14382
14929
|
VDivider,
|
|
14383
|
-
/* @__PURE__ */
|
|
14384
|
-
/* @__PURE__ */
|
|
14385
|
-
/* @__PURE__ */
|
|
14386
|
-
/* @__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" })
|
|
14387
14934
|
] }),
|
|
14388
|
-
/* @__PURE__ */
|
|
14389
|
-
/* @__PURE__ */
|
|
14390
|
-
/* @__PURE__ */
|
|
14391
|
-
/* @__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" })
|
|
14392
14939
|
] })
|
|
14393
14940
|
] })
|
|
14394
14941
|
] })
|
|
@@ -14539,9 +15086,9 @@ __export(App_exports, {
|
|
|
14539
15086
|
App: () => App
|
|
14540
15087
|
});
|
|
14541
15088
|
import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState4 } from "react";
|
|
14542
|
-
import { Box as
|
|
14543
|
-
import { Fragment as Fragment3, jsx as
|
|
14544
|
-
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;
|
|
14545
15092
|
var init_App = __esm({
|
|
14546
15093
|
"src/App.tsx"() {
|
|
14547
15094
|
"use strict";
|
|
@@ -14566,24 +15113,24 @@ var init_App = __esm({
|
|
|
14566
15113
|
init_PlanEditor();
|
|
14567
15114
|
init_SessionPicker();
|
|
14568
15115
|
init_ForkPicker();
|
|
15116
|
+
init_ModelPicker();
|
|
14569
15117
|
init_SlashMenu();
|
|
14570
15118
|
init_MultilineInput();
|
|
14571
15119
|
init_StatusStrip();
|
|
14572
15120
|
init_TopPanel();
|
|
14573
15121
|
init_inspect();
|
|
14574
|
-
KNOWN_MODELS = ["deepseek-v4", "deepseek-v4-flash"];
|
|
14575
15122
|
CWD2 = process.cwd();
|
|
14576
15123
|
RowView = ({ row, wrapW, streamTail, showThinking }) => {
|
|
14577
|
-
if (row.kind === "todos") return /* @__PURE__ */
|
|
14578
|
-
if (row.kind === "tool") return /* @__PURE__ */
|
|
14579
|
-
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 });
|
|
14580
15127
|
if (row.kind === "user") {
|
|
14581
|
-
return /* @__PURE__ */
|
|
14582
|
-
/* @__PURE__ */
|
|
14583
|
-
/* @__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 })
|
|
14584
15131
|
] });
|
|
14585
15132
|
}
|
|
14586
|
-
return /* @__PURE__ */
|
|
15133
|
+
return /* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail });
|
|
14587
15134
|
};
|
|
14588
15135
|
isDynamicRow = (r) => r.kind === "assistant" && !!r.streaming || r.kind === "thinking" && !!r.streaming || r.kind === "tool" && r.status === "running" || r.kind === "todos" && !!r.active;
|
|
14589
15136
|
App = ({ resumeSessionId, initialPlanMode, initialAutoMode, initialIncludeProject, engineReady }) => {
|
|
@@ -14659,6 +15206,15 @@ var init_App = __esm({
|
|
|
14659
15206
|
await refreshStatusLineRef.current();
|
|
14660
15207
|
})();
|
|
14661
15208
|
}, []);
|
|
15209
|
+
useEffect4(() => {
|
|
15210
|
+
void (async () => {
|
|
15211
|
+
const saved = await readModelPref();
|
|
15212
|
+
if (saved) {
|
|
15213
|
+
state.setModelOverride(saved);
|
|
15214
|
+
setModelDisplay(saved);
|
|
15215
|
+
}
|
|
15216
|
+
})();
|
|
15217
|
+
}, []);
|
|
14662
15218
|
useEffect4(() => {
|
|
14663
15219
|
void refreshStatusLineRef.current();
|
|
14664
15220
|
}, [state.busy, state.aborting, modelDisplay]);
|
|
@@ -14685,6 +15241,8 @@ var init_App = __esm({
|
|
|
14685
15241
|
return S.cmdAuto;
|
|
14686
15242
|
case "model":
|
|
14687
15243
|
return S.cmdModel;
|
|
15244
|
+
case "switch":
|
|
15245
|
+
return S.cmdSwitch;
|
|
14688
15246
|
case "thinking":
|
|
14689
15247
|
return S.cmdThinking;
|
|
14690
15248
|
case "lang":
|
|
@@ -14727,17 +15285,23 @@ var init_App = __esm({
|
|
|
14727
15285
|
const q = input.slice(1).toLowerCase();
|
|
14728
15286
|
return menuEntries.filter((c) => c.name.toLowerCase().startsWith(q));
|
|
14729
15287
|
}, [input, menuEntries]);
|
|
14730
|
-
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;
|
|
14731
15289
|
const slashVisible = !menuActive && input.startsWith("/") && filteredCommands.length > 0;
|
|
14732
15290
|
const inputActive = !menuActive;
|
|
14733
15291
|
useEffect4(() => {
|
|
14734
15292
|
setSelectIdx(0);
|
|
14735
15293
|
setPlanEditing(false);
|
|
14736
|
-
}, [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]);
|
|
14737
15295
|
useEffect4(() => {
|
|
14738
15296
|
setQCursor(0);
|
|
14739
15297
|
setQChecked(/* @__PURE__ */ new Set());
|
|
14740
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]);
|
|
14741
15305
|
const runLocalSlash = async (text) => {
|
|
14742
15306
|
const [cmd, ...rest] = text.trim().split(/\s+/);
|
|
14743
15307
|
const arg = rest.join(" ");
|
|
@@ -14814,13 +15378,15 @@ ${list}
|
|
|
14814
15378
|
}
|
|
14815
15379
|
case "/model":
|
|
14816
15380
|
if (!arg) {
|
|
14817
|
-
state.pushInfo(
|
|
14818
|
-
\u53EF\u9009\uFF1A${KNOWN_MODELS.join("\u3001")} \u6216\u4EFB\u610F\u6A21\u578B id\u3002`);
|
|
15381
|
+
state.pushInfo(S.modelUsage(modelDisplay));
|
|
14819
15382
|
return true;
|
|
14820
15383
|
}
|
|
14821
15384
|
state.setModelOverride(arg);
|
|
14822
15385
|
setModelDisplay(arg);
|
|
14823
|
-
state.pushInfo(
|
|
15386
|
+
state.pushInfo(S.modelSwitched(arg));
|
|
15387
|
+
return true;
|
|
15388
|
+
case "/switch":
|
|
15389
|
+
void state.openModelPicker();
|
|
14824
15390
|
return true;
|
|
14825
15391
|
case "/thinking": {
|
|
14826
15392
|
const lvl = arg.toLowerCase();
|
|
@@ -14909,7 +15475,7 @@ ${listText}`);
|
|
|
14909
15475
|
const v = inputRef.current.trim();
|
|
14910
15476
|
if (!v) return;
|
|
14911
15477
|
if (busyRef.current) {
|
|
14912
|
-
if (!v.startsWith("/") && state.queueInput(v)) {
|
|
15478
|
+
if (!v.startsWith("/") && !v.startsWith("!") && state.queueInput(v)) {
|
|
14913
15479
|
setInput("");
|
|
14914
15480
|
setCursor(0);
|
|
14915
15481
|
} else {
|
|
@@ -14919,6 +15485,10 @@ ${listText}`);
|
|
|
14919
15485
|
}
|
|
14920
15486
|
setInput("");
|
|
14921
15487
|
setCursor(0);
|
|
15488
|
+
if (v.startsWith("!")) {
|
|
15489
|
+
await state.runBangCommand(v);
|
|
15490
|
+
return;
|
|
15491
|
+
}
|
|
14922
15492
|
if (v.startsWith("/")) {
|
|
14923
15493
|
await executeSlash(v);
|
|
14924
15494
|
return;
|
|
@@ -15007,6 +15577,16 @@ ${listText}`);
|
|
|
15007
15577
|
} else if (key.escape || key.ctrl && ch === "g") state.resolveFork(null);
|
|
15008
15578
|
return;
|
|
15009
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
|
+
}
|
|
15010
15590
|
if (key.ctrl && ch === "t") {
|
|
15011
15591
|
state.toggleShowThinking();
|
|
15012
15592
|
return;
|
|
@@ -15047,19 +15627,19 @@ ${listText}`);
|
|
|
15047
15627
|
}
|
|
15048
15628
|
});
|
|
15049
15629
|
const sessionShort = state.sessionIdRef.current ? truncateMiddle(state.sessionIdRef.current, 12) : "";
|
|
15050
|
-
return /* @__PURE__ */
|
|
15051
|
-
/* @__PURE__ */
|
|
15052
|
-
/* @__PURE__ */
|
|
15053
|
-
menuActive ? null : /* @__PURE__ */
|
|
15054
|
-
dynamicRows.map((row) => /* @__PURE__ */
|
|
15055
|
-
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: [
|
|
15056
15636
|
"\u25CF ",
|
|
15057
15637
|
S.generating
|
|
15058
15638
|
] }) }) : null
|
|
15059
15639
|
] }),
|
|
15060
|
-
/* @__PURE__ */
|
|
15061
|
-
state.pendingApproval ? /* @__PURE__ */
|
|
15062
|
-
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(
|
|
15063
15643
|
QuestionModal,
|
|
15064
15644
|
{
|
|
15065
15645
|
question: state.pendingQuestion.req.question,
|
|
@@ -15070,7 +15650,7 @@ ${listText}`);
|
|
|
15070
15650
|
wrapW
|
|
15071
15651
|
}
|
|
15072
15652
|
) : null,
|
|
15073
|
-
state.pendingPlan ? planEditing ? /* @__PURE__ */
|
|
15653
|
+
state.pendingPlan ? planEditing ? /* @__PURE__ */ jsx18(
|
|
15074
15654
|
PlanEditor,
|
|
15075
15655
|
{
|
|
15076
15656
|
value: planDraft,
|
|
@@ -15081,15 +15661,16 @@ ${listText}`);
|
|
|
15081
15661
|
},
|
|
15082
15662
|
onSubmit: confirmPlanEdit
|
|
15083
15663
|
}
|
|
15084
|
-
) : /* @__PURE__ */
|
|
15085
|
-
state.pendingSessions ? /* @__PURE__ */
|
|
15086
|
-
state.pendingFork ? /* @__PURE__ */
|
|
15087
|
-
|
|
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
|
|
15088
15669
|
] }),
|
|
15089
|
-
/* @__PURE__ */
|
|
15670
|
+
/* @__PURE__ */ jsx18(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1, flexShrink: 0, children: (() => {
|
|
15090
15671
|
const planOn = state.getPlanMode();
|
|
15091
15672
|
const autoOn = !planOn && state.getAutoMode();
|
|
15092
|
-
const inputEl = /* @__PURE__ */
|
|
15673
|
+
const inputEl = /* @__PURE__ */ jsx18(
|
|
15093
15674
|
MultilineInput,
|
|
15094
15675
|
{
|
|
15095
15676
|
value: input,
|
|
@@ -15107,17 +15688,17 @@ ${listText}`);
|
|
|
15107
15688
|
}
|
|
15108
15689
|
);
|
|
15109
15690
|
if (planOn || autoOn) {
|
|
15110
|
-
return /* @__PURE__ */
|
|
15111
|
-
/* @__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 }),
|
|
15112
15693
|
inputEl
|
|
15113
15694
|
] });
|
|
15114
15695
|
}
|
|
15115
|
-
return /* @__PURE__ */
|
|
15116
|
-
/* @__PURE__ */
|
|
15696
|
+
return /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
15697
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, color: THEME.gray, children: dimRule(cols) }),
|
|
15117
15698
|
inputEl
|
|
15118
15699
|
] });
|
|
15119
15700
|
})() }),
|
|
15120
|
-
/* @__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 }) })
|
|
15121
15702
|
] })
|
|
15122
15703
|
] });
|
|
15123
15704
|
};
|
|
@@ -15177,7 +15758,7 @@ import { render } from "ink";
|
|
|
15177
15758
|
import os5 from "os";
|
|
15178
15759
|
import path42 from "path";
|
|
15179
15760
|
import { emitKeypressEvents } from "node:readline";
|
|
15180
|
-
import { jsx as
|
|
15761
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
15181
15762
|
var parseArgs = (argv) => {
|
|
15182
15763
|
const out = {};
|
|
15183
15764
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -15327,7 +15908,7 @@ var main = async () => {
|
|
|
15327
15908
|
resumeId = await getMostRecentSessionId2() ?? void 0;
|
|
15328
15909
|
}
|
|
15329
15910
|
const { waitUntilExit } = render(
|
|
15330
|
-
/* @__PURE__ */
|
|
15911
|
+
/* @__PURE__ */ jsx19(App2, { resumeSessionId: resumeId, initialPlanMode: args.plan, initialAutoMode: args.auto, initialIncludeProject: includeProject, engineReady }),
|
|
15331
15912
|
// exitOnCtrlC:false:Ctrl+C 交由 App useInput 处理(统一退出/中止语义);
|
|
15332
15913
|
// patchConsole:false:避免 console 劫持与全屏重绘叠加闪屏。
|
|
15333
15914
|
{ exitOnCtrlC: false, patchConsole: false }
|