deepseeker-code 1.0.46 → 1.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cli.mjs +672 -198
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -423,6 +423,12 @@ var init_config = __esm({
|
|
|
423
423
|
/** 后台工具(isSync:false)兜底超时(ms):超时强制收尾释放互斥锁,防 generator 卡死导致锁永久泄漏。
|
|
424
424
|
* abort 仍是主取消通道,此值仅作最后防线;默认 30min 远超合理后台任务时长,正常任务不受影响。 */
|
|
425
425
|
MAX_BACKGROUND_TOOL_MS: 30 * 60 * 1e3,
|
|
426
|
+
/** ★ run_command 运行时看门狗(自动转后台阈值 ms):前台流式超过此时长仍未退出 → 进程自动收编进
|
|
427
|
+
* 后台任务注册表并返回 task_id(get_background_output / stop_background_task 接管),不再阻塞主循环、
|
|
428
|
+
* 也不杀进程。与内部空闲看门狗(RUN_COMMAND_IDLE_TIMEOUT_MS,默认 60s)共用降级路径。
|
|
429
|
+
* env RUN_COMMAND_AUTO_BG_MS 覆盖。勿把 IDLE 调到高于 DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS
|
|
430
|
+
* (空闲分支到期会产出降级消息喂流,不会饿死 collectToolResult 的 idle 熔断)。 */
|
|
431
|
+
runCommandAutoBgMs: Number(process.env.RUN_COMMAND_AUTO_BG_MS) || 12e4,
|
|
426
432
|
userWorkspaceDir: (() => {
|
|
427
433
|
let cwd = process.cwd().replace(/\\/g, "/");
|
|
428
434
|
if (/^[a-z]:/i.test(cwd)) {
|
|
@@ -506,6 +512,7 @@ var init_config = __esm({
|
|
|
506
512
|
parallelSafeTools: "DEEP_SEEK_PARALLEL_SAFE_TOOLS",
|
|
507
513
|
workflowConcurrency: "DEEP_SEEK_WORKFLOW_CONCURRENCY",
|
|
508
514
|
workflowMaxSteps: "DEEP_SEEK_WORKFLOW_MAX_STEPS",
|
|
515
|
+
runCommandAutoBgMs: "RUN_COMMAND_AUTO_BG_MS",
|
|
509
516
|
planEnforcement: "DEEP_SEEK_PLAN_ENFORCEMENT",
|
|
510
517
|
mcpExposeMode: "DEEP_SEEK_MCP_EXPOSE_MODE",
|
|
511
518
|
transcriptEvents: "DEEP_SEEK_TRANSCRIPT_EVENTS",
|
|
@@ -973,11 +980,96 @@ var init_deepseek = __esm({
|
|
|
973
980
|
}
|
|
974
981
|
});
|
|
975
982
|
|
|
983
|
+
// ../core/src/session/contentParts.ts
|
|
984
|
+
var MAX_IMAGE_BYTES, msgText, imageUrlsOf, hasImagePart, isVisionEnabled, estimateImageTokens, toWireUserContent, replaceImageParts, collapseToText, degradeImagesForAux;
|
|
985
|
+
var init_contentParts = __esm({
|
|
986
|
+
"../core/src/session/contentParts.ts"() {
|
|
987
|
+
"use strict";
|
|
988
|
+
MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
989
|
+
msgText = (content) => {
|
|
990
|
+
if (typeof content === "string") return content;
|
|
991
|
+
if (Array.isArray(content)) {
|
|
992
|
+
return content.filter((p) => typeof p?.text === "string").map((p) => p.text).join(" ");
|
|
993
|
+
}
|
|
994
|
+
return "";
|
|
995
|
+
};
|
|
996
|
+
imageUrlsOf = (content) => {
|
|
997
|
+
if (!Array.isArray(content)) return [];
|
|
998
|
+
return content.filter((p) => p?.type === "image_url" && typeof p?.image_url?.url === "string").map((p) => p.image_url.url);
|
|
999
|
+
};
|
|
1000
|
+
hasImagePart = (content) => imageUrlsOf(content).length > 0;
|
|
1001
|
+
isVisionEnabled = () => {
|
|
1002
|
+
const v = process.env.DEEP_SEEK_VISION;
|
|
1003
|
+
return v === "1" || v === "true";
|
|
1004
|
+
};
|
|
1005
|
+
estimateImageTokens = () => {
|
|
1006
|
+
const n = Number(process.env.DEEP_SEEK_IMAGE_TOKENS);
|
|
1007
|
+
return Number.isFinite(n) && n >= 100 ? Math.floor(n) : 1500;
|
|
1008
|
+
};
|
|
1009
|
+
toWireUserContent = (text, attachments) => {
|
|
1010
|
+
if (!Array.isArray(attachments) || attachments.length === 0) return text;
|
|
1011
|
+
const accepted = [];
|
|
1012
|
+
const skipped = [];
|
|
1013
|
+
for (const a of attachments) {
|
|
1014
|
+
const name = typeof a?.name === "string" && a.name.trim() ? a.name : "image";
|
|
1015
|
+
const b64 = typeof a?.base64 === "string" ? a.base64 : "";
|
|
1016
|
+
if (!b64) {
|
|
1017
|
+
skipped.push(`\u{1F5BC} \u56FE\u7247 ${name} \u5DF2\u5FFD\u7565\uFF1A\u7A7A\u6570\u636E`);
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
if (!/^image\//.test(a?.mime || "")) {
|
|
1021
|
+
skipped.push(`\u{1F5BC} \u56FE\u7247 ${name} \u5DF2\u5FFD\u7565\uFF1A\u975E\u56FE\u7247\u7C7B\u578B`);
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
if (b64.length * 3 / 4 > MAX_IMAGE_BYTES) {
|
|
1025
|
+
skipped.push(`\u{1F5BC} \u56FE\u7247 ${name} \u5DF2\u5FFD\u7565\uFF1A\u8D85\u8FC7 ${Math.round(MAX_IMAGE_BYTES / 1024 / 1024)}MB \u4E0A\u9650`);
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
accepted.push({ name, url: `data:${a.mime};base64,${b64}` });
|
|
1029
|
+
}
|
|
1030
|
+
const labels = accepted.map((p) => `\u{1F5BC} [\u56FE\u7247: ${p.name}]`);
|
|
1031
|
+
const footer = [...skipped, ...labels];
|
|
1032
|
+
const finalText = footer.length ? `${text}
|
|
1033
|
+
|
|
1034
|
+
${footer.join("\n")}` : text;
|
|
1035
|
+
if (accepted.length === 0) return finalText;
|
|
1036
|
+
const parts = [
|
|
1037
|
+
{ type: "text", text: finalText },
|
|
1038
|
+
...accepted.map((p) => ({ type: "image_url", image_url: { url: p.url } }))
|
|
1039
|
+
];
|
|
1040
|
+
return parts;
|
|
1041
|
+
};
|
|
1042
|
+
replaceImageParts = (m, note) => {
|
|
1043
|
+
if (!m || !Array.isArray(m.content)) return m;
|
|
1044
|
+
let touched = false;
|
|
1045
|
+
const parts = m.content.map((p) => {
|
|
1046
|
+
if (p?.type === "image_url") {
|
|
1047
|
+
touched = true;
|
|
1048
|
+
return { type: "text", text: note };
|
|
1049
|
+
}
|
|
1050
|
+
return p;
|
|
1051
|
+
});
|
|
1052
|
+
if (!touched) return m;
|
|
1053
|
+
return { ...m, content: parts };
|
|
1054
|
+
};
|
|
1055
|
+
collapseToText = (m, imageNote) => {
|
|
1056
|
+
if (!m || !Array.isArray(m.content)) return m;
|
|
1057
|
+
const text = msgText(m.content);
|
|
1058
|
+
if (imageNote && hasImagePart(m.content)) {
|
|
1059
|
+
return { ...m, content: text ? `${text} ${imageNote}` : imageNote };
|
|
1060
|
+
}
|
|
1061
|
+
return { ...m, content: text };
|
|
1062
|
+
};
|
|
1063
|
+
degradeImagesForAux = (m) => collapseToText(m, "[\u56FE\u7247\u5DF2\u5F52\u6863]");
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
|
|
976
1067
|
// ../core/src/llm/providers/replay/index.ts
|
|
977
1068
|
var createReplayProvider;
|
|
978
1069
|
var init_replay = __esm({
|
|
979
1070
|
"../core/src/llm/providers/replay/index.ts"() {
|
|
980
1071
|
"use strict";
|
|
1072
|
+
init_contentParts();
|
|
981
1073
|
createReplayProvider = (script) => {
|
|
982
1074
|
const turns = Array.isArray(script.turns) ? script.turns : [];
|
|
983
1075
|
let cursor = 0;
|
|
@@ -1095,6 +1187,7 @@ var isCjkCodePoint, estimateTextTokens, estimateTokens, cleanMsg, groupUnits, sp
|
|
|
1095
1187
|
var init_contextCore = __esm({
|
|
1096
1188
|
"../core/src/session/contextCore.ts"() {
|
|
1097
1189
|
"use strict";
|
|
1190
|
+
init_contentParts();
|
|
1098
1191
|
isCjkCodePoint = (c) => c >= 19968 && c <= 40959 || // CJK 统一表意文字(基本区)
|
|
1099
1192
|
c >= 13312 && c <= 19903 || // CJK 扩展 A
|
|
1100
1193
|
c >= 12352 && c <= 12543 || // 日文假名(平假名 + 片假名)
|
|
@@ -1117,8 +1210,14 @@ var init_contextCore = __esm({
|
|
|
1117
1210
|
estimateTokens = (messagesArr) => {
|
|
1118
1211
|
return messagesArr.reduce((total, m) => {
|
|
1119
1212
|
let pureText = "";
|
|
1213
|
+
let imageCount = 0;
|
|
1120
1214
|
if (m.content) {
|
|
1121
|
-
|
|
1215
|
+
if (typeof m.content === "string") {
|
|
1216
|
+
pureText += m.content;
|
|
1217
|
+
} else if (Array.isArray(m.content)) {
|
|
1218
|
+
pureText += msgText(m.content);
|
|
1219
|
+
imageCount += imageUrlsOf(m.content).length;
|
|
1220
|
+
}
|
|
1122
1221
|
}
|
|
1123
1222
|
if (m.tool_calls && Array.isArray(m.tool_calls)) {
|
|
1124
1223
|
for (const call of m.tool_calls) {
|
|
@@ -1134,12 +1233,12 @@ var init_contextCore = __esm({
|
|
|
1134
1233
|
}
|
|
1135
1234
|
}
|
|
1136
1235
|
const isStructured = m.role === "tool" || Array.isArray(m.tool_calls) && m.tool_calls.length > 0;
|
|
1137
|
-
const tokens = estimateTextTokens(pureText, isStructured ? 4 : 4.8) + 4;
|
|
1236
|
+
const tokens = estimateTextTokens(pureText, isStructured ? 4 : 4.8) + imageCount * estimateImageTokens() + 4;
|
|
1138
1237
|
return total + (isNaN(tokens) ? 0 : tokens);
|
|
1139
1238
|
}, 0);
|
|
1140
1239
|
};
|
|
1141
1240
|
cleanMsg = (m) => {
|
|
1142
|
-
const { id, sessionId, ...rest } = m;
|
|
1241
|
+
const { id, sessionId, ts, ...rest } = m;
|
|
1143
1242
|
return rest;
|
|
1144
1243
|
};
|
|
1145
1244
|
groupUnits = (messagesArr) => {
|
|
@@ -1242,6 +1341,7 @@ var init_store = __esm({
|
|
|
1242
1341
|
"use strict";
|
|
1243
1342
|
init_config();
|
|
1244
1343
|
init_common();
|
|
1344
|
+
init_contentParts();
|
|
1245
1345
|
getSessionsDirPath = (mainSessionId) => {
|
|
1246
1346
|
assertSafeSessionId(mainSessionId);
|
|
1247
1347
|
const fileName = getFileName(mainSessionId);
|
|
@@ -1406,8 +1506,8 @@ var init_store = __esm({
|
|
|
1406
1506
|
}
|
|
1407
1507
|
if (typeof msg?.dscEvent === "string") continue;
|
|
1408
1508
|
messageCount++;
|
|
1409
|
-
if (!preview && msg?.role === "user" &&
|
|
1410
|
-
const t = msg.content.replace(/\s+/g, " ").trim();
|
|
1509
|
+
if (!preview && msg?.role === "user" && msg.content != null) {
|
|
1510
|
+
const t = (msgText(msg.content) || "\uFF08\u8BE5\u6761\u6D88\u606F\u5E26\u56FE\u7247\u9644\u4EF6\uFF09").replace(/\s+/g, " ").trim();
|
|
1411
1511
|
if (t.includes("\uFFFD")) {
|
|
1412
1512
|
const cleaned = t.replace(/\uFFFD+/g, "").trim();
|
|
1413
1513
|
preview = cleaned ? `\uFF08\u542B\u4E71\u7801\u7247\u6BB5\uFF09${cleaned}` : "\uFF08\u8BE5\u6761\u6D88\u606F\u5185\u5BB9\u4E3A\u4E71\u7801\uFF0C\u65E0\u6CD5\u6B63\u5E38\u663E\u793A\uFF09";
|
|
@@ -1515,7 +1615,7 @@ var init_transcript = __esm({
|
|
|
1515
1615
|
try {
|
|
1516
1616
|
await ensureSessionsDir(entry.sessionId);
|
|
1517
1617
|
const { sessionId, ...rest } = entry;
|
|
1518
|
-
const line = { id: createUUID(), ...rest };
|
|
1618
|
+
const line = { id: createUUID(), ts: (/* @__PURE__ */ new Date()).toISOString(), ...rest };
|
|
1519
1619
|
const p = getTranscriptPath(sessionId);
|
|
1520
1620
|
const payload = JSON.stringify(line) + "\n";
|
|
1521
1621
|
if (payload.includes("\uFFFD")) {
|
|
@@ -1831,13 +1931,14 @@ function microcompactTextContent(raw) {
|
|
|
1831
1931
|
function isAsyncGenerator(x) {
|
|
1832
1932
|
return x != null && typeof x[Symbol.asyncIterator] === "function";
|
|
1833
1933
|
}
|
|
1834
|
-
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, compactBatch, compactToLine, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, ensureFitsWindow, collectToolResult;
|
|
1934
|
+
var ANSI_ESCAPE, getFileAccessRoots, relativizeWorkspacePathsInText, truncateToolResult, truncateApprovalDetail, compactBatch, ARCHIVE_INDEX_MAX_ENTRIES, ARCHIVE_INDEX_BATCH_CAP, extractArchiveEntities, parseSummarySlot, mergeSummarySlot, compactSlotNarrative, compactToLine, ensureSummarySlot, SUMMARY_SELF_COMPACT_THRESHOLD, ensureFitsWindow, collectToolResult;
|
|
1835
1935
|
var init_truncate = __esm({
|
|
1836
1936
|
"../core/src/agent/truncate.ts"() {
|
|
1837
1937
|
"use strict";
|
|
1838
1938
|
init_config();
|
|
1839
1939
|
init_model();
|
|
1840
1940
|
init_contextCore();
|
|
1941
|
+
init_contentParts();
|
|
1841
1942
|
init_store();
|
|
1842
1943
|
init_transcript();
|
|
1843
1944
|
init_hooks();
|
|
@@ -1878,7 +1979,7 @@ var init_truncate = __esm({
|
|
|
1878
1979
|
}
|
|
1879
1980
|
return out;
|
|
1880
1981
|
};
|
|
1881
|
-
truncateToolResult = (result, maxChars) => {
|
|
1982
|
+
truncateToolResult = (result, maxChars, sidecarNote) => {
|
|
1882
1983
|
const finalMaxChars = maxChars ?? appConfig.MAX_TOOL_RESULT_CHARS;
|
|
1883
1984
|
const newResult = microcompactTextContent(result);
|
|
1884
1985
|
if (!newResult || newResult.length <= finalMaxChars) return newResult;
|
|
@@ -1887,7 +1988,8 @@ var init_truncate = __esm({
|
|
|
1887
1988
|
const tail = newResult.slice(-half);
|
|
1888
1989
|
const totalLines = newResult.split("\n").length;
|
|
1889
1990
|
const omitted = Math.max(0, totalLines - head.split("\n").length - tail.split("\n").length);
|
|
1890
|
-
|
|
1991
|
+
const note = sidecarNote ? `\uFF1B${sidecarNote}` : "";
|
|
1992
|
+
return [head, "", `\u2026(\u5DF2\u7701\u7565\u4E2D\u95F4\u7EA6 ${omitted} \u884C\uFF0C\u5171 ${totalLines} \u884C${note})\u2026`, "", tail].join("\n");
|
|
1891
1993
|
};
|
|
1892
1994
|
truncateApprovalDetail = (detail, maxChars = 2e3) => {
|
|
1893
1995
|
if (!detail || detail.length <= maxChars) return detail;
|
|
@@ -1903,12 +2005,74 @@ ${tail}`;
|
|
|
1903
2005
|
};
|
|
1904
2006
|
compactBatch = async (batch, signal) => {
|
|
1905
2007
|
const resp = await chatWithModelWithSummary(
|
|
1906
|
-
|
|
2008
|
+
// ★ 辅助模型是 text-only:送前把 image part 降级为占位符——base64 绝不能进摘要批(烧钱且无意义)
|
|
2009
|
+
[...batch.map(degradeImagesForAux), { role: "user", content: '\u7528\u4E00\u884C\u8BDD\u6982\u62EC\u4EE5\u4E0A\u5BF9\u8BDD\u4E0E\u5DE5\u5177\u8C03\u7528\uFF1A\u4EFB\u52A1\u76EE\u6807\u3001\u5173\u952E\u51B3\u7B56\u3001\u52A8\u8FC7\u7684\u6587\u4EF6\u3001\u5F53\u524D\u8FDB\u5EA6\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\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' }],
|
|
1907
2010
|
[],
|
|
1908
2011
|
{ signal }
|
|
1909
2012
|
);
|
|
1910
2013
|
return `- ${resp.choices[0].message.content || ""}`;
|
|
1911
2014
|
};
|
|
2015
|
+
ARCHIVE_INDEX_MAX_ENTRIES = 120;
|
|
2016
|
+
ARCHIVE_INDEX_BATCH_CAP = 60;
|
|
2017
|
+
extractArchiveEntities = (batch) => {
|
|
2018
|
+
let text = "";
|
|
2019
|
+
for (const m of batch) {
|
|
2020
|
+
if (m.content) text += ` ${msgText(m.content)}`;
|
|
2021
|
+
const calls = m.tool_calls;
|
|
2022
|
+
if (Array.isArray(calls)) for (const c of calls) text += ` ${c?.function?.name ?? ""} ${c?.function?.arguments ?? ""}`;
|
|
2023
|
+
}
|
|
2024
|
+
const found = [];
|
|
2025
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2026
|
+
const push = (raw) => {
|
|
2027
|
+
const s = raw.trim();
|
|
2028
|
+
if (!s || s.length < 3 || s.length > 60 || seen.has(s)) return;
|
|
2029
|
+
seen.add(s);
|
|
2030
|
+
found.push(s);
|
|
2031
|
+
};
|
|
2032
|
+
for (const m of text.match(/(?:[A-Za-z]:)?[\w.\-]+(?:[/\\][\w.\-]+)+\.[A-Za-z0-9]{1,6}/g) ?? []) push(m);
|
|
2033
|
+
for (const m of text.match(/`([^`\n]{2,48})`/g) ?? []) push(m.slice(1, -1));
|
|
2034
|
+
return found.slice(0, ARCHIVE_INDEX_BATCH_CAP);
|
|
2035
|
+
};
|
|
2036
|
+
parseSummarySlot = (content) => {
|
|
2037
|
+
const raw = content ?? "";
|
|
2038
|
+
const idxMark = raw.indexOf("\u27E6DSC:ARCHIVE-INDEX\u27E7");
|
|
2039
|
+
const notesMark = raw.indexOf("\u27E6DSC:ARCHIVE-NOTES\u27E7");
|
|
2040
|
+
if (idxMark === -1 || notesMark === -1 || notesMark < idxMark) return { index: [], notes: raw };
|
|
2041
|
+
const indexText = raw.slice(idxMark + "\u27E6DSC:ARCHIVE-INDEX\u27E7".length, notesMark);
|
|
2042
|
+
const entityText = indexText.includes("\n") ? indexText.slice(indexText.indexOf("\n") + 1) : "";
|
|
2043
|
+
const notes = raw.slice(notesMark + "\u27E6DSC:ARCHIVE-NOTES\u27E7".length).replace(/^\n+/, "");
|
|
2044
|
+
const index = entityText.split("|").map((s) => s.trim()).filter(Boolean);
|
|
2045
|
+
return { index, notes };
|
|
2046
|
+
};
|
|
2047
|
+
mergeSummarySlot = (oldContent, noteLine, newEntities) => {
|
|
2048
|
+
const { index, notes } = parseSummarySlot(oldContent);
|
|
2049
|
+
const merged = [];
|
|
2050
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2051
|
+
for (const e of [...newEntities, ...index]) {
|
|
2052
|
+
if (!e || seen.has(e)) continue;
|
|
2053
|
+
seen.add(e);
|
|
2054
|
+
merged.push(e);
|
|
2055
|
+
if (merged.length >= ARCHIVE_INDEX_MAX_ENTRIES) break;
|
|
2056
|
+
}
|
|
2057
|
+
const newNotes = notes ? `${notes}
|
|
2058
|
+
${noteLine}` : noteLine;
|
|
2059
|
+
return [
|
|
2060
|
+
"\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
|
+
merged.join(" | "),
|
|
2062
|
+
"\u27E6DSC:ARCHIVE-NOTES\u27E7",
|
|
2063
|
+
newNotes
|
|
2064
|
+
].join("\n");
|
|
2065
|
+
};
|
|
2066
|
+
compactSlotNarrative = async (slotContent, modelWindow, signal) => {
|
|
2067
|
+
const { index } = parseSummarySlot(slotContent);
|
|
2068
|
+
const compactedNotes = await compactToLine([{ role: "system", content: slotContent }], modelWindow, signal);
|
|
2069
|
+
return [
|
|
2070
|
+
"\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",
|
|
2071
|
+
index.join(" | "),
|
|
2072
|
+
"\u27E6DSC:ARCHIVE-NOTES\u27E7",
|
|
2073
|
+
compactedNotes
|
|
2074
|
+
].join("\n");
|
|
2075
|
+
};
|
|
1912
2076
|
compactToLine = async (toCompact, _modelWindow, signal) => {
|
|
1913
2077
|
const MAX_BATCH_TOKENS = 16e3;
|
|
1914
2078
|
const units = groupUnits(toCompact);
|
|
@@ -1963,11 +2127,9 @@ ${tail}`;
|
|
|
1963
2127
|
try {
|
|
1964
2128
|
if (toCompact.length > 0) {
|
|
1965
2129
|
const line = await compactToLine(toCompact, event.modelWindow, event.signal);
|
|
1966
|
-
|
|
1967
|
-
summaryMsg.content = old ? `${old}
|
|
1968
|
-
${line}` : line;
|
|
2130
|
+
summaryMsg.content = mergeSummarySlot(summaryMsg?.content || "", line, extractArchiveEntities(toCompact));
|
|
1969
2131
|
if (estimateTokens([summaryMsg]) > SUMMARY_SELF_COMPACT_THRESHOLD) {
|
|
1970
|
-
summaryMsg.content = await
|
|
2132
|
+
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal);
|
|
1971
2133
|
}
|
|
1972
2134
|
const endTime = performance.now();
|
|
1973
2135
|
event.messageArr.length = 0;
|
|
@@ -2004,7 +2166,7 @@ ${line}` : line;
|
|
|
2004
2166
|
keep--;
|
|
2005
2167
|
continue;
|
|
2006
2168
|
} else if (summaryMsg?.content) {
|
|
2007
|
-
summaryMsg.content = await
|
|
2169
|
+
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal);
|
|
2008
2170
|
event.messageArr.length = 0;
|
|
2009
2171
|
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
2010
2172
|
const store = await getRollingState(event.sessionId);
|
|
@@ -2642,7 +2804,7 @@ async function killBackgroundTasksUnder(dirPath) {
|
|
|
2642
2804
|
}
|
|
2643
2805
|
return killed;
|
|
2644
2806
|
}
|
|
2645
|
-
var _winShellCache, resolveWinShell, MAX_BUFFER_CHARS, registry, backgroundTools, killAllBackgroundTasks;
|
|
2807
|
+
var _winShellCache, resolveWinShell, MAX_BUFFER_CHARS, registry, createBgTask, attachTaskLifecycle, adoptRunningProcess, backgroundTools, killAllBackgroundTasks;
|
|
2646
2808
|
var init_background = __esm({
|
|
2647
2809
|
"../core/src/tool/registry/background.ts"() {
|
|
2648
2810
|
"use strict";
|
|
@@ -2683,12 +2845,110 @@ var init_background = __esm({
|
|
|
2683
2845
|
};
|
|
2684
2846
|
MAX_BUFFER_CHARS = 1e5;
|
|
2685
2847
|
registry = /* @__PURE__ */ new Map();
|
|
2848
|
+
createBgTask = (proc, command, cwd, sessionId) => {
|
|
2849
|
+
const task = {
|
|
2850
|
+
taskId: createUUID(),
|
|
2851
|
+
command,
|
|
2852
|
+
cwd,
|
|
2853
|
+
sessionId: sessionId ?? "",
|
|
2854
|
+
proc,
|
|
2855
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2856
|
+
status: "running",
|
|
2857
|
+
exitCode: null,
|
|
2858
|
+
outputBuffer: ""
|
|
2859
|
+
};
|
|
2860
|
+
registry.set(task.taskId, task);
|
|
2861
|
+
return task;
|
|
2862
|
+
};
|
|
2863
|
+
attachTaskLifecycle = (task, proc, opts = {}) => {
|
|
2864
|
+
return new Promise((resolve) => {
|
|
2865
|
+
let finished = false;
|
|
2866
|
+
const finish = (apply) => {
|
|
2867
|
+
if (finished) return;
|
|
2868
|
+
finished = true;
|
|
2869
|
+
apply();
|
|
2870
|
+
setTimeout(() => registry.delete(task.taskId), 6e4);
|
|
2871
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
2872
|
+
try {
|
|
2873
|
+
proc?.stdout?.removeAllListeners?.();
|
|
2874
|
+
} catch {
|
|
2875
|
+
}
|
|
2876
|
+
try {
|
|
2877
|
+
proc?.stderr?.removeAllListeners?.();
|
|
2878
|
+
} catch {
|
|
2879
|
+
}
|
|
2880
|
+
try {
|
|
2881
|
+
proc?.removeAllListeners?.();
|
|
2882
|
+
} catch {
|
|
2883
|
+
}
|
|
2884
|
+
resolve();
|
|
2885
|
+
};
|
|
2886
|
+
const onAbort = () => {
|
|
2887
|
+
killTree(proc).finally(() => {
|
|
2888
|
+
finish(() => {
|
|
2889
|
+
if (task.status === "running") task.status = "killed";
|
|
2890
|
+
task.exitCode = task.exitCode ?? -1;
|
|
2891
|
+
appendOutput(task, `
|
|
2892
|
+
[\u7528\u6237\u4E2D\u6B62\uFF0C\u8FDB\u7A0B\u6811\u5DF2\u7EC8\u6B62]`);
|
|
2893
|
+
});
|
|
2894
|
+
});
|
|
2895
|
+
};
|
|
2896
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
2897
|
+
proc.on("close", (code) => {
|
|
2898
|
+
finish(() => {
|
|
2899
|
+
if (opts.codec) {
|
|
2900
|
+
try {
|
|
2901
|
+
appendOutput(task, opts.codec.flush());
|
|
2902
|
+
} catch {
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
task.status = task.status === "killed" ? "killed" : "exited";
|
|
2906
|
+
task.exitCode ??= code ?? 0;
|
|
2907
|
+
appendOutput(task, `
|
|
2908
|
+
[\u8FDB\u7A0B\u7ED3\u675F exit=${code}]`);
|
|
2909
|
+
});
|
|
2910
|
+
});
|
|
2911
|
+
proc.on("error", (e) => {
|
|
2912
|
+
finish(() => {
|
|
2913
|
+
if (task.status === "running") task.status = "exited";
|
|
2914
|
+
task.exitCode = task.exitCode ?? -1;
|
|
2915
|
+
appendOutput(task, `
|
|
2916
|
+
[spawn error: ${e.message}]`);
|
|
2917
|
+
});
|
|
2918
|
+
});
|
|
2919
|
+
});
|
|
2920
|
+
};
|
|
2921
|
+
adoptRunningProcess = (proc, meta, seedOutput, codec) => {
|
|
2922
|
+
const task = createBgTask(proc, meta.command, meta.cwd, meta.sessionId);
|
|
2923
|
+
if (seedOutput) appendOutput(task, seedOutput);
|
|
2924
|
+
try {
|
|
2925
|
+
proc?.stdout?.removeAllListeners?.("data");
|
|
2926
|
+
} catch {
|
|
2927
|
+
}
|
|
2928
|
+
try {
|
|
2929
|
+
proc?.stderr?.removeAllListeners?.("data");
|
|
2930
|
+
} catch {
|
|
2931
|
+
}
|
|
2932
|
+
try {
|
|
2933
|
+
proc?.removeAllListeners?.("close");
|
|
2934
|
+
} catch {
|
|
2935
|
+
}
|
|
2936
|
+
try {
|
|
2937
|
+
proc?.removeAllListeners?.("error");
|
|
2938
|
+
} catch {
|
|
2939
|
+
}
|
|
2940
|
+
const onData = (d) => appendOutput(task, codec.decode(d));
|
|
2941
|
+
proc.stdout?.on("data", onData);
|
|
2942
|
+
proc.stderr?.on("data", onData);
|
|
2943
|
+
void attachTaskLifecycle(task, proc, { signal: meta.signal, codec });
|
|
2944
|
+
return task.taskId;
|
|
2945
|
+
};
|
|
2686
2946
|
backgroundTools = [
|
|
2687
2947
|
{
|
|
2688
2948
|
type: "function",
|
|
2689
2949
|
function: {
|
|
2690
2950
|
name: "run_in_background",
|
|
2691
|
-
description: "\u5728\u540E\u53F0\u542F\u52A8\u4E00\u4E2A\u957F\
|
|
2951
|
+
description: "\u5728\u540E\u53F0\u542F\u52A8\u4E00\u4E2A\u957F\u65F6 shell \u547D\u4EE4\u5E76\u7ACB\u5373\u8FD4\u56DE task_id\uFF0C\u4E0D\u963B\u585E\u540E\u7EED\u63A8\u7406\u3002\u9002\u7528\u4E24\u7C7B\u573A\u666F\uFF1A\u2460 \u957F\u8FDE\u63A5/\u5E38\u9A7B\u8FDB\u7A0B\uFF08dev server\u3001watch\u3001tail -f\uFF09\u2014\u2014\u5148\u8D77\u670D\u52A1\u518D\u7EE7\u7EED\u5E72\u522B\u7684\u6D3B\uFF1B\u2461 \u9884\u8BA1\u8FD0\u884C\u6570\u5206\u949F\u4EE5\u4E0A\u3001\u65E0\u9700\u5B9E\u65F6\u76EF\u770B\u7684\u6709\u9650\u957F\u4EFB\u52A1\uFF08\u5168\u91CF\u6D4B\u8BD5 / \u5927\u6784\u5EFA / \u5927\u4F53\u79EF\u5B89\u88C5\u2014\u2014\u8DD1\u5B8C\u7528 get_background_output \u5E26 wait_seconds \u7B49\u7ED3\u679C\uFF0C\u4E0D\u8981\u7528\u524D\u53F0 run_command \u5E72\u7B49\uFF09\u3002\u7528 get_background_output \u67E5\u65E5\u5FD7\u4E0E\u72B6\u6001\uFF0Cstop_background_task \u7EC8\u6B62\u3002",
|
|
2692
2952
|
parameters: {
|
|
2693
2953
|
type: "object",
|
|
2694
2954
|
properties: {
|
|
@@ -2738,75 +2998,25 @@ var init_background = __esm({
|
|
|
2738
2998
|
yield `\u274C [\u540E\u53F0\u542F\u52A8\u5931\u8D25]\uFF1A${e.message}`;
|
|
2739
2999
|
return;
|
|
2740
3000
|
}
|
|
2741
|
-
const
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
exitCode: null,
|
|
2751
|
-
outputBuffer: ""
|
|
3001
|
+
const codec = {
|
|
3002
|
+
decode: decodeChunk,
|
|
3003
|
+
// flush:close 时收尾两个 stream 解码器的尾字节(GBK/UTF-8 残留,不 flush 丢最后一个字符)
|
|
3004
|
+
flush: () => {
|
|
3005
|
+
let s = "";
|
|
3006
|
+
if (decoder) s += decoder.decode();
|
|
3007
|
+
s += pendingUtf8.decode();
|
|
3008
|
+
return s;
|
|
3009
|
+
}
|
|
2752
3010
|
};
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
proc.
|
|
3011
|
+
const task = createBgTask(proc, args.command, cwd, ctx?.sessionId);
|
|
3012
|
+
const taskId = task.taskId;
|
|
3013
|
+
proc.stdout?.on("data", (d) => appendOutput(task, codec.decode(d)));
|
|
3014
|
+
proc.stderr?.on("data", (d) => appendOutput(task, codec.decode(d)));
|
|
2756
3015
|
yield `\u2705 [\u540E\u53F0\u4EFB\u52A1\u5DF2\u542F\u52A8]
|
|
2757
3016
|
task_id: ${taskId}
|
|
2758
3017
|
\u547D\u4EE4: ${args.command}
|
|
2759
3018
|
\u7528 get_background_output(task_id="${taskId}") \u67E5\u65E5\u5FD7\uFF0Cstop_background_task(task_id="${taskId}") \u7EC8\u6B62\u3002`;
|
|
2760
|
-
await
|
|
2761
|
-
let finished = false;
|
|
2762
|
-
const finish = (apply) => {
|
|
2763
|
-
if (finished) return;
|
|
2764
|
-
finished = true;
|
|
2765
|
-
apply();
|
|
2766
|
-
setTimeout(() => registry.delete(taskId), 6e4);
|
|
2767
|
-
ctx?.abortSignal?.removeEventListener("abort", onAbort);
|
|
2768
|
-
try {
|
|
2769
|
-
proc?.stdout?.removeAllListeners?.();
|
|
2770
|
-
} catch {
|
|
2771
|
-
}
|
|
2772
|
-
try {
|
|
2773
|
-
proc?.stderr?.removeAllListeners?.();
|
|
2774
|
-
} catch {
|
|
2775
|
-
}
|
|
2776
|
-
try {
|
|
2777
|
-
proc?.removeAllListeners?.();
|
|
2778
|
-
} catch {
|
|
2779
|
-
}
|
|
2780
|
-
resolve();
|
|
2781
|
-
};
|
|
2782
|
-
const onAbort = () => {
|
|
2783
|
-
killTree(proc).finally(() => {
|
|
2784
|
-
finish(() => {
|
|
2785
|
-
if (task.status === "running") task.status = "killed";
|
|
2786
|
-
task.exitCode = task.exitCode ?? -1;
|
|
2787
|
-
appendOutput(task, `
|
|
2788
|
-
[\u7528\u6237\u4E2D\u6B62\uFF0C\u8FDB\u7A0B\u6811\u5DF2\u7EC8\u6B62]`);
|
|
2789
|
-
});
|
|
2790
|
-
});
|
|
2791
|
-
};
|
|
2792
|
-
ctx?.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
2793
|
-
proc.on("close", (code) => {
|
|
2794
|
-
finish(() => {
|
|
2795
|
-
task.status = task.status === "killed" ? "killed" : "exited";
|
|
2796
|
-
task.exitCode ??= code ?? 0;
|
|
2797
|
-
appendOutput(task, `
|
|
2798
|
-
[\u8FDB\u7A0B\u7ED3\u675F exit=${code}]`);
|
|
2799
|
-
});
|
|
2800
|
-
});
|
|
2801
|
-
proc.on("error", (e) => {
|
|
2802
|
-
finish(() => {
|
|
2803
|
-
if (task.status === "running") task.status = "exited";
|
|
2804
|
-
task.exitCode = task.exitCode ?? -1;
|
|
2805
|
-
appendOutput(task, `
|
|
2806
|
-
[spawn error: ${e.message}]`);
|
|
2807
|
-
});
|
|
2808
|
-
});
|
|
2809
|
-
});
|
|
3019
|
+
await attachTaskLifecycle(task, proc, { signal: ctx?.abortSignal, codec });
|
|
2810
3020
|
}
|
|
2811
3021
|
}
|
|
2812
3022
|
},
|
|
@@ -2818,7 +3028,7 @@ task_id: ${taskId}
|
|
|
2818
3028
|
parameters: {
|
|
2819
3029
|
type: "object",
|
|
2820
3030
|
properties: {
|
|
2821
|
-
task_id: { type: "string", description: "
|
|
3031
|
+
task_id: { type: "string", description: "\u540E\u53F0\u4EFB\u52A1\u7684 task_id\uFF08run_in_background \u8FD4\u56DE\uFF0C\u6216 run_command \u8D85\u65F6\u81EA\u52A8\u8F6C\u540E\u53F0\u8FD4\u56DE\uFF09" },
|
|
2822
3032
|
tail_lines: { type: "number", description: "\u53EA\u8FD4\u56DE\u6700\u540E N \u884C\u65E5\u5FD7\uFF08\u9ED8\u8BA4 50\uFF0C\u907F\u514D\u4E00\u6B21\u704C\u5165\u8FC7\u591A\uFF09" },
|
|
2823
3033
|
wait_seconds: { type: "number", description: "\u963B\u585E\u7B49\u5F85\u4EFB\u52A1\u9000\u51FA\uFF08\u6216\u5230\u8FBE\u6B64\u65F6\u957F\uFF09\u540E\u518D\u8FD4\u56DE\uFF0C\u4E0A\u9650 120 \u79D2\uFF1B\u4EFB\u52A1\u5DF2\u5728\u8DD1\u4E14\u9700\u8981\u7B49\u7ED3\u679C\u65F6\u4F7F\u7528\uFF0C\u4E0D\u9700\u8981\u7B49\u5C31\u7701\u7565" }
|
|
2824
3034
|
},
|
|
@@ -2859,7 +3069,7 @@ task_id: ${taskId}
|
|
|
2859
3069
|
parameters: {
|
|
2860
3070
|
type: "object",
|
|
2861
3071
|
properties: {
|
|
2862
|
-
task_id: { type: "string", description: "
|
|
3072
|
+
task_id: { type: "string", description: "\u540E\u53F0\u4EFB\u52A1\u7684 task_id\uFF08run_in_background \u8FD4\u56DE\uFF0C\u6216 run_command \u8D85\u65F6\u81EA\u52A8\u8F6C\u540E\u53F0\u8FD4\u56DE\uFF09" }
|
|
2863
3073
|
},
|
|
2864
3074
|
required: ["task_id"]
|
|
2865
3075
|
},
|
|
@@ -4016,6 +4226,8 @@ var init_planMode = __esm({
|
|
|
4016
4226
|
"get_diagnostics",
|
|
4017
4227
|
"goto_definition",
|
|
4018
4228
|
// ★ P0-A 补漏:LSP 导航/诊断恰是调研阶段最需要的(原白名单漂移漏登记,schema 档与 runtime 档共用此表)
|
|
4229
|
+
"recall",
|
|
4230
|
+
// 只读检索本会话历史(长调研中早前轮次可能已被压缩归档,调研阶段恰是 recall 主场景)
|
|
4019
4231
|
"web_fetch",
|
|
4020
4232
|
"web_search"
|
|
4021
4233
|
// 只读研究类(虽为 DANGER 但不写本地状态;仍走各自审批)
|
|
@@ -5908,6 +6120,7 @@ var init_command = __esm({
|
|
|
5908
6120
|
init_type();
|
|
5909
6121
|
init_guard();
|
|
5910
6122
|
init_background();
|
|
6123
|
+
init_config();
|
|
5911
6124
|
EXIT_SENTINEL = (code) => `
|
|
5912
6125
|
\u27E6DSC_EXIT:${code}\u27E7`;
|
|
5913
6126
|
EXIT_SENTINEL_RE = /⟦DSC_EXIT:(-?\d+)⟧/g;
|
|
@@ -5917,7 +6130,7 @@ var init_command = __esm({
|
|
|
5917
6130
|
type: "function",
|
|
5918
6131
|
function: {
|
|
5919
6132
|
name: "run_command",
|
|
5920
|
-
description: "\u5728\u5DE5\u4F5C\u533A\u6267\u884C shell \u547D\u4EE4\uFF08\
|
|
6133
|
+
description: "\u5728\u5DE5\u4F5C\u533A\u6267\u884C shell \u547D\u4EE4\uFF08\u77ED\u5E73\u5FEB\u7684\u6D4B\u8BD5 / \u6784\u5EFA / git \u7B49\uFF09\uFF0C\u6D41\u5F0F\u8FD4\u56DE stdout/stderr \u5E76\u9644\u5E26\u9000\u51FA\u7801\u3002\u5C5E\u4E8E\u9AD8\u5371\u64CD\u4F5C\uFF0C\u6BCF\u6B21\u6267\u884C\u90FD\u9700\u8981\u7528\u6237\u5BA1\u6279\u3002\u9884\u8BA1\u8FD0\u884C\u6570\u5206\u949F\u4EE5\u4E0A\u7684\u957F\u4EFB\u52A1\uFF08\u5168\u91CF\u6D4B\u8BD5 / \u5927\u6784\u5EFA / \u5927\u4F53\u79EF\u5B89\u88C5\uFF09\u8BF7\u6539\u7528 run_in_background \u540E\u53F0\u6267\u884C\uFF1B\u82E5\u672C\u5DE5\u5177\u6267\u884C\u8FC7\u4E45\u4ECD\u672A\u7ED3\u675F\uFF0C\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u628A\u8FDB\u7A0B\u8F6C\u5165\u540E\u53F0\u5E76\u8FD4\u56DE task_id\uFF08\u7528 get_background_output \u67E5\u7ED3\u679C\u3001stop_background_task \u7EC8\u6B62\uFF09\u3002",
|
|
5921
6134
|
parameters: {
|
|
5922
6135
|
type: "object",
|
|
5923
6136
|
properties: {
|
|
@@ -5962,6 +6175,10 @@ ${tail}`,
|
|
|
5962
6175
|
const cwd = args.cwd ? resolveSafePath(args.cwd) : getActiveWorkspaceRoot();
|
|
5963
6176
|
const maxChars = RUN_COMMAND_MAX_CHARS;
|
|
5964
6177
|
let totalYieldedChars = 0;
|
|
6178
|
+
let fullOutput = "";
|
|
6179
|
+
let degraded = false;
|
|
6180
|
+
let degradeDue = false;
|
|
6181
|
+
let degradeReason = null;
|
|
5965
6182
|
const isWin = process.platform === "win32";
|
|
5966
6183
|
if (ctx?.abortSignal?.aborted) {
|
|
5967
6184
|
yield `\u274C [\u5DF2\u4E2D\u6B62]\uFF1A\u547D\u4EE4 [${args.command}] \u672A\u6267\u884C\uFF08\u7528\u6237\u5DF2\u4E2D\u65AD\uFF09\u3002`;
|
|
@@ -6016,6 +6233,15 @@ ${tail}`,
|
|
|
6016
6233
|
}
|
|
6017
6234
|
return (decoder ?? pendingUtf8).decode(buf, { stream: true });
|
|
6018
6235
|
};
|
|
6236
|
+
const codec = {
|
|
6237
|
+
decode: decodeChunk,
|
|
6238
|
+
flush: () => {
|
|
6239
|
+
let s = "";
|
|
6240
|
+
if (decoder) s += decoder.decode();
|
|
6241
|
+
s += pendingUtf8.decode();
|
|
6242
|
+
return s;
|
|
6243
|
+
}
|
|
6244
|
+
};
|
|
6019
6245
|
proc.stdout?.on("data", (d) => {
|
|
6020
6246
|
queue.push(decodeChunk(d));
|
|
6021
6247
|
notifyNewData();
|
|
@@ -6042,11 +6268,22 @@ ${tail}`,
|
|
|
6042
6268
|
void killTree(proc);
|
|
6043
6269
|
};
|
|
6044
6270
|
ctx?.abortSignal?.addEventListener("abort", onAbort);
|
|
6271
|
+
const IDLE_TIMEOUT_MS = Number(process.env.RUN_COMMAND_IDLE_TIMEOUT_MS) || 6e4;
|
|
6272
|
+
const autoBgMs = Math.max(1, appConfig.runCommandAutoBgMs);
|
|
6273
|
+
const runtimeTimer = setTimeout(() => {
|
|
6274
|
+
degradeDue = true;
|
|
6275
|
+
notifyNewData();
|
|
6276
|
+
}, autoBgMs);
|
|
6277
|
+
runtimeTimer.unref?.();
|
|
6045
6278
|
let overLimit = false;
|
|
6046
6279
|
try {
|
|
6047
|
-
while ((!settled || queue.length > 0) && !overLimit) {
|
|
6280
|
+
while ((!settled || queue.length > 0) && !overLimit && !degraded) {
|
|
6281
|
+
if (degradeDue && !settled) {
|
|
6282
|
+
degraded = true;
|
|
6283
|
+
degradeReason = "runtime";
|
|
6284
|
+
break;
|
|
6285
|
+
}
|
|
6048
6286
|
if (queue.length === 0) {
|
|
6049
|
-
const IDLE_TIMEOUT_MS = 6e4;
|
|
6050
6287
|
let timedOut = false;
|
|
6051
6288
|
await new Promise((r) => {
|
|
6052
6289
|
resolveWaiter = r;
|
|
@@ -6055,20 +6292,26 @@ ${tail}`,
|
|
|
6055
6292
|
r();
|
|
6056
6293
|
}, IDLE_TIMEOUT_MS);
|
|
6057
6294
|
});
|
|
6295
|
+
if (degradeDue && !settled) {
|
|
6296
|
+
degraded = true;
|
|
6297
|
+
degradeReason = "runtime";
|
|
6298
|
+
break;
|
|
6299
|
+
}
|
|
6058
6300
|
if (timedOut && !settled && queue.length === 0) {
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
\u23F1\uFE0F [\u770B\u95E8\u72D7]\uFF1A\u547D\u4EE4\u8FDE\u7EED ${IDLE_TIMEOUT_MS / 1e3}s \u65E0\u8F93\u51FA\u4E14\u672A\u9000\u51FA\uFF0C\u5224\u5B9A\u4E3A\u5E38\u9A7B\u8FDB\u7A0B\uFF08\u5982 dev server / tail -f\uFF09\u3002\u5DF2\u4E3B\u52A8\u7EC8\u6B62\u4EE5\u91CA\u653E\u4E3B\u5FAA\u73AF\u2014\u2014\u5E38\u9A7B\u547D\u4EE4\u8BF7\u6539\u7528 run_in_background\u3002
|
|
6062
|
-
`;
|
|
6063
|
-
onAbort();
|
|
6064
|
-
settled = true;
|
|
6065
|
-
overLimit = true;
|
|
6301
|
+
degraded = true;
|
|
6302
|
+
degradeReason = "idle";
|
|
6066
6303
|
break;
|
|
6067
6304
|
}
|
|
6068
6305
|
}
|
|
6069
6306
|
while (queue.length > 0) {
|
|
6307
|
+
if (degradeDue && !settled) {
|
|
6308
|
+
degraded = true;
|
|
6309
|
+
degradeReason = "runtime";
|
|
6310
|
+
break;
|
|
6311
|
+
}
|
|
6070
6312
|
const chunk = queue.shift();
|
|
6071
6313
|
totalYieldedChars += chunk.length;
|
|
6314
|
+
fullOutput += chunk;
|
|
6072
6315
|
if (totalYieldedChars > maxChars) {
|
|
6073
6316
|
yield `
|
|
6074
6317
|
|
|
@@ -6082,14 +6325,30 @@ ${tail}`,
|
|
|
6082
6325
|
yield chunk;
|
|
6083
6326
|
}
|
|
6084
6327
|
}
|
|
6085
|
-
if (
|
|
6328
|
+
if (degraded) {
|
|
6329
|
+
const taskId = adoptRunningProcess(
|
|
6330
|
+
proc,
|
|
6331
|
+
{ command: args.command, cwd, sessionId: ctx?.sessionId, signal: ctx?.abortSignal },
|
|
6332
|
+
fullOutput + queue.join(""),
|
|
6333
|
+
codec
|
|
6334
|
+
);
|
|
6335
|
+
const why = degradeReason === "idle" ? `\u8FDE\u7EED ${Math.round(IDLE_TIMEOUT_MS / 1e3)}s \u65E0\u8F93\u51FA\u4E14\u672A\u9000\u51FA` : `\u5DF2\u6301\u7EED\u8FD0\u884C\u8D85\u8FC7 ${Math.round(autoBgMs / 1e3)}s`;
|
|
6336
|
+
yield `
|
|
6337
|
+
|
|
6338
|
+
\u23F3 [\u81EA\u52A8\u8F6C\u540E\u53F0]\uFF1A\u547D\u4EE4 [${args.command}] ${why}\uFF0C\u5DF2\u81EA\u52A8\u8F6C\u4E3A\u540E\u53F0\u4EFB\u52A1\uFF08\u524D\u53F0\u6D41\u5F0F\u7ED3\u675F\uFF0C\u672A\u6D88\u8D39\u7684\u5269\u4F59\u8F93\u51FA\u5DF2\u5E76\u5165\u540E\u53F0\u7F13\u51B2\uFF09\u3002
|
|
6339
|
+
task_id: ${taskId}
|
|
6340
|
+
\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
|
|
6341
|
+
`;
|
|
6342
|
+
} else if (overLimit) {
|
|
6086
6343
|
yield EXIT_SENTINEL(-1);
|
|
6087
6344
|
} else if (exitCode !== null) {
|
|
6088
6345
|
yield EXIT_SENTINEL(exitCode);
|
|
6089
6346
|
}
|
|
6090
6347
|
} finally {
|
|
6091
6348
|
if (idleTimer) clearTimeout(idleTimer);
|
|
6349
|
+
clearTimeout(runtimeTimer);
|
|
6092
6350
|
ctx?.abortSignal?.removeEventListener("abort", onAbort);
|
|
6351
|
+
if (!settled && !degraded) void killTree(proc);
|
|
6093
6352
|
}
|
|
6094
6353
|
}
|
|
6095
6354
|
}
|
|
@@ -8824,6 +9083,182 @@ ${lines.join("\n")}`;
|
|
|
8824
9083
|
}
|
|
8825
9084
|
});
|
|
8826
9085
|
|
|
9086
|
+
// ../core/src/tool/registry/recall.ts
|
|
9087
|
+
import fs26 from "fs/promises";
|
|
9088
|
+
import path29 from "path";
|
|
9089
|
+
var escapeRegExp2, lineText, primaryPathArg, annotateStaleness, snippetAround, recallTools;
|
|
9090
|
+
var init_recall = __esm({
|
|
9091
|
+
"../core/src/tool/registry/recall.ts"() {
|
|
9092
|
+
"use strict";
|
|
9093
|
+
init_type();
|
|
9094
|
+
init_guard();
|
|
9095
|
+
init_transcript();
|
|
9096
|
+
init_store();
|
|
9097
|
+
escapeRegExp2 = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9098
|
+
lineText = (l) => {
|
|
9099
|
+
let t = "";
|
|
9100
|
+
if (typeof l.content === "string") t += l.content;
|
|
9101
|
+
else if (Array.isArray(l.content)) t += l.content.map((p) => typeof p?.text === "string" ? p.text : "").join(" ");
|
|
9102
|
+
if (Array.isArray(l.tool_calls)) {
|
|
9103
|
+
for (const c of l.tool_calls) {
|
|
9104
|
+
if (c?.function?.name === "recall") continue;
|
|
9105
|
+
t += ` ${c?.function?.name ?? ""} ${c?.function?.arguments ?? ""}`;
|
|
9106
|
+
}
|
|
9107
|
+
}
|
|
9108
|
+
return t;
|
|
9109
|
+
};
|
|
9110
|
+
primaryPathArg = (args) => {
|
|
9111
|
+
for (const k of ["path", "file_path", "source"]) {
|
|
9112
|
+
if (typeof args?.[k] === "string" && args[k]) return args[k];
|
|
9113
|
+
}
|
|
9114
|
+
return void 0;
|
|
9115
|
+
};
|
|
9116
|
+
annotateStaleness = async (args, observedAt) => {
|
|
9117
|
+
const p = primaryPathArg(args);
|
|
9118
|
+
if (!p) return "\u5FEB\u7167\uFF08\u65E0\u8DEF\u5F84\u5B9E\u4F53\uFF0C\u672A\u7ECF\u91CD\u9A8C\u2014\u2014\u636E\u4EE5\u884C\u52A8\u524D\u8BF7\u91CD\u8DD1\u9A8C\u8BC1\uFF09";
|
|
9119
|
+
const abs = path29.isAbsolute(p) ? p : path29.resolve(getActiveWorkspaceRoot(), p);
|
|
9120
|
+
try {
|
|
9121
|
+
const st = await fs26.stat(abs);
|
|
9122
|
+
if (observedAt && st.mtime.toISOString() > observedAt) {
|
|
9123
|
+
return `\u26A0\uFE0F \u89C2\u5BDF\u540E\u8BE5\u6587\u4EF6\u5DF2\u88AB\u4FEE\u6539\uFF08${p}\uFF09\u2014\u2014\u5FC5\u987B\u91CD\u65B0 read_file \u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539`;
|
|
9124
|
+
}
|
|
9125
|
+
return `\u2713 \u6587\u4EF6\u672A\u53D8\uFF08${p}\uFF09`;
|
|
9126
|
+
} catch {
|
|
9127
|
+
return `\u26A0\uFE0F \u8BE5\u6587\u4EF6\u5DF2\u4E0D\u5B58\u5728\uFF08${p}\uFF09`;
|
|
9128
|
+
}
|
|
9129
|
+
};
|
|
9130
|
+
snippetAround = (text, re, maxChars) => {
|
|
9131
|
+
const m = re.exec(text);
|
|
9132
|
+
const start = Math.max(0, (m?.index ?? 0) - 120);
|
|
9133
|
+
const slice = text.slice(start, start + maxChars);
|
|
9134
|
+
const headMark = start > 0 ? "\u2026" : "";
|
|
9135
|
+
const tailMark = start + maxChars < text.length ? "\u2026\uFF08\u7247\u6BB5\u622A\u65AD\uFF0C\u5B8C\u6574\u5185\u5BB9\u53EF\u7528 with_full\uFF09" : "";
|
|
9136
|
+
return `${headMark}${slice}${tailMark}`;
|
|
9137
|
+
};
|
|
9138
|
+
recallTools = [
|
|
9139
|
+
{
|
|
9140
|
+
type: "function",
|
|
9141
|
+
function: {
|
|
9142
|
+
name: "recall",
|
|
9143
|
+
description: "\u68C0\u7D22\u3010\u672C\u4F1A\u8BDD\u3011\u5168\u91CF\u5386\u53F2\u8F6C\u5F55\uFF08transcript\uFF09\uFF0C\u5305\u62EC\u5DF2\u88AB\u4E0A\u4E0B\u6587\u538B\u7F29\u5F52\u6863\u7684\u539F\u59CB\u6D88\u606F\u4E0E\u5DE5\u5177\u7ED3\u679C\u3002\u4F7F\u7528\u65F6\u673A\uFF1A\u6EDA\u52A8\u6458\u8981\uFF08\u27E6DSC:ARCHIVE-INDEX\u27E7/\u27E6DSC:ARCHIVE-NOTES\u27E7\uFF09\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u7EC6\u8282\u65F6\u2014\u2014\u5982\u5F52\u6863\u524D\u7684\u6587\u4EF6\u5185\u5BB9\u3001\u62A5\u9519\u539F\u6587\u3001\u7528\u6237\u65E9\u524D\u7684\u8981\u6C42\u2014\u2014\u5148\u7528\u672C\u5DE5\u5177\u68C0\u7D22\uFF0C\u4E0D\u8981\u51ED\u6458\u8981\u81C6\u6D4B\uFF0C\u4E5F\u4E0D\u8981\u91CD\u8DD1\u5DE5\u5177\u3002\u2605 \u9996\u67E5\u7B56\u7565\uFF1Aquery \u5FC5\u987B\u7528\u5177\u4F53\u5B9E\u4F53\u8BCD\u2014\u2014\u62A5\u9519\u5173\u952E\u8BCD\uFF08\u5982 TypeError\uFF09\u3001\u6587\u4EF6\u8DEF\u5F84\u3001\u51FD\u6570/\u7B26\u53F7\u540D\uFF08\u6458\u8981\u5B9E\u4F53\u7D22\u5F15\u91CC\u51FA\u73B0\u8FC7\u4EC0\u4E48\u5C31\u7528\u4EC0\u4E48\uFF09\uFF1B\u4E0D\u8981\u7528\u5DE5\u5177\u540D\uFF08read_file \u7B49\uFF09\u6216\u6CDB\u8BCD\uFF08\u4EE3\u7801/\u6587\u4EF6/\u95EE\u9898\uFF09\u4F5C query\uFF0C\u4F1A\u547D\u4E2D\u5927\u91CF\u65E0\u5173\u5DE5\u5177\u884C\u3002\u4E00\u6B21\u6CA1\u4E2D\u5C31\u6362\u66F4\u5177\u4F53\u7684\u8BCD\u6216\u7528 is_regex \u4EE5 | \u5408\u5E76\u591A\u4E2A\u5019\u9009\u8BCD\uFF0C\u901A\u5E38 1-2 \u6B21\u5185\u547D\u4E2D\u3002\u8FD4\u56DE\u6309\u65F6\u95F4\u65E7\u2192\u65B0\uFF08\u4F18\u5148\u5F52\u6863\u533A\uFF09\uFF1B\u6587\u4EF6\u7C7B\u5DE5\u5177\u7ED3\u679C\u9644\u5B9E\u65F6\u6821\u9A8C\uFF1A\u26A0\uFE0F \u5DF2\u4FEE\u6539/\u5DF2\u4E0D\u5B58\u5728 \u7684\u5FC5\u987B\u91CD\u65B0 read_file \u9A8C\u8BC1\u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539\uFF0C\u2713 \u672A\u53D8 \u65B9\u53EF\u76F4\u63A5\u5F15\u7528\u3002\u7ED3\u679C\u66FE\u88AB\u622A\u65AD\u7684\u4F1A\u6807\u6CE8 with_full \u53EF\u53D6\u5B58\u6863\u5168\u6587\u3002\u6458\u8981\u5DF2\u591F\u7528\u65F6\u52FF\u8C03\u7528\uFF08\u7701 token\uFF09\u3002",
|
|
9144
|
+
parameters: {
|
|
9145
|
+
type: "object",
|
|
9146
|
+
properties: {
|
|
9147
|
+
query: { type: "string", description: "\u68C0\u7D22\u5173\u952E\u8BCD\u3002\u9ED8\u8BA4\u5B57\u9762\u91CF\u5339\u914D\uFF1Bis_regex=true \u65F6\u6309\u6B63\u5219\u89E3\u6790\uFF08\u591A\u5173\u952E\u8BCD\u7528 | \u5408\u5E76\uFF09" },
|
|
9148
|
+
is_regex: { type: "boolean", description: "query \u662F\u5426\u6309\u6B63\u5219\u89E3\u6790\uFF0C\u9ED8\u8BA4 false" },
|
|
9149
|
+
run_id: { type: "string", description: "\u9650\u5B9A\u67D0\u4E2A run\uFF08\u4E00\u6B21\u7528\u6237\u8F93\u5165\u7684\u56DE\u5408\uFF09\u5185\u68C0\u7D22\uFF1A\u4F20\u547D\u4E2D\u5934\u5C55\u793A\u7684 runId \u524D\u7F00\uFF08\u53EF\u9009\uFF09" },
|
|
9150
|
+
limit: { type: "number", description: "\u6700\u5927\u547D\u4E2D\u6761\u6570\uFF08\u9ED8\u8BA4 6\uFF0C\u4E0A\u9650 12\uFF09" },
|
|
9151
|
+
with_full: { type: "string", description: "\u53D6\u56DE\u67D0\u4E2A\u5DE5\u5177\u7ED3\u679C\u7684\u5B58\u6863\u5168\u6587\uFF08\u66FE\u88AB\u622A\u65AD\u7684\u8D85\u957F\u7ED3\u679C\uFF09\uFF1A\u4F20\u5176 tool_call_id\uFF08\u622A\u65AD\u6807\u8BB0\u884C\u4E2D\u7ED9\u51FA\uFF09\u3002\u4E0E query \u4E92\u65A5" },
|
|
9152
|
+
full_offset: { type: "number", description: "with_full \u5206\u9875\u504F\u79FB\uFF08\u5B57\u7B26\uFF09\uFF0C\u9ED8\u8BA4 0\uFF1B\u8FD4\u56DE\u5C3E\u6807\u63D0\u793A\u4E0B\u4E00\u9875\u504F\u79FB" }
|
|
9153
|
+
},
|
|
9154
|
+
required: []
|
|
9155
|
+
},
|
|
9156
|
+
safetyLevel: "safe" /* SAFE */,
|
|
9157
|
+
isSync: true,
|
|
9158
|
+
// ★ 检索结果预算与 web 等工具对齐 16000 口径;命中数 × 单片段双重限流防 context thrashing
|
|
9159
|
+
maxOutputCharacters: 16e3,
|
|
9160
|
+
async execute(args, ctx) {
|
|
9161
|
+
if (!ctx?.sessionId) return "\u274C [recall] \u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587\uFF08sessionId\uFF09\uFF0C\u65E0\u6CD5\u68C0\u7D22\u3002";
|
|
9162
|
+
try {
|
|
9163
|
+
if (args.with_full) {
|
|
9164
|
+
const safeId = String(args.with_full).replace(/[^A-Za-z0-9_-]/g, "");
|
|
9165
|
+
if (!safeId) return "\u274C [recall] with_full \u542B\u975E\u6CD5\u5B57\u7B26\u3002";
|
|
9166
|
+
const sidecar = path29.join(getSessionsDirPath(ctx.sessionId), "tool-outputs", `${safeId}.txt`);
|
|
9167
|
+
let full = "";
|
|
9168
|
+
try {
|
|
9169
|
+
full = await fs26.readFile(sidecar, "utf-8");
|
|
9170
|
+
} catch {
|
|
9171
|
+
return `\u274C [recall] \u672A\u627E\u5230\u8BE5 id \u7684\u5B58\u6863\u539F\u6587\uFF08\u53EF\u80FD\u672A\u66FE\u89E6\u53D1\u622A\u65AD\u5B58\u6863\u3001\u6216\u4F1A\u8BDD\u5DF2\u6E05\u7406\uFF09\uFF1A${args.with_full}`;
|
|
9172
|
+
}
|
|
9173
|
+
const CHUNK = 14e3;
|
|
9174
|
+
const off = Math.max(0, Math.floor(args.full_offset ?? 0));
|
|
9175
|
+
const slice = full.slice(off, off + CHUNK);
|
|
9176
|
+
const more = off + CHUNK < full.length ? `
|
|
9177
|
+
|
|
9178
|
+
[\u672A\u5B8C\uFF0C\u5171 ${full.length} \u5B57\u7B26\u2014\u2014\u7EE7\u7EED\u4F20 full_offset=${off + CHUNK} \u53D6\u4E0B\u4E00\u6BB5]` : "\n\n[\u5168\u6587\u5B8C]";
|
|
9179
|
+
return `[\u5B58\u6863\u539F\u6587 ${args.with_full} \xB7 \u7B2C ${off}-${Math.min(off + CHUNK, full.length)} / ${full.length} \u5B57\u7B26]
|
|
9180
|
+
|
|
9181
|
+
${slice}${more}`;
|
|
9182
|
+
}
|
|
9183
|
+
const cleanQuery = (args.query || "").trim();
|
|
9184
|
+
if (!cleanQuery) return "\u274C [recall] \u68C0\u7D22\u5173\u952E\u8BCD\u4E0D\u80FD\u4E3A\u7A7A\uFF08\u6216\u6539\u7528 with_full \u53D6\u5B58\u6863\u5168\u6587\uFF09\u3002";
|
|
9185
|
+
const re = new RegExp(args.is_regex ? cleanQuery : escapeRegExp2(cleanQuery), "i");
|
|
9186
|
+
const lines = await readTranscriptLines(ctx.sessionId);
|
|
9187
|
+
const toolCallInfo = /* @__PURE__ */ new Map();
|
|
9188
|
+
for (const l of lines) {
|
|
9189
|
+
if (isEventLine(l) || !Array.isArray(l.tool_calls)) continue;
|
|
9190
|
+
for (const c of l.tool_calls) {
|
|
9191
|
+
let a = {};
|
|
9192
|
+
try {
|
|
9193
|
+
a = JSON.parse(c?.function?.arguments || "{}");
|
|
9194
|
+
} catch {
|
|
9195
|
+
}
|
|
9196
|
+
toolCallInfo.set(c.id, { name: c?.function?.name ?? "", args: a, ts: l.ts });
|
|
9197
|
+
}
|
|
9198
|
+
}
|
|
9199
|
+
const limit = Math.min(Math.max(Math.floor(args.limit ?? 6), 1), 12);
|
|
9200
|
+
const runFilter = args.run_id?.trim();
|
|
9201
|
+
const blocks = [];
|
|
9202
|
+
let runN = 0;
|
|
9203
|
+
let runId = "";
|
|
9204
|
+
for (const l of lines) {
|
|
9205
|
+
if (isEventLine(l)) {
|
|
9206
|
+
if (l.dscEvent === "run.start") {
|
|
9207
|
+
runN++;
|
|
9208
|
+
runId = String(l.runId ?? "");
|
|
9209
|
+
}
|
|
9210
|
+
continue;
|
|
9211
|
+
}
|
|
9212
|
+
const role = l.role;
|
|
9213
|
+
if (role === "system") continue;
|
|
9214
|
+
if (runFilter && !(runId && runId.startsWith(runFilter))) continue;
|
|
9215
|
+
let info;
|
|
9216
|
+
if (role === "tool") {
|
|
9217
|
+
info = toolCallInfo.get(l.tool_call_id);
|
|
9218
|
+
if (info?.name === "recall") continue;
|
|
9219
|
+
}
|
|
9220
|
+
const text = lineText(l);
|
|
9221
|
+
if (!text || !re.test(text)) continue;
|
|
9222
|
+
const ts = l.ts;
|
|
9223
|
+
const roleDesc = role === "tool" ? `${info?.name ?? "tool"} \u8C03\u7528\u7ED3\u679C` : role === "assistant" ? "assistant\uFF08\u6587\u672C/\u5DE5\u5177\u8C03\u7528\u53C2\u6570\uFF09" : "\u7528\u6237\u6D88\u606F";
|
|
9224
|
+
let header = `\u2500\u2500 \u547D\u4E2D${blocks.length + 1} \xB7 run#${runN}${runId ? `(${runId.slice(0, 8)})` : ""} \xB7 ${roleDesc} \xB7 ${ts ?? "\u65F6\u95F4\u672A\u77E5"} \u2500\u2500`;
|
|
9225
|
+
if (role === "tool") {
|
|
9226
|
+
header += `
|
|
9227
|
+
\u6821\u9A8C\uFF1A${await annotateStaleness(info?.args, ts)}`;
|
|
9228
|
+
if (typeof l.content === "string" && l.content.includes("\u5B8C\u6574\u539F\u6587\u5DF2\u5B58\u6863")) {
|
|
9229
|
+
header += `
|
|
9230
|
+
\u2702\uFE0F \u8BE5\u7ED3\u679C\u66FE\u88AB\u622A\u65AD\uFF0C\u4F20 with_full="${l.tool_call_id}" \u53EF\u53D6\u5B58\u6863\u5168\u6587`;
|
|
9231
|
+
}
|
|
9232
|
+
}
|
|
9233
|
+
blocks.push(`${header}
|
|
9234
|
+
${snippetAround(text, re, 700)}`);
|
|
9235
|
+
if (blocks.length >= limit) break;
|
|
9236
|
+
}
|
|
9237
|
+
if (blocks.length === 0) {
|
|
9238
|
+
return [
|
|
9239
|
+
`\u672A\u547D\u4E2D "${args.query}"\u3002\u5EFA\u8BAE\uFF1A`,
|
|
9240
|
+
"\xB7 \u6362\u7528\u6458\u8981\u69FD \u27E6DSC:ARCHIVE-INDEX\u27E7 \u4E2D\u51FA\u73B0\u8FC7\u7684\u5B9E\u4F53\u540D\uFF08\u6587\u4EF6\u8DEF\u5F84/\u51FD\u6570\u540D/\u62A5\u9519\u5173\u952E\u8BCD\uFF09",
|
|
9241
|
+
"\xB7 \u591A\u5173\u952E\u8BCD\u7528 is_regex=true \u4EE5 | \u5408\u5E76\u6269\u5927\u5339\u914D",
|
|
9242
|
+
"\xB7 \u8BB0\u5F97\u5F52\u6863\u533A\u5728\u6458\u8981\u69FD\u4E4B\u524D\u7684\u66F4\u65E9\u8F6E\u6B21\u2014\u2014\u7528\u66F4\u65E9\u9636\u6BB5\u51FA\u73B0\u8FC7\u7684\u8BCD"
|
|
9243
|
+
].join("\n");
|
|
9244
|
+
}
|
|
9245
|
+
return [
|
|
9246
|
+
`[recall] \u672C\u4F1A\u8BDD\u5168\u91CF\u8F6C\u5F55\u547D\u4E2D ${blocks.length} \u6761\uFF08\u6309\u65F6\u95F4\u65E7\u2192\u65B0\uFF0C\u542B\u5DF2\u5F52\u6863\u6D88\u606F\uFF09\uFF1A`,
|
|
9247
|
+
"",
|
|
9248
|
+
blocks.join("\n\n"),
|
|
9249
|
+
"",
|
|
9250
|
+
"\u63D0\u793A\uFF1A\u26A0\uFE0F \u6807\u6CE8\u7684\u6587\u4EF6\u5FC5\u987B\u91CD\u65B0 read_file \u9A8C\u8BC1\u540E\u624D\u80FD\u636E\u4EE5\u4FEE\u6539\uFF1B\u672C\u5DE5\u5177\u7ED3\u679C\u4EC5\u4F5C\u5386\u53F2\u7EBF\u7D22\uFF0C\u4E0D\u66FF\u4EE3\u5F53\u524D\u6587\u4EF6\u72B6\u6001\u3002"
|
|
9251
|
+
].join("\n");
|
|
9252
|
+
} catch (e) {
|
|
9253
|
+
return `\u274C [recall] \u68C0\u7D22\u5931\u8D25: ${e instanceof Error ? e.message : String(e)}`;
|
|
9254
|
+
}
|
|
9255
|
+
}
|
|
9256
|
+
}
|
|
9257
|
+
}
|
|
9258
|
+
];
|
|
9259
|
+
}
|
|
9260
|
+
});
|
|
9261
|
+
|
|
8827
9262
|
// ../core/src/tool/registry/spreadsheet.ts
|
|
8828
9263
|
var getExcelJs, colLetter, cellToText, esc, spreadsheetTools;
|
|
8829
9264
|
var init_spreadsheet = __esm({
|
|
@@ -8940,7 +9375,7 @@ var init_spreadsheet = __esm({
|
|
|
8940
9375
|
});
|
|
8941
9376
|
|
|
8942
9377
|
// ../core/src/tool/registry/document.ts
|
|
8943
|
-
import
|
|
9378
|
+
import fs27 from "fs/promises";
|
|
8944
9379
|
var getMammoth, getUnpdf, documentTools;
|
|
8945
9380
|
var init_document = __esm({
|
|
8946
9381
|
"../core/src/tool/registry/document.ts"() {
|
|
@@ -9030,7 +9465,7 @@ var init_document = __esm({
|
|
|
9030
9465
|
}
|
|
9031
9466
|
const start = args.start_char ? Math.max(0, Math.floor(args.start_char)) : 0;
|
|
9032
9467
|
const maxChars = Math.min(args.max_chars ? Math.max(1, Math.floor(args.max_chars)) : 3e4, 5e4);
|
|
9033
|
-
const buf = await
|
|
9468
|
+
const buf = await fs27.readFile(absPath);
|
|
9034
9469
|
const unpdf = await getUnpdf();
|
|
9035
9470
|
const pdf = await unpdf.getDocumentProxy(new Uint8Array(buf));
|
|
9036
9471
|
const { text, totalPages } = await unpdf.extractText(pdf, { mergePages: true });
|
|
@@ -9085,6 +9520,7 @@ var init_tool = __esm({
|
|
|
9085
9520
|
init_worktree();
|
|
9086
9521
|
init_notebook();
|
|
9087
9522
|
init_memory();
|
|
9523
|
+
init_recall();
|
|
9088
9524
|
init_spreadsheet();
|
|
9089
9525
|
init_document();
|
|
9090
9526
|
init_type();
|
|
@@ -9110,6 +9546,7 @@ var init_tool = __esm({
|
|
|
9110
9546
|
...worktreeTools,
|
|
9111
9547
|
...notebookTools,
|
|
9112
9548
|
...memoryTools,
|
|
9549
|
+
...recallTools,
|
|
9113
9550
|
...spreadsheetTools,
|
|
9114
9551
|
...documentTools
|
|
9115
9552
|
// read_docx / read_pdf(Word / PDF 文档读取,补 read_file 读不了的二进制文档)
|
|
@@ -9233,7 +9670,7 @@ var init_backgroundTool = __esm({
|
|
|
9233
9670
|
});
|
|
9234
9671
|
|
|
9235
9672
|
// ../core/src/tool/autoPermission.ts
|
|
9236
|
-
import
|
|
9673
|
+
import path30 from "path";
|
|
9237
9674
|
var AUTO_SCOPE, AUTO_DEFAULT_EXTRA, AUTO_AGGRESSIVE_EXTRA, isMcpTool, BUILTIN_AUTO_DENY, matchBuiltinDeny, COMMAND_DENY, matchCommandDeny, hasShellMetachars, READONLY_HEADS, hasWriteModifier, SENSITIVE_FILE_ARG_RE, hasSensitiveFileArg, isReadOnlyCommand, isWithinWorkspace, runAutoCheck;
|
|
9238
9675
|
var init_autoPermission = __esm({
|
|
9239
9676
|
"../core/src/tool/autoPermission.ts"() {
|
|
@@ -9368,9 +9805,9 @@ var init_autoPermission = __esm({
|
|
|
9368
9805
|
isWithinWorkspace = (p, cwd) => {
|
|
9369
9806
|
if (!p || !cwd) return false;
|
|
9370
9807
|
try {
|
|
9371
|
-
const abs =
|
|
9372
|
-
const rel =
|
|
9373
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
9808
|
+
const abs = path30.isAbsolute(p) ? p : path30.resolve(cwd, p);
|
|
9809
|
+
const rel = path30.relative(cwd, abs);
|
|
9810
|
+
return rel === "" || !rel.startsWith("..") && !path30.isAbsolute(rel);
|
|
9374
9811
|
} catch {
|
|
9375
9812
|
return false;
|
|
9376
9813
|
}
|
|
@@ -9398,6 +9835,8 @@ var init_autoPermission = __esm({
|
|
|
9398
9835
|
});
|
|
9399
9836
|
|
|
9400
9837
|
// ../core/src/agent/toolExecution.ts
|
|
9838
|
+
import fs28 from "fs/promises";
|
|
9839
|
+
import path31 from "path";
|
|
9401
9840
|
var applyPrivacyMasking, processToolCall;
|
|
9402
9841
|
var init_toolExecution = __esm({
|
|
9403
9842
|
"../core/src/agent/toolExecution.ts"() {
|
|
@@ -9413,6 +9852,7 @@ var init_toolExecution = __esm({
|
|
|
9413
9852
|
init_autoPermission();
|
|
9414
9853
|
init_loader();
|
|
9415
9854
|
init_config();
|
|
9855
|
+
init_store();
|
|
9416
9856
|
init_planMode();
|
|
9417
9857
|
applyPrivacyMasking = (rules3, args, output) => {
|
|
9418
9858
|
if (!rules3) return output;
|
|
@@ -9634,7 +10074,20 @@ ${result}`;
|
|
|
9634
10074
|
events({ sessionId, eventType: "tool.validation.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 } });
|
|
9635
10075
|
}
|
|
9636
10076
|
result = applyPrivacyMasking(matchedTool?.function?.privacyMaskingRules, calledArgs, result);
|
|
9637
|
-
|
|
10077
|
+
let sidecarNote;
|
|
10078
|
+
const truncBudget = matchedTool?.function?.maxOutputCharacters ?? appConfig.MAX_TOOL_RESULT_CHARS;
|
|
10079
|
+
if (result.length > truncBudget) {
|
|
10080
|
+
try {
|
|
10081
|
+
const sidecarDir = path31.join(getSessionsDirPath(sessionId), "tool-outputs");
|
|
10082
|
+
await fs28.mkdir(sidecarDir, { recursive: true });
|
|
10083
|
+
const safeId = String(toolCall.id).replace(/[^A-Za-z0-9_-]/g, "");
|
|
10084
|
+
await fs28.writeFile(path31.join(sidecarDir, `${safeId}.txt`), result, "utf-8");
|
|
10085
|
+
sidecarNote = `\u5B8C\u6574\u539F\u6587\u5DF2\u5B58\u6863\uFF0Crecall \u5DE5\u5177\u4F20 with_full="${toolCall.id}" \u53EF\u53D6\u56DE`;
|
|
10086
|
+
} catch (e) {
|
|
10087
|
+
console.warn(`\u26A0\uFE0F [sidecar] \u5DE5\u5177\u539F\u6587\u5B58\u6863\u5931\u8D25\uFF08\u5DF2\u964D\u7EA7\u4E3A\u666E\u901A\u622A\u65AD\u63D0\u793A\uFF09:`, e instanceof Error ? e.message : e);
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
result = truncateToolResult(result, matchedTool?.function?.maxOutputCharacters, sidecarNote);
|
|
9638
10091
|
const FAILED_PREFIXES = ["\u5DE5\u5177\u6267\u884C\u5931\u8D25", "\u53C2\u6570\u89E3\u6790\u5931\u8D25", "\u274C", "\u3010\u7CFB\u7EDF\u5224\u5B9A", "\u{1F512}", "\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25", "\u9879\u76EE\u6811\u626B\u63CF\u5931\u8D25", "\u7B26\u53F7\u5927\u7EB2\u5206\u6790\u5931\u8D25", "\u64CD\u4F5C\u5931\u8D25:"];
|
|
9639
10092
|
const ok = explicitOk ?? !FAILED_PREFIXES.some((p) => result.startsWith(p));
|
|
9640
10093
|
let resultForModel = result;
|
|
@@ -9777,6 +10230,7 @@ var init_streamInference = __esm({
|
|
|
9777
10230
|
init_truncate();
|
|
9778
10231
|
init_transcript();
|
|
9779
10232
|
init_contextCore();
|
|
10233
|
+
init_contentParts();
|
|
9780
10234
|
streamInference = async function* (ctx) {
|
|
9781
10235
|
const {
|
|
9782
10236
|
message,
|
|
@@ -9804,7 +10258,8 @@ var init_streamInference = __esm({
|
|
|
9804
10258
|
eventType: "llm.request",
|
|
9805
10259
|
metadata: { depth, decisionSource: userDecisionSource, ok: true, durationMs: performance.now() - startTime, round },
|
|
9806
10260
|
usage: { prompt_tokens: estimateTokens(inferenceMessages) },
|
|
9807
|
-
payload: { input: message[message.length - 1].content }
|
|
10261
|
+
payload: { input: msgText(message[message.length - 1].content) }
|
|
10262
|
+
// ★ 多模态:trace 只记文本视图
|
|
9808
10263
|
});
|
|
9809
10264
|
console.log(`\u{1F504} \u4EE3\u7406\u63A8\u7406\u7B2C ${round} \u8F6E\uFF08\u6D41\u5F0F\uFF09...`);
|
|
9810
10265
|
let contentBuf = "";
|
|
@@ -9936,7 +10391,8 @@ var init_streamInference = __esm({
|
|
|
9936
10391
|
prompt_cache_hit_tokens: lastUsage?.cached_tokens,
|
|
9937
10392
|
prompt_cache_miss_tokens: (lastUsage?.prompt_tokens || 0) - (lastUsage?.cached_tokens || 0)
|
|
9938
10393
|
},
|
|
9939
|
-
payload: { input: message[message.length - 1].content }
|
|
10394
|
+
payload: { input: msgText(message[message.length - 1].content) }
|
|
10395
|
+
// ★ 多模态:trace 只记文本视图
|
|
9940
10396
|
});
|
|
9941
10397
|
console.log(`[DSC-DIAG] streamInference round ${round} \u5B8C\u6210: content=${contentBuf.length}chars reasoning=${reasoningBuf.length}chars toolCalls=${toolCallsBuf.size}`);
|
|
9942
10398
|
return { kind: "completed", assistantMessage, usage: lastUsage };
|
|
@@ -9949,7 +10405,8 @@ var init_streamInference = __esm({
|
|
|
9949
10405
|
sessionId,
|
|
9950
10406
|
eventType: "llm.error",
|
|
9951
10407
|
metadata: { depth, decisionSource: llmDecisionSource, ok: false, durationMs: performance.now() - startTime, attempt: round },
|
|
9952
|
-
payload: { input: message[message.length - 1].content, output: err.message }
|
|
10408
|
+
payload: { input: msgText(message[message.length - 1].content), output: err.message }
|
|
10409
|
+
// ★ 多模态:文本视图
|
|
9953
10410
|
});
|
|
9954
10411
|
console.log(`[DSC-DIAG] streamInference round ${round} \u2550\u2550\u2550 ERROR: ${err.message}`);
|
|
9955
10412
|
return { kind: "error", error: err };
|
|
@@ -10164,7 +10621,7 @@ async function* runAgent(message, options) {
|
|
|
10164
10621
|
const firstPrompt = (() => {
|
|
10165
10622
|
if (depth !== 0) return "";
|
|
10166
10623
|
const m = message.find((x) => x?.role === "user");
|
|
10167
|
-
return
|
|
10624
|
+
return msgText(m?.content);
|
|
10168
10625
|
})();
|
|
10169
10626
|
const nudges = createNudgeScheduler({ firstPrompt, planMode: !!options.planMode, noEarlyFinal: !!options.noEarlyFinal });
|
|
10170
10627
|
const userDecisionSource = depth > 0 ? "spawn_agent" : "user";
|
|
@@ -10292,7 +10749,7 @@ async function* runAgent(message, options) {
|
|
|
10292
10749
|
const assistantMessage = infResult.assistantMessage;
|
|
10293
10750
|
message.push(assistantMessage);
|
|
10294
10751
|
await appendMessage({ ...assistantMessage, sessionId });
|
|
10295
|
-
if (assistantMessage.content) {
|
|
10752
|
+
if (typeof assistantMessage.content === "string" && assistantMessage.content) {
|
|
10296
10753
|
lastContent = assistantMessage.content;
|
|
10297
10754
|
}
|
|
10298
10755
|
if (!assistantMessage.tool_calls || assistantMessage.tool_calls.length === 0) {
|
|
@@ -10385,6 +10842,7 @@ var init_runAgent = __esm({
|
|
|
10385
10842
|
init_inbox();
|
|
10386
10843
|
init_common();
|
|
10387
10844
|
init_contextCore();
|
|
10845
|
+
init_contentParts();
|
|
10388
10846
|
init_store();
|
|
10389
10847
|
init_truncate();
|
|
10390
10848
|
init_hooks();
|
|
@@ -10477,11 +10935,12 @@ var init_recovery = __esm({
|
|
|
10477
10935
|
});
|
|
10478
10936
|
|
|
10479
10937
|
// ../core/src/session/content.ts
|
|
10480
|
-
var decayOldToolResults, buildContextMessages;
|
|
10938
|
+
var decayOldToolResults, NO_VISION_IMAGE_NOTE, enforceVisionGate, buildContextMessages;
|
|
10481
10939
|
var init_content = __esm({
|
|
10482
10940
|
"../core/src/session/content.ts"() {
|
|
10483
10941
|
"use strict";
|
|
10484
10942
|
init_contextCore();
|
|
10943
|
+
init_contentParts();
|
|
10485
10944
|
init_transcript();
|
|
10486
10945
|
init_store();
|
|
10487
10946
|
init_config();
|
|
@@ -10491,15 +10950,20 @@ var init_content = __esm({
|
|
|
10491
10950
|
const cutoffUnitIdx = Math.max(0, units.length - appConfig.KEEP_RECENT_UNITS);
|
|
10492
10951
|
if (cutoffUnitIdx === 0) return msgs;
|
|
10493
10952
|
const decayIds = /* @__PURE__ */ new Set();
|
|
10953
|
+
let hasOldImage = false;
|
|
10494
10954
|
for (let u = 0; u < cutoffUnitIdx; u++) {
|
|
10495
10955
|
for (const m of units[u]) {
|
|
10496
10956
|
const mm = m;
|
|
10497
10957
|
if (mm.role === "tool" && typeof mm.tool_call_id === "string") decayIds.add(mm.tool_call_id);
|
|
10958
|
+
if (hasImagePart(m.content)) hasOldImage = true;
|
|
10498
10959
|
}
|
|
10499
10960
|
}
|
|
10500
|
-
if (decayIds.size === 0) return msgs;
|
|
10961
|
+
if (decayIds.size === 0 && !hasOldImage) return msgs;
|
|
10501
10962
|
const keep = appConfig.BOUNDARY_TOOL_KEEP_CHARS;
|
|
10963
|
+
const oldRefs = /* @__PURE__ */ new Set();
|
|
10964
|
+
for (let u = 0; u < cutoffUnitIdx; u++) for (const m of units[u]) oldRefs.add(m);
|
|
10502
10965
|
return msgs.map((m) => {
|
|
10966
|
+
if (!oldRefs.has(m)) return m;
|
|
10503
10967
|
const mm = m;
|
|
10504
10968
|
if (mm.role === "tool" && decayIds.has(mm.tool_call_id) && typeof mm.content === "string" && mm.content.length > keep) {
|
|
10505
10969
|
const head = mm.content.slice(0, keep);
|
|
@@ -10507,9 +10971,11 @@ var init_content = __esm({
|
|
|
10507
10971
|
|
|
10508
10972
|
[\u2026 \u8BE5\u5386\u53F2\u5DE5\u5177\u8F93\u51FA\u5DF2\u6298\u53E0\uFF08\u5171 ${mm.content.length} \u5B57\u7B26\uFF09\uFF0C\u5982\u9700\u7EC6\u8282\u8BF7\u91CD\u65B0\u8C03\u7528\u5DE5\u5177 \u2026]` };
|
|
10509
10973
|
}
|
|
10510
|
-
return
|
|
10974
|
+
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]");
|
|
10511
10975
|
});
|
|
10512
10976
|
};
|
|
10977
|
+
NO_VISION_IMAGE_NOTE = "[\u56FE\u7247\u672A\u9001\u8FBE\uFF1A\u5F53\u524D\u672A\u5F00\u542F\u89C6\u89C9\u80FD\u529B\uFF08DEEP_SEEK_VISION\uFF09\uFF0C\u6A21\u578B\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]";
|
|
10978
|
+
enforceVisionGate = (msgs) => isVisionEnabled() ? msgs : msgs.map((m) => collapseToText(m, NO_VISION_IMAGE_NOTE));
|
|
10513
10979
|
buildContextMessages = async (sessionId, currentUserMsg, systemPrompt) => {
|
|
10514
10980
|
const lines = await readTranscriptLines(sessionId);
|
|
10515
10981
|
const store = await getRollingState(sessionId);
|
|
@@ -10529,18 +10995,18 @@ var init_content = __esm({
|
|
|
10529
10995
|
const messageAll = all.slice(archivedMessageCount);
|
|
10530
10996
|
if (messageAll.length === 0) {
|
|
10531
10997
|
result.push(currentUserMsg);
|
|
10532
|
-
return result;
|
|
10998
|
+
return enforceVisionGate(result);
|
|
10533
10999
|
}
|
|
10534
11000
|
const repair = repairOrphanToolCalls(messageAll, recovery.interruption.kind === "crashed");
|
|
10535
11001
|
result.push(...decayOldToolResults(repair.msgs));
|
|
10536
11002
|
result.push(currentUserMsg);
|
|
10537
|
-
return result;
|
|
11003
|
+
return enforceVisionGate(result);
|
|
10538
11004
|
};
|
|
10539
11005
|
}
|
|
10540
11006
|
});
|
|
10541
11007
|
|
|
10542
11008
|
// ../core/src/session/lineage.ts
|
|
10543
|
-
import
|
|
11009
|
+
import fs29 from "node:fs";
|
|
10544
11010
|
var parentOfSubsession, stringAncestorsOf, readForkedFromSync, lineageClosureOf, ownerCanApprove;
|
|
10545
11011
|
var init_lineage = __esm({
|
|
10546
11012
|
"../core/src/session/lineage.ts"() {
|
|
@@ -10563,7 +11029,7 @@ var init_lineage = __esm({
|
|
|
10563
11029
|
};
|
|
10564
11030
|
readForkedFromSync = (sessionId) => {
|
|
10565
11031
|
try {
|
|
10566
|
-
const raw =
|
|
11032
|
+
const raw = fs29.readFileSync(getStatePath(sessionId), "utf-8");
|
|
10567
11033
|
const v = JSON.parse(raw)?.forkedFrom;
|
|
10568
11034
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
10569
11035
|
} catch {
|
|
@@ -10760,8 +11226,8 @@ var init_subagent = __esm({
|
|
|
10760
11226
|
});
|
|
10761
11227
|
|
|
10762
11228
|
// ../core/src/hooks/loader.ts
|
|
10763
|
-
import
|
|
10764
|
-
import
|
|
11229
|
+
import fs30 from "fs/promises";
|
|
11230
|
+
import path32 from "path";
|
|
10765
11231
|
var readHooksConfig, appendValidated, validateRule, parseStdoutDecision, parseAgentDecision, compileRule2, loadHooks, initHooks;
|
|
10766
11232
|
var init_loader4 = __esm({
|
|
10767
11233
|
"../core/src/hooks/loader.ts"() {
|
|
@@ -10776,15 +11242,15 @@ var init_loader4 = __esm({
|
|
|
10776
11242
|
readHooksConfig = async (includeProject) => {
|
|
10777
11243
|
const merged = {};
|
|
10778
11244
|
const paths = [
|
|
10779
|
-
|
|
11245
|
+
path32.join(appConfig.dataDir, "settings.json"),
|
|
10780
11246
|
// 全局用户级
|
|
10781
|
-
...includeProject ? [
|
|
11247
|
+
...includeProject ? [path32.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
10782
11248
|
// 项目级(叠加);未信任时省略
|
|
10783
11249
|
];
|
|
10784
11250
|
for (const configPath of paths) {
|
|
10785
11251
|
let raw;
|
|
10786
11252
|
try {
|
|
10787
|
-
raw = await
|
|
11253
|
+
raw = await fs30.readFile(configPath, "utf-8");
|
|
10788
11254
|
} catch {
|
|
10789
11255
|
continue;
|
|
10790
11256
|
}
|
|
@@ -11114,8 +11580,8 @@ ${m.context}`;
|
|
|
11114
11580
|
});
|
|
11115
11581
|
|
|
11116
11582
|
// ../core/src/skills/loader.ts
|
|
11117
|
-
import
|
|
11118
|
-
import
|
|
11583
|
+
import fs31 from "fs/promises";
|
|
11584
|
+
import path33 from "path";
|
|
11119
11585
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11120
11586
|
var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
|
|
11121
11587
|
var init_loader5 = __esm({
|
|
@@ -11126,18 +11592,18 @@ var init_loader5 = __esm({
|
|
|
11126
11592
|
init_registry3();
|
|
11127
11593
|
init_skill();
|
|
11128
11594
|
init_registry2();
|
|
11129
|
-
BUILTIN_DIR =
|
|
11595
|
+
BUILTIN_DIR = path33.join(path33.dirname(fileURLToPath2(import.meta.url)), "builtin");
|
|
11130
11596
|
SOURCES2 = [
|
|
11131
11597
|
{ dir: BUILTIN_DIR, source: "builtin" },
|
|
11132
|
-
{ dir:
|
|
11133
|
-
{ dir:
|
|
11598
|
+
{ dir: path33.join(appConfig.dataDir, "skills"), source: "global" },
|
|
11599
|
+
{ dir: path33.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
|
|
11134
11600
|
];
|
|
11135
11601
|
MAX_SKILL_BODY_BYTES = 64 * 1024;
|
|
11136
11602
|
splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
11137
11603
|
parseSkillAt = async (skillFile, dir, source) => {
|
|
11138
11604
|
let raw;
|
|
11139
11605
|
try {
|
|
11140
|
-
raw = await
|
|
11606
|
+
raw = await fs31.readFile(skillFile, "utf-8");
|
|
11141
11607
|
} catch {
|
|
11142
11608
|
return null;
|
|
11143
11609
|
}
|
|
@@ -11176,7 +11642,7 @@ var init_loader5 = __esm({
|
|
|
11176
11642
|
loadSkills = async (includeProject) => {
|
|
11177
11643
|
const picked = await scanSources(
|
|
11178
11644
|
filterSources(SOURCES2, includeProject),
|
|
11179
|
-
(e, dir) => e.isDirectory() ?
|
|
11645
|
+
(e, dir) => e.isDirectory() ? path33.join(dir, e.name, "SKILL.md") : void 0,
|
|
11180
11646
|
parseSkillAt
|
|
11181
11647
|
);
|
|
11182
11648
|
for (const { item } of picked) registerSkill(item);
|
|
@@ -11207,8 +11673,8 @@ var init_loader5 = __esm({
|
|
|
11207
11673
|
});
|
|
11208
11674
|
|
|
11209
11675
|
// ../core/src/agents/loader.ts
|
|
11210
|
-
import
|
|
11211
|
-
import
|
|
11676
|
+
import fs32 from "fs/promises";
|
|
11677
|
+
import path34 from "path";
|
|
11212
11678
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
11213
11679
|
var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
|
|
11214
11680
|
var init_loader6 = __esm({
|
|
@@ -11218,16 +11684,16 @@ var init_loader6 = __esm({
|
|
|
11218
11684
|
init_frontmatter();
|
|
11219
11685
|
init_registry4();
|
|
11220
11686
|
init_registry2();
|
|
11221
|
-
BUILTIN_DIR2 =
|
|
11687
|
+
BUILTIN_DIR2 = path34.join(path34.dirname(fileURLToPath3(import.meta.url)), "builtin");
|
|
11222
11688
|
SOURCES3 = [
|
|
11223
11689
|
{ dir: BUILTIN_DIR2, source: "builtin" },
|
|
11224
|
-
{ dir:
|
|
11225
|
-
{ dir:
|
|
11690
|
+
{ dir: path34.join(appConfig.dataDir, "agents"), source: "global" },
|
|
11691
|
+
{ dir: path34.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
|
|
11226
11692
|
];
|
|
11227
11693
|
parseAgentAt = async (file, dir, source) => {
|
|
11228
11694
|
let raw;
|
|
11229
11695
|
try {
|
|
11230
|
-
raw = await
|
|
11696
|
+
raw = await fs32.readFile(file, "utf-8");
|
|
11231
11697
|
} catch {
|
|
11232
11698
|
return null;
|
|
11233
11699
|
}
|
|
@@ -11262,7 +11728,7 @@ var init_loader6 = __esm({
|
|
|
11262
11728
|
const known = new Set(into.map((t) => t.function.name));
|
|
11263
11729
|
const picked = await scanSources(
|
|
11264
11730
|
filterSources(SOURCES3, includeProject),
|
|
11265
|
-
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ?
|
|
11731
|
+
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path34.join(dir, e.name) : void 0,
|
|
11266
11732
|
parseAgentAt
|
|
11267
11733
|
);
|
|
11268
11734
|
for (const { item: m, file, source } of picked) {
|
|
@@ -11299,8 +11765,8 @@ var init_registry7 = __esm({
|
|
|
11299
11765
|
});
|
|
11300
11766
|
|
|
11301
11767
|
// ../core/src/commands/loader.ts
|
|
11302
|
-
import
|
|
11303
|
-
import
|
|
11768
|
+
import fs33 from "fs/promises";
|
|
11769
|
+
import path35 from "path";
|
|
11304
11770
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
11305
11771
|
var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
|
|
11306
11772
|
var init_loader7 = __esm({
|
|
@@ -11310,17 +11776,17 @@ var init_loader7 = __esm({
|
|
|
11310
11776
|
init_frontmatter();
|
|
11311
11777
|
init_registry7();
|
|
11312
11778
|
init_registry2();
|
|
11313
|
-
BUILTIN_DIR3 =
|
|
11779
|
+
BUILTIN_DIR3 = path35.join(path35.dirname(fileURLToPath4(import.meta.url)), "builtin");
|
|
11314
11780
|
SOURCES4 = [
|
|
11315
11781
|
{ dir: BUILTIN_DIR3, source: "builtin" },
|
|
11316
|
-
{ dir:
|
|
11317
|
-
{ dir:
|
|
11782
|
+
{ dir: path35.join(appConfig.dataDir, "commands"), source: "global" },
|
|
11783
|
+
{ dir: path35.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
|
|
11318
11784
|
];
|
|
11319
11785
|
MAX_COMMAND_BODY_BYTES = 64 * 1024;
|
|
11320
11786
|
parseCommandAt = async (file, _dir, source) => {
|
|
11321
11787
|
let raw;
|
|
11322
11788
|
try {
|
|
11323
|
-
raw = await
|
|
11789
|
+
raw = await fs33.readFile(file, "utf-8");
|
|
11324
11790
|
} catch {
|
|
11325
11791
|
return null;
|
|
11326
11792
|
}
|
|
@@ -11331,7 +11797,7 @@ var init_loader7 = __esm({
|
|
|
11331
11797
|
}
|
|
11332
11798
|
const name = parsed.frontmatter.name;
|
|
11333
11799
|
const description = parsed.frontmatter.description;
|
|
11334
|
-
const fallbackName =
|
|
11800
|
+
const fallbackName = path35.basename(file, ".md");
|
|
11335
11801
|
const finalName = name || fallbackName;
|
|
11336
11802
|
if (!description) {
|
|
11337
11803
|
console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
@@ -11357,7 +11823,7 @@ var init_loader7 = __esm({
|
|
|
11357
11823
|
loadCommands = async (includeProject) => {
|
|
11358
11824
|
const picked = await scanSources(
|
|
11359
11825
|
filterSources(SOURCES4, includeProject),
|
|
11360
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
11826
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path35.join(dir, e.name) : void 0,
|
|
11361
11827
|
parseCommandAt
|
|
11362
11828
|
);
|
|
11363
11829
|
for (const { item } of picked) registerCommand(item);
|
|
@@ -11375,8 +11841,8 @@ var init_loader7 = __esm({
|
|
|
11375
11841
|
});
|
|
11376
11842
|
|
|
11377
11843
|
// ../core/src/outputStyles/loader.ts
|
|
11378
|
-
import
|
|
11379
|
-
import
|
|
11844
|
+
import fs34 from "fs/promises";
|
|
11845
|
+
import path36 from "path";
|
|
11380
11846
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
11381
11847
|
var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
|
|
11382
11848
|
var init_loader8 = __esm({
|
|
@@ -11386,17 +11852,17 @@ var init_loader8 = __esm({
|
|
|
11386
11852
|
init_frontmatter();
|
|
11387
11853
|
init_registry5();
|
|
11388
11854
|
init_registry2();
|
|
11389
|
-
BUILTIN_DIR4 =
|
|
11855
|
+
BUILTIN_DIR4 = path36.join(path36.dirname(fileURLToPath5(import.meta.url)), "builtin");
|
|
11390
11856
|
MAX_STYLE_BODY_BYTES = 64 * 1024;
|
|
11391
11857
|
SOURCES5 = [
|
|
11392
11858
|
{ dir: BUILTIN_DIR4, source: "builtin" },
|
|
11393
|
-
{ dir:
|
|
11394
|
-
{ dir:
|
|
11859
|
+
{ dir: path36.join(appConfig.dataDir, "output-styles"), source: "global" },
|
|
11860
|
+
{ dir: path36.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
|
|
11395
11861
|
];
|
|
11396
11862
|
parseStyleAt = async (file, _dir, source) => {
|
|
11397
11863
|
let raw;
|
|
11398
11864
|
try {
|
|
11399
|
-
raw = await
|
|
11865
|
+
raw = await fs34.readFile(file, "utf-8");
|
|
11400
11866
|
} catch {
|
|
11401
11867
|
return null;
|
|
11402
11868
|
}
|
|
@@ -11428,7 +11894,7 @@ var init_loader8 = __esm({
|
|
|
11428
11894
|
loadOutputStyles = async (includeProject) => {
|
|
11429
11895
|
const picked = await scanSources(
|
|
11430
11896
|
filterSources(SOURCES5, includeProject),
|
|
11431
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
11897
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path36.join(dir, e.name) : void 0,
|
|
11432
11898
|
parseStyleAt
|
|
11433
11899
|
);
|
|
11434
11900
|
for (const { item } of picked) registerOutputStyle(item);
|
|
@@ -11509,8 +11975,8 @@ var init_bootstrap = __esm({
|
|
|
11509
11975
|
});
|
|
11510
11976
|
|
|
11511
11977
|
// ../core/src/statusLine/config.ts
|
|
11512
|
-
import
|
|
11513
|
-
import
|
|
11978
|
+
import fs35 from "fs/promises";
|
|
11979
|
+
import path37 from "path";
|
|
11514
11980
|
var parseBlock, readStatusLineConfig;
|
|
11515
11981
|
var init_config2 = __esm({
|
|
11516
11982
|
"../core/src/statusLine/config.ts"() {
|
|
@@ -11526,16 +11992,16 @@ var init_config2 = __esm({
|
|
|
11526
11992
|
};
|
|
11527
11993
|
readStatusLineConfig = async (includeProject) => {
|
|
11528
11994
|
const paths = [
|
|
11529
|
-
|
|
11995
|
+
path37.join(appConfig.dataDir, "settings.json"),
|
|
11530
11996
|
// 全局用户级
|
|
11531
|
-
...includeProject ? [
|
|
11997
|
+
...includeProject ? [path37.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
11532
11998
|
// 项目级(覆盖);未信任时省略
|
|
11533
11999
|
];
|
|
11534
12000
|
let result = null;
|
|
11535
12001
|
for (const configPath of paths) {
|
|
11536
12002
|
let raw;
|
|
11537
12003
|
try {
|
|
11538
|
-
raw = await
|
|
12004
|
+
raw = await fs35.readFile(configPath, "utf-8");
|
|
11539
12005
|
} catch {
|
|
11540
12006
|
continue;
|
|
11541
12007
|
}
|
|
@@ -11555,8 +12021,8 @@ var init_config2 = __esm({
|
|
|
11555
12021
|
|
|
11556
12022
|
// ../core/src/statusLine/runner.ts
|
|
11557
12023
|
import { spawn as spawn5 } from "child_process";
|
|
11558
|
-
import
|
|
11559
|
-
import
|
|
12024
|
+
import fs36 from "fs";
|
|
12025
|
+
import path38 from "path";
|
|
11560
12026
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
11561
12027
|
var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
|
|
11562
12028
|
var init_runner = __esm({
|
|
@@ -11565,16 +12031,16 @@ var init_runner = __esm({
|
|
|
11565
12031
|
init_guard();
|
|
11566
12032
|
STATUSLINE_TIMEOUT_MS = 3e3;
|
|
11567
12033
|
try {
|
|
11568
|
-
const here =
|
|
12034
|
+
const here = path38.dirname(fileURLToPath6(import.meta.url));
|
|
11569
12035
|
const candidates = [
|
|
11570
|
-
|
|
12036
|
+
path38.join(here, "../../../package.json"),
|
|
11571
12037
|
// src/core/package.json
|
|
11572
|
-
|
|
12038
|
+
path38.join(here, "../../../../package.json")
|
|
11573
12039
|
// 仓库根 package.json
|
|
11574
12040
|
];
|
|
11575
12041
|
for (const p of candidates) {
|
|
11576
12042
|
try {
|
|
11577
|
-
const pkg = JSON.parse(
|
|
12043
|
+
const pkg = JSON.parse(fs36.readFileSync(p, "utf-8"));
|
|
11578
12044
|
if (typeof pkg.version === "string" && pkg.version) {
|
|
11579
12045
|
cachedVersion = pkg.version;
|
|
11580
12046
|
break;
|
|
@@ -11633,8 +12099,8 @@ var init_createModel = __esm({
|
|
|
11633
12099
|
});
|
|
11634
12100
|
|
|
11635
12101
|
// ../core/src/observability/store.ts
|
|
11636
|
-
import
|
|
11637
|
-
import
|
|
12102
|
+
import path39 from "path";
|
|
12103
|
+
import fs37 from "fs/promises";
|
|
11638
12104
|
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
11639
12105
|
var init_store3 = __esm({
|
|
11640
12106
|
"../core/src/observability/store.ts"() {
|
|
@@ -11644,21 +12110,21 @@ var init_store3 = __esm({
|
|
|
11644
12110
|
init_common();
|
|
11645
12111
|
getTraceDirPath = (mainTraceId) => {
|
|
11646
12112
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
11647
|
-
return
|
|
12113
|
+
return path39.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
11648
12114
|
};
|
|
11649
12115
|
getTracePath = () => {
|
|
11650
|
-
return
|
|
12116
|
+
return path39.join(appConfig.dataDir, "trace");
|
|
11651
12117
|
};
|
|
11652
12118
|
tracePathCache = /* @__PURE__ */ new Map();
|
|
11653
12119
|
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
11654
12120
|
ensureTraceDir = async (mainTraceId) => {
|
|
11655
12121
|
const dir = getTraceDirPath(mainTraceId);
|
|
11656
12122
|
if (ensuredTraceDirs.has(dir)) return;
|
|
11657
|
-
await
|
|
12123
|
+
await fs37.mkdir(dir, { recursive: true });
|
|
11658
12124
|
ensuredTraceDirs.add(dir);
|
|
11659
12125
|
};
|
|
11660
12126
|
getGlobalClockPath = () => {
|
|
11661
|
-
return
|
|
12127
|
+
return path39.join(getTracePath(), "trace-cleanup-clock.json");
|
|
11662
12128
|
};
|
|
11663
12129
|
getTraceStorePath = async (mainTraceId) => {
|
|
11664
12130
|
assertSafeSessionId(mainTraceId, "traceId");
|
|
@@ -11667,7 +12133,7 @@ var init_store3 = __esm({
|
|
|
11667
12133
|
if (cached2) return cached2;
|
|
11668
12134
|
await ensureTraceDir(rootId);
|
|
11669
12135
|
const dir = getTraceDirPath(rootId);
|
|
11670
|
-
const files = await
|
|
12136
|
+
const files = await fs37.readdir(dir);
|
|
11671
12137
|
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
11672
12138
|
let fileName = "";
|
|
11673
12139
|
if (existedFile) {
|
|
@@ -11676,7 +12142,7 @@ var init_store3 = __esm({
|
|
|
11676
12142
|
const todayStr = getTodayDateString();
|
|
11677
12143
|
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
11678
12144
|
}
|
|
11679
|
-
const resolved =
|
|
12145
|
+
const resolved = path39.join(dir, fileName);
|
|
11680
12146
|
tracePathCache.set(rootId, resolved);
|
|
11681
12147
|
return resolved;
|
|
11682
12148
|
};
|
|
@@ -11684,8 +12150,8 @@ var init_store3 = __esm({
|
|
|
11684
12150
|
});
|
|
11685
12151
|
|
|
11686
12152
|
// ../core/src/observability/trace.ts
|
|
11687
|
-
import
|
|
11688
|
-
import
|
|
12153
|
+
import fs38 from "fs/promises";
|
|
12154
|
+
import path40 from "path";
|
|
11689
12155
|
async function emitTrace(base) {
|
|
11690
12156
|
const event = {
|
|
11691
12157
|
sessionId: base.sessionId,
|
|
@@ -11707,7 +12173,7 @@ async function emitTrace(base) {
|
|
|
11707
12173
|
async function appendTraceEvent(event) {
|
|
11708
12174
|
const p = await getTraceStorePath(event.sessionId);
|
|
11709
12175
|
const line = JSON.stringify(event) + "\n";
|
|
11710
|
-
await
|
|
12176
|
+
await fs38.appendFile(p, line, "utf-8");
|
|
11711
12177
|
if (workspaceTraceBytes < 0) {
|
|
11712
12178
|
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
11713
12179
|
}
|
|
@@ -11739,8 +12205,8 @@ async function maybeCleanupAfterAppend(sessionId) {
|
|
|
11739
12205
|
lastSizeCleanupAt2 = now;
|
|
11740
12206
|
diskLastCleanupAt2 = now;
|
|
11741
12207
|
const clockPath = getGlobalClockPath();
|
|
11742
|
-
await
|
|
11743
|
-
await
|
|
12208
|
+
await fs38.mkdir(path40.dirname(clockPath), { recursive: true });
|
|
12209
|
+
await fs38.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
11744
12210
|
if (deletedCount > 0) {
|
|
11745
12211
|
console.log(`\u2728 [Trace\u8FD0\u7EF4] \u5171\u9500\u6BC1 ${deletedCount} \u4E2A\u4F1A\u8BDD\u65E5\u5FD7\uFF08\u8F6F\u89C4\u5219\u8FC7\u671F\u6E05\u7406 + \u5BB9\u91CF\u786C\u9A71\u9010\uFF09\uFF0C\u78C1\u76D8\u6C34\u4F4D\u56DE\u843D\u3002`);
|
|
11746
12212
|
}
|
|
@@ -11760,22 +12226,22 @@ async function cleanupOldTraceFiles() {
|
|
|
11760
12226
|
let deleted = 0;
|
|
11761
12227
|
let relativePaths;
|
|
11762
12228
|
try {
|
|
11763
|
-
relativePaths = await
|
|
12229
|
+
relativePaths = await fs38.readdir(dir, { recursive: true });
|
|
11764
12230
|
} catch {
|
|
11765
12231
|
return 0;
|
|
11766
12232
|
}
|
|
11767
12233
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
11768
12234
|
for (const relativePath of relativePaths) {
|
|
11769
|
-
const fileName =
|
|
12235
|
+
const fileName = path40.basename(relativePath);
|
|
11770
12236
|
const m = fileName.match(re);
|
|
11771
12237
|
if (!m) continue;
|
|
11772
12238
|
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
11773
12239
|
if (fileBornDay >= cutoff) continue;
|
|
11774
|
-
const fullPath =
|
|
12240
|
+
const fullPath = path40.join(dir, relativePath);
|
|
11775
12241
|
try {
|
|
11776
|
-
const st = await
|
|
12242
|
+
const st = await fs38.stat(fullPath);
|
|
11777
12243
|
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
11778
|
-
await
|
|
12244
|
+
await fs38.unlink(fullPath);
|
|
11779
12245
|
deleted += 1;
|
|
11780
12246
|
} catch {
|
|
11781
12247
|
}
|
|
@@ -11786,18 +12252,18 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
11786
12252
|
const dir = getTracePath();
|
|
11787
12253
|
let relativePaths;
|
|
11788
12254
|
try {
|
|
11789
|
-
relativePaths = await
|
|
12255
|
+
relativePaths = await fs38.readdir(dir, { recursive: true });
|
|
11790
12256
|
} catch {
|
|
11791
12257
|
return 0;
|
|
11792
12258
|
}
|
|
11793
12259
|
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
11794
12260
|
const candidates = [];
|
|
11795
12261
|
for (const relativePath of relativePaths) {
|
|
11796
|
-
const fileName =
|
|
12262
|
+
const fileName = path40.basename(relativePath);
|
|
11797
12263
|
if (!re.test(fileName)) continue;
|
|
11798
12264
|
try {
|
|
11799
|
-
const st = await
|
|
11800
|
-
candidates.push({ mtime: st.mtimeMs, fullPath:
|
|
12265
|
+
const st = await fs38.stat(path40.join(dir, relativePath));
|
|
12266
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path40.join(dir, relativePath), size: st.size });
|
|
11801
12267
|
} catch {
|
|
11802
12268
|
}
|
|
11803
12269
|
}
|
|
@@ -11807,7 +12273,7 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
11807
12273
|
for (const c of candidates) {
|
|
11808
12274
|
if (totalBytes <= targetBytes) break;
|
|
11809
12275
|
try {
|
|
11810
|
-
await
|
|
12276
|
+
await fs38.unlink(c.fullPath);
|
|
11811
12277
|
totalBytes -= c.size;
|
|
11812
12278
|
deleted += 1;
|
|
11813
12279
|
} catch {
|
|
@@ -11839,7 +12305,7 @@ var init_trace = __esm({
|
|
|
11839
12305
|
if (clockLoaded2) return;
|
|
11840
12306
|
clockLoaded2 = true;
|
|
11841
12307
|
try {
|
|
11842
|
-
const rawClock = await
|
|
12308
|
+
const rawClock = await fs38.readFile(getGlobalClockPath(), "utf-8");
|
|
11843
12309
|
diskLastCleanupAt2 = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
11844
12310
|
} catch {
|
|
11845
12311
|
diskLastCleanupAt2 = 0;
|
|
@@ -11985,8 +12451,8 @@ ${PLAN_MODE_AUTO_ENTER_HINT}
|
|
|
11985
12451
|
});
|
|
11986
12452
|
|
|
11987
12453
|
// ../core/src/serve/chatProcessing.ts
|
|
11988
|
-
import
|
|
11989
|
-
import
|
|
12454
|
+
import path41 from "path";
|
|
12455
|
+
import fs39 from "fs";
|
|
11990
12456
|
var handleUnifiedChat;
|
|
11991
12457
|
var init_chatProcessing = __esm({
|
|
11992
12458
|
"../core/src/serve/chatProcessing.ts"() {
|
|
@@ -11998,6 +12464,7 @@ var init_chatProcessing = __esm({
|
|
|
11998
12464
|
init_store();
|
|
11999
12465
|
init_transcript();
|
|
12000
12466
|
init_content();
|
|
12467
|
+
init_contentParts();
|
|
12001
12468
|
init_trace();
|
|
12002
12469
|
init_webHost();
|
|
12003
12470
|
init_registry();
|
|
@@ -12040,23 +12507,29 @@ ${inject}`;
|
|
|
12040
12507
|
if (roots.length > 1) {
|
|
12041
12508
|
let activeReal = getActiveWorkspaceRoot();
|
|
12042
12509
|
try {
|
|
12043
|
-
activeReal =
|
|
12510
|
+
activeReal = fs39.realpathSync(activeReal);
|
|
12044
12511
|
} catch {
|
|
12045
12512
|
}
|
|
12046
|
-
const lines = roots.map((r) => `- ${
|
|
12513
|
+
const lines = roots.map((r) => `- ${path41.basename(r) || r}: ${r}${r === activeReal ? "\uFF08\u9ED8\u8BA4\u6839\uFF1A\u76F8\u5BF9\u8DEF\u5F84/\u547D\u4EE4\u57FA\u51C6\uFF09" : "\uFF08\u53EF\u76F4\u63A5\u8BFB\u5199\uFF09"}`);
|
|
12047
12514
|
sysPrompt = sysPrompt + `
|
|
12048
12515
|
|
|
12049
12516
|
\u3010\u5DE5\u4F5C\u533A\uFF08\u591A\u9879\u76EE\uFF09\u3011
|
|
12050
12517
|
\u65E0\u9700\u5207\u6362\u9879\u76EE\uFF0C\u4EE5\u4E0B\u6240\u6709\u6839\u90FD\u53EF\u76F4\u63A5\u7528\u7EDD\u5BF9\u8DEF\u5F84\u8BBF\u95EE\uFF1B\u8DE8\u9879\u76EE\u7528\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9\u9ED8\u8BA4\u6839\u7684 ../<\u5144\u5F1F\u76EE\u5F55>:
|
|
12051
12518
|
${lines.join("\n")}
|
|
12052
|
-
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${
|
|
12053
|
-
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${
|
|
12519
|
+
\u2605 \u8DEF\u5F84\u951A\u5B9A\u94C1\u5F8B\uFF1A\u5DE5\u5177\u7F3A\u7701\u53EA\u4F5C\u7528\u4E8E\u9ED8\u8BA4\u6839\uFF08${path41.basename(activeReal) || activeReal} = IDE \u5934\u90E8\u6240\u793A\u6839\uFF09\u3002\u5F53\u7528\u6237\u5728\u5BF9\u8BDD\u4E2D\u6307\u660E\u4E86\u67D0\u4E2A\u9879\u76EE\uFF08\u5982\u300C\u5728 A \u9879\u76EE\u300D\u300C\u6539\u524D\u7AEF\u7684 xxx\u300D\u300C\u641C\u540E\u7AEF\u300D\uFF09\uFF0C\u8BE5\u8F6E\u6240\u6709\u5E26 path \u53C2\u6570\u7684\u5DE5\u5177\u8C03\u7528\uFF08read_file / edit_file / search_grep / glob / list_dir / read_xlsx / read_docx \u7B49\uFF09\u5FC5\u987B\u628A\u5BF9\u5E94\u9879\u76EE\u6839\u4F5C\u4E3A path \u4F20\u5165\uFF08\u7EDD\u5BF9\u8DEF\u5F84\u3001../<\u5144\u5F1F\u76EE\u5F55>\u3001\u6216\u9879\u76EE\u76EE\u5F55\u540D\uFF09\uFF0C\u5426\u5219\u53EA\u4F1A\u8BFB\u5199/\u641C\u7D22\u9ED8\u8BA4\u6839\uFF0C\u4E0E\u7528\u6237\u610F\u56FE\u4E0D\u7B26\u3002
|
|
12520
|
+
\u6CE8\u610F\uFF1A\u9879\u76EE\u7EA7\u914D\u7F6E\uFF08.deepseeker-code/\uFF09\u4EC5\u5728\u9ED8\u8BA4\u6839 ${path41.basename(activeReal) || activeReal} \u751F\u6548\u3002`;
|
|
12054
12521
|
}
|
|
12055
12522
|
let replyText = "";
|
|
12523
|
+
let userContent = inbound.content;
|
|
12524
|
+
if (Array.isArray(inbound.attachments) && inbound.attachments.length > 0) {
|
|
12525
|
+
userContent = isVisionEnabled() ? toWireUserContent(inbound.content, inbound.attachments) : `${inbound.content}
|
|
12526
|
+
|
|
12527
|
+
\u{1F5BC} \u6536\u5230\u56FE\u7247\u9644\u4EF6\uFF08${inbound.attachments.map((a) => a?.name || "image").join("\u3001")}\uFF09\uFF1A\u5F53\u524D\u6A21\u578B\u672A\u5F00\u542F\u89C6\u89C9\u80FD\u529B\uFF08DEEP_SEEK_VISION\uFF09\uFF0C\u5DF2\u5FFD\u7565\u56FE\u7247\u5185\u5BB9\u3002`;
|
|
12528
|
+
}
|
|
12056
12529
|
try {
|
|
12057
12530
|
const fullMessages = await buildContextMessages(
|
|
12058
12531
|
sessionId,
|
|
12059
|
-
{ role: "user", content:
|
|
12532
|
+
{ role: "user", content: userContent },
|
|
12060
12533
|
sysPrompt
|
|
12061
12534
|
);
|
|
12062
12535
|
await emitTrace({
|
|
@@ -12069,7 +12542,7 @@ ${lines.join("\n")}
|
|
|
12069
12542
|
});
|
|
12070
12543
|
void sweepStaleAtomicTmp().catch(() => {
|
|
12071
12544
|
});
|
|
12072
|
-
await appendMessage({ sessionId, role: "user", content:
|
|
12545
|
+
await appendMessage({ sessionId, role: "user", content: userContent });
|
|
12073
12546
|
let streamedAnyText = false;
|
|
12074
12547
|
const onUIEvent = opts?.onUIEvent ?? ((evt) => sseWrite?.(evt));
|
|
12075
12548
|
const requestApproval2 = opts?.requestApproval ?? createWebRequestApproval((evt) => sseWrite?.(evt), abortSignal);
|
|
@@ -12137,12 +12610,13 @@ ${lines.join("\n")}
|
|
|
12137
12610
|
});
|
|
12138
12611
|
|
|
12139
12612
|
// ../core/src/session/fork.ts
|
|
12140
|
-
import
|
|
12613
|
+
import fs40 from "fs/promises";
|
|
12141
12614
|
var listForkAnchors, derivePrefix, forkSession;
|
|
12142
12615
|
var init_fork = __esm({
|
|
12143
12616
|
"../core/src/session/fork.ts"() {
|
|
12144
12617
|
"use strict";
|
|
12145
12618
|
init_common();
|
|
12619
|
+
init_contentParts();
|
|
12146
12620
|
init_transcript();
|
|
12147
12621
|
init_store();
|
|
12148
12622
|
listForkAnchors = (lines) => {
|
|
@@ -12152,7 +12626,7 @@ var init_fork = __esm({
|
|
|
12152
12626
|
if (isEventLine(l)) continue;
|
|
12153
12627
|
const row = l;
|
|
12154
12628
|
if (row?.role === "user") {
|
|
12155
|
-
lastUser =
|
|
12629
|
+
lastUser = msgText(row.content) || (hasImagePart(row.content) ? "\u{1F5BC} [\u56FE\u7247\u6D88\u606F]" : "");
|
|
12156
12630
|
} else if (row?.role === "assistant") {
|
|
12157
12631
|
const content = typeof row.content === "string" ? row.content : "";
|
|
12158
12632
|
const names = Array.isArray(row.tool_calls) ? row.tool_calls.map((tc) => tc?.function?.name ?? "").filter(Boolean).join(", ") : "";
|
|
@@ -12209,7 +12683,7 @@ var init_fork = __esm({
|
|
|
12209
12683
|
const prefix = derivePrefix(lines, upToLineId);
|
|
12210
12684
|
const newId = createUUID();
|
|
12211
12685
|
await ensureSessionsDir(newId);
|
|
12212
|
-
const rawText = await
|
|
12686
|
+
const rawText = await fs40.readFile(getTranscriptPath(sourceId), "utf-8");
|
|
12213
12687
|
const kept = [];
|
|
12214
12688
|
let good = 0;
|
|
12215
12689
|
for (const s of rawText.split("\n")) {
|
|
@@ -12225,7 +12699,7 @@ var init_fork = __esm({
|
|
|
12225
12699
|
}
|
|
12226
12700
|
let payload = kept.join("\n");
|
|
12227
12701
|
if (payload.length > 0 && !payload.endsWith("\n")) payload += "\n";
|
|
12228
|
-
await
|
|
12702
|
+
await fs40.writeFile(getTranscriptPath(newId), payload, "utf-8");
|
|
12229
12703
|
const srcState = await readStore(sourceId);
|
|
12230
12704
|
const srcRolling = await getRollingState(sourceId);
|
|
12231
12705
|
const legacy = !lines.some(isEventLine);
|
|
@@ -13924,7 +14398,7 @@ var init_TopPanel = __esm({
|
|
|
13924
14398
|
});
|
|
13925
14399
|
|
|
13926
14400
|
// ../core/src/observability/inspect.ts
|
|
13927
|
-
import
|
|
14401
|
+
import fs41 from "fs";
|
|
13928
14402
|
var CWD, fmt, readTrace, inspectUsage, inspectContext, inspectPermissions, inspectMcp, inspectHooks, inspectDebug;
|
|
13929
14403
|
var init_inspect = __esm({
|
|
13930
14404
|
"../core/src/observability/inspect.ts"() {
|
|
@@ -13942,7 +14416,7 @@ var init_inspect = __esm({
|
|
|
13942
14416
|
if (!sessionId) return [];
|
|
13943
14417
|
try {
|
|
13944
14418
|
const p = await getTraceStorePath(sessionId);
|
|
13945
|
-
const text = await
|
|
14419
|
+
const text = await fs41.promises.readFile(p, "utf8");
|
|
13946
14420
|
const out = [];
|
|
13947
14421
|
for (const line of text.split("\n")) {
|
|
13948
14422
|
if (!line.trim()) continue;
|
|
@@ -14701,7 +15175,7 @@ init_updateCheck();
|
|
|
14701
15175
|
init_trust();
|
|
14702
15176
|
import { render } from "ink";
|
|
14703
15177
|
import os5 from "os";
|
|
14704
|
-
import
|
|
15178
|
+
import path42 from "path";
|
|
14705
15179
|
import { emitKeypressEvents } from "node:readline";
|
|
14706
15180
|
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
14707
15181
|
var parseArgs = (argv) => {
|
|
@@ -14834,7 +15308,7 @@ var main = async () => {
|
|
|
14834
15308
|
process.stdout.write("\x1B[2J\x1B[3J\x1B[1;1H");
|
|
14835
15309
|
const cwdIsHome = () => {
|
|
14836
15310
|
try {
|
|
14837
|
-
return
|
|
15311
|
+
return path42.resolve(cwd).toLowerCase() === path42.resolve(os5.homedir()).toLowerCase();
|
|
14838
15312
|
} catch {
|
|
14839
15313
|
return false;
|
|
14840
15314
|
}
|