deepseeker-code 1.0.49 → 1.0.51
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 +10 -9
- package/dist/cli.mjs +899 -317
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -130,6 +130,7 @@ var init_strings = __esm({
|
|
|
130
130
|
approvalDeny: "\u62D2\u7EDD",
|
|
131
131
|
errAborted: "\u5DF2\u4E2D\u6B62\u5F53\u524D\u8F6E\u3002",
|
|
132
132
|
busyBlockSend: "\u23F3 \u6B63\u5728\u751F\u6210\uFF0C\u8BF7\u7B49\u5F85\u6216\u6309 Esc \u4E2D\u6B62\u540E\u518D\u53D1\u9001\u3002",
|
|
133
|
+
escInterrupt: "Esc \u4E2D\u6B62",
|
|
133
134
|
inboxQueued: "\u{1F4EE} \u5DF2\u6392\u961F\uFF0C\u5C06\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\u6A21\u578B\uFF08Esc \u4ECD\u53EF\u4E2D\u6B62\uFF09\u3002",
|
|
134
135
|
inboxClaimed: (n) => `\u{1F4EC} \u5DF2\u9001\u8FBE\u6A21\u578B\uFF08${n} \u6761\u8865\u5145\u8F93\u5165\uFF09`,
|
|
135
136
|
inboxCarryover: (n) => `\u{1F4EC} \u672C\u8F6E\u7ED3\u675F\u65F6 ${n} \u6761\u8865\u5145\u8F93\u5165\u672A\u5728\u56DE\u5408\u8FB9\u754C\u9001\u8FBE\uFF0C\u5DF2\u5199\u5165\u4F1A\u8BDD\u5386\u53F2\uFF0C\u4E0B\u8F6E\u5BF9\u8BDD\u81EA\u52A8\u5E26\u5165\u3002`,
|
|
@@ -161,7 +162,8 @@ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
|
|
|
161
162
|
cmdStatus: "\u67E5\u770B\u5F53\u524D\u6A21\u578B/\u4F1A\u8BDD/\u6A21\u5F0F",
|
|
162
163
|
cmdPlan: "\u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814\u2192\u5BA1\u6279\u2192\u5B9E\u73B0\uFF09",
|
|
163
164
|
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
|
|
165
|
+
cmdModel: "\u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF09\uFF1A/model <\u6A21\u578Bid>\uFF0C\u65E0\u53C2\u67E5\u770B\u5F53\u524D\u6A21\u578B",
|
|
166
|
+
cmdSwitch: "\u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668\uFF08\u2191\u2193 \u9009\u62E9\uFF09",
|
|
165
167
|
cmdThinking: "\u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF1A/thinking <off|high|max>",
|
|
166
168
|
cmdLang: "\u5207\u6362\u754C\u9762\u8BED\u8A00\uFF1A/lang <zh|en>",
|
|
167
169
|
cmdOutputStyle: "\u5207\u6362\u8F93\u51FA\u98CE\u683C\uFF1A/output-style <name|off>",
|
|
@@ -185,6 +187,12 @@ ${dim} \u8FD0\u884C npm i -g deepseeker-code@latest \u66F4\u65B0${reset}
|
|
|
185
187
|
forkEmpty: "\uFF08\u5F53\u524D\u4F1A\u8BDD\u6682\u65E0\u53EF\u5206\u53C9\u7684\u68C0\u67E5\u70B9\uFF09",
|
|
186
188
|
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
189
|
forkFailed: (e) => `\u5206\u53C9\u5931\u8D25\uFF1A${e}`,
|
|
190
|
+
modelUsage: (current) => `\u5F53\u524D\u6A21\u578B\uFF1A${current || "\u9ED8\u8BA4\uFF08DEEP_SEEK_MODEL\uFF09"}
|
|
191
|
+
\u7528\u6CD5\uFF1A/model <\u6A21\u578Bid> \u76F4\u8F93\u5207\u6362\uFF0C\u6216 /switch \u5F39\u51FA\u5019\u9009\u9009\u62E9\u5668`,
|
|
192
|
+
modelPickerTitle: (current) => `\u{1F9E0} \u9009\u62E9\u6A21\u578B\uFF08\u5F53\u524D\uFF1A${current || "\u9ED8\u8BA4"}\uFF09`,
|
|
193
|
+
modelPickerPrompt: "\u2191\u2193 \u9009\u62E9 \xB7 Enter \u5207\u6362 \xB7 Esc \u53D6\u6D88\uFF08\u5176\u5B83\u6A21\u578B\uFF1A/model <\u6A21\u578Bid>\uFF09",
|
|
194
|
+
modelCurrentTag: "\u5F53\u524D",
|
|
195
|
+
modelSwitched: (m) => `\u6A21\u578B\u5DF2\u5207\u6362\uFF1A${m}\uFF08\u4E0B\u6B21\u56DE\u590D\u751F\u6548\uFF0C\u91CD\u542F\u540E\u4FDD\u6301\uFF09`,
|
|
188
196
|
relTime: (iso) => {
|
|
189
197
|
const t = Date.parse(iso);
|
|
190
198
|
if (!t) return "";
|
|
@@ -213,10 +221,11 @@ ${cwd}
|
|
|
213
221
|
DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u548C\u6267\u884C\u6587\u4EF6\u3002`,
|
|
214
222
|
optTrust: "\u4FE1\u4EFB\u6B64\u76EE\u5F55",
|
|
215
223
|
optExit: "\u9000\u51FA",
|
|
216
|
-
helpText: (
|
|
224
|
+
helpText: (model, thinking, locale2) => [
|
|
217
225
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
218
226
|
"/plan \u2014 \u5207\u6362\u8BA1\u5212\u6A21\u5F0F\uFF08\u53EA\u8BFB\u8C03\u7814 \u2192 \u65B9\u6848\u5BA1\u6279 \u2192 \u5B9E\u73B0\uFF09",
|
|
219
|
-
`/model
|
|
227
|
+
`/model <\u6A21\u578Bid> \u2014 \u5207\u6362\u6A21\u578B\uFF08\u76F4\u8F93\uFF0C\u5F53\u524D ${model}\uFF09`,
|
|
228
|
+
"/switch \u2014 \u5F39\u51FA\u5019\u9009\u6A21\u578B\u9009\u62E9\u5668",
|
|
220
229
|
`/thinking [off|high|max] \u2014 \u5207\u6362\u601D\u8003\u7B49\u7EA7\uFF08\u5F53\u524D ${thinking}\uFF09`,
|
|
221
230
|
`/lang [zh|en] \u2014 \u5207\u6362\u754C\u9762\u8BED\u8A00\uFF08\u5F53\u524D ${locale2}\uFF09`,
|
|
222
231
|
"/sessions \u2014 \u9009\u62E9\u5E76\u8F7D\u5165\u5386\u53F2\u4F1A\u8BDD\uFF08\u7EED\u63A5\u5BF9\u8BDD\uFF09",
|
|
@@ -224,8 +233,8 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
|
|
|
224
233
|
"/trust \u2014 \u7BA1\u7406\u5DF2\u4FE1\u4EFB\u76EE\u5F55\uFF08\u9879\u76EE\u7EA7 hooks/skills \u7B49\u4EC5\u5728\u4FE1\u4EFB\u76EE\u5F55\u52A0\u8F7D\uFF1BCI \u7528 --trust \u663E\u5F0F\u4FE1\u4EFB\uFF09",
|
|
225
234
|
"Ctrl+C \u9000\u51FA \xB7 Esc \u4E2D\u6B62/\u6E05\u8F93\u5165 \xB7 Ctrl+G \u4E2D\u6B62 \xB7 Ctrl+T \u5C55\u5F00/\u6536\u8D77\u601D\u8003"
|
|
226
235
|
].join("\n"),
|
|
227
|
-
statusText: (
|
|
228
|
-
`\u6A21\u578B\uFF1A${
|
|
236
|
+
statusText: (model, thinking, planOn, locale2, cwd) => [
|
|
237
|
+
`\u6A21\u578B\uFF1A${model}`,
|
|
229
238
|
`\u601D\u8003\u7B49\u7EA7\uFF1A${thinking}`,
|
|
230
239
|
`\u8BA1\u5212\u6A21\u5F0F\uFF1A${planOn ? "\u5F00" : "\u5173"}`,
|
|
231
240
|
`\u754C\u9762\u8BED\u8A00\uFF1A${locale2}`,
|
|
@@ -270,6 +279,7 @@ DeepSeeker-Code \u5C06\u5728\u6B64\u76EE\u5F55\u8BFB\u53D6\u3001\u7F16\u8F91\u54
|
|
|
270
279
|
approvalDeny: "Deny",
|
|
271
280
|
errAborted: "Aborted current turn.",
|
|
272
281
|
busyBlockSend: "\u23F3 Still generating\u2014wait or press Esc to abort before sending.",
|
|
282
|
+
escInterrupt: "esc to interrupt",
|
|
273
283
|
inboxQueued: "\u{1F4EE} Queued\u2014will reach the model at the next round boundary (Esc still aborts).",
|
|
274
284
|
inboxClaimed: (n) => `\u{1F4EC} Delivered to the model (${n} supplemental input${n > 1 ? "s" : ""})`,
|
|
275
285
|
inboxCarryover: (n) => `\u{1F4EC} ${n} supplemental input${n > 1 ? "s" : ""} not claimed at a round boundary before this run ended; saved to session history and carried into the next turn.`,
|
|
@@ -301,7 +311,8 @@ ${dim} Run npm i -g deepseeker-code@latest to update${reset}
|
|
|
301
311
|
cmdStatus: "Show current model/session/mode",
|
|
302
312
|
cmdPlan: "Toggle plan mode (read-only research \u2192 review \u2192 implement)",
|
|
303
313
|
cmdAuto: "Toggle auto mode (classifier auto-approves file edits, escalates risky)",
|
|
304
|
-
cmdModel: "Switch model: /model <
|
|
314
|
+
cmdModel: "Switch model (direct): /model <model-id>; no arg shows current",
|
|
315
|
+
cmdSwitch: "Open the model picker (\u2191\u2193 to pick)",
|
|
305
316
|
cmdThinking: "Switch thinking level: /thinking <off|high|max>",
|
|
306
317
|
cmdLang: "Switch interface language: /lang <zh|en>",
|
|
307
318
|
cmdOutputStyle: "Switch output style: /output-style <name|off>",
|
|
@@ -325,6 +336,12 @@ ${dim} Run npm i -g deepseeker-code@latest to update${reset}
|
|
|
325
336
|
forkEmpty: "(no checkpoints to fork from in this session)",
|
|
326
337
|
forkDone: (id, roundNo) => `Forked from round ${roundNo} \u2192 new session ${id} (loaded; new messages go to the fork, source untouched)`,
|
|
327
338
|
forkFailed: (e) => `Fork failed: ${e}`,
|
|
339
|
+
modelUsage: (current) => `Current model: ${current || "default (DEEP_SEEK_MODEL)"}
|
|
340
|
+
Usage: /model <model-id> to switch directly, or /switch for the picker`,
|
|
341
|
+
modelPickerTitle: (current) => `\u{1F9E0} Pick a model (current: ${current || "default"})`,
|
|
342
|
+
modelPickerPrompt: "\u2191\u2193 pick \xB7 Enter switch \xB7 Esc cancel (any other model: /model <id>)",
|
|
343
|
+
modelCurrentTag: "current",
|
|
344
|
+
modelSwitched: (m) => `Model switched: ${m} (takes effect on next reply, persists across restarts)`,
|
|
328
345
|
relTime: (iso) => {
|
|
329
346
|
const t = Date.parse(iso);
|
|
330
347
|
if (!t) return "";
|
|
@@ -353,10 +370,11 @@ ${cwd}
|
|
|
353
370
|
DeepSeeker-Code will read, edit, and execute files here.`,
|
|
354
371
|
optTrust: "Yes, I trust this folder",
|
|
355
372
|
optExit: "No, exit",
|
|
356
|
-
helpText: (
|
|
373
|
+
helpText: (model, thinking, locale2) => [
|
|
357
374
|
"/help \xB7 /status \xB7 /clear \xB7 /exit",
|
|
358
375
|
"/plan \u2014 Toggle plan mode (read-only research \u2192 review \u2192 implement)",
|
|
359
|
-
`/model
|
|
376
|
+
`/model <model-id> \u2014 Switch model (direct input; current ${model})`,
|
|
377
|
+
"/switch \u2014 Open the model picker",
|
|
360
378
|
`/thinking [off|high|max] \u2014 Switch thinking level (current ${thinking})`,
|
|
361
379
|
`/lang [zh|en] \u2014 Switch interface language (current ${locale2})`,
|
|
362
380
|
"/sessions \u2014 Pick a past session to resume",
|
|
@@ -364,8 +382,8 @@ DeepSeeker-Code will read, edit, and execute files here.`,
|
|
|
364
382
|
"/trust \u2014 Manage trusted dirs (project hooks/skills load only when trusted; CI uses --trust)",
|
|
365
383
|
"Ctrl+C exit \xB7 Esc abort/clear input \xB7 Ctrl+G abort \xB7 Ctrl+T toggle thinking"
|
|
366
384
|
].join("\n"),
|
|
367
|
-
statusText: (
|
|
368
|
-
`Model: ${
|
|
385
|
+
statusText: (model, thinking, planOn, locale2, cwd) => [
|
|
386
|
+
`Model: ${model}`,
|
|
369
387
|
`Thinking: ${thinking}`,
|
|
370
388
|
`Plan mode: ${planOn ? "on" : "off"}`,
|
|
371
389
|
`Language: ${locale2}`,
|
|
@@ -381,7 +399,7 @@ DeepSeeker-Code will read, edit, and execute files here.`,
|
|
|
381
399
|
S = new Proxy({}, {
|
|
382
400
|
get: (_t, k) => typeof k === "string" ? STRINGS[locale][k] : void 0
|
|
383
401
|
});
|
|
384
|
-
LOCAL_COMMAND_NAMES = ["help", "status", "plan", "auto", "model", "thinking", "lang", "output-style", "sessions", "fork", "usage", "context", "permissions", "mcp", "hooks", "trust", "debug", "clear", "exit"];
|
|
402
|
+
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
403
|
}
|
|
386
404
|
});
|
|
387
405
|
|
|
@@ -690,7 +708,7 @@ ${body}`) return;
|
|
|
690
708
|
// src/prefs.ts
|
|
691
709
|
import path4 from "path";
|
|
692
710
|
import fs2 from "fs/promises";
|
|
693
|
-
var PREFS_FILE, readPrefs, readLocale, writePrefs, writeLocale;
|
|
711
|
+
var PREFS_FILE, readPrefs, readModelPref, readLocale, writePrefs, writeLocale;
|
|
694
712
|
var init_prefs = __esm({
|
|
695
713
|
"src/prefs.ts"() {
|
|
696
714
|
"use strict";
|
|
@@ -701,6 +719,10 @@ var init_prefs = __esm({
|
|
|
701
719
|
const p = await readJSONFile(PREFS_FILE);
|
|
702
720
|
return p && typeof p === "object" ? p : {};
|
|
703
721
|
};
|
|
722
|
+
readModelPref = async () => {
|
|
723
|
+
const { model } = await readPrefs();
|
|
724
|
+
return typeof model === "string" && model.trim() ? model.trim() : null;
|
|
725
|
+
};
|
|
704
726
|
readLocale = async () => {
|
|
705
727
|
const { locale: locale2 } = await readPrefs();
|
|
706
728
|
return locale2 === "zh" || locale2 === "en" ? locale2 : null;
|
|
@@ -784,22 +806,23 @@ var init_type = __esm({
|
|
|
784
806
|
|
|
785
807
|
// ../core/src/llm/providers/deepseek/client.ts
|
|
786
808
|
import OpenAI from "openai";
|
|
787
|
-
var
|
|
809
|
+
var _model, getModel, MODEL_NAME, AUX_MODEL_NAME, REASONING_EFFORTS, clampReasoningEffort, MODEL_REASONING_EFFORT, MODEL_THINKING_ENABLED;
|
|
788
810
|
var init_client = __esm({
|
|
789
811
|
"../core/src/llm/providers/deepseek/client.ts"() {
|
|
790
812
|
"use strict";
|
|
791
|
-
|
|
813
|
+
getModel = () => _model ??= new OpenAI({
|
|
792
814
|
baseURL: process.env.DEEP_SEEK_API_URL || "https://api.deepseek.com",
|
|
793
815
|
apiKey: process.env.DEEP_SEEK_API_KEY,
|
|
794
816
|
// ★ 瞬态错误自动指数退避重试(SDK 内置:408/409/429/500/502/503/504 + 连接错误),
|
|
795
|
-
//
|
|
796
|
-
//
|
|
817
|
+
// 覆盖非流式 helper(summarize / classifyRisk)。★ 流式对话不在此列:stream.ts 按
|
|
818
|
+
// maxRetries: 0 关掉 SDK 层,瞬态重试单层归 streamInference 应用层(Retry-After 感知 +
|
|
819
|
+
// text.reset/abort/超长降级语义,SDK 层不具备)——两层同开会把 429 放大成 5×3=15 次请求。
|
|
797
820
|
maxRetries: 4,
|
|
798
821
|
timeout: 12e4
|
|
799
822
|
// 单次请求 120s 兜底(长上下文 / 长生成场景)
|
|
800
823
|
});
|
|
801
|
-
MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-
|
|
802
|
-
AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-
|
|
824
|
+
MODEL_NAME = process.env.DEEP_SEEK_MODEL || "deepseek-flash";
|
|
825
|
+
AUX_MODEL_NAME = process.env.DEEP_SEEK_AUX_MODEL || "deepseek-flash";
|
|
803
826
|
REASONING_EFFORTS = ["high", "max"];
|
|
804
827
|
clampReasoningEffort = (raw) => raw && REASONING_EFFORTS.includes(raw) ? raw : "high";
|
|
805
828
|
MODEL_REASONING_EFFORT = clampReasoningEffort(process.env.DEEP_SEEK_REASONING_EFFORT);
|
|
@@ -808,18 +831,37 @@ var init_client = __esm({
|
|
|
808
831
|
});
|
|
809
832
|
|
|
810
833
|
// ../core/src/llm/providers/deepseek/stream.ts
|
|
811
|
-
var STREAM_IDLE_TIMEOUT_MS, streamChat;
|
|
834
|
+
var STREAM_IDLE_TIMEOUT_MS, stripHistoricalReasoning, streamChat;
|
|
812
835
|
var init_stream = __esm({
|
|
813
836
|
"../core/src/llm/providers/deepseek/stream.ts"() {
|
|
814
837
|
"use strict";
|
|
815
838
|
init_client();
|
|
816
839
|
STREAM_IDLE_TIMEOUT_MS = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
840
|
+
stripHistoricalReasoning = (messages) => {
|
|
841
|
+
if (process.env.DEEP_SEEK_REASONING_PASSTHROUGH === "1") return messages;
|
|
842
|
+
let lastNonSystem = null;
|
|
843
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
844
|
+
if (messages[i]?.role !== "system") {
|
|
845
|
+
lastNonSystem = messages[i];
|
|
846
|
+
break;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
if (lastNonSystem?.role === "assistant") return messages;
|
|
850
|
+
return messages.map((m) => {
|
|
851
|
+
const wire = m;
|
|
852
|
+
if (wire?.role !== "assistant" || typeof wire.reasoning_content !== "string") return m;
|
|
853
|
+
const copy = { ...wire };
|
|
854
|
+
delete copy.reasoning_content;
|
|
855
|
+
return copy;
|
|
856
|
+
});
|
|
857
|
+
};
|
|
817
858
|
streamChat = async function* (messages, tools, opts) {
|
|
818
859
|
const level = opts.thinkingLevel;
|
|
819
860
|
const thinkingType = (level === void 0 ? MODEL_THINKING_ENABLED : level !== "off") ? "enabled" : "disabled";
|
|
820
861
|
const effort = level === "max" ? "max" : level === "high" ? "high" : level === "off" ? "high" : MODEL_REASONING_EFFORT;
|
|
821
862
|
const requestBody = {
|
|
822
|
-
messages,
|
|
863
|
+
messages: stripHistoricalReasoning(messages),
|
|
864
|
+
// ★ 出口剥离历史思考记录(见函数注释;默认开)
|
|
823
865
|
model: opts.model ?? MODEL_NAME,
|
|
824
866
|
// per-agent 覆盖(声明式子 Agent);缺省回退全局
|
|
825
867
|
tool_choice: "auto",
|
|
@@ -835,8 +877,9 @@ var init_stream = __esm({
|
|
|
835
877
|
const idleAc = new AbortController();
|
|
836
878
|
const extSignal = opts.signal;
|
|
837
879
|
const combinedSignal = extSignal ? AbortSignal.any([idleAc.signal, extSignal]) : idleAc.signal;
|
|
838
|
-
const stream = await
|
|
839
|
-
signal: combinedSignal
|
|
880
|
+
const stream = await getModel().chat.completions.create(requestBody, {
|
|
881
|
+
signal: combinedSignal,
|
|
882
|
+
maxRetries: 0
|
|
840
883
|
});
|
|
841
884
|
const reader = stream[Symbol.asyncIterator]();
|
|
842
885
|
try {
|
|
@@ -903,7 +946,8 @@ var init_deepseek = __esm({
|
|
|
903
946
|
summarize = async (messages, tools, opts) => {
|
|
904
947
|
try {
|
|
905
948
|
const requestBody = {
|
|
906
|
-
messages,
|
|
949
|
+
messages: stripHistoricalReasoning(messages),
|
|
950
|
+
// ★ 出口剥离历史思考记录(压缩输入全价计费,省得最实)
|
|
907
951
|
model: AUX_MODEL_NAME,
|
|
908
952
|
tool_choice: "auto",
|
|
909
953
|
tools,
|
|
@@ -911,7 +955,7 @@ var init_deepseek = __esm({
|
|
|
911
955
|
thinking: { type: "disabled" },
|
|
912
956
|
stream: false
|
|
913
957
|
};
|
|
914
|
-
const completion = await
|
|
958
|
+
const completion = await getModel().chat.completions.create(requestBody, {
|
|
915
959
|
signal: opts.signal
|
|
916
960
|
});
|
|
917
961
|
if (completion && "choices" in completion) return completion;
|
|
@@ -926,7 +970,7 @@ var init_deepseek = __esm({
|
|
|
926
970
|
const timer = setTimeout(() => ac.abort(), 1e4);
|
|
927
971
|
if (signal) signal.addEventListener("abort", () => ac.abort(), { once: true });
|
|
928
972
|
try {
|
|
929
|
-
const completion = await
|
|
973
|
+
const completion = await getModel().chat.completions.create({
|
|
930
974
|
messages: [
|
|
931
975
|
{ role: "system", content: "\u4F60\u662F\u5DE5\u5177\u8C03\u7528\u98CE\u9669\u5206\u7C7B\u5668\u3002\u53EA\u56DE SAFE \u6216 RISKY\uFF0C\u4E0D\u8981\u4EFB\u4F55\u89E3\u91CA\u3002\u6309\u5DE5\u5177\u7C7B\u578B\u5224\u5B9A\uFF1A\u2460\u6587\u4EF6(edit/write/create/move_file/delete_path)\u2014\u2014\u5DE5\u4F5C\u533A\u5185\u5E38\u89C4\u6587\u4EF6\u64CD\u4F5C(\u542B\u79FB\u52A8/\u91CD\u547D\u540D)=SAFE\uFF0C\u8986\u76D6/\u5220\u9664/\u79FB\u52A8\u654F\u611F\u6587\u4EF6(.env/.git/.ssh/.aws/\u5BC6\u94A5/credentials/settings.json)\u6216\u5DE5\u4F5C\u533A\u5916=RISKY\uFF1B\u2461\u547D\u4EE4(run_command/run_in_background)\u2014\u2014\u53EA\u8BFB/\u6784\u5EFA/\u6D4B\u8BD5/\u67E5\u770B\u7C7B(ls/cat/git status/npm test/pnpm build/node -v/tsc/lint)=SAFE\uFF0C\u7834\u574F\u6027/\u5916\u5411/\u63D0\u6743(rm -rf\u3001\u683C\u5F0F\u5316\u3001curl|sh\u3001\u5916\u4F20\u6587\u4EF6\u3001chmod 777\u3001shutdown\u3001\u5199\u7CFB\u7EDF\u76EE\u5F55\u3001\u5B89\u88C5\u964C\u751F\u5305)=RISKY\uFF1B\u2462\u7F51\u7EDC(web_fetch/web_search)\u2014\u2014\u6293\u53D6\u516C\u5F00\u6587\u6863/\u5E38\u89C4 URL=SAFE\uFF0C\u5185\u7F51/\u53EF\u7591/\u672A\u77E5 URL=RISKY\uFF1B\u2463git_commit\u2014\u2014\u5E38\u89C4\u63D0\u4EA4=SAFE\uFF0C\u542B\u6076\u610F\u811A\u672C/\u5F02\u5E38\u6539\u52A8=RISKY\uFF1B\u2464MCP(mcp__*)\u2014\u2014\u9ED8\u8BA4 RISKY(\u9ED1\u76D2\u5DE5\u5177\u65E0\u6CD5\u5224\u5B9A\u5185\u90E8\u884C\u4E3A)\u3002\u4EFB\u4F55\u4E0D\u786E\u5B9A\u4E00\u5F8B RISKY\u3002" },
|
|
932
976
|
{ role: "user", content: `\u5DE5\u5177:${toolName}
|
|
@@ -980,11 +1024,22 @@ var init_deepseek = __esm({
|
|
|
980
1024
|
}
|
|
981
1025
|
});
|
|
982
1026
|
|
|
1027
|
+
// ../core/src/llm/createModel.ts
|
|
1028
|
+
var SELECTABLE_MODELS;
|
|
1029
|
+
var init_createModel = __esm({
|
|
1030
|
+
"../core/src/llm/createModel.ts"() {
|
|
1031
|
+
"use strict";
|
|
1032
|
+
init_client();
|
|
1033
|
+
SELECTABLE_MODELS = ["deepseek-flash", "deepseek-v4-pro", "deepseek-flash-vision-exp"];
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
|
|
983
1037
|
// ../core/src/session/contentParts.ts
|
|
984
|
-
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, isVisionEnabled, estimateImageTokens, toWireUserContent, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
1038
|
+
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, modelSupportsVision, isVisionEnabled, estimateImageTokens, toWireUserContent, toIngestContents, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
985
1039
|
var init_contentParts = __esm({
|
|
986
1040
|
"../core/src/session/contentParts.ts"() {
|
|
987
1041
|
"use strict";
|
|
1042
|
+
init_createModel();
|
|
988
1043
|
MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
989
1044
|
msgText = (content) => {
|
|
990
1045
|
if (typeof content === "string") return content;
|
|
@@ -998,9 +1053,13 @@ var init_contentParts = __esm({
|
|
|
998
1053
|
return content.filter((p) => p?.type === "image_url" && typeof p?.image_url?.url === "string").map((p) => p.image_url.url);
|
|
999
1054
|
};
|
|
1000
1055
|
hasImagePart = (content) => imageUrlsOf(content).length > 0;
|
|
1001
|
-
|
|
1056
|
+
modelSupportsVision = (modelId) => /vision|vlm|(^|[-_.])vl([-_.0-9]|$)/i.test(modelId || "");
|
|
1057
|
+
isVisionEnabled = (modelId) => {
|
|
1002
1058
|
const v = process.env.DEEP_SEEK_VISION;
|
|
1003
|
-
|
|
1059
|
+
if (v === "1" || v === "true") return true;
|
|
1060
|
+
if (v === "0" || v === "false") return false;
|
|
1061
|
+
const effective = typeof modelId === "string" && modelId.trim() ? modelId.trim() : MODEL_NAME;
|
|
1062
|
+
return modelSupportsVision(effective);
|
|
1004
1063
|
};
|
|
1005
1064
|
estimateImageTokens = () => {
|
|
1006
1065
|
const n = Number(process.env.DEEP_SEEK_IMAGE_TOKENS);
|
|
@@ -1039,6 +1098,22 @@ ${footer.join("\n")}` : text;
|
|
|
1039
1098
|
];
|
|
1040
1099
|
return parts;
|
|
1041
1100
|
};
|
|
1101
|
+
toIngestContents = (text, attachments, modelId) => {
|
|
1102
|
+
const archive = toWireUserContent(text, attachments);
|
|
1103
|
+
if (!Array.isArray(attachments) || attachments.length === 0) return { wire: archive, archive };
|
|
1104
|
+
if (isVisionEnabled(modelId)) return { wire: archive, archive };
|
|
1105
|
+
const names = attachments.map((a) => a?.name || "image").join("\u3001");
|
|
1106
|
+
const paths = attachments.map((a) => typeof a?.path === "string" && a.path ? ` ${a?.name || "image"} \u2192 ${a.path}` : "").filter(Boolean);
|
|
1107
|
+
const relay = paths.length ? `\u56FE\u7247\u5DF2\u5B58\u5DE5\u4F5C\u533A\uFF1A
|
|
1108
|
+
${paths.join("\n")}
|
|
1109
|
+
\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";
|
|
1110
|
+
return {
|
|
1111
|
+
wire: `${text}
|
|
1112
|
+
|
|
1113
|
+
\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}`,
|
|
1114
|
+
archive
|
|
1115
|
+
};
|
|
1116
|
+
};
|
|
1042
1117
|
replaceImageParts = (m, note) => {
|
|
1043
1118
|
if (!m || !Array.isArray(m.content)) return m;
|
|
1044
1119
|
let touched = false;
|
|
@@ -1719,7 +1794,7 @@ var init_shellExecutor = __esm({
|
|
|
1719
1794
|
};
|
|
1720
1795
|
executeHookCommand = (input) => {
|
|
1721
1796
|
return new Promise((resolve) => {
|
|
1722
|
-
const
|
|
1797
|
+
const timeoutMs2 = Math.min(input.timeoutMs ?? DEFAULT_TIMEOUT_MS, HARD_TIMEOUT_CAP_MS);
|
|
1723
1798
|
const childEnv = {};
|
|
1724
1799
|
for (const k of ENV_WHITELIST) {
|
|
1725
1800
|
const v = process.env[k];
|
|
@@ -1755,7 +1830,7 @@ var init_shellExecutor = __esm({
|
|
|
1755
1830
|
const timer = setTimeout(() => {
|
|
1756
1831
|
timedOut = true;
|
|
1757
1832
|
void killTree(child);
|
|
1758
|
-
},
|
|
1833
|
+
}, timeoutMs2);
|
|
1759
1834
|
child.stdout?.on("data", (d) => {
|
|
1760
1835
|
if (stdout.length < MAX_OUTPUT) stdout += d.toString();
|
|
1761
1836
|
});
|
|
@@ -1787,7 +1862,7 @@ var init_shellExecutor = __esm({
|
|
|
1787
1862
|
});
|
|
1788
1863
|
|
|
1789
1864
|
// ../core/src/hooks/registry.ts
|
|
1790
|
-
var rules, matches,
|
|
1865
|
+
var rules, matches, DECLARATIVE_RULE, replaceDeclarativeHooks, listHooks, isPlainObject, dispatch, runPreHooks, HOOK_RESULT_MAX, truncateForHook, runPostHooks;
|
|
1791
1866
|
var init_registry = __esm({
|
|
1792
1867
|
"../core/src/hooks/registry.ts"() {
|
|
1793
1868
|
"use strict";
|
|
@@ -1796,7 +1871,12 @@ var init_registry = __esm({
|
|
|
1796
1871
|
init_config();
|
|
1797
1872
|
rules = [];
|
|
1798
1873
|
matches = (matcher, toolName) => {
|
|
1799
|
-
if (typeof matcher === "string")
|
|
1874
|
+
if (typeof matcher === "string") {
|
|
1875
|
+
if (matcher === "*") return true;
|
|
1876
|
+
if (matcher === "mcp_call") return toolName.startsWith("mcp__");
|
|
1877
|
+
if (matcher.endsWith("*")) return toolName.startsWith(matcher.slice(0, -1));
|
|
1878
|
+
return matcher === toolName;
|
|
1879
|
+
}
|
|
1800
1880
|
if (matcher instanceof RegExp) return matcher.test(toolName);
|
|
1801
1881
|
try {
|
|
1802
1882
|
return matcher(toolName);
|
|
@@ -1804,8 +1884,15 @@ var init_registry = __esm({
|
|
|
1804
1884
|
return false;
|
|
1805
1885
|
}
|
|
1806
1886
|
};
|
|
1807
|
-
|
|
1808
|
-
|
|
1887
|
+
DECLARATIVE_RULE = Symbol("dsc.hook.declarative");
|
|
1888
|
+
replaceDeclarativeHooks = (rs) => {
|
|
1889
|
+
for (let i = rules.length - 1; i >= 0; i--) {
|
|
1890
|
+
if (rules[i][DECLARATIVE_RULE]) rules.splice(i, 1);
|
|
1891
|
+
}
|
|
1892
|
+
for (const r of rs) {
|
|
1893
|
+
r[DECLARATIVE_RULE] = true;
|
|
1894
|
+
rules.push(r);
|
|
1895
|
+
}
|
|
1809
1896
|
};
|
|
1810
1897
|
listHooks = () => {
|
|
1811
1898
|
const strMatcher = (m) => {
|
|
@@ -1923,15 +2010,14 @@ function stripAnsi(text) {
|
|
|
1923
2010
|
}
|
|
1924
2011
|
function microcompactTextContent(raw) {
|
|
1925
2012
|
let s = stripAnsi(raw || "");
|
|
1926
|
-
s = s.replace(/<!--[\s\S]*?-->/g, "");
|
|
1927
2013
|
s = relativizeWorkspacePathsInText(s);
|
|
1928
|
-
s = s.replace(/\n{3,}/g, "\n\n").
|
|
2014
|
+
s = s.replace(/\n{3,}/g, "\n\n").trim();
|
|
1929
2015
|
return s;
|
|
1930
2016
|
}
|
|
1931
2017
|
function isAsyncGenerator(x) {
|
|
1932
2018
|
return x != null && typeof x[Symbol.asyncIterator] === "function";
|
|
1933
2019
|
}
|
|
1934
|
-
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, compactSlotNarrative,
|
|
2020
|
+
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, persistCompaction, ensureFitsWindow, collectToolResult;
|
|
1935
2021
|
var init_truncate = __esm({
|
|
1936
2022
|
"../core/src/agent/truncate.ts"() {
|
|
1937
2023
|
"use strict";
|
|
@@ -2003,10 +2089,11 @@ var init_truncate = __esm({
|
|
|
2003
2089
|
|
|
2004
2090
|
${tail}`;
|
|
2005
2091
|
};
|
|
2006
|
-
|
|
2092
|
+
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';
|
|
2093
|
+
compactBatch = async (batch, signal, tailContext) => {
|
|
2007
2094
|
const resp = await chatWithModelWithSummary(
|
|
2008
2095
|
// ★ 辅助模型是 text-only:送前把 image part 降级为占位符——base64 绝不能进摘要批(烧钱且无意义)
|
|
2009
|
-
[...batch.map(degradeImagesForAux), { role: "user", content:
|
|
2096
|
+
[...batch.map(degradeImagesForAux), { role: "user", content: batchSummaryPrompt(tailContext) }],
|
|
2010
2097
|
[],
|
|
2011
2098
|
{ signal }
|
|
2012
2099
|
);
|
|
@@ -2026,6 +2113,8 @@ ${tail}`;
|
|
|
2026
2113
|
const push = (raw) => {
|
|
2027
2114
|
const s = raw.trim();
|
|
2028
2115
|
if (!s || s.length < 3 || s.length > 60 || seen.has(s)) return;
|
|
2116
|
+
const lastSeg = s.split(/[\\/]/).pop() ?? "";
|
|
2117
|
+
if (/^[\d.]+$/.test(lastSeg)) return;
|
|
2029
2118
|
seen.add(s);
|
|
2030
2119
|
found.push(s);
|
|
2031
2120
|
};
|
|
@@ -2054,8 +2143,8 @@ ${tail}`;
|
|
|
2054
2143
|
merged.push(e);
|
|
2055
2144
|
if (merged.length >= ARCHIVE_INDEX_MAX_ENTRIES) break;
|
|
2056
2145
|
}
|
|
2057
|
-
const newNotes = notes ? `${notes}
|
|
2058
|
-
${noteLine}` : noteLine;
|
|
2146
|
+
const newNotes = noteLine ? notes ? `${notes}
|
|
2147
|
+
${noteLine}` : noteLine : notes;
|
|
2059
2148
|
return [
|
|
2060
2149
|
"\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
2150
|
merged.join(" | "),
|
|
@@ -2063,17 +2152,57 @@ ${noteLine}` : noteLine;
|
|
|
2063
2152
|
newNotes
|
|
2064
2153
|
].join("\n");
|
|
2065
2154
|
};
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2155
|
+
CHECKPOINT_MAX_CHARS = 800;
|
|
2156
|
+
SLOT_PLACEHOLDER = "SYSTEM_ROLLING_SUMMARY_SLOT";
|
|
2157
|
+
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';
|
|
2158
|
+
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";
|
|
2159
|
+
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);
|
|
2160
|
+
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);
|
|
2161
|
+
assembleSlot = (index, newNotes) => [
|
|
2162
|
+
"\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",
|
|
2163
|
+
index.join(" | "),
|
|
2164
|
+
"\u27E6DSC:ARCHIVE-NOTES\u27E7",
|
|
2165
|
+
newNotes
|
|
2166
|
+
].join("\n");
|
|
2167
|
+
parseSlotNarrativeState = (slotContent) => {
|
|
2168
|
+
const { index, notes } = parseSummarySlot(slotContent);
|
|
2169
|
+
const trimmedNotes = notes.trim();
|
|
2170
|
+
const hasPrevious = trimmedNotes.length > 0 && trimmedNotes !== SLOT_PLACEHOLDER;
|
|
2171
|
+
return { index, hasPrevious };
|
|
2172
|
+
};
|
|
2173
|
+
synthesizeSlotNarrative = async (slotContent, newLines, signal) => {
|
|
2174
|
+
const { index, hasPrevious } = parseSlotNarrativeState(slotContent);
|
|
2175
|
+
const lines = newLines.trim();
|
|
2176
|
+
const resp = await chatWithModelWithSummary(
|
|
2177
|
+
[
|
|
2178
|
+
{ role: "system", content: slotContent },
|
|
2179
|
+
{ role: "user", content: `${lines ? `\u672C\u8F6E\u65B0\u5F52\u6863\u7684\u6458\u8981\u884C\uFF1A
|
|
2180
|
+
${lines}
|
|
2181
|
+
|
|
2182
|
+
` : ""}${checkpointPrompt(hasPrevious)}` }
|
|
2183
|
+
],
|
|
2184
|
+
[],
|
|
2185
|
+
{ signal }
|
|
2186
|
+
);
|
|
2187
|
+
const newNotes = (resp.choices[0].message.content || "").trim();
|
|
2188
|
+
return assembleSlot(index, newNotes);
|
|
2189
|
+
};
|
|
2190
|
+
synthesizeSlotNarrativeFromBatch = async (slotContent, batch, signal) => {
|
|
2191
|
+
const { index, hasPrevious } = parseSlotNarrativeState(slotContent);
|
|
2192
|
+
const resp = await chatWithModelWithSummary(
|
|
2193
|
+
[
|
|
2194
|
+
{ role: "system", content: slotContent },
|
|
2195
|
+
...batch.map(degradeImagesForAux),
|
|
2196
|
+
{ role: "user", content: checkpointDirectPrompt(hasPrevious) }
|
|
2197
|
+
],
|
|
2198
|
+
[],
|
|
2199
|
+
{ signal }
|
|
2200
|
+
);
|
|
2201
|
+
const newNotes = (resp.choices[0].message.content || "").trim();
|
|
2202
|
+
return assembleSlot(index, newNotes);
|
|
2075
2203
|
};
|
|
2076
|
-
|
|
2204
|
+
compactSlotNarrative = async (slotContent, _modelWindow, signal) => synthesizeSlotNarrative(slotContent, "", signal);
|
|
2205
|
+
splitIntoBatches = (toCompact) => {
|
|
2077
2206
|
const MAX_BATCH_TOKENS = 16e3;
|
|
2078
2207
|
const units = groupUnits(toCompact);
|
|
2079
2208
|
const batches = [];
|
|
@@ -2090,7 +2219,10 @@ ${noteLine}` : noteLine;
|
|
|
2090
2219
|
batchTokens += size;
|
|
2091
2220
|
}
|
|
2092
2221
|
if (batch.length > 0) batches.push(batch);
|
|
2093
|
-
|
|
2222
|
+
return batches;
|
|
2223
|
+
};
|
|
2224
|
+
compactBatches = async (batches, signal) => {
|
|
2225
|
+
const lines = await Promise.all(batches.map((b, i) => compactBatch(b, signal, i === batches.length - 1)));
|
|
2094
2226
|
return lines.join("\n");
|
|
2095
2227
|
};
|
|
2096
2228
|
ensureSummarySlot = (messageArr) => {
|
|
@@ -2098,13 +2230,27 @@ ${noteLine}` : noteLine;
|
|
|
2098
2230
|
messageArr.unshift({ role: "system", content: "SYSTEM_META_CONTEXT_START" });
|
|
2099
2231
|
}
|
|
2100
2232
|
if (messageArr.length < 2 || messageArr[1]?.role !== "system") {
|
|
2101
|
-
messageArr.splice(1, 0, { role: "system", content:
|
|
2233
|
+
messageArr.splice(1, 0, { role: "system", content: SLOT_PLACEHOLDER });
|
|
2102
2234
|
}
|
|
2103
2235
|
};
|
|
2104
2236
|
SUMMARY_SELF_COMPACT_THRESHOLD = 2e3;
|
|
2237
|
+
persistCompaction = async (sessionId, archivedMessageCount, summary) => {
|
|
2238
|
+
await setRollingState(sessionId, {
|
|
2239
|
+
archivedMessageCount,
|
|
2240
|
+
rollingSummary: summary,
|
|
2241
|
+
consecutiveFailures: 0,
|
|
2242
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2243
|
+
});
|
|
2244
|
+
await appendEvent(sessionId, {
|
|
2245
|
+
dscEvent: "compaction",
|
|
2246
|
+
archivedMessageCount,
|
|
2247
|
+
summary
|
|
2248
|
+
});
|
|
2249
|
+
};
|
|
2105
2250
|
ensureFitsWindow = async (event) => {
|
|
2106
2251
|
const correctionRatio = event.correctionRatio ?? 1.4;
|
|
2107
|
-
const
|
|
2252
|
+
const toolsTokens = event.toolsTokens ?? 0;
|
|
2253
|
+
const estReal = (arr) => estimateTokens(arr) * correctionRatio + toolsTokens;
|
|
2108
2254
|
const hitRate = event.lastRealPromptTokens && event.lastCachedTokens != null && event.lastRealPromptTokens > 0 ? event.lastCachedTokens / event.lastRealPromptTokens : null;
|
|
2109
2255
|
const cacheFactor = hitRate == null ? 1 : Math.min(1.1, Math.max(0.9, 0.9 + hitRate * 0.2));
|
|
2110
2256
|
const effectiveRatio = Math.min(event.compactRatio * cacheFactor, 0.82);
|
|
@@ -2126,8 +2272,9 @@ ${noteLine}` : noteLine;
|
|
|
2126
2272
|
const { toCompact, keepRecent } = splitUntils(active, keep);
|
|
2127
2273
|
try {
|
|
2128
2274
|
if (toCompact.length > 0) {
|
|
2129
|
-
|
|
2130
|
-
|
|
2275
|
+
summaryMsg.content = mergeSummarySlot(summaryMsg?.content || "", "", extractArchiveEntities(toCompact));
|
|
2276
|
+
const batches = splitIntoBatches(toCompact);
|
|
2277
|
+
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
2278
|
if (estimateTokens([summaryMsg]) > SUMMARY_SELF_COMPACT_THRESHOLD) {
|
|
2132
2279
|
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal);
|
|
2133
2280
|
}
|
|
@@ -2151,17 +2298,7 @@ ${noteLine}` : noteLine;
|
|
|
2151
2298
|
});
|
|
2152
2299
|
const store = await getRollingState(event.sessionId);
|
|
2153
2300
|
store.archivedMessageCount = (store.archivedMessageCount || 0) + toCompact.length;
|
|
2154
|
-
await
|
|
2155
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2156
|
-
rollingSummary: summaryMsg.content,
|
|
2157
|
-
consecutiveFailures: 0,
|
|
2158
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2159
|
-
});
|
|
2160
|
-
await appendEvent(event.sessionId, {
|
|
2161
|
-
dscEvent: "compaction",
|
|
2162
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2163
|
-
summary: summaryMsg.content
|
|
2164
|
-
});
|
|
2301
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
2165
2302
|
} else if (keep > 1) {
|
|
2166
2303
|
keep--;
|
|
2167
2304
|
continue;
|
|
@@ -2170,17 +2307,7 @@ ${noteLine}` : noteLine;
|
|
|
2170
2307
|
event.messageArr.length = 0;
|
|
2171
2308
|
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
2172
2309
|
const store = await getRollingState(event.sessionId);
|
|
2173
|
-
await
|
|
2174
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2175
|
-
rollingSummary: summaryMsg.content,
|
|
2176
|
-
consecutiveFailures: 0,
|
|
2177
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2178
|
-
});
|
|
2179
|
-
await appendEvent(event.sessionId, {
|
|
2180
|
-
dscEvent: "compaction",
|
|
2181
|
-
archivedMessageCount: store.archivedMessageCount,
|
|
2182
|
-
summary: summaryMsg.content
|
|
2183
|
-
});
|
|
2310
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
2184
2311
|
} else {
|
|
2185
2312
|
break;
|
|
2186
2313
|
}
|
|
@@ -2263,12 +2390,12 @@ ${noteLine}` : noteLine;
|
|
|
2263
2390
|
}
|
|
2264
2391
|
return full;
|
|
2265
2392
|
}
|
|
2266
|
-
const
|
|
2393
|
+
const timeoutMs2 = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
2267
2394
|
let timer;
|
|
2268
2395
|
const raced = await Promise.race([
|
|
2269
2396
|
Promise.resolve(ret).then((v) => ({ kind: "ok", value: typeof v === "string" ? v : JSON.stringify(v) })),
|
|
2270
2397
|
new Promise((resolve) => {
|
|
2271
|
-
timer = setTimeout(() => resolve({ kind: "timeout" }),
|
|
2398
|
+
timer = setTimeout(() => resolve({ kind: "timeout" }), timeoutMs2);
|
|
2272
2399
|
}),
|
|
2273
2400
|
...signal ? [new Promise((resolve) => {
|
|
2274
2401
|
signal.addEventListener("abort", () => resolve({ kind: "abort" }), { once: true });
|
|
@@ -2276,7 +2403,7 @@ ${noteLine}` : noteLine;
|
|
|
2276
2403
|
]);
|
|
2277
2404
|
if (timer) clearTimeout(timer);
|
|
2278
2405
|
if (raced.kind === "timeout") {
|
|
2279
|
-
return `[\u23F3 \u5DE5\u5177\u6267\u884C\u8D85\u65F6\uFF08${Math.round(
|
|
2406
|
+
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
2407
|
}
|
|
2281
2408
|
if (raced.kind === "abort") {
|
|
2282
2409
|
throw new Error("aborted");
|
|
@@ -4038,19 +4165,19 @@ var init_httpExecutor = __esm({
|
|
|
4038
4165
|
};
|
|
4039
4166
|
executeHttpHook = async (input) => {
|
|
4040
4167
|
const method = (input.method || "POST").toUpperCase();
|
|
4041
|
-
const
|
|
4168
|
+
const timeoutMs2 = input.timeoutMs ?? 3e4;
|
|
4042
4169
|
try {
|
|
4043
4170
|
const res = await fetch(input.url, {
|
|
4044
4171
|
method,
|
|
4045
4172
|
headers: { "content-type": "application/json", ...input.headers ?? {} },
|
|
4046
4173
|
body: input.body !== void 0 ? JSON.stringify(input.body) : void 0,
|
|
4047
|
-
signal: AbortSignal.timeout(
|
|
4174
|
+
signal: AbortSignal.timeout(timeoutMs2)
|
|
4048
4175
|
});
|
|
4049
4176
|
const text = await res.text();
|
|
4050
4177
|
return { ok: true, status: res.status, responseBody: truncateBody(text) };
|
|
4051
4178
|
} catch (e) {
|
|
4052
4179
|
const name = e?.name ?? "";
|
|
4053
|
-
if (name === "TimeoutError") return { ok: false, status: 0, responseBody: "", error: `\u8BF7\u6C42\u8D85\u65F6\uFF08>${
|
|
4180
|
+
if (name === "TimeoutError") return { ok: false, status: 0, responseBody: "", error: `\u8BF7\u6C42\u8D85\u65F6\uFF08>${timeoutMs2}ms\uFF09` };
|
|
4054
4181
|
if (name === "AbortError") return { ok: false, status: 0, responseBody: "", error: "\u8BF7\u6C42\u88AB\u4E2D\u6B62" };
|
|
4055
4182
|
return { ok: false, status: 0, responseBody: "", error: e?.message ?? String(e) };
|
|
4056
4183
|
}
|
|
@@ -4351,7 +4478,7 @@ var init_registry3 = __esm({
|
|
|
4351
4478
|
getSkillCatalog = () => {
|
|
4352
4479
|
const all = listSkills();
|
|
4353
4480
|
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");
|
|
4481
|
+
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
4482
|
};
|
|
4356
4483
|
}
|
|
4357
4484
|
});
|
|
@@ -4391,7 +4518,7 @@ var init_registry4 = __esm({
|
|
|
4391
4518
|
getAgentCatalog = () => {
|
|
4392
4519
|
const all = listAgents();
|
|
4393
4520
|
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");
|
|
4521
|
+
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
4522
|
};
|
|
4396
4523
|
}
|
|
4397
4524
|
});
|
|
@@ -4593,6 +4720,7 @@ var init_systemInjections = __esm({
|
|
|
4593
4720
|
type: t.type,
|
|
4594
4721
|
function: { name: t.function.name, description: t.function.description, parameters: t.function.parameters }
|
|
4595
4722
|
}));
|
|
4723
|
+
const toolsTokens = Math.round(JSON.stringify(cleanedToolSchemas).length / 4);
|
|
4596
4724
|
ensureSummarySlot(message);
|
|
4597
4725
|
const LOCALE_HINTS = {
|
|
4598
4726
|
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 +4744,7 @@ var init_systemInjections = __esm({
|
|
|
4616
4744
|
injectAgentCatalog(message);
|
|
4617
4745
|
injectProjectGuide(message);
|
|
4618
4746
|
injectMemory(message);
|
|
4619
|
-
return { rawTools, cleanedToolSchemas };
|
|
4747
|
+
return { rawTools, cleanedToolSchemas, toolsTokens };
|
|
4620
4748
|
};
|
|
4621
4749
|
}
|
|
4622
4750
|
});
|
|
@@ -4633,14 +4761,14 @@ var init_agent = __esm({
|
|
|
4633
4761
|
type: "function",
|
|
4634
4762
|
function: {
|
|
4635
4763
|
name: "spawn_agent",
|
|
4636
|
-
description: "\
|
|
4764
|
+
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
4765
|
parameters: {
|
|
4638
4766
|
type: "object",
|
|
4639
4767
|
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
|
|
4768
|
+
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" },
|
|
4769
|
+
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" },
|
|
4770
|
+
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" },
|
|
4771
|
+
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
4772
|
},
|
|
4645
4773
|
required: ["task"]
|
|
4646
4774
|
},
|
|
@@ -4907,13 +5035,9 @@ var init_workflow = __esm({
|
|
|
4907
5035
|
function: {
|
|
4908
5036
|
name: "run_workflow",
|
|
4909
5037
|
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"
|
|
5038
|
+
"\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",
|
|
5039
|
+
'\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',
|
|
5040
|
+
"\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
5041
|
].join("\n"),
|
|
4918
5042
|
parameters: {
|
|
4919
5043
|
type: "object",
|
|
@@ -4921,18 +5045,18 @@ var init_workflow = __esm({
|
|
|
4921
5045
|
mode: {
|
|
4922
5046
|
type: "string",
|
|
4923
5047
|
enum: ["parallel", "pipeline"],
|
|
4924
|
-
description: "
|
|
5048
|
+
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
5049
|
},
|
|
4926
5050
|
steps: {
|
|
4927
5051
|
type: "array",
|
|
4928
|
-
description: "\
|
|
5052
|
+
description: "\u6B65\u9AA4\u5217\u8868\uFF08parallel=\u6BCF\u4E2A\u662F\u72EC\u7ACB\u5B50 agent \u4EFB\u52A1\uFF1Bpipeline=\u6309\u5E8F\u5404\u9636\u6BB5\uFF09\u3002",
|
|
4929
5053
|
items: {
|
|
4930
5054
|
type: "object",
|
|
4931
5055
|
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\
|
|
5056
|
+
task: { type: "string", description: "\u5B50 agent \u4EFB\u52A1\u63CF\u8FF0\uFF08parallel \u987B\u81EA\u5305\u542B\uFF1Bpipeline \u53EA\u5199\u672C\u9636\u6BB5\u804C\u8D23\uFF09" },
|
|
5057
|
+
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" },
|
|
5058
|
+
role: { type: "string", description: "\u89D2\u8272\u8865\u5145\uFF08\u53EF\u9009\uFF09" },
|
|
5059
|
+
key: { type: "string", description: "\u7ED3\u679C\u6807\u7B7E\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u53D6\u4EFB\u52A1\u9996\u53E5\uFF09" }
|
|
4936
5060
|
},
|
|
4937
5061
|
required: ["task"]
|
|
4938
5062
|
},
|
|
@@ -4940,12 +5064,12 @@ var init_workflow = __esm({
|
|
|
4940
5064
|
},
|
|
4941
5065
|
concurrency: {
|
|
4942
5066
|
type: "number",
|
|
4943
|
-
description: "parallel \
|
|
5067
|
+
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
5068
|
},
|
|
4945
5069
|
isolation: {
|
|
4946
5070
|
type: "string",
|
|
4947
5071
|
enum: ["none", "worktree"],
|
|
4948
|
-
description: "
|
|
5072
|
+
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
5073
|
}
|
|
4950
5074
|
},
|
|
4951
5075
|
required: ["steps"]
|
|
@@ -5270,7 +5394,7 @@ var init_fs = __esm({
|
|
|
5270
5394
|
return lines.map((l) => l.length === 0 ? l : l.replace(re, "")).join("\n");
|
|
5271
5395
|
};
|
|
5272
5396
|
maskSecretsInContent = (_args, output) => {
|
|
5273
|
-
return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*['"]
|
|
5397
|
+
return output.replace(/((?:api[_-]?key|secret|password|passwd|token|authorization|auth[_-]?token|access[_-]?key|secret[_-]?key|private[_-]?key)\s*[:=]\s*)(['"])[A-Za-z0-9_\-+/=.]{8,}\2/gi, "$1$2[MASKED_SECRET]$2").replace(/((?:authorization|auth[_-]?token)\s*[:=]\s*Bearer\s+)[A-Za-z0-9_\-+/=.]{8,}/gi, "$1[MASKED_SECRET]").replace(/-----BEGIN [A-Z ]+PRIVATE KEY-----[\s\S]*?-----END [A-Z ]+PRIVATE KEY-----/g, "[MASKED_SECRET (private key block)]");
|
|
5274
5398
|
};
|
|
5275
5399
|
makeTmpPath = (absPath) => `${absPath}.${Date.now()}.${Math.random().toString(36).slice(2, 7)}.tmp`;
|
|
5276
5400
|
ATOMIC_TMP_RE = /\.\d+\.[a-z0-9]{1,12}\.tmp$/i;
|
|
@@ -5602,23 +5726,23 @@ ${treeResult}`;
|
|
|
5602
5726
|
type: "function",
|
|
5603
5727
|
function: {
|
|
5604
5728
|
name: "edit_file",
|
|
5605
|
-
description: "\
|
|
5729
|
+
description: "\u5BF9\u6587\u4EF6\u505A\u5C40\u90E8\u7CBE\u51C6\u4FEE\u6539\u3002\u2605 \u540C\u4E00\u6587\u4EF6\u591A\u5904\u8981\u6539\u65F6\u4E00\u6B21\u4F20 edits \u6570\u7EC4\u5168\u90E8\u5B8C\u6210\uFF08\u6309\u5E8F\u5E94\u7528\u3001\u6574\u4F53\u539F\u5B50\uFF1A\u4EFB\u4E00\u5904\u5931\u8D25\u5168\u90E8\u4E0D\u5199\u5165\uFF09\uFF0C\u52FF\u9010\u5904\u591A\u6B21\u8C03\u7528\u3002old_str \u987B\u4E0E\u6587\u4EF6\u539F\u6587\u9010\u5B57\u7B26\u4E00\u81F4\uFF1A\u53BB\u6389 read_file \u8FD4\u56DE\u7684\u300C<\u884C\u53F7>: \u300D\u524D\u7F00\uFF0C\u4FDD\u7559\u539F\u7F29\u8FDB\uFF08Tab/\u7A7A\u683C\uFF09\u4E0E\u884C\u5C3E\u7A7A\u767D\u3002\u9ED8\u8BA4\u987B\u5168\u6587\u552F\u4E00\uFF1Breplace_all=true \u66FF\u6362\u5168\u90E8\u5339\u914D\uFF08\u6279\u91CF\u91CD\u547D\u540D/\u7EDF\u4E00\u6539\u5199\uFF09\u3002",
|
|
5606
5730
|
parameters: {
|
|
5607
5731
|
type: "object",
|
|
5608
5732
|
properties: {
|
|
5609
|
-
path: { type: "string", description: "\
|
|
5610
|
-
old_str: { type: "string", description: "\
|
|
5611
|
-
new_str: { type: "string", description: "\
|
|
5612
|
-
replace_all: { type: "boolean", description: "\
|
|
5733
|
+
path: { type: "string", description: "\u76EE\u6807\u6587\u4EF6\u8DEF\u5F84" },
|
|
5734
|
+
old_str: { type: "string", description: "\u73B0\u6709\u65E7\u4EE3\u7801\u5757\uFF08\u5355\u5904\u4FEE\u6539\u7528\uFF1B\u591A\u5904\u6539\u7528 edits\uFF09" },
|
|
5735
|
+
new_str: { type: "string", description: "\u66FF\u6362\u540E\u7684\u65B0\u4EE3\u7801\u5757\uFF08\u5355\u5904\u4FEE\u6539\u7528\uFF09" },
|
|
5736
|
+
replace_all: { type: "boolean", description: "\u66FF\u6362\u5168\u6587\u6240\u6709\u5339\u914D\uFF08\u9ED8\u8BA4 false \u4EC5\u552F\u4E00\u5339\u914D\uFF09\u3002\u9876\u5C42\u4EC5\u4F5C\u7528\u5355\u6761 old_str/new_str\uFF1Bedits \u5185\u6BCF\u6761\u53EF\u72EC\u7ACB\u8BBE\u7F6E" },
|
|
5613
5737
|
edits: {
|
|
5614
5738
|
type: "array",
|
|
5615
|
-
description: "\u2605 \u540C\
|
|
5739
|
+
description: "\u2605 \u540C\u6587\u4EF6\u591A\u5904\u4FEE\u6539\u9996\u9009\uFF1A\u4E00\u6B21\u6309\u5E8F\u5B8C\u6210\u5168\u90E8\u66FF\u6362\u3002\u7B2C N \u6761 old_str \u57FA\u4E8E\u524D N-1 \u6761\u5E94\u7528\u540E\u7684\u5185\u5BB9\u6784\u9020\uFF1B\u4EFB\u4E00\u6761\u672A\u547D\u4E2D\u5219\u6574\u7EC4\u4E0D\u5199\u5165\uFF08\u539F\u5B50\uFF09\uFF0C\u4FEE\u6B63\u540E\u6574\u7EC4\u91CD\u8BD5",
|
|
5616
5740
|
items: {
|
|
5617
5741
|
type: "object",
|
|
5618
5742
|
properties: {
|
|
5619
|
-
old_str: { type: "string", description: "\
|
|
5620
|
-
new_str: { type: "string", description: "\
|
|
5621
|
-
replace_all: { type: "boolean", description: "\
|
|
5743
|
+
old_str: { type: "string", description: "\u73B0\u6709\u65E7\u4EE3\u7801\u5757" },
|
|
5744
|
+
new_str: { type: "string", description: "\u65B0\u4EE3\u7801\u5757" },
|
|
5745
|
+
replace_all: { type: "boolean", description: "\u66FF\u6362\u5168\u90E8\u5339\u914D\uFF08\u9ED8\u8BA4 false\uFF09" }
|
|
5622
5746
|
},
|
|
5623
5747
|
required: ["old_str", "new_str"]
|
|
5624
5748
|
}
|
|
@@ -5784,7 +5908,7 @@ ${summaries.join("\n")}`;
|
|
|
5784
5908
|
type: "function",
|
|
5785
5909
|
function: {
|
|
5786
5910
|
name: "write_file",
|
|
5787
|
-
description: "\u5C06\u5B8C\u6574\u5185\u5BB9\u5168\u91CF\u5199\u5165\u6307\u5B9A\u6587\u4EF6\uFF08\u8986\u76D6\uFF09\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u5219\u65B0\u5EFA\uFF08\u542B\u7236\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u5219\u6574\u4F53\u8986\u76D6\u3002\u2605 \u4EC5\u7528\u4E8E\u3010\u65B0\u5EFA\u6587\u4EF6\u3011\u6216\u3010\u5F7B\u5E95\u91CD\u5199\u6574\u4E2A\u6587\u4EF6\u3011\
|
|
5911
|
+
description: "\u5C06\u5B8C\u6574\u5185\u5BB9\u5168\u91CF\u5199\u5165\u6307\u5B9A\u6587\u4EF6\uFF08\u8986\u76D6\uFF09\u3002\u6587\u4EF6\u4E0D\u5B58\u5728\u5219\u65B0\u5EFA\uFF08\u542B\u7236\u76EE\u5F55\uFF09\uFF1B\u5DF2\u5B58\u5728\u5219\u6574\u4F53\u8986\u76D6\u3002\u2605 \u4EC5\u7528\u4E8E\u3010\u65B0\u5EFA\u6587\u4EF6\u3011\u6216\u3010\u5F7B\u5E95\u91CD\u5199\u6574\u4E2A\u6587\u4EF6\u3011\uFF1B\u4FEE\u6539\u65E2\u6709\u6587\u4EF6\u4E00\u5F8B\u6539\u7528 edit_file\uFF08\u5C40\u90E8\u7CBE\u51C6\u66FF\u6362\u3001\u6700\u5C0F diff\uFF09\u3002",
|
|
5788
5912
|
parameters: {
|
|
5789
5913
|
type: "object",
|
|
5790
5914
|
properties: {
|
|
@@ -5970,14 +6094,14 @@ var init_search = __esm({
|
|
|
5970
6094
|
type: "function",
|
|
5971
6095
|
function: {
|
|
5972
6096
|
name: "search_grep",
|
|
5973
|
-
description: "\u5728\u5DE5\u4F5C\u533A\
|
|
6097
|
+
description: "\u5728\u5DE5\u4F5C\u533A\u6587\u4EF6\u4E2D\u68C0\u7D22\u5339\u914D\u7684\u4EE3\u7801\u884C\uFF0C\u6BCF\u4E2A\u547D\u4E2D\u9ED8\u8BA4\u5E26\u524D\u540E\u5404 2 \u884C\u4E0A\u4E0B\u6587\uFF08\u53EF\u76F4\u63A5\u5224\u65AD\u7528\u6CD5\uFF1B\u6784\u9020 edit_file \u7684 old_str \u524D\u53EF\u7528 context \u8C03\u5927\u4E00\u6B21\u62FF\u8DB3\uFF09\u3002\u9ED8\u8BA4\u5B57\u9762\u91CF\u5339\u914D\uFF0C\u6B63\u5219\u4F20 is_regex=true\u3002\u2605 \u591A\u5173\u952E\u8BCD\u7528 is_regex=true \u4EE5 | \u5408\u5E76\uFF08\u5982 'uploadVisible|uploadTip'\uFF09\u4E00\u6B21\u67E5\u5B8C\uFF0C\u52FF\u9010\u8BCD\u591A\u6B21\u8C03\u7528\u3002path \u53EF\u9650\u5B9A\u76EE\u5F55\u6216\u6587\u4EF6\uFF08\u5355\u5927\u6587\u4EF6\u591A\u5904\u5B9A\u4F4D\u4F20\u6587\u4EF6\u8DEF\u5F84\u6700\u9AD8\u6548\uFF09\u3002\u591A\u6839\u5DE5\u4F5C\u533A\uFF1Apath \u53EF\u4F20\u9879\u76EE\u76EE\u5F55\u540D\uFF08\u5982 'frontend'\uFF09\u3001\u7EDD\u5BF9\u8DEF\u5F84\u6216 ../\u5144\u5F1F\u76EE\u5F55\u3002\u2605 \u7528\u6237\u6307\u660E\u4E86\u9879\u76EE\u65F6\u52A1\u5FC5\u628A\u8BE5\u9879\u76EE\u4F5C\u4E3A path \u4F20\u5165\u2014\u2014\u7F3A\u7701\u53EA\u641C\u6D3B\u52A8\u6839\uFF0C\u5E38\u4E0E\u610F\u56FE\u4E0D\u7B26\u3002",
|
|
5974
6098
|
parameters: {
|
|
5975
6099
|
type: "object",
|
|
5976
6100
|
properties: {
|
|
5977
|
-
query: { type: "string", description: "\u68C0\u7D22\
|
|
5978
|
-
is_regex: { type: "boolean", description: "
|
|
5979
|
-
path: { type: "string", description: "\u9650\u5B9A\u641C\u7D22\u7684\u76EE\u5F55\u6216\
|
|
5980
|
-
context: { type: "number", description: "\u6BCF\
|
|
6101
|
+
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" },
|
|
6102
|
+
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" },
|
|
6103
|
+
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" },
|
|
6104
|
+
context: { type: "number", description: "\u6BCF\u547D\u4E2D\u9644\u5E26\u4E0A\u4E0B\u6587\u884C\u6570\uFF080-10\uFF0C\u9ED8\u8BA4 2\uFF09\u3002\u8981\u62FF\u8DB3\u5B8C\u6574\u4EE3\u7801\u4F5C old_str \u65F6\u8C03\u5927\uFF08\u5982 5-8\uFF09" }
|
|
5981
6105
|
},
|
|
5982
6106
|
required: ["query"]
|
|
5983
6107
|
},
|
|
@@ -6121,7 +6245,7 @@ ${content}`;
|
|
|
6121
6245
|
|
|
6122
6246
|
// ../core/src/tool/registry/command.ts
|
|
6123
6247
|
import { spawn as spawn4 } from "child_process";
|
|
6124
|
-
var EXIT_SENTINEL, EXIT_SENTINEL_RE, RUN_COMMAND_MAX_CHARS, commandTools;
|
|
6248
|
+
var EXIT_SENTINEL, EXIT_SENTINEL_RE, AUTO_BG_NOTICE, AUTO_BG_SENTINEL_RE, RUN_COMMAND_MAX_CHARS, commandTools;
|
|
6125
6249
|
var init_command = __esm({
|
|
6126
6250
|
"../core/src/tool/registry/command.ts"() {
|
|
6127
6251
|
"use strict";
|
|
@@ -6132,6 +6256,8 @@ var init_command = __esm({
|
|
|
6132
6256
|
EXIT_SENTINEL = (code) => `
|
|
6133
6257
|
\u27E6DSC_EXIT:${code}\u27E7`;
|
|
6134
6258
|
EXIT_SENTINEL_RE = /⟦DSC_EXIT:(-?\d+)⟧/g;
|
|
6259
|
+
AUTO_BG_NOTICE = "\u27E6DSC_BG\u27E7";
|
|
6260
|
+
AUTO_BG_SENTINEL_RE = /⟦DSC_BG⟧\s*$/;
|
|
6135
6261
|
RUN_COMMAND_MAX_CHARS = 2e4;
|
|
6136
6262
|
commandTools = [
|
|
6137
6263
|
{
|
|
@@ -6156,8 +6282,13 @@ var init_command = __esm({
|
|
|
6156
6282
|
// 💡 我们将在 execute 内部真正落地这个长度限制
|
|
6157
6283
|
verifyResult: (rawOutput) => {
|
|
6158
6284
|
const matches2 = [...rawOutput.matchAll(EXIT_SENTINEL_RE)];
|
|
6159
|
-
const
|
|
6285
|
+
const last = matches2[matches2.length - 1];
|
|
6286
|
+
const code = last ? parseInt(last[1], 10) : null;
|
|
6160
6287
|
if (code === 0) return { status: "success" /* SUCCESS */ };
|
|
6288
|
+
if (code === null) {
|
|
6289
|
+
if (AUTO_BG_SENTINEL_RE.test(rawOutput.trimEnd())) return { status: "success" /* SUCCESS */ };
|
|
6290
|
+
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" };
|
|
6291
|
+
}
|
|
6161
6292
|
const hint = code === 9009 ? "\uFF08Windows\uFF1A\u547D\u4EE4\u672A\u88AB\u8BC6\u522B\u2014\u2014\u547D\u4EE4\u4E0D\u5B58\u5728\u6216 PATH \u7F3A\u5931\uFF09" : code === 127 ? "\uFF08\u547D\u4EE4\u672A\u627E\u5230\u2014\u2014\u68C0\u67E5\u547D\u4EE4\u540D/PATH\uFF09" : code === 255 ? "\uFF08255 \u5E38\u89C1\u4E8E Unix \u547D\u4EE4\u5728\u975E POSIX shell \u4E0B\u7F3A\u5931\uFF0C\u6216\u8FDB\u7A0B\u663E\u5F0F exit(-1/255)\u3001\u8FDE\u63A5\u5931\u8D25\uFF09" : code === 4294967295 || code === -1 ? "\uFF08\u8FDB\u7A0B\u9000\u51FA\u7801 -1/\u672A\u6355\u83B7\u5F02\u5E38\u88AB\u6740\uFF09" : "";
|
|
6162
6293
|
return { status: "failed" /* FAILED */, summary: `\u547D\u4EE4\u9000\u51FA\u7801\u975E\u96F6\uFF1A${code}${hint}` };
|
|
6163
6294
|
},
|
|
@@ -6346,6 +6477,7 @@ ${tail}`,
|
|
|
6346
6477
|
\u23F3 [\u81EA\u52A8\u8F6C\u540E\u53F0]\uFF1A\u547D\u4EE4 [${args.command}] ${why}\uFF0C\u5DF2\u81EA\u52A8\u8F6C\u4E3A\u540E\u53F0\u4EFB\u52A1\uFF08\u524D\u53F0\u6D41\u5F0F\u7ED3\u675F\uFF0C\u672A\u6D88\u8D39\u7684\u5269\u4F59\u8F93\u51FA\u5DF2\u5E76\u5165\u540E\u53F0\u7F13\u51B2\uFF09\u3002
|
|
6347
6478
|
task_id: ${taskId}
|
|
6348
6479
|
\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
|
|
6480
|
+
${AUTO_BG_NOTICE}
|
|
6349
6481
|
`;
|
|
6350
6482
|
} else if (overLimit) {
|
|
6351
6483
|
yield EXIT_SENTINEL(-1);
|
|
@@ -7267,9 +7399,9 @@ var init_http = __esm({
|
|
|
7267
7399
|
function: {
|
|
7268
7400
|
name: "http_request",
|
|
7269
7401
|
description: [
|
|
7270
|
-
"\u5168\u65B9\u6CD5 HTTP \u5BA2\u6237\u7AEF\
|
|
7271
|
-
"\u4E0E web_fetch \
|
|
7272
|
-
"SSRF\uFF1A\
|
|
7402
|
+
"\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",
|
|
7403
|
+
"\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",
|
|
7404
|
+
"SSRF\uFF1A\u59CB\u7EC8\u62E6\u4E91\u5143\u6570\u636E\u7AEF\u70B9 169.254.169.254\uFF1B\u4EC5 http/https\u3002"
|
|
7273
7405
|
].join(" "),
|
|
7274
7406
|
parameters: {
|
|
7275
7407
|
type: "object",
|
|
@@ -7365,7 +7497,7 @@ var init_http = __esm({
|
|
|
7365
7497
|
// ../core/src/tool/registry/typescript.ts
|
|
7366
7498
|
import fs16 from "fs/promises";
|
|
7367
7499
|
import path20 from "path";
|
|
7368
|
-
var MAX_FILE_BYTES, toDisplayPath, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, diagnoseOneFile, typescriptTools;
|
|
7500
|
+
var MAX_FILE_BYTES, toDisplayPath, isLibFile, precheck, MAX_DIAG_ENTRIES, MAX_DIAG_FILES, MAX_REF_ENTRIES, REF_SNIPPET_MAX, diagnoseOneFile, typescriptTools;
|
|
7369
7501
|
var init_typescript = __esm({
|
|
7370
7502
|
"../core/src/tool/registry/typescript.ts"() {
|
|
7371
7503
|
"use strict";
|
|
@@ -7379,6 +7511,7 @@ var init_typescript = __esm({
|
|
|
7379
7511
|
if (rel && !rel.startsWith("..") && !path20.isAbsolute(rel)) return rel.replace(/\\/g, "/");
|
|
7380
7512
|
return abs.replace(/\\/g, "/").split("/").slice(-3).join("/");
|
|
7381
7513
|
};
|
|
7514
|
+
isLibFile = (abs) => /(?:^|\/)node_modules\//.test(abs.replace(/\\/g, "/")) || /\.d\.ts$/i.test(abs);
|
|
7382
7515
|
precheck = async (displayPath, absPath) => {
|
|
7383
7516
|
const readBlock = await assertReadable(absPath, displayPath);
|
|
7384
7517
|
if (readBlock) return readBlock;
|
|
@@ -7392,6 +7525,8 @@ var init_typescript = __esm({
|
|
|
7392
7525
|
};
|
|
7393
7526
|
MAX_DIAG_ENTRIES = 300;
|
|
7394
7527
|
MAX_DIAG_FILES = 20;
|
|
7528
|
+
MAX_REF_ENTRIES = 200;
|
|
7529
|
+
REF_SNIPPET_MAX = 160;
|
|
7395
7530
|
diagnoseOneFile = async (TS, displayPath, checkJs) => {
|
|
7396
7531
|
try {
|
|
7397
7532
|
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
@@ -7446,7 +7581,7 @@ ${body}${tail}` };
|
|
|
7446
7581
|
type: "function",
|
|
7447
7582
|
function: {
|
|
7448
7583
|
name: "get_diagnostics",
|
|
7449
|
-
description: "\u5BF9\u4E00\u4E2A\u6216\u591A\u4E2A TS/JS \u6587\u4EF6\u53D6
|
|
7584
|
+
description: "\u5BF9\u4E00\u4E2A\u6216\u591A\u4E2A TS/JS \u6587\u4EF6\u53D6\u7C7B\u578B+\u8BED\u4E49\u8BCA\u65AD\uFF08\u7C7B\u578B\u9519\u8BEF/\u672A\u7528\u53D8\u91CF/\u4E0D\u53EF\u8FBE\u4EE3\u7801\uFF09\uFF0C\u8F93\u51FA\u884C:\u5217/\u4E25\u91CD\u5EA6/TS \u9519\u8BEF\u7801\uFF0C\u683C\u5F0F\u5BF9\u9F50 tsc\u3002\u2605 \u6539\u5B8C\u591A\u4E2A\u6587\u4EF6\u540E\u9A8C\u8BC1\uFF1A\u4F20 paths \u6570\u7EC4\u4E00\u6B21\u8BCA\u65AD\u5168\u90E8\uFF08\u6700\u591A 20 \u4E2A\uFF09\uFF0C\u52FF\u9010\u6587\u4EF6\u591A\u6B21\u8C03\u7528\u3002\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B.vue SFC \u4E0E\u5176\u4ED6\u8BED\u8A00\u6269\u5C55\u540D\uFF08.java/.py \u7B49\uFF09\u76F4\u63A5\u62D2\u7EDD\u3001\u52FF\u4F20\u5165\u3002\u9879\u76EE\u7EA7\u5168\u91CF\u8BCA\u65AD\u7528 run_command \u8DD1 `tsc --noEmit`\u3002",
|
|
7450
7585
|
parameters: {
|
|
7451
7586
|
type: "object",
|
|
7452
7587
|
properties: {
|
|
@@ -7501,7 +7636,7 @@ ${sections.join("\n\n")}`;
|
|
|
7501
7636
|
type: "function",
|
|
7502
7637
|
function: {
|
|
7503
7638
|
name: "goto_definition",
|
|
7504
|
-
description: "\u8DF3\u8F6C\u5230
|
|
7639
|
+
description: "\u8DF3\u8F6C\u5230 TS/JS \u6587\u4EF6\u67D0\u884C\u67D0\u5217\u7B26\u53F7\u7684\u5B9A\u4E49\u4F4D\u7F6E\uFF0C\u8FD4\u56DE rel/path:line:col\uFF08\u53EF\u591A\u5904\uFF09\u3002\u8DE8\u6587\u4EF6\u8FFD\u8E2A\u51FD\u6570/\u7C7B\u578B/\u53D8\u91CF\u7684\u6765\u6E90\uFF0C\u66FF\u4EE3 grep \u731C\u6D4B\u3002\u843D\u70B9\u5728 node_modules/.d.ts \u65F6\u6807\u6CE8 (declaration/library)\u3002\u884C\u5217 1-based\u3002\u652F\u6301 .ts/.tsx/.js/.jsx/.mjs/.cjs\uFF1B.vue SFC \u4E0E\u5176\u4ED6\u8BED\u8A00\u6269\u5C55\u540D\u76F4\u63A5\u62D2\u7EDD\u3001\u52FF\u4F20\u5165\u3002",
|
|
7505
7640
|
parameters: {
|
|
7506
7641
|
type: "object",
|
|
7507
7642
|
properties: {
|
|
@@ -7541,7 +7676,7 @@ ${sections.join("\n\n")}`;
|
|
|
7541
7676
|
const lc = posToLineCol(TS, defSf, def.textSpan.start);
|
|
7542
7677
|
loc = `${toDisplayPath(wsRoot, def.fileName)}:${lc.line}:${lc.column}`;
|
|
7543
7678
|
}
|
|
7544
|
-
const isLib =
|
|
7679
|
+
const isLib = isLibFile(def.fileName);
|
|
7545
7680
|
const name = def.name || "(anonymous)";
|
|
7546
7681
|
const kind = def.kind ? ` [${def.kind}]` : "";
|
|
7547
7682
|
return `${name}${kind} \u2192 ${loc}${isLib ? " (declaration/library)" : ""}`;
|
|
@@ -7553,6 +7688,97 @@ ${out.join("\n")}`;
|
|
|
7553
7688
|
}
|
|
7554
7689
|
}
|
|
7555
7690
|
}
|
|
7691
|
+
},
|
|
7692
|
+
{
|
|
7693
|
+
type: "function",
|
|
7694
|
+
function: {
|
|
7695
|
+
name: "find_references",
|
|
7696
|
+
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",
|
|
7697
|
+
parameters: {
|
|
7698
|
+
type: "object",
|
|
7699
|
+
properties: {
|
|
7700
|
+
path: { type: "string", description: "\u76EE\u6807\u6587\u4EF6\u76F8\u5BF9\u8DEF\u5F84\uFF08\u5982 'src/index.ts'\uFF09" },
|
|
7701
|
+
line: { type: "integer", description: "\u7B26\u53F7\u6240\u5728\u884C\u53F7\uFF081-based\uFF09" },
|
|
7702
|
+
column: { type: "integer", description: "\u7B26\u53F7\u6240\u5728\u5217\u53F7\uFF081-based\uFF09" }
|
|
7703
|
+
},
|
|
7704
|
+
required: ["path", "line", "column"]
|
|
7705
|
+
},
|
|
7706
|
+
safetyLevel: "safe" /* SAFE */,
|
|
7707
|
+
isSync: true,
|
|
7708
|
+
maxOutputCharacters: 48e3,
|
|
7709
|
+
// 200 条引用 × ~160 字符摘录的理论上界之内;中心 truncateToolResult 仍是最终兜底
|
|
7710
|
+
privacyMaskingRules: maskSecretsInContent,
|
|
7711
|
+
validateEnvironment: async () => !!await getTs(),
|
|
7712
|
+
async execute(args, _ctx) {
|
|
7713
|
+
const { path: displayPath, line, column } = args;
|
|
7714
|
+
try {
|
|
7715
|
+
const TS = await getTs();
|
|
7716
|
+
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`;
|
|
7717
|
+
const absPath = realpathNative(resolveReadablePath(displayPath));
|
|
7718
|
+
const block = await precheck(displayPath, absPath);
|
|
7719
|
+
if (block) return block;
|
|
7720
|
+
const { ls } = await getLanguageService(TS, absPath);
|
|
7721
|
+
const program = ls.getProgram();
|
|
7722
|
+
if (!program) return `\u274C \u65E0\u6CD5\u53D6\u5F97 TS program\uFF08\u5185\u90E8\u9519\u8BEF\uFF09\u3002`;
|
|
7723
|
+
const sf = program.getSourceFile(absPath);
|
|
7724
|
+
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`;
|
|
7725
|
+
const pos = lineColToPos(TS, sf, line, column);
|
|
7726
|
+
const groups = ls.findReferences(absPath, pos);
|
|
7727
|
+
if (!groups || groups.length === 0) {
|
|
7728
|
+
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`;
|
|
7729
|
+
}
|
|
7730
|
+
const wsRoot = getContainingRoot(absPath);
|
|
7731
|
+
const lineTextCache = /* @__PURE__ */ new Map();
|
|
7732
|
+
const lineSnippet = async (abs, line1) => {
|
|
7733
|
+
let lines = lineTextCache.get(abs);
|
|
7734
|
+
if (!lines) {
|
|
7735
|
+
try {
|
|
7736
|
+
lines = (await fs16.readFile(abs, "utf-8")).split(/\r?\n/);
|
|
7737
|
+
} catch {
|
|
7738
|
+
lines = [];
|
|
7739
|
+
}
|
|
7740
|
+
lineTextCache.set(abs, lines);
|
|
7741
|
+
}
|
|
7742
|
+
const text = (lines[line1 - 1] ?? "").trim();
|
|
7743
|
+
if (!text) return "";
|
|
7744
|
+
return " " + (text.length > REF_SNIPPET_MAX ? text.slice(0, REF_SNIPPET_MAX) + "\u2026" : text);
|
|
7745
|
+
};
|
|
7746
|
+
const sections = [];
|
|
7747
|
+
let shown = 0, overflow = 0;
|
|
7748
|
+
for (const g of groups) {
|
|
7749
|
+
const defSf = program.getSourceFile(g.definition.fileName);
|
|
7750
|
+
let defLoc = toDisplayPath(wsRoot, g.definition.fileName);
|
|
7751
|
+
if (defSf && g.definition.textSpan) {
|
|
7752
|
+
const lc = posToLineCol(TS, defSf, g.definition.textSpan.start);
|
|
7753
|
+
defLoc = `${defLoc}:${lc.line}:${lc.column}`;
|
|
7754
|
+
}
|
|
7755
|
+
const defLib = isLibFile(g.definition.fileName) ? " (declaration/library)" : "";
|
|
7756
|
+
const defName = (g.definition.name || "(anonymous)").replace(/\s+/g, " ");
|
|
7757
|
+
const header = `${defName}${g.definition.kind ? ` [${g.definition.kind}]` : ""} \u2014 ${g.references.length} \u5904\u5F15\u7528\uFF08\u58F0\u660E ${defLoc}\uFF09${defLib}`;
|
|
7758
|
+
const bodyLines = [];
|
|
7759
|
+
for (const r of g.references) {
|
|
7760
|
+
if (shown >= MAX_REF_ENTRIES) {
|
|
7761
|
+
overflow++;
|
|
7762
|
+
continue;
|
|
7763
|
+
}
|
|
7764
|
+
shown++;
|
|
7765
|
+
const refSf = program.getSourceFile(r.fileName);
|
|
7766
|
+
const lc = refSf ? posToLineCol(TS, refSf, r.textSpan.start) : { line: 0, column: 0 };
|
|
7767
|
+
const tag = r.isDefinition ? "[def]" : r.isWriteAccess ? "(write)" : "(read)";
|
|
7768
|
+
const snippet = r.isDefinition ? "" : await lineSnippet(r.fileName, lc.line);
|
|
7769
|
+
bodyLines.push(` ${toDisplayPath(wsRoot, r.fileName)}:${lc.line}:${lc.column} ${tag}${snippet}`);
|
|
7770
|
+
}
|
|
7771
|
+
sections.push([header, ...bodyLines].join("\n"));
|
|
7772
|
+
}
|
|
7773
|
+
const tail = overflow > 0 ? `
|
|
7774
|
+
\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` : "";
|
|
7775
|
+
return `[References: ${displayPath}:${line}:${column}]
|
|
7776
|
+
${sections.join("\n")}${tail}`;
|
|
7777
|
+
} catch (e) {
|
|
7778
|
+
return `\u274C \u67E5\u627E\u5F15\u7528\u5931\u8D25 [${displayPath}:${line}:${column}]: ${e?.message ?? e}`;
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7781
|
+
}
|
|
7556
7782
|
}
|
|
7557
7783
|
];
|
|
7558
7784
|
}
|
|
@@ -8528,10 +8754,9 @@ var init_ask = __esm({
|
|
|
8528
8754
|
function: {
|
|
8529
8755
|
name: "ask_question",
|
|
8530
8756
|
description: [
|
|
8531
|
-
"\u5411\u7528\u6237\u63D0\u51FA\
|
|
8532
|
-
"
|
|
8533
|
-
"\
|
|
8534
|
-
"\u6CE8\u610F\uFF1A\u4EC5\u5728\u4EA4\u4E92\u5F0F\u73AF\u5883\u53EF\u7528\uFF1B\u82E5\u7ED3\u679C\u63D0\u793A\u300C\u4E0D\u652F\u6301\u300D\uFF0C\u6539\u7528\u7EAF\u6587\u672C\u5411\u7528\u6237\u63D0\u95EE\u3002"
|
|
8757
|
+
"\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",
|
|
8758
|
+
"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",
|
|
8759
|
+
"\u4EC5\u4EA4\u4E92\u5F0F\u73AF\u5883\u53EF\u7528\uFF1B\u7ED3\u679C\u63D0\u793A\u300C\u4E0D\u652F\u6301\u300D\u65F6\u6539\u7528\u7EAF\u6587\u672C\u63D0\u95EE\u3002"
|
|
8535
8760
|
].join("\n"),
|
|
8536
8761
|
parameters: {
|
|
8537
8762
|
type: "object",
|
|
@@ -8974,30 +9199,30 @@ ${body.trim()}
|
|
|
8974
9199
|
type: "function",
|
|
8975
9200
|
function: {
|
|
8976
9201
|
name: "memory_save",
|
|
8977
|
-
description: "\u4FDD\u5B58\u4E00\u6761\u6301\u4E45\u8BB0\u5FC6\uFF08\u8DE8\u4F1A\u8BDD\u4FDD\u7559\uFF09\
|
|
9202
|
+
description: "\u4FDD\u5B58\u4E00\u6761\u6301\u4E45\u8BB0\u5FC6\uFF08\u8DE8\u4F1A\u8BDD\u4FDD\u7559\uFF09\uFF1A\u975E\u663E\u7136\u7684\u4E8B\u5B9E\u3001\u7528\u6237\u504F\u597D\u3001\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\u3001\u9879\u76EE\u7EA6\u675F\u3001\u5916\u90E8\u8D44\u6E90\u6307\u9488\u2014\u2014\u300C\u4E0D\u5E94\u6BCF\u6B21\u91CD\u65B0\u53D1\u73B0\u300D\u300C\u4EE3\u7801/git \u4E0D\u4F1A\u76F4\u63A5\u544A\u8BC9\u4F60\u300D\u7684\u4FE1\u606F\u3002\u52FF\u5B58\u4F1A\u8BDD\u5185\u5373\u629B\u7684\u4E34\u65F6\u4FE1\u606F\u3002\u4FDD\u5B58\u540E\u8BB0\u5FC6\u7D22\u5F15\u81EA\u52A8\u66F4\u65B0\uFF1B\u540C\u540D\u8BB0\u5FC6\u88AB\u8986\u76D6\u3002",
|
|
8978
9203
|
parameters: {
|
|
8979
9204
|
type: "object",
|
|
8980
9205
|
properties: {
|
|
8981
9206
|
name: {
|
|
8982
9207
|
type: "string",
|
|
8983
|
-
description: "\
|
|
9208
|
+
description: "\u552F\u4E00\u952E\uFF0C\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u8FDE\u5B57\u7B26\uFF08\u63CF\u8FF0\u6027 kebab-case\uFF0C\u5982 user-prefers-arrow-fns\uFF09"
|
|
8984
9209
|
},
|
|
8985
9210
|
description: {
|
|
8986
9211
|
type: "string",
|
|
8987
|
-
description: "\u4E00\u53E5\u8BDD\u6982\u62EC\
|
|
9212
|
+
description: "\u4E00\u53E5\u8BDD\u6982\u62EC\uFF08\u6CE8\u5165\u7D22\u5F15\u4F9B\u65E5\u540E\u5224\u65AD\u662F\u5426\u53EC\u56DE\uFF09\u3002\u52FF\u6362\u884C"
|
|
8988
9213
|
},
|
|
8989
9214
|
body: {
|
|
8990
9215
|
type: "string",
|
|
8991
|
-
description: "\u8BB0\u5FC6\u6B63\u6587\
|
|
9216
|
+
description: "\u8BB0\u5FC6\u6B63\u6587\uFF0C\u53EF\u591A\u884C\uFF0C\u4E0A\u9650 64KB"
|
|
8992
9217
|
},
|
|
8993
9218
|
type: {
|
|
8994
9219
|
type: "string",
|
|
8995
9220
|
enum: ["user", "feedback", "project", "reference"],
|
|
8996
|
-
description: "user=\u7528\u6237\u753B\u50CF/\u504F\u597D\uFF1Bfeedback=\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\uFF08\u542B\u539F\u56E0\u4E0E\u505A\u6CD5\uFF09\uFF1Bproject=\u9879\u76EE\u76EE\u6807/\u7EA6\u675F\uFF1Breference=\u5916\u90E8\u8D44\u6E90\u6307\u9488\
|
|
9221
|
+
description: "user=\u7528\u6237\u753B\u50CF/\u504F\u597D\uFF1Bfeedback=\u5DE5\u4F5C\u65B9\u5F0F\u53CD\u9988\uFF08\u542B\u539F\u56E0\u4E0E\u505A\u6CD5\uFF09\uFF1Bproject=\u9879\u76EE\u76EE\u6807/\u7EA6\u675F\uFF1Breference=\u5916\u90E8\u8D44\u6E90\u6307\u9488\u3002\u9ED8\u8BA4 reference"
|
|
8997
9222
|
},
|
|
8998
9223
|
project: {
|
|
8999
9224
|
type: "boolean",
|
|
9000
|
-
description: "
|
|
9225
|
+
description: "true=\u5199\u5165\u9879\u76EE .deepseeker-code/memory\uFF08\u53EF\u63D0\u4EA4 git \u5171\u4EAB\uFF09\uFF1B\u9ED8\u8BA4 false\uFF08\u5168\u5C40\uFF0C\u4EC5\u672C\u673A\uFF09"
|
|
9001
9226
|
}
|
|
9002
9227
|
},
|
|
9003
9228
|
required: ["name", "description", "body"]
|
|
@@ -9150,7 +9375,7 @@ var init_recall = __esm({
|
|
|
9150
9375
|
type: "function",
|
|
9151
9376
|
function: {
|
|
9152
9377
|
name: "recall",
|
|
9153
|
-
description: "\u68C0\u7D22\u3010\u672C\u4F1A\u8BDD\u3011\u5168\u91CF\u5386\u53F2\
|
|
9378
|
+
description: "\u68C0\u7D22\u3010\u672C\u4F1A\u8BDD\u3011\u5168\u91CF\u5386\u53F2\uFF08\u542B\u5DF2\u88AB\u538B\u7F29\u5F52\u6863\u7684\u539F\u59CB\u6D88\u606F\u4E0E\u5DE5\u5177\u7ED3\u679C\uFF09\u3002\u65F6\u673A\uFF1A\u6EDA\u52A8\u6458\u8981\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u7EC6\u8282\u65F6\uFF08\u5F52\u6863\u524D\u7684\u6587\u4EF6\u5185\u5BB9/\u62A5\u9519\u539F\u6587/\u7528\u6237\u65E9\u524D\u8981\u6C42\uFF09\u2014\u2014\u5148\u68C0\u7D22\uFF0C\u4E0D\u8981\u51ED\u6458\u8981\u81C6\u6D4B\uFF0C\u4E5F\u4E0D\u8981\u91CD\u8DD1\u5DE5\u5177\u3002query \u7528\u5177\u4F53\u5B9E\u4F53\u8BCD\uFF1A\u62A5\u9519\u5173\u952E\u8BCD\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u51FD\u6570/\u7B26\u53F7\u540D\uFF08\u4F18\u5148\u53D6\u6458\u8981\u5B9E\u4F53\u7D22\u5F15 \u27E6DSC:ARCHIVE-INDEX\u27E7 \u91CC\u51FA\u73B0\u8FC7\u7684\uFF09\uFF1B\u5FCC\u7528\u5DE5\u5177\u540D\u6216\u6CDB\u8BCD\uFF08\u4EE3\u7801/\u6587\u4EF6/\u95EE\u9898\uFF09\u3002\u672A\u547D\u4E2D\u5C31\u6362\u66F4\u5177\u4F53\u7684\u8BCD\uFF0C\u6216 is_regex=true \u7528 | \u5408\u5E76\u591A\u5019\u9009\u8BCD\uFF0C\u901A\u5E38 1-2 \u6B21\u5185\u547D\u4E2D\u3002\u8FD4\u56DE\u6309\u65F6\u95F4\u65E7\u2192\u65B0\uFF1B\u6587\u4EF6\u7C7B\u7ED3\u679C\u9644\u5B9E\u65F6\u6821\u9A8C\uFF1A\u26A0\uFE0F \u5DF2\u4FEE\u6539/\u5DF2\u4E0D\u5B58\u5728\u5FC5\u987B\u91CD\u65B0 read_file \u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539\uFF0C\u2713 \u672A\u53D8\u53EF\u76F4\u63A5\u5F15\u7528\u3002\u66FE\u88AB\u622A\u65AD\u7684\u7ED3\u679C\u4F1A\u6807\u6CE8 with_full \u53D6\u5B58\u6863\u5168\u6587\u3002\u6458\u8981\u5DF2\u591F\u65F6\u52FF\u8C03\u7528\uFF08\u7701 token\uFF09\u3002",
|
|
9154
9379
|
parameters: {
|
|
9155
9380
|
type: "object",
|
|
9156
9381
|
properties: {
|
|
@@ -9630,7 +9855,8 @@ async function runBackgroundTool(gen, lockKey, toolName, signal) {
|
|
|
9630
9855
|
if (lockKey && !acquireLock(lockKey)) {
|
|
9631
9856
|
try {
|
|
9632
9857
|
await gen.return(void 0);
|
|
9633
|
-
} catch {
|
|
9858
|
+
} catch (e) {
|
|
9859
|
+
console.warn("\u26A0\uFE0F \u5173\u95ED\u672A\u6D88\u8D39\u7684\u540E\u53F0 generator \u5931\u8D25:", e instanceof Error ? e.message : e);
|
|
9634
9860
|
}
|
|
9635
9861
|
return `\u{1F512} [\u4E92\u65A5\u9501\u963B\u585E]\uFF1A\u9501 [${lockKey}] \u5DF2\u88AB\u5360\u7528\uFF0C[${toolName}] \u672A\u542F\u52A8\u3002`;
|
|
9636
9862
|
}
|
|
@@ -9681,7 +9907,7 @@ var init_backgroundTool = __esm({
|
|
|
9681
9907
|
|
|
9682
9908
|
// ../core/src/tool/autoPermission.ts
|
|
9683
9909
|
import path30 from "path";
|
|
9684
|
-
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9910
|
+
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, PKG_MGR, SCRIPT_RUNNER_HEADS, SCRIPT_RUNNER_READONLY, isScriptRunnerCommand, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9685
9911
|
var init_autoPermission = __esm({
|
|
9686
9912
|
"../core/src/tool/autoPermission.ts"() {
|
|
9687
9913
|
"use strict";
|
|
@@ -9788,12 +10014,25 @@ var init_autoPermission = __esm({
|
|
|
9788
10014
|
// —— 版本号 ——
|
|
9789
10015
|
/^(node|npm|pnpm|npx|git|tsc|python|python3)\s+(-v|-V|--version)\b/,
|
|
9790
10016
|
// —— 验证类(跑项目代码但不改源码)——
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
10017
|
+
// ★ npm/pnpm/npx/yarn 系「跑脚本」命令已整类移出免审清单(isScriptRunnerCommand 单独治理,见下方):
|
|
10018
|
+
// package.json scripts 是仓库作者的任意代码、npx 未装包时还会从 registry 拉取执行——
|
|
10019
|
+
// hasShellMetachars 检查的是命令串本身,拦不到脚本内容(恶意 repo 投毒面)。
|
|
10020
|
+
// 改走「首次人工确认 + allow-always 按精确命令串记住」路径(toolExecution 的 scriptRunnerBlocked 门)。
|
|
9795
10021
|
/^tsc --noEmit\b/
|
|
9796
10022
|
];
|
|
10023
|
+
PKG_MGR = String.raw`\s*([^\s"'\`]*[\\/])?(npx|npm|pnpm|yarn|corepack)(\.cmd|\.exe|\.ps1|\.bat)?\b`;
|
|
10024
|
+
SCRIPT_RUNNER_HEADS = [
|
|
10025
|
+
new RegExp(`^${PKG_MGR}`, "i")
|
|
10026
|
+
];
|
|
10027
|
+
SCRIPT_RUNNER_READONLY = [
|
|
10028
|
+
new RegExp(`^${PKG_MGR}\\s+(-v|-V|--version)\\b`, "i")
|
|
10029
|
+
];
|
|
10030
|
+
isScriptRunnerCommand = (cmd) => {
|
|
10031
|
+
const c = (cmd || "").trim();
|
|
10032
|
+
if (!c || hasShellMetachars(c)) return false;
|
|
10033
|
+
if (SCRIPT_RUNNER_READONLY.some((re) => re.test(c))) return false;
|
|
10034
|
+
return SCRIPT_RUNNER_HEADS.some((re) => re.test(c));
|
|
10035
|
+
};
|
|
9797
10036
|
hasWriteModifier = (cmd) => {
|
|
9798
10037
|
if (!cmd) return false;
|
|
9799
10038
|
if (/^sed\b/.test(cmd) && /(^|\s)-i\b/.test(cmd)) return true;
|
|
@@ -9950,7 +10189,7 @@ var init_toolExecution = __esm({
|
|
|
9950
10189
|
preHooksAdvanced = true;
|
|
9951
10190
|
let veto;
|
|
9952
10191
|
try {
|
|
9953
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10192
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
9954
10193
|
} catch (e) {
|
|
9955
10194
|
veto = { deny: true, reason: `\u274C [Pre-hook \u5F02\u5E38]\uFF1A${e?.message ?? e}\u3002\u51FA\u4E8E\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD [${calledName}] \u7684\u6267\u884C\u3002` };
|
|
9956
10195
|
}
|
|
@@ -9982,7 +10221,20 @@ var init_toolExecution = __esm({
|
|
|
9982
10221
|
} catch {
|
|
9983
10222
|
perm = null;
|
|
9984
10223
|
}
|
|
9985
|
-
|
|
10224
|
+
const cmdIsScriptRunner = (calledName === "run_command" || calledName === "run_in_background") && isScriptRunnerCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "");
|
|
10225
|
+
const argCwd = typeof calledArgs?.cwd === "string" ? calledArgs.cwd.trim() : "";
|
|
10226
|
+
const samePath = (a, b) => {
|
|
10227
|
+
try {
|
|
10228
|
+
const ra = path31.resolve(a), rb = path31.resolve(b);
|
|
10229
|
+
return process.platform === "win32" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;
|
|
10230
|
+
} catch {
|
|
10231
|
+
return false;
|
|
10232
|
+
}
|
|
10233
|
+
};
|
|
10234
|
+
const scriptRunnerCwdDrift = cmdIsScriptRunner && argCwd !== "" && !samePath(argCwd, toolCtx.cwd ?? process.cwd());
|
|
10235
|
+
const scriptRunnerBlocked = cmdIsScriptRunner && (perm === null || scriptRunnerCwdDrift);
|
|
10236
|
+
if (scriptRunnerCwdDrift) needApproval = true;
|
|
10237
|
+
if (perm === null && needApproval && !denied && !scriptRunnerBlocked && calledName === "run_command" && isReadOnlyCommand(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
9986
10238
|
needApproval = false;
|
|
9987
10239
|
}
|
|
9988
10240
|
if ((calledName === "run_command" || calledName === "run_in_background") && matchCommandDeny(typeof calledArgs?.command === "string" ? calledArgs.command : "")) {
|
|
@@ -9995,7 +10247,7 @@ var init_toolExecution = __esm({
|
|
|
9995
10247
|
denied = true;
|
|
9996
10248
|
result = `\u{1F512} [\u4E92\u65A5\u9501\u963B\u585E]\uFF1A\u5DF2\u6709\u540E\u53F0\u4EFB\u52A1\u6301\u6709\u9501 [${lockKey}]\uFF0C[${calledName}] \u8C03\u7528\u88AB\u8DF3\u8FC7\u3002`;
|
|
9997
10249
|
}
|
|
9998
|
-
if (needApproval && !denied) {
|
|
10250
|
+
if (needApproval && !denied && !scriptRunnerBlocked) {
|
|
9999
10251
|
const auto = await runAutoCheck(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx, permissionMode === "auto");
|
|
10000
10252
|
if (auto === "allow") {
|
|
10001
10253
|
needApproval = false;
|
|
@@ -10030,7 +10282,7 @@ var init_toolExecution = __esm({
|
|
|
10030
10282
|
if (!denied && !preHooksAdvanced) {
|
|
10031
10283
|
let veto;
|
|
10032
10284
|
try {
|
|
10033
|
-
veto = await runPreHooks(calledName, calledArgs, toolCtx);
|
|
10285
|
+
veto = await runPreHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, toolCtx);
|
|
10034
10286
|
} catch (e) {
|
|
10035
10287
|
veto = { deny: true, reason: `\u274C [Pre-hook \u5F02\u5E38]\uFF1A${e?.message ?? e}\u3002\u51FA\u4E8E\u5B89\u5168\u9ED8\u8BA4\u62D2\u7EDD [${calledName}] \u7684\u6267\u884C\u3002` };
|
|
10036
10288
|
}
|
|
@@ -10072,7 +10324,7 @@ ${result}`;
|
|
|
10072
10324
|
events({ sessionId, eventType: "tool.failed", metadata: { depth, decisionSource: llmDecisionSource, durationMs: performance.now() - startTime, round, tools_id: toolCall.id, toolName: calledName, toolSource: "builtin", ok: false, attempt: round }, payload: { output: result } });
|
|
10073
10325
|
}
|
|
10074
10326
|
try {
|
|
10075
|
-
const post = await runPostHooks(calledName, calledArgs, result, toolCtx);
|
|
10327
|
+
const post = await runPostHooks(resolveMcpPermissionName(calledName, calledArgs), calledArgs, result, toolCtx);
|
|
10076
10328
|
postHookOverride = post?.resultOverride;
|
|
10077
10329
|
} catch (e) {
|
|
10078
10330
|
console.warn(`\u26A0\uFE0F post-hook [${calledName}] \u5F02\u5E38\uFF08\u5DF2\u5FFD\u7565\uFF09:`, e?.message ?? e);
|
|
@@ -10232,7 +10484,8 @@ var init_toolScheduling = __esm({
|
|
|
10232
10484
|
});
|
|
10233
10485
|
|
|
10234
10486
|
// ../core/src/agent/streamInference.ts
|
|
10235
|
-
|
|
10487
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
10488
|
+
var sha1short, RETRY_BACKOFF_CAP_MS, extractRetryAfterMs, withNudgeTail, streamInference;
|
|
10236
10489
|
var init_streamInference = __esm({
|
|
10237
10490
|
"../core/src/agent/streamInference.ts"() {
|
|
10238
10491
|
"use strict";
|
|
@@ -10241,6 +10494,32 @@ var init_streamInference = __esm({
|
|
|
10241
10494
|
init_transcript();
|
|
10242
10495
|
init_contextCore();
|
|
10243
10496
|
init_contentParts();
|
|
10497
|
+
sha1short = (s) => createHash2("sha1").update(s).digest("hex").slice(0, 10);
|
|
10498
|
+
RETRY_BACKOFF_CAP_MS = 3e4;
|
|
10499
|
+
extractRetryAfterMs = (e) => {
|
|
10500
|
+
try {
|
|
10501
|
+
const h = e?.headers;
|
|
10502
|
+
if (!h) return null;
|
|
10503
|
+
const get = (k) => typeof h.get === "function" ? h.get(k) ?? void 0 : h[k] ?? h[k.toLowerCase()];
|
|
10504
|
+
const ms = get("retry-after-ms");
|
|
10505
|
+
if (ms != null) {
|
|
10506
|
+
const n = Number(ms);
|
|
10507
|
+
if (Number.isFinite(n) && n >= 0) return n;
|
|
10508
|
+
}
|
|
10509
|
+
const sec = get("retry-after");
|
|
10510
|
+
if (sec != null) {
|
|
10511
|
+
const n = Number(sec);
|
|
10512
|
+
if (Number.isFinite(n) && n >= 0) return n * 1e3;
|
|
10513
|
+
}
|
|
10514
|
+
} catch {
|
|
10515
|
+
}
|
|
10516
|
+
return null;
|
|
10517
|
+
};
|
|
10518
|
+
withNudgeTail = (base, nudge) => {
|
|
10519
|
+
if (!nudge) return base;
|
|
10520
|
+
const lastRole = base[base.length - 1]?.role;
|
|
10521
|
+
return [...base, lastRole === "assistant" ? { ...nudge, role: "user" } : nudge];
|
|
10522
|
+
};
|
|
10244
10523
|
streamInference = async function* (ctx) {
|
|
10245
10524
|
const {
|
|
10246
10525
|
message,
|
|
@@ -10253,21 +10532,29 @@ var init_streamInference = __esm({
|
|
|
10253
10532
|
llmDecisionSource,
|
|
10254
10533
|
signal,
|
|
10255
10534
|
cleanedToolSchemas,
|
|
10256
|
-
model
|
|
10535
|
+
model,
|
|
10257
10536
|
thinkingLevel,
|
|
10258
10537
|
events,
|
|
10259
10538
|
keepRecentUnits,
|
|
10260
10539
|
compactRatio,
|
|
10261
|
-
modelWindow
|
|
10540
|
+
modelWindow,
|
|
10541
|
+
toolsTokens = 0
|
|
10262
10542
|
} = ctx;
|
|
10263
|
-
let inferenceMessages =
|
|
10543
|
+
let inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10264
10544
|
let assistantMessage = { role: "assistant", content: null };
|
|
10265
10545
|
try {
|
|
10546
|
+
const prefixFingerprint = {
|
|
10547
|
+
toolsHash: sha1short(JSON.stringify(cleanedToolSchemas)),
|
|
10548
|
+
sysHash: sha1short(String(message[0]?.content ?? "")),
|
|
10549
|
+
sumHash: sha1short(String(message[1]?.content ?? "")),
|
|
10550
|
+
msgCount: message.length
|
|
10551
|
+
};
|
|
10266
10552
|
events({
|
|
10267
10553
|
sessionId,
|
|
10268
10554
|
eventType: "llm.request",
|
|
10269
|
-
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
10270
|
-
|
|
10555
|
+
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model, ...prefixFingerprint },
|
|
10556
|
+
// ★ P2 口径:估算加上工具 schema 常数项(与 API 真实 prompt_tokens 同口径,trace 里 est/real 才可比)
|
|
10557
|
+
usage: { prompt_tokens: estimateTokens(inferenceMessages) + toolsTokens },
|
|
10271
10558
|
payload: { input: msgText(message[message.length - 1].content) }
|
|
10272
10559
|
// ★ 多模态:trace 只记文本视图
|
|
10273
10560
|
});
|
|
@@ -10277,12 +10564,12 @@ var init_streamInference = __esm({
|
|
|
10277
10564
|
const toolCallsBuf = /* @__PURE__ */ new Map();
|
|
10278
10565
|
let lastUsage;
|
|
10279
10566
|
const MAX_STREAM_RETRIES = 2;
|
|
10280
|
-
const MAX_API_RETRIES =
|
|
10567
|
+
const MAX_API_RETRIES = 3;
|
|
10281
10568
|
let apiRetries = 0;
|
|
10282
10569
|
let compactedThisRound = false;
|
|
10283
10570
|
for (let streamAttempt = 0; ; streamAttempt++) {
|
|
10284
10571
|
try {
|
|
10285
|
-
for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model
|
|
10572
|
+
for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model, thinkingLevel })) {
|
|
10286
10573
|
if (signal?.aborted) break;
|
|
10287
10574
|
switch (chunk.kind) {
|
|
10288
10575
|
case "text":
|
|
@@ -10337,10 +10624,15 @@ var init_streamInference = __esm({
|
|
|
10337
10624
|
}
|
|
10338
10625
|
if (activeProvider.isTransientError(streamErr) && apiRetries < MAX_API_RETRIES && !signal?.aborted) {
|
|
10339
10626
|
apiRetries++;
|
|
10340
|
-
const
|
|
10627
|
+
const retryAfterMs = extractRetryAfterMs(streamErr);
|
|
10628
|
+
const backoffMs = Math.min(
|
|
10629
|
+
Math.max(1e3 * Math.pow(2, apiRetries - 1), retryAfterMs ?? 0),
|
|
10630
|
+
RETRY_BACKOFF_CAP_MS
|
|
10631
|
+
);
|
|
10341
10632
|
if (!noOutputYet) yield { type: "text.reset" };
|
|
10342
10633
|
const statusHint = streamErr?.status ? `${streamErr.status} ` : "";
|
|
10343
|
-
|
|
10634
|
+
const raHint = retryAfterMs != null ? `\uFF0C\u9075 Retry-After=${retryAfterMs}ms` : "";
|
|
10635
|
+
console.warn(`\u26A0\uFE0F API \u77AC\u65F6\u9519\u8BEF\uFF08${statusHint}${streamErr instanceof Error ? streamErr.message : String(streamErr)}\uFF09\uFF0C${backoffMs}ms \u540E\u7B2C ${apiRetries}/${MAX_API_RETRIES} \u6B21\u91CD\u8BD5${raHint}...`);
|
|
10344
10636
|
await new Promise((resolve, reject) => {
|
|
10345
10637
|
const t = setTimeout(resolve, backoffMs);
|
|
10346
10638
|
signal?.addEventListener("abort", () => {
|
|
@@ -10364,9 +10656,10 @@ var init_streamInference = __esm({
|
|
|
10364
10656
|
modelWindow,
|
|
10365
10657
|
events,
|
|
10366
10658
|
depth,
|
|
10367
|
-
signal
|
|
10659
|
+
signal,
|
|
10660
|
+
toolsTokens
|
|
10368
10661
|
});
|
|
10369
|
-
inferenceMessages =
|
|
10662
|
+
inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
10370
10663
|
compactedThisRound = true;
|
|
10371
10664
|
contentBuf = "";
|
|
10372
10665
|
reasoningBuf = "";
|
|
@@ -10393,7 +10686,7 @@ var init_streamInference = __esm({
|
|
|
10393
10686
|
events({
|
|
10394
10687
|
sessionId,
|
|
10395
10688
|
eventType: "llm.response",
|
|
10396
|
-
metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
10689
|
+
metadata: { depth, decisionSource: llmDecisionSource, ok: true, durationMs: performance.now() - startTime, round, model },
|
|
10397
10690
|
usage: {
|
|
10398
10691
|
prompt_tokens: lastUsage?.prompt_tokens,
|
|
10399
10692
|
completion_tokens: lastUsage?.completion_tokens,
|
|
@@ -10447,12 +10740,12 @@ var init_agentNudges = __esm({
|
|
|
10447
10740
|
GREP_REPEAT_THRESHOLD = 2;
|
|
10448
10741
|
REPEAT_NUDGE_MAX = 3;
|
|
10449
10742
|
PHANTOM_TEXT = "\u4F60\u7684\u4E0A\u4E00\u6761\u56DE\u590D\u6CA1\u6709\u4EFB\u4F55\u5185\u5BB9\u3001\u4E5F\u6CA1\u6709\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\uFF0C\u4F46\u4EFB\u52A1\u5C1A\u672A\u5B8C\u6210\u3002\u8BF7\u7EE7\u7EED\u63A8\u8FDB\uFF08\u8C03\u7528\u5DE5\u5177\u6216\u7ED9\u51FA\u5B9E\u8D28\u56DE\u7B54\uFF09\uFF1B\u82E5\u786E\u5B9E\u53D7\u963B\u3001\u9700\u8981\u7528\u6237\u51B3\u7B56\uFF0C\u7528 ask_question \u8BF4\u660E\u5177\u4F53\u963B\u585E\u70B9\u3002\u4E0D\u8981\u8FD4\u56DE\u7A7A\u56DE\u590D\u3002";
|
|
10450
|
-
EARLY_FINAL_TEXT = (round) => `\u4F60\u4EC5
|
|
10743
|
+
EARLY_FINAL_TEXT = (round) => `\u4F60\u4EC5 ${round} \u8F6E\u5C31\u51C6\u5907\u6536\u5C3E\uFF0C\u4E14\u56DE\u7B54\u4E2D\u6CA1\u6709\u660E\u786E\u7684\u5B8C\u6210\u58F0\u660E\u3002\u8BF7\u81EA\u68C0\uFF1A\u82E5\u7528\u6237\u8F93\u5165\u672C\u5C31\u65E0\u9700\u5DE5\u5177\uFF08\u5BD2\u6684/\u95F2\u804A/\u7EAF\u95EE\u7B54\uFF09\u3001\u6216\u4F60\u5728\u7B49\u7528\u6237\u6F84\u6E05\u51B3\u7B56\uFF0C\u76F4\u63A5\u6B63\u5E38\u56DE\u5E94\u5373\u53EF\uFF0C\u5FFD\u7565\u672C\u81EA\u68C0\u3001\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u81EA\u68C0\u8BF4\u660E\uFF1B\u82E5\u786E\u6709\u4EFB\u52A1\u672A\u843D\u5730\uFF08\u6240\u9700\u4FE1\u606F\u672A\u83B7\u53D6\u9F50 / \u8BE5\u6539\u7684\u6587\u4EF6\u672A\u6539\u5B8C / \u672A\u9A8C\u8BC1\uFF09\uFF0C\u7ACB\u5373\u7EE7\u7EED\u8C03\u7528\u5DE5\u5177\u63A8\u8FDB\uFF0C\u4E0D\u8981\u8349\u7387\u603B\u7ED3\u6536\u5C3E\uFF1B\u82E5\u786E\u5DF2\u5168\u90E8\u5B8C\u6210\uFF0C\u8BF7\u660E\u786E\u56DE\u590D\u300C\u5DF2\u5B8C\u6210\u300D\u5E76\u7B80\u8FF0\u6210\u679C\u3002`;
|
|
10451
10744
|
TOOL_DIGEST_TEXT = "\u4F60\u521A\u6267\u884C\u5B8C\u5DE5\u5177\u62FF\u5230\u7ED3\u679C\uFF0C\u5374\u672A\u57FA\u4E8E\u8BE5\u7ED3\u679C\u7ED9\u51FA\u5B9E\u8D28\u56DE\u5E94\u5C31\u51C6\u5907\u6536\u5C3E\u3002\u8BF7\u7ED3\u5408\u5DE5\u5177\u8FD4\u56DE\u7ED3\u679C\u7EE7\u7EED\u63A8\u8FDB\uFF1B\u82E5\u7ED3\u679C\u8868\u660E\u4EFB\u52A1\u5C1A\u672A\u5B8C\u6210\uFF08\u5982\u4ECD\u5728\u7F16\u8BD1/\u8FD0\u884C\u3001\u9700\u7EE7\u7EED\u8F6E\u8BE2\uFF09\uFF0C\u7ACB\u5373\u91C7\u53D6\u4E0B\u4E00\u6B65\u884C\u52A8\uFF0C\u4E0D\u8981\u7A7A\u624B\u6536\u5C3E\u3002\u82E5\u786E\u5DF2\u5168\u90E8\u5B8C\u6210\uFF0C\u8BF7\u660E\u786E\u56DE\u590D\u300C\u5DF2\u5B8C\u6210\u300D\u5E76\u7B80\u8FF0\u6210\u679C\u3002";
|
|
10452
10745
|
NUDGE_TEXT = (round) => `\u4F60\u5DF2\u6267\u884C\u7EA6 ${round} \u8F6E\u5DE5\u5177\u8C03\u7528\u3002\u8BF7\u81EA\u8BC4\uFF1A\u82E5\u4EFB\u52A1\u5DF2\u53EF\u5B8C\u6210\uFF0C\u7ACB\u5373\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\u3001\u4E0D\u518D\u8C03\u7528\u5DE5\u5177\uFF1B\u82E5\u786E\u9700\u66F4\u591A\u6B65\u9AA4\uFF0C\u7EE7\u7EED\uFF0C\u4F46\u786E\u4FDD\u6BCF\u6B65\u90FD\u5728\u5B9E\u8D28\u63A8\u8FDB\u4EFB\u52A1\u3001\u4E0D\u91CD\u590D\u68C0\u7D22\u3002`;
|
|
10453
|
-
COMPLEX_VERBS =
|
|
10454
|
-
COMPLEX_OBJECTS =
|
|
10455
|
-
COMPLEX_MARKERS = /多个文件|多文件|整体|全套|端到端|从零|重新设计|一整套|跨[^,。\s]{1,6}
|
|
10746
|
+
COMPLEX_VERBS = /实现|新增|添加|重构|改造|迁移|重写|拆分|升级|开发|编写|构建|集成|支持|完善|implement|refactor|migrate|rewrite|rebuild|restructure|split|upgrade|integrate|develop/i;
|
|
10747
|
+
COMPLEX_OBJECTS = /功能|模块|系统|架构|流程|机制|组件|服务|页面|接口|能力|特性|面板|feature|module|system|architecture|pipeline|component|service|page|api\b|interface|panel|workflow|endpoint/i;
|
|
10748
|
+
COMPLEX_MARKERS = /多个文件|多文件|整体|全套|端到端|从零|重新设计|一整套|跨[^,。\s]{1,6}|multiple files|multi-file|end-to-end|from scratch|across\s+\S+/i;
|
|
10456
10749
|
QUERY_LEAD = /^(请)?\s*(解释|说明|查(一下|询)?|搜索|搜一下|怎么看|如何(用|使用|配置|启动)|怎么用|为什么|是什么|帮我看看|分析一下|检查|review|对比|评价)/i;
|
|
10457
10750
|
looksComplex = (text) => {
|
|
10458
10751
|
const t = (text || "").trim();
|
|
@@ -10480,7 +10773,7 @@ var init_agentNudges = __esm({
|
|
|
10480
10773
|
return s;
|
|
10481
10774
|
};
|
|
10482
10775
|
normQuery = (q) => String(q ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
10483
|
-
REPEAT_READ_TEXT = (p, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u8BFB\u53D6\u300C${p}\u300D\u2014\u2014\u8BE5\u6587\u4EF6\u5185\u5BB9\u4F60\u65E9\u5DF2\u62E5\u6709\uFF0C\u65E0\u9700\u6574\u6587\u4EF6\u91CD\u8BFB\u3002\u5982\u9700\u67D0\u5904\u7EC6\u8282\u8BF7\u56DE\u770B\u4E4B\u524D\u7684\u5DE5\u5177\u7ED3\u679C\uFF1B\u82E5\u8BE5\u6587\u4EF6\u521A\u88AB\u6539\u52A8\u3001\u786E\u9700\u786E\u8BA4\uFF0C\u53EA\u8BFB\u6539\u52A8\u9644\u8FD1\u51E0\u884C\u5373\u53EF\uFF0C\u4E0D\u8981\u6574\u6587\u4EF6\u91CD\u8BFB\u3002`;
|
|
10776
|
+
REPEAT_READ_TEXT = (p, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u8BFB\u53D6\u300C${p}\u300D\u2014\u2014\u8BE5\u6587\u4EF6\u5185\u5BB9\u4F60\u65E9\u5DF2\u62E5\u6709\uFF0C\u65E0\u9700\u6574\u6587\u4EF6\u91CD\u8BFB\u3002\u5982\u9700\u67D0\u5904\u7EC6\u8282\u8BF7\u56DE\u770B\u4E4B\u524D\u7684\u5DE5\u5177\u7ED3\u679C\uFF08\u65E9\u524D\u8BFB\u53D6\u53EF\u80FD\u5DF2\u88AB\u5F52\u6863\uFF0C\u53EF\u7528 recall \u5DE5\u5177\u68C0\u7D22\u53D6\u56DE\u539F\u6587\uFF09\uFF1B\u82E5\u8BE5\u6587\u4EF6\u521A\u88AB\u6539\u52A8\u3001\u786E\u9700\u786E\u8BA4\uFF0C\u53EA\u8BFB\u6539\u52A8\u9644\u8FD1\u51E0\u884C\u5373\u53EF\uFF0C\u4E0D\u8981\u6574\u6587\u4EF6\u91CD\u8BFB\u3002`;
|
|
10484
10777
|
REPEAT_GREP_TEXT = (q, n) => `\u4F60\u5DF2\u7B2C ${n} \u6B21\u68C0\u7D22\u300C${q}\u300D\u2014\u2014\u4E4B\u524D\u7684\u7ED3\u679C\u4F60\u5DF2\u62E5\u6709\u3002\u8BF7\u6539\u7528 read_file \u8BFB\u5B8C\u6574\u76EE\u6807\u6587\u4EF6\u7406\u89E3\u4E0A\u4E0B\u6587\uFF0C\u6216\u7F29\u5C0F/\u8C03\u6574\u68C0\u7D22\u8303\u56F4\uFF0C\u4E0D\u8981\u91CD\u590D\u540C\u4E00\u68C0\u7D22\u3002`;
|
|
10485
10778
|
createNudgeScheduler = (opts = {}) => {
|
|
10486
10779
|
const firstPrompt = opts.firstPrompt ?? "";
|
|
@@ -10548,7 +10841,7 @@ ${TOOL_DIGEST_TEXT}` };
|
|
|
10548
10841
|
${PHANTOM_TEXT}` };
|
|
10549
10842
|
return true;
|
|
10550
10843
|
}
|
|
10551
|
-
if (!noEarlyFinal && text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
10844
|
+
if (!noEarlyFinal && (lastToolCallRound > 0 || looksComplex(firstPrompt)) && text !== "" && round <= EARLY_FINAL_TURN_THRESHOLD && earlyFinalNudges < EARLY_FINAL_MAX && !looksComplete(finalText)) {
|
|
10552
10845
|
earlyFinalNudges++;
|
|
10553
10846
|
earlyFinalPending = { role: "system", content: `${EARLY_FINAL_FENCE}
|
|
10554
10847
|
${EARLY_FINAL_TEXT(round)}` };
|
|
@@ -10608,10 +10901,11 @@ ${REPEAT_GREP_TEXT(q, n)}` };
|
|
|
10608
10901
|
// ../core/src/agent/runAgent.ts
|
|
10609
10902
|
async function* runAgent(message, options) {
|
|
10610
10903
|
const sessionId = options.sessionId;
|
|
10904
|
+
const runId = createUUID();
|
|
10611
10905
|
const rawEvents = options.events;
|
|
10612
10906
|
const events = async (base) => {
|
|
10613
10907
|
try {
|
|
10614
|
-
await rawEvents(base);
|
|
10908
|
+
await rawEvents({ ...base, metadata: { ...base.metadata, runId } });
|
|
10615
10909
|
} catch (e) {
|
|
10616
10910
|
console.warn("\u26A0\uFE0F \u57CB\u70B9\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u63A8\u7406\uFF09:", e instanceof Error ? e.message : e);
|
|
10617
10911
|
}
|
|
@@ -10623,7 +10917,7 @@ async function* runAgent(message, options) {
|
|
|
10623
10917
|
const keepRecentUnits = options.keepRecentUnits;
|
|
10624
10918
|
const compactRatio = options.compactRatio;
|
|
10625
10919
|
const parentSystemPrompt = options.parentSystemPrompt;
|
|
10626
|
-
const { rawTools, cleanedToolSchemas } = await prepareToolsAndInjections(message, options, events);
|
|
10920
|
+
const { rawTools, cleanedToolSchemas, toolsTokens } = await prepareToolsAndInjections(message, options, events);
|
|
10627
10921
|
let round = 0;
|
|
10628
10922
|
let lastContent = "";
|
|
10629
10923
|
let stopReason = "normal";
|
|
@@ -10642,7 +10936,6 @@ async function* runAgent(message, options) {
|
|
|
10642
10936
|
let lastRealPromptTokens = persistedCalib.lastRealPromptTokens;
|
|
10643
10937
|
let lastCachedTokens = persistedCalib.lastCachedTokens;
|
|
10644
10938
|
const breaker = createRepeatBreaker({ sessionId, depth, llmDecisionSource, startTime, events });
|
|
10645
|
-
const runId = createUUID();
|
|
10646
10939
|
let usageSum;
|
|
10647
10940
|
const addUsage = (u) => {
|
|
10648
10941
|
if (!u) return;
|
|
@@ -10703,7 +10996,8 @@ async function* runAgent(message, options) {
|
|
|
10703
10996
|
signal,
|
|
10704
10997
|
correctionRatio: calibRatio,
|
|
10705
10998
|
lastRealPromptTokens,
|
|
10706
|
-
lastCachedTokens
|
|
10999
|
+
lastCachedTokens,
|
|
11000
|
+
toolsTokens
|
|
10707
11001
|
}
|
|
10708
11002
|
);
|
|
10709
11003
|
} catch (e) {
|
|
@@ -10735,7 +11029,8 @@ async function* runAgent(message, options) {
|
|
|
10735
11029
|
events,
|
|
10736
11030
|
keepRecentUnits,
|
|
10737
11031
|
compactRatio,
|
|
10738
|
-
modelWindow
|
|
11032
|
+
modelWindow,
|
|
11033
|
+
toolsTokens
|
|
10739
11034
|
});
|
|
10740
11035
|
if (infResult.kind === "aborted") {
|
|
10741
11036
|
yield { type: "final", text: infResult.partialText || lastContent || "\uFF08\u5DF2\u4E2D\u6B62\uFF09" };
|
|
@@ -10747,7 +11042,7 @@ async function* runAgent(message, options) {
|
|
|
10747
11042
|
return;
|
|
10748
11043
|
}
|
|
10749
11044
|
if (infResult.usage?.prompt_tokens) {
|
|
10750
|
-
const estAtInfer = estimateTokens(message);
|
|
11045
|
+
const estAtInfer = estimateTokens(message) + toolsTokens;
|
|
10751
11046
|
if (estAtInfer > 1e3) {
|
|
10752
11047
|
const observed = infResult.usage.prompt_tokens / estAtInfer;
|
|
10753
11048
|
calibRatio = calibRatio * 0.6 + observed * 0.4;
|
|
@@ -10837,11 +11132,13 @@ async function* runAgent(message, options) {
|
|
|
10837
11132
|
try {
|
|
10838
11133
|
const reason = signal?.aborted ? "aborted" : stopReason;
|
|
10839
11134
|
await dispatch("Stop", { sessionId, cwd, lastText: lastContent || "", reason });
|
|
10840
|
-
} catch {
|
|
11135
|
+
} catch (e) {
|
|
11136
|
+
console.warn("\u26A0\uFE0F Stop hook \u5916\u5C42\u515C\u5E95\uFF08dispatch \u5185\u90E8\u5BB9\u9519\u5931\u6548\uFF0C\u5C5E\u5F02\u5E38\u4FE1\u53F7\uFF09:", e instanceof Error ? e.message : e);
|
|
10841
11137
|
}
|
|
10842
11138
|
try {
|
|
10843
11139
|
await updateCalibration(sessionId, { calibRatio, lastRealPromptTokens, lastCachedTokens });
|
|
10844
|
-
} catch {
|
|
11140
|
+
} catch (e) {
|
|
11141
|
+
console.warn("\u26A0\uFE0F \u538B\u7F29\u6821\u51C6\u72B6\u6001\u843D\u76D8\u5931\u8D25\uFF08\u4E0B run \u6821\u51C6\u91CD\u96F6\uFF0C\u7F13\u5B58\u611F\u77E5\u538B\u7F29\u9000\u5316\u56DE\u7F3A\u7701 1.4\uFF09:", e instanceof Error ? e.message : e);
|
|
10845
11142
|
}
|
|
10846
11143
|
}
|
|
10847
11144
|
}
|
|
@@ -10984,9 +11281,9 @@ var init_content = __esm({
|
|
|
10984
11281
|
return replaceImageParts(mm, "[\u5386\u53F2\u56FE\u7247\u5DF2\u6298\u53E0\uFF1A\u539F\u56FE\u4ECD\u5728\u4F1A\u8BDD\u5F52\u6863\u4E2D\uFF0C\u5982\u9700\u518D\u6B21\u67E5\u770B\u8BF7\u91CD\u65B0\u63D0\u4F9B\u8BE5\u56FE\u7247]");
|
|
10985
11282
|
});
|
|
10986
11283
|
};
|
|
10987
|
-
NO_VISION_IMAGE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\
|
|
10988
|
-
enforceVisionGate = (msgs) => isVisionEnabled() ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
10989
|
-
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt) => {
|
|
11284
|
+
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]";
|
|
11285
|
+
enforceVisionGate = (msgs, modelId) => isVisionEnabled(modelId) ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
11286
|
+
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt, modelId) => {
|
|
10990
11287
|
const lines = await readTranscriptLines(sessionId);
|
|
10991
11288
|
const store = await getRollingState(sessionId);
|
|
10992
11289
|
const eventAware = appConfig.transcriptEvents || lines.some(isEventLine);
|
|
@@ -11005,12 +11302,12 @@ var init_content = __esm({
|
|
|
11005
11302
|
const messageAll = all.slice(archivedMessageCount);
|
|
11006
11303
|
if (messageAll.length === 0) {
|
|
11007
11304
|
result.push(currentUserMsg);
|
|
11008
|
-
return enforceVisionGate(result);
|
|
11305
|
+
return enforceVisionGate(result, modelId);
|
|
11009
11306
|
}
|
|
11010
11307
|
const repair = repairOrphanToolCalls(messageAll, recovery.interruption.kind === "crashed");
|
|
11011
11308
|
result.push(...decayOldToolResults(repair.msgs));
|
|
11012
11309
|
result.push(currentUserMsg);
|
|
11013
|
-
return enforceVisionGate(result);
|
|
11310
|
+
return enforceVisionGate(result, modelId);
|
|
11014
11311
|
};
|
|
11015
11312
|
}
|
|
11016
11313
|
});
|
|
@@ -11171,7 +11468,7 @@ var init_subagent = __esm({
|
|
|
11171
11468
|
console.log(`${resuming ? "\u{1F501} \u7EED\u8DD1" : "\u{1F423} \u6D3E\u751F"}\u5B50 Agent [\u6DF1\u5EA6: ${ctx.depth + 1}/${MAX_AGENT_DEPTH}][${subSessionId}]${manifest ? ` \u58F0\u660E\u5F0F=${manifest.name}` : ""} \u4EFB\u52A1: "${task.slice(0, 50)}..."`);
|
|
11172
11469
|
activeSubagents.add(subSessionId);
|
|
11173
11470
|
try {
|
|
11174
|
-
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem);
|
|
11471
|
+
const subMessages = await buildContextMessages(subSessionId, { role: "user", content: task }, subSystem, manifest?.model);
|
|
11175
11472
|
await appendMessage({ sessionId: subSessionId, role: "user", content: task });
|
|
11176
11473
|
let subResult = "";
|
|
11177
11474
|
let hasFinalResult = false;
|
|
@@ -11348,7 +11645,7 @@ var init_loader4 = __esm({
|
|
|
11348
11645
|
console.warn(`\u26A0\uFE0F [hooks] ${where} \u975E\u5DE5\u5177\u4E8B\u4EF6\u4E0D\u652F\u6301 matcher\uFF0C\u5DF2\u5FFD\u7565`);
|
|
11349
11646
|
}
|
|
11350
11647
|
const matcher = TOOL_EVENTS.has(event) && typeof raw.matcher === "string" ? raw.matcher : void 0;
|
|
11351
|
-
const
|
|
11648
|
+
const timeoutMs2 = typeof raw.timeoutMs === "number" && raw.timeoutMs > 0 ? raw.timeoutMs : void 0;
|
|
11352
11649
|
let denyOnNonZero = typeof raw.denyOnNonZero === "boolean" ? raw.denyOnNonZero : void 0;
|
|
11353
11650
|
if (denyOnNonZero === true && !INTERCEPTABLE_EVENTS.has(event)) {
|
|
11354
11651
|
console.warn(`\u26A0\uFE0F [hooks] ${where} \u975E\u62E6\u622A\u4E8B\u4EF6\uFF0CdenyOnNonZero \u4E0D\u751F\u6548\uFF08\u4EC5 PreToolUse/UserPromptSubmit \u53EF\u62E6\u622A\uFF09\uFF0C\u5DF2\u5FFD\u7565`);
|
|
@@ -11376,7 +11673,7 @@ var init_loader4 = __esm({
|
|
|
11376
11673
|
text: type === "prompt" && typeof raw.text === "string" ? raw.text : void 0,
|
|
11377
11674
|
task: type === "agent" && typeof raw.task === "string" ? raw.task : void 0,
|
|
11378
11675
|
matcher,
|
|
11379
|
-
timeoutMs,
|
|
11676
|
+
timeoutMs: timeoutMs2,
|
|
11380
11677
|
denyOnNonZero,
|
|
11381
11678
|
onError,
|
|
11382
11679
|
requireApproval: raw.requireApproval === true ? true : void 0
|
|
@@ -11419,7 +11716,7 @@ var init_loader4 = __esm({
|
|
|
11419
11716
|
};
|
|
11420
11717
|
compileRule2 = (event, raw) => {
|
|
11421
11718
|
const denyOnNonZero = raw.denyOnNonZero ?? event === "PreToolUse";
|
|
11422
|
-
const
|
|
11719
|
+
const timeoutMs2 = raw.timeoutMs ?? DEFAULT_TIMEOUT_BY_EVENT[event];
|
|
11423
11720
|
const base = { event, matcher: raw.matcher, source: "config", onError: raw.onError };
|
|
11424
11721
|
if (raw.type === "prompt") {
|
|
11425
11722
|
const text = raw.text;
|
|
@@ -11464,7 +11761,7 @@ var init_loader4 = __esm({
|
|
|
11464
11761
|
headers: raw.headers,
|
|
11465
11762
|
body: ctx,
|
|
11466
11763
|
// 整个 hook 上下文 JSON 化发出(含 sessionId/toolName/args/prompt 等)
|
|
11467
|
-
timeoutMs
|
|
11764
|
+
timeoutMs: timeoutMs2
|
|
11468
11765
|
});
|
|
11469
11766
|
if (!res.ok) {
|
|
11470
11767
|
return denyOnNonZero ? { deny: true, reason: `hook http \u8BF7\u6C42\u5931\u8D25\uFF1A${res.error}` } : { deny: false };
|
|
@@ -11498,11 +11795,11 @@ var init_loader4 = __esm({
|
|
|
11498
11795
|
command,
|
|
11499
11796
|
cwd: ctx?.cwd,
|
|
11500
11797
|
env: ctx?.env,
|
|
11501
|
-
timeoutMs,
|
|
11798
|
+
timeoutMs: timeoutMs2,
|
|
11502
11799
|
stdinPayload: ctx
|
|
11503
11800
|
});
|
|
11504
11801
|
if (res.timedOut) {
|
|
11505
|
-
return denyOnNonZero ? { deny: true, reason: `hook \u6267\u884C\u8D85\u65F6\uFF08>${
|
|
11802
|
+
return denyOnNonZero ? { deny: true, reason: `hook \u6267\u884C\u8D85\u65F6\uFF08>${timeoutMs2}ms\uFF09` } : { deny: false };
|
|
11506
11803
|
}
|
|
11507
11804
|
if (denyOnNonZero && res.exitCode !== 0) {
|
|
11508
11805
|
const detail = res.stderr ? `\uFF1A${res.stderr.slice(0, 200)}` : "";
|
|
@@ -11524,9 +11821,7 @@ var init_loader4 = __esm({
|
|
|
11524
11821
|
if (!list || list.length === 0) continue;
|
|
11525
11822
|
for (const raw of list) compiled.push(compileRule2(event, raw));
|
|
11526
11823
|
}
|
|
11527
|
-
|
|
11528
|
-
registerHooks(compiled);
|
|
11529
|
-
}
|
|
11824
|
+
replaceDeclarativeHooks(compiled);
|
|
11530
11825
|
return compiled.length;
|
|
11531
11826
|
};
|
|
11532
11827
|
initHooks = async (includeProject) => {
|
|
@@ -11715,7 +12010,7 @@ var init_loader6 = __esm({
|
|
|
11715
12010
|
console.warn(`\u26A0\uFE0F [agents] frontmatter \u683C\u5F0F\u65E0\u6548\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
11716
12011
|
return null;
|
|
11717
12012
|
}
|
|
11718
|
-
const { name, description, role, tools, model
|
|
12013
|
+
const { name, description, role, tools, model } = parsed.frontmatter;
|
|
11719
12014
|
if (!name || !description) {
|
|
11720
12015
|
console.warn(`\u26A0\uFE0F [agents] \u7F3A\u5C11 name \u6216 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
11721
12016
|
return null;
|
|
@@ -11730,7 +12025,7 @@ var init_loader6 = __esm({
|
|
|
11730
12025
|
description,
|
|
11731
12026
|
role: role || void 0,
|
|
11732
12027
|
tools: toolList,
|
|
11733
|
-
model:
|
|
12028
|
+
model: model || void 0,
|
|
11734
12029
|
body: parsed.body,
|
|
11735
12030
|
source,
|
|
11736
12031
|
dir
|
|
@@ -12103,14 +12398,6 @@ var init_runner = __esm({
|
|
|
12103
12398
|
}
|
|
12104
12399
|
});
|
|
12105
12400
|
|
|
12106
|
-
// ../core/src/llm/createModel.ts
|
|
12107
|
-
var init_createModel = __esm({
|
|
12108
|
-
"../core/src/llm/createModel.ts"() {
|
|
12109
|
-
"use strict";
|
|
12110
|
-
init_client();
|
|
12111
|
-
}
|
|
12112
|
-
});
|
|
12113
|
-
|
|
12114
12401
|
// ../core/src/observability/store.ts
|
|
12115
12402
|
import path39 from "path";
|
|
12116
12403
|
import fs37 from "fs/promises";
|
|
@@ -12427,11 +12714,12 @@ var init_systemPrompt = __esm({
|
|
|
12427
12714
|
- \u88AB\u95EE"\u4F60\u662F\u8C01"\u65F6\u636E\u5B9E\u56DE\u7B54\uFF1A\u4F60\u662F ${p.displayName}\u3002\u5207\u52FF\u81EA\u79F0 ChatGPT\u3001GPT \u6216\u4EFB\u4F55\u5176\u4ED6\u516C\u53F8\u7684\u5927\u6A21\u578B/AI \u4EA7\u54C1\u3002
|
|
12428
12715
|
|
|
12429
12716
|
\u3010\u56DE\u7B54\u51C6\u5219 / \u5B8C\u6210\u5224\u5B9A\u3011
|
|
12430
|
-
- \u4EFB\u52A1\u5B8C\u6210\u540E\u76F4\u63A5\u7528\u81EA\u7136\u8BED\u8A00\u7ED9\u51FA\u6700\u7EC8\u7B54\u6848\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u5DE5\u5177\u3002
|
|
12431
|
-
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
- **\
|
|
12717
|
+
- \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
|
|
12718
|
+
- \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
|
|
12719
|
+
|
|
12720
|
+
\u3010\u56DE\u7B54\u5F62\u5F0F\u3011
|
|
12721
|
+
- **\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
|
|
12722
|
+
- **\u4E0D\u56DE\u8D34\u5927\u6BB5\u4EE3\u7801**\uFF1A\u6539\u52A8\u5185\u5BB9\u7528\u6237\u5728\u7F16\u8F91\u5668/diff \u91CC\u770B\u5F97\u5230\uFF0C\u6B63\u6587\u53EA\u9700\u4E00\u53E5\u8BDD\u8BF4\u660E\u6539\u4E86\u4EC0\u4E48\u3001\u4E3A\u4EC0\u4E48\uFF0C\u6216\u5F15\u7528\u5173\u952E\u51E0\u884C\u3002
|
|
12435
12723
|
|
|
12436
12724
|
\u3010\u5DE5\u5177\u4F7F\u7528\u51C6\u5219\u3011
|
|
12437
12725
|
- \u4FEE\u6539\u6587\u4EF6**\u53EA\u80FD**\u7528 edit_file / create_file / write_file\u3002**\u4E25\u7981**\u7528 run_command \u901A\u8FC7 python/node/sed/awk/perl \u7B49\u811A\u672C\u8BFB\u5199\u6216\u4FEE\u6539\u6587\u4EF6\u2014\u2014\u811A\u672C\u8F6C\u4E49\u6781\u6613\u51FA\u9519\u3001\u6BCF\u6761\u547D\u4EE4\u90FD\u8981\u7528\u6237\u5BA1\u6279\u3001\u6548\u7387\u6781\u4F4E\uFF0C\u662F\u88AB\u660E\u786E\u7981\u6B62\u7684\u9000\u8DEF\u3002
|
|
@@ -12532,18 +12820,29 @@ ${lines.join("\n")}
|
|
|
12532
12820
|
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path41.basename(activeReal) || activeReal} = IDE \u5934\u90E8\u6240\u793A\u6839\uFF09\u3002\u5F53\u7528\u6237\u5728\u5BF9\u8BDD\u4E2D\u6307\u660E\u4E86\u67D0\u4E2A\u9879\u76EE\uFF08\u5982\u300C\u5728 A \u9879\u76EE\u300D\u300C\u6539\u524D\u7AEF\u7684 xxx\u300D\u300C\u641C\u540E\u7AEF\u300D\uFF09\uFF0C\u8BE5\u8F6E\u6240\u6709\u5E26 path \u53C2\u6570\u7684\u5DE5\u5177\u8C03\u7528\uFF08read_file / edit_file / search_grep / glob / list_dir / read_xlsx / read_docx \u7B49\uFF09\u5FC5\u987B\u628A\u5BF9\u5E94\u9879\u76EE\u6839\u4F5C\u4E3A path \u4F20\u5165\uFF08\u7EDD\u5BF9\u8DEF\u5F84\u3001../<\u5144\u5F1F\u76EE\u5F55>\u3001\u6216\u9879\u76EE\u76EE\u5F55\u540D\uFF09\uFF0C\u5426\u5219\u53EA\u4F1A\u8BFB\u5199/\u641C\u7D22\u9ED8\u8BA4\u6839\uFF0C\u4E0E\u7528\u6237\u610F\u56FE\u4E0D\u7B26\u3002
|
|
12533
12821
|
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path41.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
|
|
12534
12822
|
}
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12823
|
+
const osName = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
12824
|
+
const now = /* @__PURE__ */ new Date();
|
|
12825
|
+
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
12826
|
+
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";
|
|
12827
|
+
const envLines = [
|
|
12828
|
+
...roots.length > 1 ? [] : [`- \u5DE5\u4F5C\u533A\u6839\uFF08\u5DE5\u5177\u76F8\u5BF9\u8DEF\u5F84\u7684\u57FA\u51C6\uFF09: ${getActiveWorkspaceRoot()}`],
|
|
12829
|
+
`- \u64CD\u4F5C\u7CFB\u7EDF: ${osName}\uFF08${process.platform}\uFF09`,
|
|
12830
|
+
`- \u547D\u4EE4\u6267\u884C: ${shellNote}`,
|
|
12831
|
+
`- \u4ECA\u5929: ${today}`
|
|
12832
|
+
];
|
|
12833
|
+
sysPrompt = sysPrompt + `
|
|
12539
12834
|
|
|
12540
|
-
\
|
|
12541
|
-
|
|
12835
|
+
\u3010\u73AF\u5883\u3011
|
|
12836
|
+
${envLines.join("\n")}`;
|
|
12837
|
+
let replyText = "";
|
|
12838
|
+
const { wire: userContent, archive: archiveContent } = toIngestContents(inbound.content, inbound.attachments, opts?.model);
|
|
12542
12839
|
try {
|
|
12543
12840
|
const fullMessages = await buildContextMessages(
|
|
12544
12841
|
sessionId,
|
|
12545
12842
|
{ role: "user", content: userContent },
|
|
12546
|
-
sysPrompt
|
|
12843
|
+
sysPrompt,
|
|
12844
|
+
opts?.model
|
|
12845
|
+
// ★ vision 自动判定与实际请求模型(opts.model ?? MODEL_NAME)同源
|
|
12547
12846
|
);
|
|
12548
12847
|
await emitTrace({
|
|
12549
12848
|
sessionId,
|
|
@@ -12555,7 +12854,7 @@ ${lines.join("\n")}
|
|
|
12555
12854
|
});
|
|
12556
12855
|
void sweepStaleAtomicTmp().catch(() => {
|
|
12557
12856
|
});
|
|
12558
|
-
await appendMessage({ sessionId, role: "user", content:
|
|
12857
|
+
await appendMessage({ sessionId, role: "user", content: archiveContent });
|
|
12559
12858
|
let streamedAnyText = false;
|
|
12560
12859
|
const onUIEvent = opts?.onUIEvent ?? ((evt) => sseWrite?.(evt));
|
|
12561
12860
|
const requestApproval2 = opts?.requestApproval ?? createWebRequestApproval((evt) => sseWrite?.(evt), abortSignal);
|
|
@@ -12744,6 +13043,75 @@ var init_fork = __esm({
|
|
|
12744
13043
|
}
|
|
12745
13044
|
});
|
|
12746
13045
|
|
|
13046
|
+
// ../core/src/commands/bashDirect.ts
|
|
13047
|
+
import { exec } from "node:child_process";
|
|
13048
|
+
var OUTPUT_MAX_CHARS, timeoutMs, truncateOutput, decodeBuffer, runBashDirect, formatBashEntry, recordBashEntry;
|
|
13049
|
+
var init_bashDirect = __esm({
|
|
13050
|
+
"../core/src/commands/bashDirect.ts"() {
|
|
13051
|
+
"use strict";
|
|
13052
|
+
init_transcript();
|
|
13053
|
+
init_guard();
|
|
13054
|
+
OUTPUT_MAX_CHARS = 4e3;
|
|
13055
|
+
timeoutMs = () => {
|
|
13056
|
+
const n = Number(process.env.DEEP_SEEK_BANG_TIMEOUT_MS);
|
|
13057
|
+
return Number.isFinite(n) && n > 0 ? n : 6e4;
|
|
13058
|
+
};
|
|
13059
|
+
truncateOutput = (s) => {
|
|
13060
|
+
if (s.length <= OUTPUT_MAX_CHARS) return s;
|
|
13061
|
+
const half = Math.floor(OUTPUT_MAX_CHARS / 2);
|
|
13062
|
+
return `${s.slice(0, half)}
|
|
13063
|
+
\u2026\uFF08\u4E2D\u6BB5\u7701\u7565 ${s.length - OUTPUT_MAX_CHARS} \u5B57\u7B26\uFF09\u2026
|
|
13064
|
+
${s.slice(-half)}`;
|
|
13065
|
+
};
|
|
13066
|
+
decodeBuffer = (buf) => {
|
|
13067
|
+
const utf8 = buf.toString("utf8");
|
|
13068
|
+
if (!utf8.includes("\uFFFD")) return utf8;
|
|
13069
|
+
try {
|
|
13070
|
+
return new TextDecoder("gbk").decode(buf);
|
|
13071
|
+
} catch {
|
|
13072
|
+
return utf8;
|
|
13073
|
+
}
|
|
13074
|
+
};
|
|
13075
|
+
runBashDirect = (cmd, cwd, signal) => new Promise((resolve) => {
|
|
13076
|
+
let settled = false;
|
|
13077
|
+
const finish = (r) => {
|
|
13078
|
+
if (!settled) {
|
|
13079
|
+
settled = true;
|
|
13080
|
+
resolve(r);
|
|
13081
|
+
}
|
|
13082
|
+
};
|
|
13083
|
+
const start = Date.now();
|
|
13084
|
+
const child = exec(cmd, { cwd, timeout: timeoutMs(), maxBuffer: 4 * 1024 * 1024, windowsHide: true, env: scrubCommandEnv(), encoding: "buffer" }, (err, stdout, stderr) => {
|
|
13085
|
+
const durationMs = Date.now() - start;
|
|
13086
|
+
const out = stdout;
|
|
13087
|
+
const errBuf = stderr;
|
|
13088
|
+
const timedOut = err != null && err.killed === true && signal?.aborted !== true;
|
|
13089
|
+
const combined = errBuf.length ? (out.length ? `${decodeBuffer(out)}
|
|
13090
|
+
` : "") + decodeBuffer(errBuf) : decodeBuffer(out);
|
|
13091
|
+
const exitCode = err == null ? 0 : typeof err.code === "number" ? err.code : null;
|
|
13092
|
+
finish({ ok: err == null, output: truncateOutput(combined ?? ""), exitCode, timedOut, durationMs });
|
|
13093
|
+
});
|
|
13094
|
+
if (signal) {
|
|
13095
|
+
const onAbort = () => {
|
|
13096
|
+
try {
|
|
13097
|
+
child.kill();
|
|
13098
|
+
} catch {
|
|
13099
|
+
}
|
|
13100
|
+
};
|
|
13101
|
+
if (signal.aborted) onAbort();
|
|
13102
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
13103
|
+
}
|
|
13104
|
+
});
|
|
13105
|
+
formatBashEntry = (cmd, r) => `!bash $ ${cmd}
|
|
13106
|
+
` + (r.timedOut ? `[\u8D85\u65F6\u4E2D\u6B62\uFF08>${Math.round(r.durationMs / 1e3)}s\uFF09]
|
|
13107
|
+
` : "") + (r.exitCode != null && r.exitCode !== 0 ? `[\u9000\u51FA\u7801 ${r.exitCode}]
|
|
13108
|
+
` : "") + (r.output.trim() || "(\u65E0\u8F93\u51FA)");
|
|
13109
|
+
recordBashEntry = async (sessionId, text) => {
|
|
13110
|
+
await appendMessage({ sessionId, role: "user", content: text });
|
|
13111
|
+
};
|
|
13112
|
+
}
|
|
13113
|
+
});
|
|
13114
|
+
|
|
12747
13115
|
// src/cliHost.ts
|
|
12748
13116
|
var createCliRequestApproval, createCliRequestQuestion;
|
|
12749
13117
|
var init_cliHost = __esm({
|
|
@@ -12938,9 +13306,12 @@ var init_useChatState = __esm({
|
|
|
12938
13306
|
init_fork();
|
|
12939
13307
|
init_inbox();
|
|
12940
13308
|
init_contextCore();
|
|
13309
|
+
init_bashDirect();
|
|
13310
|
+
init_guard();
|
|
12941
13311
|
init_createModel();
|
|
12942
13312
|
init_tool();
|
|
12943
13313
|
init_cliHost();
|
|
13314
|
+
init_prefs();
|
|
12944
13315
|
init_strings();
|
|
12945
13316
|
init_util();
|
|
12946
13317
|
init_replay2();
|
|
@@ -12962,6 +13333,7 @@ var init_useChatState = __esm({
|
|
|
12962
13333
|
const [pendingPlan, setPendingPlan] = useState(null);
|
|
12963
13334
|
const [pendingSessions, setPendingSessions] = useState(null);
|
|
12964
13335
|
const [pendingFork, setPendingFork] = useState(null);
|
|
13336
|
+
const [pendingModel, setPendingModel] = useState(null);
|
|
12965
13337
|
const nextId = useRef(1);
|
|
12966
13338
|
const assistantStreamingId = useRef(null);
|
|
12967
13339
|
const thinkingStreamingId = useRef(null);
|
|
@@ -13333,6 +13705,22 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13333
13705
|
if (turnGenRef.current === myGen) setBusy(false);
|
|
13334
13706
|
}
|
|
13335
13707
|
}, [busy, initialSessionId, pushUser, pushInfo, runOnce, runPlanStage, takeEnterPlanRequest, takeProposedPlan, approveAndImplement]);
|
|
13708
|
+
const runBangCommand = useCallback(async (raw) => {
|
|
13709
|
+
const cmd = raw.replace(/^!/, "").trim();
|
|
13710
|
+
if (!cmd) {
|
|
13711
|
+
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");
|
|
13712
|
+
return;
|
|
13713
|
+
}
|
|
13714
|
+
pushUser(raw);
|
|
13715
|
+
if (sessionIdRef.current == null) {
|
|
13716
|
+
sessionIdRef.current = await getOrCreateSessionId(initialSessionId ?? void 0);
|
|
13717
|
+
}
|
|
13718
|
+
const r = await runBashDirect(cmd, getActiveWorkspaceRoot());
|
|
13719
|
+
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`;
|
|
13720
|
+
pushInfo(`${head} \xB7 ${Math.round(r.durationMs / 100) / 10}s
|
|
13721
|
+
${r.output.trim() || "(\u65E0\u8F93\u51FA)"}`);
|
|
13722
|
+
await recordBashEntry(sessionIdRef.current, formatBashEntry(cmd, r));
|
|
13723
|
+
}, [initialSessionId, pushUser, pushInfo]);
|
|
13336
13724
|
const abortCurrent = useCallback(() => {
|
|
13337
13725
|
const ac = currentAcRef.current;
|
|
13338
13726
|
if (!ac) return;
|
|
@@ -13416,7 +13804,22 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13416
13804
|
}, [pushInfo, loadSession]);
|
|
13417
13805
|
const setModelOverride = useCallback((m) => {
|
|
13418
13806
|
modelRef.current = m;
|
|
13807
|
+
void writePrefs({ model: m });
|
|
13419
13808
|
}, []);
|
|
13809
|
+
const resolveModel = useCallback((model) => {
|
|
13810
|
+
setPendingModel((prev) => {
|
|
13811
|
+
prev?.resolve(model);
|
|
13812
|
+
return null;
|
|
13813
|
+
});
|
|
13814
|
+
}, []);
|
|
13815
|
+
const openModelPicker = useCallback(async () => {
|
|
13816
|
+
const picked = await new Promise((resolve) => setPendingModel({ models: SELECTABLE_MODELS, resolve }));
|
|
13817
|
+
if (picked) {
|
|
13818
|
+
setModelOverride(picked);
|
|
13819
|
+
pushInfo(S.modelSwitched(picked));
|
|
13820
|
+
}
|
|
13821
|
+
return picked;
|
|
13822
|
+
}, [pushInfo, setModelOverride]);
|
|
13420
13823
|
const setPlanMode = useCallback((on) => {
|
|
13421
13824
|
planModeRef.current = on;
|
|
13422
13825
|
}, []);
|
|
@@ -13444,6 +13847,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13444
13847
|
pendingPlan,
|
|
13445
13848
|
pendingSessions,
|
|
13446
13849
|
pendingFork,
|
|
13850
|
+
pendingModel,
|
|
13447
13851
|
sessionIdRef,
|
|
13448
13852
|
// 动作
|
|
13449
13853
|
submit,
|
|
@@ -13452,6 +13856,7 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13452
13856
|
pushUser,
|
|
13453
13857
|
pushInfo,
|
|
13454
13858
|
pushEvent,
|
|
13859
|
+
runBangCommand,
|
|
13455
13860
|
askApproval,
|
|
13456
13861
|
resolveApproval,
|
|
13457
13862
|
resolveQuestion,
|
|
@@ -13472,7 +13877,9 @@ ${finalPlan}`, false, res.autoExecute);
|
|
|
13472
13877
|
resolveSession,
|
|
13473
13878
|
loadSession,
|
|
13474
13879
|
openForkPicker,
|
|
13475
|
-
resolveFork
|
|
13880
|
+
resolveFork,
|
|
13881
|
+
openModelPicker,
|
|
13882
|
+
resolveModel
|
|
13476
13883
|
};
|
|
13477
13884
|
};
|
|
13478
13885
|
}
|
|
@@ -13561,7 +13968,7 @@ var init_StreamingCursor = __esm({
|
|
|
13561
13968
|
// src/components/MessageBlock.tsx
|
|
13562
13969
|
import { Box, Text as Text3 } from "ink";
|
|
13563
13970
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
13564
|
-
var UsageFooter, listPrefix, AssistantLine, MessageBlock;
|
|
13971
|
+
var UsageFooter, listPrefix, AssistantLine, isFenceMark, isMdRow, isMdSep, mdCells, parseBlocks, fitCell, tableWidths, buildVLines, AssistantVLine, MessageBlock;
|
|
13565
13972
|
var init_MessageBlock = __esm({
|
|
13566
13973
|
"src/components/MessageBlock.tsx"() {
|
|
13567
13974
|
"use strict";
|
|
@@ -13600,6 +14007,94 @@ var init_MessageBlock = __esm({
|
|
|
13600
14007
|
}
|
|
13601
14008
|
return /* @__PURE__ */ jsx3(RichText, { text: line });
|
|
13602
14009
|
};
|
|
14010
|
+
isFenceMark = (l) => /^\s*```/.test(l);
|
|
14011
|
+
isMdRow = (l) => l.includes("|");
|
|
14012
|
+
isMdSep = (l) => /^[ \t|:-]+$/.test(l) && l.includes("-") && l.includes("|");
|
|
14013
|
+
mdCells = (l) => l.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim());
|
|
14014
|
+
parseBlocks = (text) => {
|
|
14015
|
+
const src = String(text || "").split("\n");
|
|
14016
|
+
const blocks = [];
|
|
14017
|
+
let i = 0;
|
|
14018
|
+
while (i < src.length) {
|
|
14019
|
+
if (isFenceMark(src[i])) {
|
|
14020
|
+
const body = [];
|
|
14021
|
+
i++;
|
|
14022
|
+
while (i < src.length && !isFenceMark(src[i])) body.push(src[i++]);
|
|
14023
|
+
if (i < src.length) i++;
|
|
14024
|
+
blocks.push({ kind: "fence", lines: body });
|
|
14025
|
+
continue;
|
|
14026
|
+
}
|
|
14027
|
+
if (isMdRow(src[i]) && i + 1 < src.length && isMdSep(src[i + 1])) {
|
|
14028
|
+
const header = mdCells(src[i]);
|
|
14029
|
+
const rows = [];
|
|
14030
|
+
i += 2;
|
|
14031
|
+
while (i < src.length && isMdRow(src[i])) rows.push(mdCells(src[i++]));
|
|
14032
|
+
blocks.push({ kind: "table", header, rows });
|
|
14033
|
+
continue;
|
|
14034
|
+
}
|
|
14035
|
+
blocks.push({ kind: "line", text: src[i++] });
|
|
14036
|
+
}
|
|
14037
|
+
return blocks;
|
|
14038
|
+
};
|
|
14039
|
+
fitCell = (s, w) => {
|
|
14040
|
+
if (strWidth(s) <= w) return s + " ".repeat(w - strWidth(s));
|
|
14041
|
+
let out = "";
|
|
14042
|
+
let width = 0;
|
|
14043
|
+
const limit = Math.max(1, w - 1);
|
|
14044
|
+
for (const ch of s) {
|
|
14045
|
+
const cw = strWidth(ch);
|
|
14046
|
+
if (width + cw > limit) break;
|
|
14047
|
+
out += ch;
|
|
14048
|
+
width += cw;
|
|
14049
|
+
}
|
|
14050
|
+
return out + "\u2026";
|
|
14051
|
+
};
|
|
14052
|
+
tableWidths = (header, rows, contentW) => {
|
|
14053
|
+
const n = Math.max(1, header.length);
|
|
14054
|
+
const w = Array.from({ length: n }, (_, c) => {
|
|
14055
|
+
let m = strWidth(header[c] ?? "");
|
|
14056
|
+
for (const r of rows) m = Math.max(m, strWidth(r[c] ?? ""));
|
|
14057
|
+
return Math.min(m, 30);
|
|
14058
|
+
});
|
|
14059
|
+
const total = () => w.reduce((a, b) => a + b, 0) + 2 * (n - 1);
|
|
14060
|
+
while (total() > contentW && Math.max(...w) > 1) {
|
|
14061
|
+
const maxW = Math.max(...w);
|
|
14062
|
+
w[w.indexOf(maxW)] = maxW - 1;
|
|
14063
|
+
}
|
|
14064
|
+
return w;
|
|
14065
|
+
};
|
|
14066
|
+
buildVLines = (text, contentW) => {
|
|
14067
|
+
const out = [];
|
|
14068
|
+
for (const b of parseBlocks(text)) {
|
|
14069
|
+
if (b.kind === "line") {
|
|
14070
|
+
for (const l of wrapText(b.text, contentW)) out.push({ k: "text", s: l });
|
|
14071
|
+
} else if (b.kind === "fence") {
|
|
14072
|
+
for (const l of b.lines) out.push({ k: "code", s: l });
|
|
14073
|
+
} else {
|
|
14074
|
+
const w = tableWidths(b.header, b.rows, contentW);
|
|
14075
|
+
out.push({ k: "thead", cells: b.header, w }, { k: "tsep", w });
|
|
14076
|
+
for (const r of b.rows) out.push({ k: "trow", cells: r, w });
|
|
14077
|
+
}
|
|
14078
|
+
}
|
|
14079
|
+
return out.length ? out : [{ k: "text", s: "" }];
|
|
14080
|
+
};
|
|
14081
|
+
AssistantVLine = ({ v }) => {
|
|
14082
|
+
switch (v.k) {
|
|
14083
|
+
case "text":
|
|
14084
|
+
return /* @__PURE__ */ jsx3(AssistantLine, { line: v.s });
|
|
14085
|
+
case "code":
|
|
14086
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
14087
|
+
/* @__PURE__ */ jsx3(Text3, { color: THEME.divider, children: "\u2502 " }),
|
|
14088
|
+
/* @__PURE__ */ jsx3(Text3, { color: THEME.gray, children: v.s.length ? v.s : " " })
|
|
14089
|
+
] });
|
|
14090
|
+
case "thead":
|
|
14091
|
+
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)) });
|
|
14092
|
+
case "tsep":
|
|
14093
|
+
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)) });
|
|
14094
|
+
case "trow":
|
|
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, { color: THEME.body, children: fitCell(v.cells[i] ?? "", cw) }) }, i)) });
|
|
14096
|
+
}
|
|
14097
|
+
};
|
|
13603
14098
|
MessageBlock = ({ row, wrapW, streamTail }) => {
|
|
13604
14099
|
if (row.kind === "meta") {
|
|
13605
14100
|
if (/^第 \d+ 轮$/.test(row.text)) {
|
|
@@ -13616,15 +14111,15 @@ var init_MessageBlock = __esm({
|
|
|
13616
14111
|
] }) });
|
|
13617
14112
|
}
|
|
13618
14113
|
if (row.kind === "info") {
|
|
13619
|
-
const
|
|
13620
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14114
|
+
const lines = wrapText(row.text, Math.max(8, wrapW));
|
|
14115
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsxs(Text3, { color: THEME.coralMuted, children: [
|
|
13621
14116
|
j === 0 ? "\u203A " : " ",
|
|
13622
14117
|
line
|
|
13623
14118
|
] }, j)) });
|
|
13624
14119
|
}
|
|
13625
14120
|
if (row.kind === "user") {
|
|
13626
|
-
const
|
|
13627
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14121
|
+
const lines = wrapText(row.text, Math.max(8, wrapW - 2));
|
|
14122
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsx3(Text3, { children: j === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13628
14123
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.coralBright, bold: true, children: "> " }),
|
|
13629
14124
|
/* @__PURE__ */ jsx3(Text3, { color: THEME.white, children: line })
|
|
13630
14125
|
] }) : /* @__PURE__ */ jsxs(Text3, { color: THEME.white, children: [
|
|
@@ -13633,19 +14128,19 @@ var init_MessageBlock = __esm({
|
|
|
13633
14128
|
] }) }, j)) });
|
|
13634
14129
|
}
|
|
13635
14130
|
if (row.kind === "system") {
|
|
13636
|
-
const
|
|
13637
|
-
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children:
|
|
14131
|
+
const lines = wrapText(row.text, Math.max(8, wrapW - 2));
|
|
14132
|
+
return /* @__PURE__ */ jsx3(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: lines.map((line, j) => /* @__PURE__ */ jsxs(Text3, { color: THEME.warn, children: [
|
|
13638
14133
|
j === 0 ? "! " : " ",
|
|
13639
14134
|
line
|
|
13640
14135
|
] }, j)) });
|
|
13641
14136
|
}
|
|
13642
14137
|
const contentW = Math.max(8, wrapW - 2);
|
|
13643
|
-
const allLines =
|
|
13644
|
-
let
|
|
14138
|
+
const allLines = buildVLines(row.text, contentW);
|
|
14139
|
+
let vlines = allLines;
|
|
13645
14140
|
let folded = 0;
|
|
13646
14141
|
if (row.streaming && streamTail && allLines.length > streamTail) {
|
|
13647
14142
|
folded = allLines.length - streamTail;
|
|
13648
|
-
|
|
14143
|
+
vlines = allLines.slice(folded);
|
|
13649
14144
|
}
|
|
13650
14145
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0.5, marginBottom: 0.5, children: [
|
|
13651
14146
|
folded > 0 ? /* @__PURE__ */ jsxs(Text3, { color: THEME.grayDim, children: [
|
|
@@ -13653,11 +14148,11 @@ var init_MessageBlock = __esm({
|
|
|
13653
14148
|
folded,
|
|
13654
14149
|
" \u884C\u2026"
|
|
13655
14150
|
] }) : null,
|
|
13656
|
-
|
|
13657
|
-
const isLast = j ===
|
|
14151
|
+
vlines.map((v, j) => {
|
|
14152
|
+
const isLast = j === vlines.length - 1;
|
|
13658
14153
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
|
|
13659
14154
|
/* @__PURE__ */ jsx3(Text3, { bold: true, color: THEME.coralBright, children: j === 0 ? "\u25CF " : " " }),
|
|
13660
|
-
/* @__PURE__ */ jsx3(
|
|
14155
|
+
/* @__PURE__ */ jsx3(AssistantVLine, { v }),
|
|
13661
14156
|
isLast && row.streaming ? /* @__PURE__ */ jsx3(StreamingCursor, {}) : null
|
|
13662
14157
|
] }, j);
|
|
13663
14158
|
}),
|
|
@@ -14281,9 +14776,44 @@ var init_ForkPicker = __esm({
|
|
|
14281
14776
|
}
|
|
14282
14777
|
});
|
|
14283
14778
|
|
|
14284
|
-
// src/components/
|
|
14779
|
+
// src/components/ModelPicker.tsx
|
|
14285
14780
|
import { Box as Box12, Text as Text14 } from "ink";
|
|
14286
14781
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
14782
|
+
var PAGE_SIZE3, ModelPicker;
|
|
14783
|
+
var init_ModelPicker = __esm({
|
|
14784
|
+
"src/components/ModelPicker.tsx"() {
|
|
14785
|
+
"use strict";
|
|
14786
|
+
init_theme();
|
|
14787
|
+
init_strings();
|
|
14788
|
+
init_util();
|
|
14789
|
+
PAGE_SIZE3 = 8;
|
|
14790
|
+
ModelPicker = ({ models, currentModel, selectedIndex, wrapW }) => {
|
|
14791
|
+
const start = Math.floor(Math.max(0, selectedIndex) / PAGE_SIZE3) * PAGE_SIZE3;
|
|
14792
|
+
const visible = models.slice(start, start + PAGE_SIZE3);
|
|
14793
|
+
const contentW = Math.max(24, wrapW);
|
|
14794
|
+
const metaSample = " \xB7 \uFF08\u5F53\u524D\uFF09";
|
|
14795
|
+
const modelW = Math.max(12, contentW - strWidth(metaSample) - 4);
|
|
14796
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", borderStyle: "round", borderColor: THEME.blue, paddingX: 1, paddingY: 1, marginTop: 1, children: [
|
|
14797
|
+
/* @__PURE__ */ jsx14(Text14, { color: THEME.blue, bold: true, children: S.modelPickerTitle(currentModel) }),
|
|
14798
|
+
/* @__PURE__ */ jsx14(Text14, { color: THEME.grayDim, children: S.modelPickerPrompt }),
|
|
14799
|
+
/* @__PURE__ */ jsx14(Box12, { flexDirection: "column", marginTop: 0.5, children: visible.map((m, i) => {
|
|
14800
|
+
const idx = start + i;
|
|
14801
|
+
const active = idx === selectedIndex;
|
|
14802
|
+
const current = m === currentModel;
|
|
14803
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "row", children: [
|
|
14804
|
+
/* @__PURE__ */ jsx14(Text14, { color: active ? THEME.coralBright : void 0, bold: true, children: active ? "\u203A " : " " }),
|
|
14805
|
+
/* @__PURE__ */ jsx14(Text14, { color: active ? THEME.white : THEME.gray, bold: active, children: `${current ? "\u25CF " : " "}${truncateMiddle(m, modelW)}` }),
|
|
14806
|
+
current ? /* @__PURE__ */ jsx14(Text14, { color: THEME.grayDim, children: ` \xB7 ${S.modelCurrentTag}` }) : null
|
|
14807
|
+
] }, m);
|
|
14808
|
+
}) })
|
|
14809
|
+
] });
|
|
14810
|
+
};
|
|
14811
|
+
}
|
|
14812
|
+
});
|
|
14813
|
+
|
|
14814
|
+
// src/components/SlashMenu.tsx
|
|
14815
|
+
import { Box as Box13, Text as Text15 } from "ink";
|
|
14816
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
14287
14817
|
var MAX_ROWS, SlashMenu;
|
|
14288
14818
|
var init_SlashMenu = __esm({
|
|
14289
14819
|
"src/components/SlashMenu.tsx"() {
|
|
@@ -14295,22 +14825,22 @@ var init_SlashMenu = __esm({
|
|
|
14295
14825
|
const visible = entries.slice(start, start + MAX_ROWS);
|
|
14296
14826
|
const cmdW = Math.min(22, Math.max(8, ...visible.map((e) => e.name.length)) + 1);
|
|
14297
14827
|
const descMax = Math.max(12, cols - cmdW - 6);
|
|
14298
|
-
return /* @__PURE__ */
|
|
14828
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", borderStyle: "round", borderColor: THEME.coral, paddingX: 1, paddingY: 0, marginTop: 1, children: [
|
|
14299
14829
|
visible.map((e, i) => {
|
|
14300
14830
|
const active = i + start === selectedIndex;
|
|
14301
14831
|
const desc = e.description.length > descMax ? `${e.description.slice(0, descMax - 1)}\u2026` : e.description;
|
|
14302
14832
|
const gap = Math.max(1, cmdW - e.name.length);
|
|
14303
|
-
return /* @__PURE__ */
|
|
14304
|
-
/* @__PURE__ */
|
|
14305
|
-
/* @__PURE__ */
|
|
14833
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "row", children: [
|
|
14834
|
+
/* @__PURE__ */ jsx15(Text15, { color: active ? THEME.coralBright : void 0, bold: true, children: active ? "\u276F " : " " }),
|
|
14835
|
+
/* @__PURE__ */ jsxs13(Text15, { color: active ? THEME.white : THEME.gray, bold: active, children: [
|
|
14306
14836
|
"/",
|
|
14307
14837
|
e.name
|
|
14308
14838
|
] }),
|
|
14309
|
-
/* @__PURE__ */
|
|
14310
|
-
/* @__PURE__ */
|
|
14839
|
+
/* @__PURE__ */ jsx15(Text15, { color: THEME.grayDim, children: " ".repeat(gap) }),
|
|
14840
|
+
/* @__PURE__ */ jsx15(Text15, { color: active ? THEME.gray : THEME.grayDim, children: desc })
|
|
14311
14841
|
] }, e.name);
|
|
14312
14842
|
}),
|
|
14313
|
-
entries.length > MAX_ROWS ? /* @__PURE__ */
|
|
14843
|
+
entries.length > MAX_ROWS ? /* @__PURE__ */ jsxs13(Text15, { color: THEME.coralMuted, children: [
|
|
14314
14844
|
"\u2191\u2193 \u6EDA\u52A8 \xB7 ",
|
|
14315
14845
|
selectedIndex + 1,
|
|
14316
14846
|
"/",
|
|
@@ -14323,36 +14853,36 @@ var init_SlashMenu = __esm({
|
|
|
14323
14853
|
});
|
|
14324
14854
|
|
|
14325
14855
|
// src/components/StatusStrip.tsx
|
|
14326
|
-
import { Box as
|
|
14327
|
-
import { jsx as
|
|
14856
|
+
import { Box as Box14, Text as Text16 } from "ink";
|
|
14857
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
14328
14858
|
var StatusStrip;
|
|
14329
14859
|
var init_StatusStrip = __esm({
|
|
14330
14860
|
"src/components/StatusStrip.tsx"() {
|
|
14331
14861
|
"use strict";
|
|
14332
14862
|
init_theme();
|
|
14333
14863
|
init_strings();
|
|
14334
|
-
StatusStrip = ({ model
|
|
14864
|
+
StatusStrip = ({ model, busy, aborting, planMode, autoMode, sessionShort, customLine }) => {
|
|
14335
14865
|
const stateText = aborting ? S.statusAborting : busy ? S.statusStreaming : S.statusIdle;
|
|
14336
14866
|
const stateColor = busy ? THEME.coralBright : THEME.gray;
|
|
14337
14867
|
const bits = [
|
|
14338
|
-
|
|
14868
|
+
model ? `model: ${model}` : "",
|
|
14339
14869
|
planMode ? S.statusPlan : "",
|
|
14340
14870
|
autoMode ? S.statusAuto : "",
|
|
14341
14871
|
`state: ${stateText}`,
|
|
14342
14872
|
sessionShort ? `session: ${sessionShort}` : ""
|
|
14343
14873
|
].filter(Boolean);
|
|
14344
|
-
return /* @__PURE__ */
|
|
14345
|
-
/* @__PURE__ */
|
|
14346
|
-
/* @__PURE__ */
|
|
14347
|
-
/* @__PURE__ */
|
|
14874
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexShrink: 0, children: [
|
|
14875
|
+
/* @__PURE__ */ jsx16(Text16, { color: THEME.coralMuted, children: customLine && customLine.trim() ? customLine : bits.join(" \xB7 ") }),
|
|
14876
|
+
/* @__PURE__ */ jsx16(Text16, { color: stateColor, children: "" }),
|
|
14877
|
+
/* @__PURE__ */ jsx16(Text16, { color: THEME.grayDim, children: S.cmdHint })
|
|
14348
14878
|
] });
|
|
14349
14879
|
};
|
|
14350
14880
|
}
|
|
14351
14881
|
});
|
|
14352
14882
|
|
|
14353
14883
|
// src/components/TopPanel.tsx
|
|
14354
|
-
import { Box as
|
|
14355
|
-
import { jsx as
|
|
14884
|
+
import { Box as Box15, Text as Text17 } from "ink";
|
|
14885
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
14356
14886
|
var ROBOT, INNER_H, TopPanel;
|
|
14357
14887
|
var init_TopPanel = __esm({
|
|
14358
14888
|
"src/components/TopPanel.tsx"() {
|
|
@@ -14372,36 +14902,36 @@ var init_TopPanel = __esm({
|
|
|
14372
14902
|
const leftW = Math.floor(innerW * 0.33);
|
|
14373
14903
|
const rightW = innerW - leftW - 1;
|
|
14374
14904
|
const ruleLen = Math.max(8, rightW - 2);
|
|
14375
|
-
const VDivider = /* @__PURE__ */
|
|
14376
|
-
return /* @__PURE__ */
|
|
14377
|
-
/* @__PURE__ */
|
|
14378
|
-
/* @__PURE__ */
|
|
14379
|
-
/* @__PURE__ */
|
|
14380
|
-
/* @__PURE__ */
|
|
14381
|
-
/* @__PURE__ */
|
|
14382
|
-
/* @__PURE__ */
|
|
14905
|
+
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)) });
|
|
14906
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: panelW, marginBottom: 1, children: [
|
|
14907
|
+
/* @__PURE__ */ jsxs15(Text17, { children: [
|
|
14908
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "* Welcome to " }),
|
|
14909
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.white, children: "deep" }),
|
|
14910
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.coralBright, children: "Seek" }),
|
|
14911
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: THEME.white, children: "Code" }),
|
|
14912
|
+
/* @__PURE__ */ jsxs15(Text17, { color: THEME.coralMuted, children: [
|
|
14383
14913
|
" ",
|
|
14384
14914
|
VERSION
|
|
14385
14915
|
] })
|
|
14386
14916
|
] }),
|
|
14387
|
-
/* @__PURE__ */
|
|
14388
|
-
/* @__PURE__ */
|
|
14389
|
-
/* @__PURE__ */
|
|
14390
|
-
/* @__PURE__ */
|
|
14391
|
-
ROBOT.map((l, i) => /* @__PURE__ */
|
|
14392
|
-
/* @__PURE__ */
|
|
14393
|
-
/* @__PURE__ */
|
|
14917
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: cwd }),
|
|
14918
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "row", borderStyle: "round", borderColor: THEME.coral, marginTop: 1, paddingX: 0, paddingY: 0, children: [
|
|
14919
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: leftW, height: INNER_H, alignItems: "center", justifyContent: "center", children: [
|
|
14920
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, bold: true, children: "Welcome back!" }),
|
|
14921
|
+
ROBOT.map((l, i) => /* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, children: l }, i)),
|
|
14922
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "Ctrl+C \u9000\u51FA \xB7 Esc \u4E2D\u6B62" }),
|
|
14923
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "\u8F93\u5165 / \u67E5\u770B\u547D\u4EE4" })
|
|
14394
14924
|
] }),
|
|
14395
14925
|
VDivider,
|
|
14396
|
-
/* @__PURE__ */
|
|
14397
|
-
/* @__PURE__ */
|
|
14398
|
-
/* @__PURE__ */
|
|
14399
|
-
/* @__PURE__ */
|
|
14926
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", width: rightW, height: INNER_H, justifyContent: "space-between", paddingX: 1, children: [
|
|
14927
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
14928
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "Tips for getting started" }),
|
|
14929
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, children: "\u8F93\u5165\u9700\u6C42\u5F00\u59CB\uFF0C\u8F93\u5165 / \u5524\u51FA\u547D\u4EE4\u3002" })
|
|
14400
14930
|
] }),
|
|
14401
|
-
/* @__PURE__ */
|
|
14402
|
-
/* @__PURE__ */
|
|
14403
|
-
/* @__PURE__ */
|
|
14404
|
-
/* @__PURE__ */
|
|
14931
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.grayDim, children: "\u2500".repeat(ruleLen) }),
|
|
14932
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
14933
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.coralBright, bold: true, children: "What's new" }),
|
|
14934
|
+
/* @__PURE__ */ jsx17(Text17, { color: THEME.white, children: "\u5DF2\u5BF9\u63A5\u672C\u5730 Tool Call \u667A\u80FD\u51FD\u6570\u8C03\u7528\u3002" })
|
|
14405
14935
|
] })
|
|
14406
14936
|
] })
|
|
14407
14937
|
] })
|
|
@@ -14552,9 +15082,9 @@ __export(App_exports, {
|
|
|
14552
15082
|
App: () => App
|
|
14553
15083
|
});
|
|
14554
15084
|
import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef as useRef2, useState as useState4 } from "react";
|
|
14555
|
-
import { Box as
|
|
14556
|
-
import { Fragment as Fragment3, jsx as
|
|
14557
|
-
var
|
|
15085
|
+
import { Box as Box16, Static, Text as Text18, useApp, useInput as useInput2, useStdout } from "ink";
|
|
15086
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
15087
|
+
var CWD2, RowView, isDynamicRow, SPINNER_FRAMES, App;
|
|
14558
15088
|
var init_App = __esm({
|
|
14559
15089
|
"src/App.tsx"() {
|
|
14560
15090
|
"use strict";
|
|
@@ -14579,26 +15109,27 @@ var init_App = __esm({
|
|
|
14579
15109
|
init_PlanEditor();
|
|
14580
15110
|
init_SessionPicker();
|
|
14581
15111
|
init_ForkPicker();
|
|
15112
|
+
init_ModelPicker();
|
|
14582
15113
|
init_SlashMenu();
|
|
14583
15114
|
init_MultilineInput();
|
|
14584
15115
|
init_StatusStrip();
|
|
14585
15116
|
init_TopPanel();
|
|
14586
15117
|
init_inspect();
|
|
14587
|
-
KNOWN_MODELS = ["deepseek-v4", "deepseek-v4-flash"];
|
|
14588
15118
|
CWD2 = process.cwd();
|
|
14589
15119
|
RowView = ({ row, wrapW, streamTail, showThinking }) => {
|
|
14590
|
-
if (row.kind === "todos") return /* @__PURE__ */
|
|
14591
|
-
if (row.kind === "tool") return /* @__PURE__ */
|
|
14592
|
-
if (row.kind === "thinking") return /* @__PURE__ */
|
|
15120
|
+
if (row.kind === "todos") return /* @__PURE__ */ jsx18(TodosPanel, { todos: row.todos, wrapW });
|
|
15121
|
+
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 });
|
|
15122
|
+
if (row.kind === "thinking") return /* @__PURE__ */ jsx18(ThinkingBlock, { streaming: row.streaming ?? false, startedAt: row.startedAt, durationMs: row.durationMs, tokens: row.tokens, text: row.text, expanded: showThinking, wrapW });
|
|
14593
15123
|
if (row.kind === "user") {
|
|
14594
|
-
return /* @__PURE__ */
|
|
14595
|
-
/* @__PURE__ */
|
|
14596
|
-
/* @__PURE__ */
|
|
15124
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", marginTop: 1, children: [
|
|
15125
|
+
/* @__PURE__ */ jsx18(Text18, { color: THEME.grayDim, children: "\u2500".repeat(Math.max(8, wrapW)) }),
|
|
15126
|
+
/* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail })
|
|
14597
15127
|
] });
|
|
14598
15128
|
}
|
|
14599
|
-
return /* @__PURE__ */
|
|
15129
|
+
return /* @__PURE__ */ jsx18(MessageBlock, { row, wrapW, streamTail });
|
|
14600
15130
|
};
|
|
14601
15131
|
isDynamicRow = (r) => r.kind === "assistant" && !!r.streaming || r.kind === "thinking" && !!r.streaming || r.kind === "tool" && r.status === "running" || r.kind === "todos" && !!r.active;
|
|
15132
|
+
SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
14602
15133
|
App = ({ resumeSessionId, initialPlanMode, initialAutoMode, initialIncludeProject, engineReady }) => {
|
|
14603
15134
|
const state = useChatState(resumeSessionId, initialPlanMode, initialAutoMode);
|
|
14604
15135
|
const { exit } = useApp();
|
|
@@ -14672,6 +15203,15 @@ var init_App = __esm({
|
|
|
14672
15203
|
await refreshStatusLineRef.current();
|
|
14673
15204
|
})();
|
|
14674
15205
|
}, []);
|
|
15206
|
+
useEffect4(() => {
|
|
15207
|
+
void (async () => {
|
|
15208
|
+
const saved = await readModelPref();
|
|
15209
|
+
if (saved) {
|
|
15210
|
+
state.setModelOverride(saved);
|
|
15211
|
+
setModelDisplay(saved);
|
|
15212
|
+
}
|
|
15213
|
+
})();
|
|
15214
|
+
}, []);
|
|
14675
15215
|
useEffect4(() => {
|
|
14676
15216
|
void refreshStatusLineRef.current();
|
|
14677
15217
|
}, [state.busy, state.aborting, modelDisplay]);
|
|
@@ -14698,6 +15238,8 @@ var init_App = __esm({
|
|
|
14698
15238
|
return S.cmdAuto;
|
|
14699
15239
|
case "model":
|
|
14700
15240
|
return S.cmdModel;
|
|
15241
|
+
case "switch":
|
|
15242
|
+
return S.cmdSwitch;
|
|
14701
15243
|
case "thinking":
|
|
14702
15244
|
return S.cmdThinking;
|
|
14703
15245
|
case "lang":
|
|
@@ -14740,17 +15282,41 @@ var init_App = __esm({
|
|
|
14740
15282
|
const q = input.slice(1).toLowerCase();
|
|
14741
15283
|
return menuEntries.filter((c) => c.name.toLowerCase().startsWith(q));
|
|
14742
15284
|
}, [input, menuEntries]);
|
|
14743
|
-
const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null;
|
|
15285
|
+
const menuActive = state.pendingApproval != null || state.pendingQuestion != null || state.pendingPlan != null || state.pendingSessions != null || state.pendingFork != null || state.pendingModel != null;
|
|
15286
|
+
const [busyClock, setBusyClock] = useState4({ frame: 0, sec: 0 });
|
|
15287
|
+
const busyStartRef = useRef2(0);
|
|
15288
|
+
useEffect4(() => {
|
|
15289
|
+
if (!state.busy) {
|
|
15290
|
+
busyStartRef.current = 0;
|
|
15291
|
+
setBusyClock((c) => c.frame === 0 && c.sec === 0 ? c : { frame: 0, sec: 0 });
|
|
15292
|
+
return;
|
|
15293
|
+
}
|
|
15294
|
+
if (busyStartRef.current === 0) busyStartRef.current = Date.now();
|
|
15295
|
+
if (menuActive) return;
|
|
15296
|
+
const drive = () => setBusyClock({
|
|
15297
|
+
frame: Math.floor(Date.now() / 120) % SPINNER_FRAMES.length,
|
|
15298
|
+
sec: Math.floor((Date.now() - busyStartRef.current) / 1e3)
|
|
15299
|
+
});
|
|
15300
|
+
drive();
|
|
15301
|
+
const t = setInterval(drive, 120);
|
|
15302
|
+
return () => clearInterval(t);
|
|
15303
|
+
}, [state.busy, menuActive]);
|
|
14744
15304
|
const slashVisible = !menuActive && input.startsWith("/") && filteredCommands.length > 0;
|
|
14745
15305
|
const inputActive = !menuActive;
|
|
14746
15306
|
useEffect4(() => {
|
|
14747
15307
|
setSelectIdx(0);
|
|
14748
15308
|
setPlanEditing(false);
|
|
14749
|
-
}, [state.pendingApproval, state.pendingQuestion, state.pendingPlan, state.pendingSessions, state.pendingFork, slashVisible, filteredCommands.length]);
|
|
15309
|
+
}, [state.pendingApproval, state.pendingQuestion, state.pendingPlan, state.pendingSessions, state.pendingFork, state.pendingModel, slashVisible, filteredCommands.length]);
|
|
14750
15310
|
useEffect4(() => {
|
|
14751
15311
|
setQCursor(0);
|
|
14752
15312
|
setQChecked(/* @__PURE__ */ new Set());
|
|
14753
15313
|
}, [state.pendingQuestion]);
|
|
15314
|
+
useEffect4(() => {
|
|
15315
|
+
if (state.pendingModel) {
|
|
15316
|
+
const idx = state.pendingModel.models.indexOf(modelDisplay);
|
|
15317
|
+
setSelectIdx(idx >= 0 ? idx : 0);
|
|
15318
|
+
}
|
|
15319
|
+
}, [state.pendingModel]);
|
|
14754
15320
|
const runLocalSlash = async (text) => {
|
|
14755
15321
|
const [cmd, ...rest] = text.trim().split(/\s+/);
|
|
14756
15322
|
const arg = rest.join(" ");
|
|
@@ -14827,13 +15393,17 @@ ${list}
|
|
|
14827
15393
|
}
|
|
14828
15394
|
case "/model":
|
|
14829
15395
|
if (!arg) {
|
|
14830
|
-
state.pushInfo(
|
|
14831
|
-
\u53EF\u9009\uFF1A${KNOWN_MODELS.join("\u3001")} \u6216\u4EFB\u610F\u6A21\u578B id\u3002`);
|
|
15396
|
+
state.pushInfo(S.modelUsage(modelDisplay));
|
|
14832
15397
|
return true;
|
|
14833
15398
|
}
|
|
14834
15399
|
state.setModelOverride(arg);
|
|
14835
15400
|
setModelDisplay(arg);
|
|
14836
|
-
state.pushInfo(
|
|
15401
|
+
state.pushInfo(S.modelSwitched(arg));
|
|
15402
|
+
return true;
|
|
15403
|
+
case "/switch":
|
|
15404
|
+
void state.openModelPicker().then((picked) => {
|
|
15405
|
+
if (picked) setModelDisplay(picked);
|
|
15406
|
+
});
|
|
14837
15407
|
return true;
|
|
14838
15408
|
case "/thinking": {
|
|
14839
15409
|
const lvl = arg.toLowerCase();
|
|
@@ -14922,7 +15492,7 @@ ${listText}`);
|
|
|
14922
15492
|
const v = inputRef.current.trim();
|
|
14923
15493
|
if (!v) return;
|
|
14924
15494
|
if (busyRef.current) {
|
|
14925
|
-
if (!v.startsWith("/") && state.queueInput(v)) {
|
|
15495
|
+
if (!v.startsWith("/") && !v.startsWith("!") && state.queueInput(v)) {
|
|
14926
15496
|
setInput("");
|
|
14927
15497
|
setCursor(0);
|
|
14928
15498
|
} else {
|
|
@@ -14932,6 +15502,10 @@ ${listText}`);
|
|
|
14932
15502
|
}
|
|
14933
15503
|
setInput("");
|
|
14934
15504
|
setCursor(0);
|
|
15505
|
+
if (v.startsWith("!")) {
|
|
15506
|
+
await state.runBangCommand(v);
|
|
15507
|
+
return;
|
|
15508
|
+
}
|
|
14935
15509
|
if (v.startsWith("/")) {
|
|
14936
15510
|
await executeSlash(v);
|
|
14937
15511
|
return;
|
|
@@ -15020,6 +15594,16 @@ ${listText}`);
|
|
|
15020
15594
|
} else if (key.escape || key.ctrl && ch === "g") state.resolveFork(null);
|
|
15021
15595
|
return;
|
|
15022
15596
|
}
|
|
15597
|
+
if (state.pendingModel) {
|
|
15598
|
+
const list = state.pendingModel.models;
|
|
15599
|
+
if (key.upArrow) setSelectIdx((i) => (i - 1 + list.length) % list.length);
|
|
15600
|
+
else if (key.downArrow) setSelectIdx((i) => (i + 1) % list.length);
|
|
15601
|
+
else if (key.return) {
|
|
15602
|
+
const sel = list[Math.min(selectIdxRef.current, list.length - 1)];
|
|
15603
|
+
state.resolveModel(sel ?? null);
|
|
15604
|
+
} else if (key.escape || key.ctrl && ch === "g") state.resolveModel(null);
|
|
15605
|
+
return;
|
|
15606
|
+
}
|
|
15023
15607
|
if (key.ctrl && ch === "t") {
|
|
15024
15608
|
state.toggleShowThinking();
|
|
15025
15609
|
return;
|
|
@@ -15060,19 +15644,16 @@ ${listText}`);
|
|
|
15060
15644
|
}
|
|
15061
15645
|
});
|
|
15062
15646
|
const sessionShort = state.sessionIdRef.current ? truncateMiddle(state.sessionIdRef.current, 12) : "";
|
|
15063
|
-
return /* @__PURE__ */
|
|
15064
|
-
/* @__PURE__ */
|
|
15065
|
-
/* @__PURE__ */
|
|
15066
|
-
menuActive ? null : /* @__PURE__ */
|
|
15067
|
-
dynamicRows.map((row) => /* @__PURE__ */
|
|
15068
|
-
state.busy ? /* @__PURE__ */
|
|
15069
|
-
"\u25CF ",
|
|
15070
|
-
S.generating
|
|
15071
|
-
] }) }) : null
|
|
15647
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
|
|
15648
|
+
/* @__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) }),
|
|
15649
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", width: cols, children: [
|
|
15650
|
+
menuActive ? null : /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, children: [
|
|
15651
|
+
dynamicRows.map((row) => /* @__PURE__ */ jsx18(RowView, { row, wrapW, streamTail, showThinking: state.showThinkingText }, row.id)),
|
|
15652
|
+
state.busy ? /* @__PURE__ */ jsx18(Box16, { marginTop: 0.5, children: /* @__PURE__ */ jsx18(Text18, { color: THEME.coralBright, children: `${SPINNER_FRAMES[busyClock.frame]} ${S.generating} (${busyClock.sec}s \xB7 ${S.escInterrupt})` }) }) : null
|
|
15072
15653
|
] }),
|
|
15073
|
-
/* @__PURE__ */
|
|
15074
|
-
state.pendingApproval ? /* @__PURE__ */
|
|
15075
|
-
state.pendingQuestion ? /* @__PURE__ */
|
|
15654
|
+
/* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", paddingX: 1, flexShrink: 0, children: [
|
|
15655
|
+
state.pendingApproval ? /* @__PURE__ */ jsx18(ApprovalModal, { toolName: state.pendingApproval.toolName, detail: state.pendingApproval.detail, selectedIndex: selectIdx, wrapW }) : null,
|
|
15656
|
+
state.pendingQuestion ? /* @__PURE__ */ jsx18(
|
|
15076
15657
|
QuestionModal,
|
|
15077
15658
|
{
|
|
15078
15659
|
question: state.pendingQuestion.req.question,
|
|
@@ -15083,7 +15664,7 @@ ${listText}`);
|
|
|
15083
15664
|
wrapW
|
|
15084
15665
|
}
|
|
15085
15666
|
) : null,
|
|
15086
|
-
state.pendingPlan ? planEditing ? /* @__PURE__ */
|
|
15667
|
+
state.pendingPlan ? planEditing ? /* @__PURE__ */ jsx18(
|
|
15087
15668
|
PlanEditor,
|
|
15088
15669
|
{
|
|
15089
15670
|
value: planDraft,
|
|
@@ -15094,15 +15675,16 @@ ${listText}`);
|
|
|
15094
15675
|
},
|
|
15095
15676
|
onSubmit: confirmPlanEdit
|
|
15096
15677
|
}
|
|
15097
|
-
) : /* @__PURE__ */
|
|
15098
|
-
state.pendingSessions ? /* @__PURE__ */
|
|
15099
|
-
state.pendingFork ? /* @__PURE__ */
|
|
15100
|
-
|
|
15678
|
+
) : /* @__PURE__ */ jsx18(PlanModal, { selectedIndex: selectIdx }) : null,
|
|
15679
|
+
state.pendingSessions ? /* @__PURE__ */ jsx18(SessionPicker, { sessions: state.pendingSessions.sessions, selectedIndex: selectIdx, wrapW }) : null,
|
|
15680
|
+
state.pendingFork ? /* @__PURE__ */ jsx18(ForkPicker, { anchors: state.pendingFork.anchors, selectedIndex: selectIdx, wrapW }) : null,
|
|
15681
|
+
state.pendingModel ? /* @__PURE__ */ jsx18(ModelPicker, { models: state.pendingModel.models, currentModel: modelDisplay, selectedIndex: selectIdx, wrapW }) : null,
|
|
15682
|
+
slashVisible ? /* @__PURE__ */ jsx18(SlashMenu, { entries: filteredCommands, selectedIndex: selectIdx, cols }) : null
|
|
15101
15683
|
] }),
|
|
15102
|
-
/* @__PURE__ */
|
|
15684
|
+
/* @__PURE__ */ jsx18(Box16, { flexDirection: "column", paddingX: 1, marginTop: 1, flexShrink: 0, children: (() => {
|
|
15103
15685
|
const planOn = state.getPlanMode();
|
|
15104
15686
|
const autoOn = !planOn && state.getAutoMode();
|
|
15105
|
-
const inputEl = /* @__PURE__ */
|
|
15687
|
+
const inputEl = /* @__PURE__ */ jsx18(
|
|
15106
15688
|
MultilineInput,
|
|
15107
15689
|
{
|
|
15108
15690
|
value: input,
|
|
@@ -15120,17 +15702,17 @@ ${listText}`);
|
|
|
15120
15702
|
}
|
|
15121
15703
|
);
|
|
15122
15704
|
if (planOn || autoOn) {
|
|
15123
|
-
return /* @__PURE__ */
|
|
15124
|
-
/* @__PURE__ */
|
|
15705
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", borderStyle: "round", borderColor: planOn ? THEME.thinking : THEME.warn, paddingX: 1, children: [
|
|
15706
|
+
/* @__PURE__ */ jsx18(Text18, { color: planOn ? THEME.thinking : THEME.warn, children: planOn ? S.inputBadgePlan : S.inputBadgeAuto }),
|
|
15125
15707
|
inputEl
|
|
15126
15708
|
] });
|
|
15127
15709
|
}
|
|
15128
|
-
return /* @__PURE__ */
|
|
15129
|
-
/* @__PURE__ */
|
|
15710
|
+
return /* @__PURE__ */ jsxs16(Fragment3, { children: [
|
|
15711
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, color: THEME.gray, children: dimRule(cols) }),
|
|
15130
15712
|
inputEl
|
|
15131
15713
|
] });
|
|
15132
15714
|
})() }),
|
|
15133
|
-
/* @__PURE__ */
|
|
15715
|
+
/* @__PURE__ */ jsx18(Box16, { paddingX: 1, marginTop: 1, flexShrink: 0, children: /* @__PURE__ */ jsx18(StatusStrip, { model: modelDisplay, busy: state.busy, aborting: state.aborting, planMode: state.getPlanMode(), autoMode: state.getAutoMode(), sessionShort, cols, customLine: statusLineText }) })
|
|
15134
15716
|
] })
|
|
15135
15717
|
] });
|
|
15136
15718
|
};
|
|
@@ -15190,7 +15772,7 @@ import { render } from "ink";
|
|
|
15190
15772
|
import os5 from "os";
|
|
15191
15773
|
import path42 from "path";
|
|
15192
15774
|
import { emitKeypressEvents } from "node:readline";
|
|
15193
|
-
import { jsx as
|
|
15775
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
15194
15776
|
var parseArgs = (argv) => {
|
|
15195
15777
|
const out = {};
|
|
15196
15778
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -15340,7 +15922,7 @@ var main = async () => {
|
|
|
15340
15922
|
resumeId = await getMostRecentSessionId2() ?? void 0;
|
|
15341
15923
|
}
|
|
15342
15924
|
const { waitUntilExit } = render(
|
|
15343
|
-
/* @__PURE__ */
|
|
15925
|
+
/* @__PURE__ */ jsx19(App2, { resumeSessionId: resumeId, initialPlanMode: args.plan, initialAutoMode: args.auto, initialIncludeProject: includeProject, engineReady }),
|
|
15344
15926
|
// exitOnCtrlC:false:Ctrl+C 交由 App useInput 处理(统一退出/中止语义);
|
|
15345
15927
|
// patchConsole:false:避免 console 劫持与全屏重绘叠加闪屏。
|
|
15346
15928
|
{ exitOnCtrlC: false, patchConsole: false }
|