deepseeker-code 1.0.60 → 1.0.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +475 -309
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4228,7 +4228,7 @@ async function killBackgroundTasksUnder(dirPath) {
|
|
|
4228
4228
|
}
|
|
4229
4229
|
return killed;
|
|
4230
4230
|
}
|
|
4231
|
-
var _winShellCache, resolveWinShell, MAX_BUFFER_CHARS, registry, createBgTask, attachTaskLifecycle, makeTaskExitNotifier, adoptRunningProcess, backgroundTools, killAllBackgroundTasks;
|
|
4231
|
+
var _winShellCache, resolveWinShell, MAX_BUFFER_CHARS, registry, createBgTask, attachTaskLifecycle, makeTaskExitNotifier, adoptRunningProcess, BG_WAIT_SECONDS_CAP, clampWaitSeconds, backgroundTools, killAllBackgroundTasks;
|
|
4232
4232
|
var init_background = __esm({
|
|
4233
4233
|
"../core/src/tool/registry/background.ts"() {
|
|
4234
4234
|
"use strict";
|
|
@@ -4393,6 +4393,8 @@ var init_background = __esm({
|
|
|
4393
4393
|
void attachTaskLifecycle(task, proc, { signal: meta.signal, codec, onExit: meta.onExit });
|
|
4394
4394
|
return task.taskId;
|
|
4395
4395
|
};
|
|
4396
|
+
BG_WAIT_SECONDS_CAP = 90;
|
|
4397
|
+
clampWaitSeconds = (v) => Math.min(Math.max(0, Math.floor(v ?? 0)), BG_WAIT_SECONDS_CAP);
|
|
4396
4398
|
backgroundTools = [
|
|
4397
4399
|
{
|
|
4398
4400
|
type: "function",
|
|
@@ -4481,13 +4483,13 @@ task_id: ${taskId}
|
|
|
4481
4483
|
type: "function",
|
|
4482
4484
|
function: {
|
|
4483
4485
|
name: "get_background_output",
|
|
4484
|
-
description: "\u67E5\u770B\u6307\u5B9A\u540E\u53F0\u4EFB\u52A1\u7684\u6700\u8FD1\u8F93\u51FA\u65E5\u5FD7\u4E0E\u8FD0\u884C\u72B6\u6001\uFF08running/exited/killed + \u9000\u51FA\u7801\uFF09\u3002\u7EAF\u8BFB\uFF0C\u514D\u5BA1\u6279\u3002\u7528\u4E8E\u786E\u8BA4 dev server \u662F\u5426\u542F\u52A8\u6210\u529F\u3001\u67E5\u770B\u62A5\u9519\u7B49\u3002\u7B49\u957F\u4EFB\u52A1\uFF08\u6784\u5EFA/\u6D4B\u8BD5\uFF09\u8DD1\u5B8C\uFF1A\u5E26 wait_seconds \u963B\u585E\u7B49\u5F85\u4EFB\u52A1\u9000\u51FA\u540E\u518D\u8FD4\u56DE\uFF08\u4ECD\u5728\u8DD1\u5219\u7B49\
|
|
4486
|
+
description: "\u67E5\u770B\u6307\u5B9A\u540E\u53F0\u4EFB\u52A1\u7684\u6700\u8FD1\u8F93\u51FA\u65E5\u5FD7\u4E0E\u8FD0\u884C\u72B6\u6001\uFF08running/exited/killed + \u9000\u51FA\u7801\uFF09\u3002\u7EAF\u8BFB\uFF0C\u514D\u5BA1\u6279\u3002\u7528\u4E8E\u786E\u8BA4 dev server \u662F\u5426\u542F\u52A8\u6210\u529F\u3001\u67E5\u770B\u62A5\u9519\u7B49\u3002\u7B49\u957F\u4EFB\u52A1\uFF08\u6784\u5EFA/\u6D4B\u8BD5\uFF09\u8DD1\u5B8C\uFF1A\u5E26 wait_seconds \u963B\u585E\u7B49\u5F85\u4EFB\u52A1\u9000\u51FA\u540E\u518D\u8FD4\u56DE\uFF08\u4ECD\u5728\u8DD1\u5219\u7B49\u6EE1 wait_seconds \u8FD4\u56DE\u5F53\u524D\u5FEB\u7167\uFF09\u2014\u2014\u7528\u5B83\u7B49\uFF0C\u4E0D\u8981\u4E0D\u5E26 wait \u53CD\u590D\u8F6E\u8BE2\u67E5\u8BE2\u3002",
|
|
4485
4487
|
parameters: {
|
|
4486
4488
|
type: "object",
|
|
4487
4489
|
properties: {
|
|
4488
4490
|
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" },
|
|
4489
4491
|
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" },
|
|
4490
|
-
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
|
|
4492
|
+
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 90 \u79D2\u2014\u2014\u987B\u4F4E\u4E8E\u8C03\u5EA6\u5C42 120s \u5DE5\u5177\u7194\u65AD\u7EBF\uFF0C\u66F4\u957F\u7684 wait \u4F1A\u88AB\u7194\u65AD\u3001\u771F\u5B9E\u7ED3\u679C\u88AB\u4E22\u5F03\u6362\u6210\u8D85\u65F6\u6587\u6848\u3002\u9884\u8BA1\u66F4\u4E45\u5C31\u4F20 90\uFF0C\u8FD4\u56DE\u4ECD running \u5C31\u518D\u8C03\u4E00\u6B21\u63A5\u7740\u7B49\uFF1B\u53EA\u770B\u5F53\u524D\u65E5\u5FD7\u5C31\u7701\u7565\u6B64\u53C2\u6570" }
|
|
4491
4493
|
},
|
|
4492
4494
|
required: ["task_id"]
|
|
4493
4495
|
},
|
|
@@ -4498,7 +4500,7 @@ task_id: ${taskId}
|
|
|
4498
4500
|
if (!task || task.sessionId !== ctx?.sessionId) {
|
|
4499
4501
|
return toolFailure(`[\u67E5\u8BE2\u5931\u8D25]\uFF1A\u672A\u627E\u5230 task_id=${args.task_id}\uFF08\u53EF\u80FD\u5DF2\u968F\u670D\u52A1\u91CD\u542F\u4E22\u5931\uFF0C\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u4F1A\u8BDD\uFF09\u3002`);
|
|
4500
4502
|
}
|
|
4501
|
-
const waitMs =
|
|
4503
|
+
const waitMs = clampWaitSeconds(args.wait_seconds) * 1e3;
|
|
4502
4504
|
if (waitMs > 0 && task.status === "running") {
|
|
4503
4505
|
const deadline = Date.now() + waitMs;
|
|
4504
4506
|
while (task.status === "running" && Date.now() < deadline && !ctx?.abortSignal?.aborted) {
|
|
@@ -6027,13 +6029,17 @@ var init_toolResultCollect = __esm({
|
|
|
6027
6029
|
const idleMs = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
6028
6030
|
while (true) {
|
|
6029
6031
|
let timer2;
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6032
|
+
let outcome;
|
|
6033
|
+
try {
|
|
6034
|
+
outcome = await Promise.race([
|
|
6035
|
+
ret.next().then((step) => ({ timedOut: false, step })),
|
|
6036
|
+
new Promise((resolve) => {
|
|
6037
|
+
timer2 = setTimeout(() => resolve({ timedOut: true }), idleMs);
|
|
6038
|
+
})
|
|
6039
|
+
]);
|
|
6040
|
+
} finally {
|
|
6041
|
+
if (timer2) clearTimeout(timer2);
|
|
6042
|
+
}
|
|
6037
6043
|
if (outcome.timedOut) {
|
|
6038
6044
|
full += `
|
|
6039
6045
|
|
|
@@ -6054,18 +6060,22 @@ var init_toolResultCollect = __esm({
|
|
|
6054
6060
|
const timeoutMs2 = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
6055
6061
|
let timer;
|
|
6056
6062
|
let onAbort;
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
signal
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6063
|
+
let raced;
|
|
6064
|
+
try {
|
|
6065
|
+
raced = await Promise.race([
|
|
6066
|
+
Promise.resolve(ret).then((v2) => ({ kind: "ok", value: v2 })),
|
|
6067
|
+
new Promise((resolve) => {
|
|
6068
|
+
timer = setTimeout(() => resolve({ kind: "timeout" }), timeoutMs2);
|
|
6069
|
+
}),
|
|
6070
|
+
...signal ? [new Promise((resolve) => {
|
|
6071
|
+
onAbort = () => resolve({ kind: "abort" });
|
|
6072
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6073
|
+
})] : []
|
|
6074
|
+
]);
|
|
6075
|
+
} finally {
|
|
6076
|
+
if (timer) clearTimeout(timer);
|
|
6077
|
+
if (onAbort && signal) signal.removeEventListener("abort", onAbort);
|
|
6078
|
+
}
|
|
6069
6079
|
if (raced.kind === "timeout") {
|
|
6070
6080
|
return { content: `[\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]`, status: "failed", errorCategory: "runtime" };
|
|
6071
6081
|
}
|
|
@@ -7801,9 +7811,15 @@ ${tail}`,
|
|
|
7801
7811
|
cwd,
|
|
7802
7812
|
detached: !isWin,
|
|
7803
7813
|
// 非 Win 下支持整个进程组独立
|
|
7804
|
-
env: scrubCommandEnv()
|
|
7814
|
+
env: scrubCommandEnv()
|
|
7805
7815
|
// ★ 剔除 agent 自身凭证(LLM key / 服务端 token / 搜索 key),防 LLM 经 env/printenv 读取外泄
|
|
7806
|
-
|
|
7816
|
+
// ★ 中止唯一出口 = 下方 onAbort→killTree(2026-10-27 修「■ 终止无效」):
|
|
7817
|
+
// 勿把 signal 交给 spawn——Node 内部 abort 监听先于 onAbort 触发,TerminateProcess
|
|
7818
|
+
// 只杀最外层进程;随后 killTree 的 taskkill /T 对已死根「找不到进程」直接失败,
|
|
7819
|
+
// 孙进程(tsx 的 esbuild、node --test 的每文件子进程)存活并持有继承的 stdout 管道,
|
|
7820
|
+
// close 永不触发 → 工具永不结束(多层进程树命令下点终止永远转圈)。
|
|
7821
|
+
// 根存活时 taskkill /T 才能整树剿灭;进入工具时已 aborted 由上方前置检查拦截,
|
|
7822
|
+
// pre-check 与 addEventListener 之间全同步无 await,无竞态窗口。
|
|
7807
7823
|
});
|
|
7808
7824
|
} catch (e) {
|
|
7809
7825
|
yield toolFailure(`[\u542F\u52A8\u5931\u8D25]\uFF1Aspawn \u629B\u51FA\u5F02\u5E38\uFF08signal \u5DF2\u4E2D\u6B62\u6216\u547D\u4EE4\u975E\u6CD5\uFF09: ${e?.message ?? e}`).content;
|
|
@@ -7813,6 +7829,7 @@ ${tail}`,
|
|
|
7813
7829
|
const queue = [];
|
|
7814
7830
|
let settled = false;
|
|
7815
7831
|
let exitCode = null;
|
|
7832
|
+
let abortedByUser = false;
|
|
7816
7833
|
let resolveWaiter = null;
|
|
7817
7834
|
let idleTimer = null;
|
|
7818
7835
|
const notifyNewData = () => {
|
|
@@ -7866,13 +7883,14 @@ ${tail}`,
|
|
|
7866
7883
|
notifyNewData();
|
|
7867
7884
|
});
|
|
7868
7885
|
proc.on("close", (code) => {
|
|
7869
|
-
exitCode ??= code == null ? -1 : code;
|
|
7886
|
+
exitCode ??= abortedByUser ? -1 : code == null ? -1 : code;
|
|
7870
7887
|
if (decoder) queue.push(decoder.decode());
|
|
7871
7888
|
queue.push(pendingUtf8.decode());
|
|
7872
7889
|
settled = true;
|
|
7873
7890
|
notifyNewData();
|
|
7874
7891
|
});
|
|
7875
7892
|
const onAbort = () => {
|
|
7893
|
+
abortedByUser = true;
|
|
7876
7894
|
void killTree(proc);
|
|
7877
7895
|
};
|
|
7878
7896
|
ctx?.abortSignal?.addEventListener("abort", onAbort);
|
|
@@ -12033,7 +12051,7 @@ var init_autoPermission = __esm({
|
|
|
12033
12051
|
|
|
12034
12052
|
// ../core/src/agent/toolExecution.ts
|
|
12035
12053
|
import path36 from "path";
|
|
12036
|
-
var applyPrivacyMasking, scaleTruncBudget, failResult, emitValidationFailed, resolveEarlyOutcome, runSecurityGates, executeTool, finalizeOutcome, processToolCall;
|
|
12054
|
+
var applyPrivacyMasking, scaleTruncBudget, failResult, emitValidationFailed, resolveEarlyOutcome, runSecurityGates, executeTool, finalizeOutcome, previewArgs, processToolCall, processToolCallInner;
|
|
12037
12055
|
var init_toolExecution = __esm({
|
|
12038
12056
|
"../core/src/agent/toolExecution.ts"() {
|
|
12039
12057
|
"use strict";
|
|
@@ -12305,7 +12323,9 @@ ${state.result}`;
|
|
|
12305
12323
|
const { calledName, calledArgs, matchedTool } = state;
|
|
12306
12324
|
state.result = applyPrivacyMasking(matchedTool?.function?.privacyMaskingRules, calledArgs, state.result);
|
|
12307
12325
|
const fill = contextTokensEst !== void 0 && modelWindow > 0 ? contextTokensEst / modelWindow : void 0;
|
|
12308
|
-
const
|
|
12326
|
+
const baseBudget = matchedTool?.function?.maxOutputCharacters ?? appConfig.MAX_TOOL_RESULT_CHARS;
|
|
12327
|
+
const capped = ctx.batchBudgetChars !== void 0 ? Math.min(baseBudget, ctx.batchBudgetChars) : baseBudget;
|
|
12328
|
+
const truncBudget = scaleTruncBudget(capped, fill);
|
|
12309
12329
|
const sidecarNote = state.result.length > truncBudget ? await writeSidecarArchive(sessionId, String(toolCall.id), state.result) : void 0;
|
|
12310
12330
|
state.result = truncateToolResult(state.result, truncBudget, sidecarNote);
|
|
12311
12331
|
const resultStatus = state.resultStatus;
|
|
@@ -12322,7 +12342,7 @@ ${state.result}`;
|
|
|
12322
12342
|
}
|
|
12323
12343
|
if (state.postHookOverride !== void 0) {
|
|
12324
12344
|
console.log(`\u270F\uFE0F [Post-hook] [${calledName}] \u6A21\u578B\u89C6\u56FE\u7ED3\u679C\u5DF2\u88AB hook \u6539\u5199`);
|
|
12325
|
-
const overrideBudget = scaleTruncBudget(
|
|
12345
|
+
const overrideBudget = scaleTruncBudget(capped, fill);
|
|
12326
12346
|
const overrideNote = state.postHookOverride.length > overrideBudget ? await writeSidecarArchive(sessionId, String(toolCall.id), state.postHookOverride) : void 0;
|
|
12327
12347
|
resultForModel = truncateToolResult(state.postHookOverride, overrideBudget, overrideNote);
|
|
12328
12348
|
}
|
|
@@ -12332,7 +12352,36 @@ ${state.result}`;
|
|
|
12332
12352
|
}
|
|
12333
12353
|
return { toolCallId: toolCall.id, calledName, calledArgs, resultForModel, resultForUser, ok, imageAttachments: state.imageAttachments };
|
|
12334
12354
|
};
|
|
12355
|
+
previewArgs = (raw, max) => raw === void 0 ? void 0 : raw.length > max ? raw.slice(0, max) + `\u2026\uFF08\u5171 ${raw.length} \u5B57\u7B26\uFF09` : raw;
|
|
12335
12356
|
processToolCall = async (toolCall, ctx) => {
|
|
12357
|
+
try {
|
|
12358
|
+
return await processToolCallInner(toolCall, ctx);
|
|
12359
|
+
} catch (e) {
|
|
12360
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
12361
|
+
console.error(`\u274C \u5DE5\u5177\u8C03\u7528\u5904\u7406\u5F02\u5E38\uFF08\u5DF2\u9694\u79BB\uFF0C\u4E0D\u5F71\u54CD\u540C\u6279\u5176\u4ED6\u5DE5\u5177\uFF09: ${msg}`);
|
|
12362
|
+
try {
|
|
12363
|
+
ctx.events({
|
|
12364
|
+
sessionId: ctx.sessionId,
|
|
12365
|
+
eventType: "tool.failed",
|
|
12366
|
+
metadata: { depth: ctx.depth, decisionSource: ctx.llmDecisionSource, durationMs: performance.now() - ctx.startTime, round: ctx.round, tools_id: toolCall?.id ?? "", toolName: toolCall?.function?.name ?? "unknown", toolSource: "builtin", ok: false, attempt: ctx.round, errorCategory: "runtime" },
|
|
12367
|
+
payload: { output: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38\uFF1A${msg}` }
|
|
12368
|
+
});
|
|
12369
|
+
} catch {
|
|
12370
|
+
}
|
|
12371
|
+
return {
|
|
12372
|
+
toolCallId: toolCall?.id ?? "",
|
|
12373
|
+
calledName: toolCall?.function?.name ?? "unknown",
|
|
12374
|
+
calledArgs: { _preview: previewArgs(toolCall?.function?.arguments, 300) },
|
|
12375
|
+
// ★ 保留参数上下文(截断预览):否则 tool.failed 排查时看不到模型当时传了什么
|
|
12376
|
+
resultForModel: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38\uFF1A${msg}\uFF08\u672C\u8C03\u7528\u5DF2\u9694\u79BB\uFF0C\u5176\u4ED6\u5DE5\u5177\u7ED3\u679C\u4E0D\u53D7\u5F71\u54CD\uFF09`,
|
|
12377
|
+
resultForUser: `\u274C \u5DE5\u5177\u6267\u884C\u5F02\u5E38\uFF1A${msg}`,
|
|
12378
|
+
ok: false,
|
|
12379
|
+
aborted: ctx.signal?.aborted ? true : void 0
|
|
12380
|
+
// ★ 不吞 abort
|
|
12381
|
+
};
|
|
12382
|
+
}
|
|
12383
|
+
};
|
|
12384
|
+
processToolCallInner = async (toolCall, ctx) => {
|
|
12336
12385
|
const state = {
|
|
12337
12386
|
calledName: "",
|
|
12338
12387
|
calledArgs: {},
|
|
@@ -12354,7 +12403,9 @@ ${state.result}`;
|
|
|
12354
12403
|
} catch {
|
|
12355
12404
|
state.parseFailed = true;
|
|
12356
12405
|
}
|
|
12357
|
-
|
|
12406
|
+
const argsLog = JSON.stringify(state.calledArgs) ?? "";
|
|
12407
|
+
const argsPreview = process.env.DSC_DEBUG_TOOL_ARGS === "1" ? argsLog : argsLog.length > 200 ? argsLog.slice(0, 200) + `\u2026\uFF08\u5171 ${argsLog.length} \u5B57\u7B26\uFF09` : argsLog;
|
|
12408
|
+
console.log(`\u{1F916} \u6A21\u578B\u8BF7\u6C42\u8C03\u7528\u5DE5\u5177: ${state.calledName}\uFF0C\u53C2\u6570: ${argsPreview}`);
|
|
12358
12409
|
}
|
|
12359
12410
|
state.matchedTool = ctx.rawTools.find((t) => t.function.name === state.calledName);
|
|
12360
12411
|
const early = resolveEarlyOutcome(ctx, toolCall, state);
|
|
@@ -12396,13 +12447,14 @@ ${state.result}`;
|
|
|
12396
12447
|
});
|
|
12397
12448
|
|
|
12398
12449
|
// ../core/src/agent/toolScheduling.ts
|
|
12399
|
-
var dedupeSameRoundCalls, scheduleToolCalls;
|
|
12450
|
+
var dedupeSameRoundCalls, BATCH_MIN_CHARS, BATCH_WINDOW_SHARE, CHAR_PER_TOKEN, computeBatchBudget, scheduleToolCalls;
|
|
12400
12451
|
var init_toolScheduling = __esm({
|
|
12401
12452
|
"../core/src/agent/toolScheduling.ts"() {
|
|
12402
12453
|
"use strict";
|
|
12403
12454
|
init_toolExecution();
|
|
12404
12455
|
init_transcript();
|
|
12405
12456
|
init_contentParts();
|
|
12457
|
+
init_contextCore();
|
|
12406
12458
|
init_config();
|
|
12407
12459
|
init_tool();
|
|
12408
12460
|
init_permissions();
|
|
@@ -12422,6 +12474,14 @@ var init_toolScheduling = __esm({
|
|
|
12422
12474
|
}
|
|
12423
12475
|
return { batch, plan };
|
|
12424
12476
|
};
|
|
12477
|
+
BATCH_MIN_CHARS = 12e3;
|
|
12478
|
+
BATCH_WINDOW_SHARE = 0.5;
|
|
12479
|
+
CHAR_PER_TOKEN = 4;
|
|
12480
|
+
computeBatchBudget = (modelWindow, compactRatio, contextTokensEst, batchSize) => {
|
|
12481
|
+
const budgetTokensLeft = Math.max(0, modelWindow * compactRatio - (contextTokensEst ?? 0));
|
|
12482
|
+
const batchCapChars = Math.max(BATCH_MIN_CHARS, Math.floor(budgetTokensLeft * CHAR_PER_TOKEN * BATCH_WINDOW_SHARE));
|
|
12483
|
+
return { batchCapChars, perToolCapChars: Math.floor(batchCapChars / batchSize) };
|
|
12484
|
+
};
|
|
12425
12485
|
scheduleToolCalls = async function* (assistantMessage, message, ctx) {
|
|
12426
12486
|
const { sessionId, signal, rawTools } = ctx;
|
|
12427
12487
|
let abortedDuringTools = false;
|
|
@@ -12490,7 +12550,10 @@ var init_toolScheduling = __esm({
|
|
|
12490
12550
|
const bp = parseTc(p.tc);
|
|
12491
12551
|
yield { type: "tool.start", toolCallId: p.tc.id, toolName: bp.name, args: bp.args };
|
|
12492
12552
|
}
|
|
12493
|
-
const
|
|
12553
|
+
const budget = batch.length >= 2 ? computeBatchBudget(ctx.modelWindow, ctx.compactRatio, ctx.contextTokensEst, batch.length) : void 0;
|
|
12554
|
+
const tokensBefore = budget ? estimateTokens(message) : 0;
|
|
12555
|
+
const batchCtx = budget ? { ...ctx, batchBudgetChars: budget.perToolCapChars } : ctx;
|
|
12556
|
+
const outcomes = await Promise.all(batch.map((btc) => processToolCall(btc, batchCtx)));
|
|
12494
12557
|
const outcomeByTc = /* @__PURE__ */ new Map();
|
|
12495
12558
|
batch.forEach((btc, i) => outcomeByTc.set(btc, outcomes[i]));
|
|
12496
12559
|
const batchEntries = [];
|
|
@@ -12514,6 +12577,34 @@ var init_toolScheduling = __esm({
|
|
|
12514
12577
|
if (oc.aborted) abortedDuringTools = true;
|
|
12515
12578
|
}
|
|
12516
12579
|
await appendMessages(sessionId, batchEntries);
|
|
12580
|
+
if (budget) {
|
|
12581
|
+
try {
|
|
12582
|
+
const tokensAfter = estimateTokens(message);
|
|
12583
|
+
ctx.events({
|
|
12584
|
+
sessionId,
|
|
12585
|
+
eventType: "tool.batch.budget",
|
|
12586
|
+
metadata: {
|
|
12587
|
+
depth: ctx.depth,
|
|
12588
|
+
decisionSource: ctx.llmDecisionSource,
|
|
12589
|
+
ok: true,
|
|
12590
|
+
durationMs: performance.now() - ctx.startTime,
|
|
12591
|
+
round: ctx.round,
|
|
12592
|
+
batchSize: batch.length,
|
|
12593
|
+
batchCapChars: budget.batchCapChars,
|
|
12594
|
+
perToolCapChars: budget.perToolCapChars
|
|
12595
|
+
},
|
|
12596
|
+
payload: {
|
|
12597
|
+
output: JSON.stringify({
|
|
12598
|
+
injectedChars: batch.map((btc) => outcomeByTc.get(btc)?.resultForModel.length ?? 0),
|
|
12599
|
+
tokensBefore,
|
|
12600
|
+
tokensAfter,
|
|
12601
|
+
tokensDelta: tokensAfter - tokensBefore
|
|
12602
|
+
})
|
|
12603
|
+
}
|
|
12604
|
+
});
|
|
12605
|
+
} catch {
|
|
12606
|
+
}
|
|
12607
|
+
}
|
|
12517
12608
|
} else {
|
|
12518
12609
|
yield { type: "tool.start", toolCallId: tc.id, toolName: pname, args: pargs };
|
|
12519
12610
|
const oc = await processToolCall(tc, ctx);
|
|
@@ -12644,9 +12735,10 @@ var init_streamInference = __esm({
|
|
|
12644
12735
|
const MAX_STREAM_RETRIES = 2;
|
|
12645
12736
|
const MAX_API_RETRIES = 3;
|
|
12646
12737
|
let apiRetries = 0;
|
|
12738
|
+
let idleRetries = 0;
|
|
12647
12739
|
let compactedThisRound = false;
|
|
12648
12740
|
let visionDegradedThisRound = false;
|
|
12649
|
-
for (
|
|
12741
|
+
for (; ; ) {
|
|
12650
12742
|
try {
|
|
12651
12743
|
for await (const chunk of activeProvider.streamChat(inferenceMessages, cleanedToolSchemas, { signal, model, thinkingLevel })) {
|
|
12652
12744
|
if (signal?.aborted) break;
|
|
@@ -12692,10 +12784,11 @@ var init_streamInference = __esm({
|
|
|
12692
12784
|
}
|
|
12693
12785
|
);
|
|
12694
12786
|
const noOutputYet = !contentBuf && !reasoningBuf && toolCallsBuf.size === 0;
|
|
12695
|
-
if (isIdleTimeout &&
|
|
12787
|
+
if (isIdleTimeout && idleRetries < MAX_STREAM_RETRIES) {
|
|
12788
|
+
idleRetries++;
|
|
12696
12789
|
if (!noOutputYet) yield { type: "text.reset" };
|
|
12697
12790
|
const stallShape = noOutputYet ? "\uFF0C\u5C1A\u65E0\u8F93\u51FA" : hasCompleteToolCall ? "\uFF0C\u5DF2\u6709\u5B8C\u6574 tool_call\uFF08\u6D41\u5C3E\u90E8 stall\uFF09" : "\uFF0Ctool_call \u672A\u6D41\u5B8C";
|
|
12698
|
-
console.warn(`\u26A0\uFE0F \u6D41\u5F0F stall\uFF08idle \u8D85\u65F6${stallShape}\uFF09\uFF0C\u7B2C ${
|
|
12791
|
+
console.warn(`\u26A0\uFE0F \u6D41\u5F0F stall\uFF08idle \u8D85\u65F6${stallShape}\uFF09\uFF0C\u7B2C ${idleRetries}/${MAX_STREAM_RETRIES} \u6B21\u91CD\u8BD5...`);
|
|
12699
12792
|
contentBuf = "";
|
|
12700
12793
|
reasoningBuf = "";
|
|
12701
12794
|
toolCallsBuf.clear();
|
|
@@ -13365,6 +13458,280 @@ var init_usageLog = __esm({
|
|
|
13365
13458
|
}
|
|
13366
13459
|
});
|
|
13367
13460
|
|
|
13461
|
+
// ../core/src/observability/store.ts
|
|
13462
|
+
import path38 from "path";
|
|
13463
|
+
import fs35 from "fs/promises";
|
|
13464
|
+
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
13465
|
+
var init_store3 = __esm({
|
|
13466
|
+
"../core/src/observability/store.ts"() {
|
|
13467
|
+
"use strict";
|
|
13468
|
+
init_config();
|
|
13469
|
+
init_traceCalculate();
|
|
13470
|
+
init_common();
|
|
13471
|
+
getTraceDirPath = (mainTraceId) => {
|
|
13472
|
+
assertSafeSessionId(mainTraceId, "traceId");
|
|
13473
|
+
return path38.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
13474
|
+
};
|
|
13475
|
+
getTracePath = () => {
|
|
13476
|
+
return path38.join(appConfig.dataDir, "trace");
|
|
13477
|
+
};
|
|
13478
|
+
tracePathCache = /* @__PURE__ */ new Map();
|
|
13479
|
+
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
13480
|
+
ensureTraceDir = async (mainTraceId) => {
|
|
13481
|
+
const dir = getTraceDirPath(mainTraceId);
|
|
13482
|
+
if (ensuredTraceDirs.has(dir)) return;
|
|
13483
|
+
await fs35.mkdir(dir, { recursive: true });
|
|
13484
|
+
ensuredTraceDirs.add(dir);
|
|
13485
|
+
};
|
|
13486
|
+
getGlobalClockPath = () => {
|
|
13487
|
+
return path38.join(getTracePath(), "trace-cleanup-clock.json");
|
|
13488
|
+
};
|
|
13489
|
+
getTraceStorePath = async (mainTraceId) => {
|
|
13490
|
+
assertSafeSessionId(mainTraceId, "traceId");
|
|
13491
|
+
const rootId = getFileName(mainTraceId);
|
|
13492
|
+
const cached2 = tracePathCache.get(rootId);
|
|
13493
|
+
if (cached2) return cached2;
|
|
13494
|
+
await ensureTraceDir(rootId);
|
|
13495
|
+
const dir = getTraceDirPath(rootId);
|
|
13496
|
+
const files = await fs35.readdir(dir);
|
|
13497
|
+
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
13498
|
+
let fileName = "";
|
|
13499
|
+
if (existedFile) {
|
|
13500
|
+
fileName = existedFile;
|
|
13501
|
+
} else {
|
|
13502
|
+
const todayStr = getTodayDateString();
|
|
13503
|
+
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
13504
|
+
}
|
|
13505
|
+
const resolved = path38.join(dir, fileName);
|
|
13506
|
+
tracePathCache.set(rootId, resolved);
|
|
13507
|
+
return resolved;
|
|
13508
|
+
};
|
|
13509
|
+
}
|
|
13510
|
+
});
|
|
13511
|
+
|
|
13512
|
+
// ../core/src/observability/trace.ts
|
|
13513
|
+
import fs36 from "fs/promises";
|
|
13514
|
+
import path39 from "path";
|
|
13515
|
+
async function emitTrace(base) {
|
|
13516
|
+
const event = {
|
|
13517
|
+
sessionId: base.sessionId,
|
|
13518
|
+
parentId: base.parentId,
|
|
13519
|
+
eventType: base.eventType,
|
|
13520
|
+
timestamp: base.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
13521
|
+
usage: base.usage,
|
|
13522
|
+
payload: base.payload,
|
|
13523
|
+
metadata: {
|
|
13524
|
+
...base.metadata || {}
|
|
13525
|
+
}
|
|
13526
|
+
};
|
|
13527
|
+
if (event.payload) {
|
|
13528
|
+
if (typeof event.payload.input === "string") event.payload.input = truncateTracePayload(event.payload.input);
|
|
13529
|
+
if (typeof event.payload.output === "string") event.payload.output = truncateTracePayload(event.payload.output);
|
|
13530
|
+
}
|
|
13531
|
+
try {
|
|
13532
|
+
await appendTraceEvent(event);
|
|
13533
|
+
} catch (error) {
|
|
13534
|
+
console.warn("\u26A0\uFE0F [Trace] \u4E8B\u4EF6\u843D\u76D8\u5931\u8D25\uFF0C\u5DF2\u9632\u5FA1\u6027\u8DF3\u8FC7\uFF08\u4E0D\u5F71\u54CD\u4E3B\u4E1A\u52A1\uFF09:", error);
|
|
13535
|
+
}
|
|
13536
|
+
}
|
|
13537
|
+
async function appendTraceEvent(event) {
|
|
13538
|
+
const line = JSON.stringify(event) + "\n";
|
|
13539
|
+
const arr = traceBuf.get(event.sessionId);
|
|
13540
|
+
if (arr) arr.push(line);
|
|
13541
|
+
else traceBuf.set(event.sessionId, [line]);
|
|
13542
|
+
if (needImmediateFlush(event)) {
|
|
13543
|
+
await flushTraceBuffer(event.sessionId);
|
|
13544
|
+
return;
|
|
13545
|
+
}
|
|
13546
|
+
if ((traceBuf.get(event.sessionId)?.length ?? 0) >= TRACE_BATCH_LINES) {
|
|
13547
|
+
await flushTraceBuffer(event.sessionId);
|
|
13548
|
+
return;
|
|
13549
|
+
}
|
|
13550
|
+
scheduleTraceTimer(event.sessionId);
|
|
13551
|
+
}
|
|
13552
|
+
async function maybeCleanupAfterAppend(sessionId) {
|
|
13553
|
+
if (cleanupInProgress2) return;
|
|
13554
|
+
cleanupInProgress2 = true;
|
|
13555
|
+
try {
|
|
13556
|
+
await ensureClockLoaded2();
|
|
13557
|
+
const now = Date.now();
|
|
13558
|
+
const isTimeExpired = now - diskLastCleanupAt2 > CLEANUP_INTERVAL_MS2;
|
|
13559
|
+
const isSizeOverflow = workspaceTraceBytes > MAX_TRACE_FOLDER_BYTES;
|
|
13560
|
+
if (!isTimeExpired && !isSizeOverflow) return;
|
|
13561
|
+
if (isSizeOverflow && !isTimeExpired && now - lastSizeCleanupAt2 < SIZE_CLEANUP_COOLDOWN_MS2) {
|
|
13562
|
+
return;
|
|
13563
|
+
}
|
|
13564
|
+
const reason = isTimeExpired && isSizeOverflow ? "\u5BB9\u91CF+\u65F6\u95F4\u53CC\u95F8" : isSizeOverflow ? "\u5BB9\u91CF\u8D8A\u8FC750MB\u5927\u95F8" : "3\u5929\u51B7\u5374\u5468\u671F\u5DF2\u6EE1";
|
|
13565
|
+
console.log(`\u{1F9F9} [Trace\u8FD0\u7EF4] \u89E6\u53D1\u81EA\u9002\u5E94\u6E05\u7406\uFF08\u539F\u56E0: ${reason}\uFF09`);
|
|
13566
|
+
let deletedCount = 0;
|
|
13567
|
+
deletedCount += await cleanupOldTraceFiles();
|
|
13568
|
+
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
13569
|
+
if (workspaceTraceBytes > MAX_TRACE_FOLDER_BYTES) {
|
|
13570
|
+
const targetBytes = Math.floor(MAX_TRACE_FOLDER_BYTES * SIZE_RECLAIM_TARGET_RATIO2);
|
|
13571
|
+
deletedCount += await evictOldestForSize2(targetBytes);
|
|
13572
|
+
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
13573
|
+
}
|
|
13574
|
+
lastSizeCleanupAt2 = now;
|
|
13575
|
+
diskLastCleanupAt2 = now;
|
|
13576
|
+
const clockPath = getGlobalClockPath();
|
|
13577
|
+
await fs36.mkdir(path39.dirname(clockPath), { recursive: true });
|
|
13578
|
+
await fs36.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
13579
|
+
if (deletedCount > 0) {
|
|
13580
|
+
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`);
|
|
13581
|
+
}
|
|
13582
|
+
} catch (error) {
|
|
13583
|
+
console.warn("\u26A0\uFE0F [Trace\u8FD0\u7EF4] \u81EA\u52A8\u6E05\u7406\u53D1\u751F\u8F7B\u5FAE\u5F02\u5E38\uFF0C\u5DF2\u9632\u5FA1\u6027\u8DF3\u8FC7:", error);
|
|
13584
|
+
} finally {
|
|
13585
|
+
cleanupInProgress2 = false;
|
|
13586
|
+
}
|
|
13587
|
+
}
|
|
13588
|
+
async function cleanupOldTraceFiles() {
|
|
13589
|
+
const dir = getTracePath();
|
|
13590
|
+
const retentionDays = Math.max(1, appConfig.traceRetentionDays || 7);
|
|
13591
|
+
const cutoff = /* @__PURE__ */ new Date();
|
|
13592
|
+
cutoff.setHours(0, 0, 0, 0);
|
|
13593
|
+
cutoff.setDate(cutoff.getDate() - retentionDays);
|
|
13594
|
+
const now = Date.now();
|
|
13595
|
+
let deleted = 0;
|
|
13596
|
+
let relativePaths;
|
|
13597
|
+
try {
|
|
13598
|
+
relativePaths = await fs36.readdir(dir, { recursive: true });
|
|
13599
|
+
} catch {
|
|
13600
|
+
return 0;
|
|
13601
|
+
}
|
|
13602
|
+
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
13603
|
+
for (const relativePath of relativePaths) {
|
|
13604
|
+
const fileName = path39.basename(relativePath);
|
|
13605
|
+
const m = fileName.match(re);
|
|
13606
|
+
if (!m) continue;
|
|
13607
|
+
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
13608
|
+
if (fileBornDay >= cutoff) continue;
|
|
13609
|
+
const fullPath = path39.join(dir, relativePath);
|
|
13610
|
+
try {
|
|
13611
|
+
const st = await fs36.stat(fullPath);
|
|
13612
|
+
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
13613
|
+
await fs36.unlink(fullPath);
|
|
13614
|
+
deleted += 1;
|
|
13615
|
+
} catch {
|
|
13616
|
+
}
|
|
13617
|
+
}
|
|
13618
|
+
return deleted;
|
|
13619
|
+
}
|
|
13620
|
+
async function evictOldestForSize2(targetBytes) {
|
|
13621
|
+
const dir = getTracePath();
|
|
13622
|
+
let relativePaths;
|
|
13623
|
+
try {
|
|
13624
|
+
relativePaths = await fs36.readdir(dir, { recursive: true });
|
|
13625
|
+
} catch {
|
|
13626
|
+
return 0;
|
|
13627
|
+
}
|
|
13628
|
+
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
13629
|
+
const candidates = [];
|
|
13630
|
+
for (const relativePath of relativePaths) {
|
|
13631
|
+
const fileName = path39.basename(relativePath);
|
|
13632
|
+
if (!re.test(fileName)) continue;
|
|
13633
|
+
try {
|
|
13634
|
+
const st = await fs36.stat(path39.join(dir, relativePath));
|
|
13635
|
+
candidates.push({ mtime: st.mtimeMs, fullPath: path39.join(dir, relativePath), size: st.size });
|
|
13636
|
+
} catch {
|
|
13637
|
+
}
|
|
13638
|
+
}
|
|
13639
|
+
candidates.sort((a, b) => a.mtime - b.mtime);
|
|
13640
|
+
let totalBytes = candidates.reduce((sum, c) => sum + c.size, 0);
|
|
13641
|
+
let deleted = 0;
|
|
13642
|
+
for (const c of candidates) {
|
|
13643
|
+
if (totalBytes <= targetBytes) break;
|
|
13644
|
+
try {
|
|
13645
|
+
await fs36.unlink(c.fullPath);
|
|
13646
|
+
totalBytes -= c.size;
|
|
13647
|
+
deleted += 1;
|
|
13648
|
+
} catch {
|
|
13649
|
+
}
|
|
13650
|
+
}
|
|
13651
|
+
if (deleted > 0) {
|
|
13652
|
+
console.warn(`\u26A0\uFE0F [Trace\u8FD0\u7EF4] \u5BB9\u91CF\u786C\u9A71\u9010\uFF1A\u8D8A\u8FC7\u6D3B\u8DC3\u4FDD\u62A4\u5F3A\u5220 ${deleted} \u4E2A\u6700\u65E7 trace \u6587\u4EF6\uFF08\u78C1\u76D8\u538B\u529B\u515C\u5E95\uFF09\u3002`);
|
|
13653
|
+
}
|
|
13654
|
+
return deleted;
|
|
13655
|
+
}
|
|
13656
|
+
var CLEANUP_INTERVAL_MS2, ACTIVE_GRACE_MS2, MAX_TRACE_FOLDER_BYTES, SIZE_RECLAIM_TARGET_RATIO2, SIZE_CLEANUP_COOLDOWN_MS2, workspaceTraceBytes, diskLastCleanupAt2, clockLoaded2, lastSizeCleanupAt2, cleanupInProgress2, TRACE_BATCH_LINES, TRACE_BATCH_MS, traceBuf, traceTimers, cleanupTriggerCount, needImmediateFlush, scheduleTraceTimer, flushTraceBuffer, ensureClockLoaded2, tracePayloadMaxChars, truncateTracePayload;
|
|
13657
|
+
var init_trace = __esm({
|
|
13658
|
+
"../core/src/observability/trace.ts"() {
|
|
13659
|
+
"use strict";
|
|
13660
|
+
init_config();
|
|
13661
|
+
init_store3();
|
|
13662
|
+
init_traceCalculate();
|
|
13663
|
+
CLEANUP_INTERVAL_MS2 = 3 * 24 * 60 * 60 * 1e3;
|
|
13664
|
+
ACTIVE_GRACE_MS2 = 24 * 60 * 60 * 1e3;
|
|
13665
|
+
MAX_TRACE_FOLDER_BYTES = 50 * 1024 * 1024;
|
|
13666
|
+
SIZE_RECLAIM_TARGET_RATIO2 = 0.8;
|
|
13667
|
+
SIZE_CLEANUP_COOLDOWN_MS2 = 60 * 1e3;
|
|
13668
|
+
workspaceTraceBytes = -1;
|
|
13669
|
+
diskLastCleanupAt2 = 0;
|
|
13670
|
+
clockLoaded2 = false;
|
|
13671
|
+
lastSizeCleanupAt2 = 0;
|
|
13672
|
+
cleanupInProgress2 = false;
|
|
13673
|
+
TRACE_BATCH_LINES = 50;
|
|
13674
|
+
TRACE_BATCH_MS = 200;
|
|
13675
|
+
traceBuf = /* @__PURE__ */ new Map();
|
|
13676
|
+
traceTimers = /* @__PURE__ */ new Map();
|
|
13677
|
+
cleanupTriggerCount = 0;
|
|
13678
|
+
needImmediateFlush = (ev) => ev.metadata?.ok === false || ev.eventType === "user.aborted" || ev.eventType === "tool.repeat_break" || ev.eventType === "session.end";
|
|
13679
|
+
scheduleTraceTimer = (sessionId) => {
|
|
13680
|
+
if (traceTimers.has(sessionId)) return;
|
|
13681
|
+
const t = setTimeout(() => {
|
|
13682
|
+
traceTimers.delete(sessionId);
|
|
13683
|
+
void flushTraceBuffer(sessionId);
|
|
13684
|
+
}, TRACE_BATCH_MS);
|
|
13685
|
+
t.unref?.();
|
|
13686
|
+
traceTimers.set(sessionId, t);
|
|
13687
|
+
};
|
|
13688
|
+
flushTraceBuffer = async (sessionId) => {
|
|
13689
|
+
const ids = sessionId !== void 0 ? [sessionId] : [...traceBuf.keys()];
|
|
13690
|
+
for (const id of ids) {
|
|
13691
|
+
const arr = traceBuf.get(id);
|
|
13692
|
+
if (!arr || arr.length === 0) {
|
|
13693
|
+
traceBuf.delete(id);
|
|
13694
|
+
continue;
|
|
13695
|
+
}
|
|
13696
|
+
traceBuf.set(id, []);
|
|
13697
|
+
const timer = traceTimers.get(id);
|
|
13698
|
+
if (timer) {
|
|
13699
|
+
clearTimeout(timer);
|
|
13700
|
+
traceTimers.delete(id);
|
|
13701
|
+
}
|
|
13702
|
+
try {
|
|
13703
|
+
const joined = arr.join("");
|
|
13704
|
+
const p = await getTraceStorePath(id);
|
|
13705
|
+
await fs36.appendFile(p, joined, "utf-8");
|
|
13706
|
+
if (workspaceTraceBytes < 0) {
|
|
13707
|
+
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
13708
|
+
}
|
|
13709
|
+
workspaceTraceBytes += Buffer.byteLength(joined, "utf-8");
|
|
13710
|
+
cleanupTriggerCount++;
|
|
13711
|
+
void maybeCleanupAfterAppend(id);
|
|
13712
|
+
} catch (error) {
|
|
13713
|
+
console.warn("\u26A0\uFE0F [Trace] \u6279\u91CF\u843D\u76D8\u5931\u8D25\uFF0C\u4E22\u5F03\u8BE5\u6279\uFF08\u4E0D\u5F71\u54CD\u4E3B\u4E1A\u52A1\uFF09:", error);
|
|
13714
|
+
}
|
|
13715
|
+
}
|
|
13716
|
+
};
|
|
13717
|
+
ensureClockLoaded2 = async () => {
|
|
13718
|
+
if (clockLoaded2) return;
|
|
13719
|
+
clockLoaded2 = true;
|
|
13720
|
+
try {
|
|
13721
|
+
const rawClock = await fs36.readFile(getGlobalClockPath(), "utf-8");
|
|
13722
|
+
diskLastCleanupAt2 = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
13723
|
+
} catch {
|
|
13724
|
+
diskLastCleanupAt2 = 0;
|
|
13725
|
+
}
|
|
13726
|
+
};
|
|
13727
|
+
tracePayloadMaxChars = () => Number(process.env.TRACE_PAYLOAD_MAX_CHARS) || 2e3;
|
|
13728
|
+
truncateTracePayload = (s) => {
|
|
13729
|
+
const max = tracePayloadMaxChars();
|
|
13730
|
+
return s.length > max ? s.slice(0, max) + `\u2026[trace \u622A\u65AD ${s.length - max} \u5B57\u7B26\uFF08\u5171 ${s.length} \u5B57\u7B26\uFF09]` : s;
|
|
13731
|
+
};
|
|
13732
|
+
}
|
|
13733
|
+
});
|
|
13734
|
+
|
|
13368
13735
|
// ../core/src/agent/runAgent.ts
|
|
13369
13736
|
async function* runAgent(message, options) {
|
|
13370
13737
|
const sessionId = options.sessionId;
|
|
@@ -13633,7 +14000,10 @@ async function* runAgent(message, options) {
|
|
|
13633
14000
|
nudges.notePlanWriteRejected(planWriteRej);
|
|
13634
14001
|
},
|
|
13635
14002
|
// ★ P1-5 子任务预算熔断:runSubagent 经 toolCtx.budgetCheck 拿到探测闭包,子 runAgent 每轮边界自检
|
|
13636
|
-
budgetCheck: inheritedBudgetCheck
|
|
14003
|
+
budgetCheck: inheritedBudgetCheck,
|
|
14004
|
+
// ★ A 批批级预算:主循环不设(undefined);仅并行批 ≥2 时由调度层浅拷贝下发(R4/R5:
|
|
14005
|
+
// required 字段,构造处显式对齐,漏写即 tsc 打红)
|
|
14006
|
+
batchBudgetChars: void 0
|
|
13637
14007
|
};
|
|
13638
14008
|
const scheduleResult = yield* scheduleToolCalls(assistantMessage, message, toolCallCtx);
|
|
13639
14009
|
if (scheduleResult.kind === "aborted") {
|
|
@@ -13673,6 +14043,10 @@ async function* runAgent(message, options) {
|
|
|
13673
14043
|
await appendEvent(sessionId, { dscEvent: "run.end", runId, stopReason: signal?.aborted ? "aborted" : stopReason, rounds: round, usage: ledger.usageSummary() });
|
|
13674
14044
|
} catch {
|
|
13675
14045
|
}
|
|
14046
|
+
try {
|
|
14047
|
+
await flushTraceBuffer();
|
|
14048
|
+
} catch {
|
|
14049
|
+
}
|
|
13676
14050
|
try {
|
|
13677
14051
|
const us = ledger.usageSummary();
|
|
13678
14052
|
void recordUsageRun({
|
|
@@ -13751,6 +14125,7 @@ var init_runAgent = __esm({
|
|
|
13751
14125
|
init_agentNudges();
|
|
13752
14126
|
init_runLedger();
|
|
13753
14127
|
init_usageLog();
|
|
14128
|
+
init_trace();
|
|
13754
14129
|
init_createModel();
|
|
13755
14130
|
CALIB_EMA_KEEP = 0.6;
|
|
13756
14131
|
CALIB_EMA_NEW = 0.4;
|
|
@@ -13770,7 +14145,7 @@ var init_runAgent = __esm({
|
|
|
13770
14145
|
});
|
|
13771
14146
|
|
|
13772
14147
|
// ../core/src/session/lineage.ts
|
|
13773
|
-
import
|
|
14148
|
+
import fs37 from "node:fs";
|
|
13774
14149
|
var parentOfSubsession, stringAncestorsOf, readForkedFromSync, lineageClosureOf, ownerCanApprove;
|
|
13775
14150
|
var init_lineage = __esm({
|
|
13776
14151
|
"../core/src/session/lineage.ts"() {
|
|
@@ -13793,7 +14168,7 @@ var init_lineage = __esm({
|
|
|
13793
14168
|
};
|
|
13794
14169
|
readForkedFromSync = (sessionId) => {
|
|
13795
14170
|
try {
|
|
13796
|
-
const raw =
|
|
14171
|
+
const raw = fs37.readFileSync(getStatePath(sessionId), "utf-8");
|
|
13797
14172
|
const v = JSON.parse(raw)?.forkedFrom;
|
|
13798
14173
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
13799
14174
|
} catch {
|
|
@@ -13922,6 +14297,7 @@ var init_subagent = __esm({
|
|
|
13922
14297
|
sessionId: ""
|
|
13923
14298
|
};
|
|
13924
14299
|
}
|
|
14300
|
+
const SUBAGENT_REPORT_REQ = `\u3010\u6C47\u62A5\u8981\u6C42\u3011\u6700\u7EC8\u6C47\u62A5\u63A7\u5236\u5728\u4E00\u5C4F\u5185\uFF1A\u5DF2\u5B8C\u6210/\u6539\u52A8\u70B9\uFF08\u6587\u4EF6\u8DEF\u5F84\uFF09/\u9A8C\u8BC1\u7ED3\u679C/\u672A\u5B8C\u6210\u9879\u3002\u4E0D\u8981\u590D\u8FF0\u8FC7\u7A0B\u4E0E\u5DE5\u5177\u8F93\u51FA\u2014\u2014\u7236\u7EA7\u53EF\u76F4\u63A5\u7ECF resume \u8FFD\u95EE\u7EC6\u8282\u3002`;
|
|
13925
14301
|
const subSystem = manifest ? [
|
|
13926
14302
|
`# \u5B50 Agent \u8EAB\u4EFD\uFF1A${manifest.name}`,
|
|
13927
14303
|
manifest.body,
|
|
@@ -13930,7 +14306,8 @@ var init_subagent = __esm({
|
|
|
13930
14306
|
`\u5F53\u524D\u6240\u5904\u7684\u4EFB\u52A1\u6267\u884C\u5D4C\u5957\u6DF1\u5EA6: Depth ${ctx.depth + 1} / ${MAX_AGENT_DEPTH}`,
|
|
13931
14307
|
`
|
|
13932
14308
|
# \u3010\u7EE7\u627F\u7684\u5168\u5C40\u4EE3\u7801\u89C4\u8303\u3011`,
|
|
13933
|
-
parentSystemPrompt
|
|
14309
|
+
parentSystemPrompt,
|
|
14310
|
+
SUBAGENT_REPORT_REQ
|
|
13934
14311
|
].filter(Boolean).join("\n") : [
|
|
13935
14312
|
`# \u4EFB\u52A1\u4E0A\u4E0B\u6587`,
|
|
13936
14313
|
`\u5F53\u524D\u6240\u5904\u7684\u4EFB\u52A1\u6267\u884C\u5D4C\u5957\u6DF1\u5EA6: Depth ${ctx.depth + 1} / ${MAX_AGENT_DEPTH}`,
|
|
@@ -13939,7 +14316,8 @@ var init_subagent = __esm({
|
|
|
13939
14316
|
`\u4F60\u76F4\u63A5\u5171\u4EAB\u5E76\u64CD\u4F5C\u672C\u5730\u6587\u4EF6\u7CFB\u7EDF\u3002\u5F53\u4F60\u5BF9\u6587\u4EF6\u5168\u91CF\u5199\u5165\u6216\u5C40\u90E8\u4FEE\u6539\u65F6\uFF0C\u5FC5\u987B\u786E\u4FDD\u64CD\u4F5C\u7684\u7EDD\u5BF9\u7CBE\u51C6\u3002\u5B8C\u6210\u6307\u5B9A\u5B50\u4EFB\u52A1\u540E\uFF0C\u8BF7\u4F7F\u7528\u6700\u7EC8\u7684\u6587\u672C\u603B\u7ED3\u5411\u7236\u7EA7 Agent \u4EA4\u4ED8\u7ED3\u679C\u3002`,
|
|
13940
14317
|
`
|
|
13941
14318
|
# \u3010\u7EE7\u627F\u7684\u5168\u5C40\u4EE3\u7801\u89C4\u8303\u3011`,
|
|
13942
|
-
parentSystemPrompt
|
|
14319
|
+
parentSystemPrompt,
|
|
14320
|
+
SUBAGENT_REPORT_REQ
|
|
13943
14321
|
].join("\n");
|
|
13944
14322
|
const subTaskPrompt = [
|
|
13945
14323
|
role ? manifest ? `# \u672C\u6B21\u89D2\u8272\u8865\u5145: ${role}` : `\u3010\u4F60\u7684\u4E13\u5C5E\u89D2\u8272\u3011: ${role}` : manifest ? "" : `\u3010\u4F60\u7684\u4E13\u5C5E\u89D2\u8272\u3011: \u4E13\u6CE8\u6267\u884C\u7279\u5B9A\u5C40\u90E8\u5B50\u4EFB\u52A1\u7684\u72EC\u7ACB\u667A\u80FD\u4F53\u52A9\u624B`,
|
|
@@ -14033,15 +14411,15 @@ var init_subagent = __esm({
|
|
|
14033
14411
|
});
|
|
14034
14412
|
|
|
14035
14413
|
// ../core/src/hooks/trust.ts
|
|
14036
|
-
import
|
|
14037
|
-
import
|
|
14414
|
+
import path40 from "path";
|
|
14415
|
+
import fs38 from "fs/promises";
|
|
14038
14416
|
var TRUSTED_HOOKS_FILE, approved, loaded, ensureLoaded, isHookCommandApproved, approveHookCommand;
|
|
14039
14417
|
var init_trust2 = __esm({
|
|
14040
14418
|
"../core/src/hooks/trust.ts"() {
|
|
14041
14419
|
"use strict";
|
|
14042
14420
|
init_config();
|
|
14043
14421
|
init_common();
|
|
14044
|
-
TRUSTED_HOOKS_FILE =
|
|
14422
|
+
TRUSTED_HOOKS_FILE = path40.join(appConfig.dataDir, "trusted_hooks.json");
|
|
14045
14423
|
approved = /* @__PURE__ */ new Set();
|
|
14046
14424
|
loaded = false;
|
|
14047
14425
|
ensureLoaded = async () => {
|
|
@@ -14061,7 +14439,7 @@ var init_trust2 = __esm({
|
|
|
14061
14439
|
if (approved.has(ident)) return;
|
|
14062
14440
|
approved.add(ident);
|
|
14063
14441
|
try {
|
|
14064
|
-
await
|
|
14442
|
+
await fs38.mkdir(appConfig.dataDir, { recursive: true });
|
|
14065
14443
|
await atomicWriteJSON(TRUSTED_HOOKS_FILE, [...approved]);
|
|
14066
14444
|
} catch (e) {
|
|
14067
14445
|
console.warn(`\u26A0\uFE0F [hooks] \u5BA1\u6279\u8BB0\u5FC6\u843D\u76D8\u5931\u8D25\uFF08\u672C\u6B21\u5DF2\u653E\u884C\uFF0C\u4E0B\u6B21\u9996\u8DD1\u4F1A\u518D\u95EE\uFF09: ${e?.message ?? e}`);
|
|
@@ -14071,8 +14449,8 @@ var init_trust2 = __esm({
|
|
|
14071
14449
|
});
|
|
14072
14450
|
|
|
14073
14451
|
// ../core/src/hooks/loader.ts
|
|
14074
|
-
import
|
|
14075
|
-
import
|
|
14452
|
+
import fs39 from "fs/promises";
|
|
14453
|
+
import path41 from "path";
|
|
14076
14454
|
var slimHookContext, readHooksConfig, appendValidated, validateRule, parseStdoutDecision, parseAgentDecision, gateSeq, firstRunGate, compileRule2, loadHooks, initHooks;
|
|
14077
14455
|
var init_loader4 = __esm({
|
|
14078
14456
|
"../core/src/hooks/loader.ts"() {
|
|
@@ -14101,15 +14479,15 @@ var init_loader4 = __esm({
|
|
|
14101
14479
|
readHooksConfig = async (includeProject) => {
|
|
14102
14480
|
const merged = {};
|
|
14103
14481
|
const paths = [
|
|
14104
|
-
|
|
14482
|
+
path41.join(appConfig.dataDir, "settings.json"),
|
|
14105
14483
|
// 全局用户级
|
|
14106
|
-
...includeProject ? [
|
|
14484
|
+
...includeProject ? [path41.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
14107
14485
|
// 项目级(叠加);未信任时省略
|
|
14108
14486
|
];
|
|
14109
14487
|
for (const configPath of paths) {
|
|
14110
14488
|
let raw;
|
|
14111
14489
|
try {
|
|
14112
|
-
raw = await
|
|
14490
|
+
raw = await fs39.readFile(configPath, "utf-8");
|
|
14113
14491
|
} catch {
|
|
14114
14492
|
continue;
|
|
14115
14493
|
}
|
|
@@ -14482,8 +14860,8 @@ ${m.context}`;
|
|
|
14482
14860
|
});
|
|
14483
14861
|
|
|
14484
14862
|
// ../core/src/skills/loader.ts
|
|
14485
|
-
import
|
|
14486
|
-
import
|
|
14863
|
+
import fs40 from "fs/promises";
|
|
14864
|
+
import path42 from "path";
|
|
14487
14865
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
14488
14866
|
var BUILTIN_DIR, SOURCES2, MAX_SKILL_BODY_BYTES, splitList, parseSkillAt, loadSkills, initSkills;
|
|
14489
14867
|
var init_loader5 = __esm({
|
|
@@ -14494,18 +14872,18 @@ var init_loader5 = __esm({
|
|
|
14494
14872
|
init_registry3();
|
|
14495
14873
|
init_skill();
|
|
14496
14874
|
init_registry2();
|
|
14497
|
-
BUILTIN_DIR =
|
|
14875
|
+
BUILTIN_DIR = path42.join(path42.dirname(fileURLToPath2(import.meta.url)), "builtin");
|
|
14498
14876
|
SOURCES2 = [
|
|
14499
14877
|
{ dir: BUILTIN_DIR, source: "builtin" },
|
|
14500
|
-
{ dir:
|
|
14501
|
-
{ dir:
|
|
14878
|
+
{ dir: path42.join(appConfig.dataDir, "skills"), source: "global" },
|
|
14879
|
+
{ dir: path42.join(process.cwd(), ".deepseeker-code", "skills"), source: "project" }
|
|
14502
14880
|
];
|
|
14503
14881
|
MAX_SKILL_BODY_BYTES = 64 * 1024;
|
|
14504
14882
|
splitList = (raw) => (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
14505
14883
|
parseSkillAt = async (skillFile, dir, source) => {
|
|
14506
14884
|
let raw;
|
|
14507
14885
|
try {
|
|
14508
|
-
raw = await
|
|
14886
|
+
raw = await fs40.readFile(skillFile, "utf-8");
|
|
14509
14887
|
} catch {
|
|
14510
14888
|
return null;
|
|
14511
14889
|
}
|
|
@@ -14544,7 +14922,7 @@ var init_loader5 = __esm({
|
|
|
14544
14922
|
loadSkills = async (includeProject) => {
|
|
14545
14923
|
const picked = await scanSources(
|
|
14546
14924
|
filterSources(SOURCES2, includeProject),
|
|
14547
|
-
(e, dir) => e.isDirectory() ?
|
|
14925
|
+
(e, dir) => e.isDirectory() ? path42.join(dir, e.name, "SKILL.md") : void 0,
|
|
14548
14926
|
parseSkillAt
|
|
14549
14927
|
);
|
|
14550
14928
|
for (const { item } of picked) registerSkill(item);
|
|
@@ -14575,8 +14953,8 @@ var init_loader5 = __esm({
|
|
|
14575
14953
|
});
|
|
14576
14954
|
|
|
14577
14955
|
// ../core/src/agents/loader.ts
|
|
14578
|
-
import
|
|
14579
|
-
import
|
|
14956
|
+
import fs41 from "fs/promises";
|
|
14957
|
+
import path43 from "path";
|
|
14580
14958
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
14581
14959
|
var BUILTIN_DIR2, SOURCES3, parseAgentAt, initAgents;
|
|
14582
14960
|
var init_loader6 = __esm({
|
|
@@ -14586,16 +14964,16 @@ var init_loader6 = __esm({
|
|
|
14586
14964
|
init_frontmatter();
|
|
14587
14965
|
init_registry4();
|
|
14588
14966
|
init_registry2();
|
|
14589
|
-
BUILTIN_DIR2 =
|
|
14967
|
+
BUILTIN_DIR2 = path43.join(path43.dirname(fileURLToPath3(import.meta.url)), "builtin");
|
|
14590
14968
|
SOURCES3 = [
|
|
14591
14969
|
{ dir: BUILTIN_DIR2, source: "builtin" },
|
|
14592
|
-
{ dir:
|
|
14593
|
-
{ dir:
|
|
14970
|
+
{ dir: path43.join(appConfig.dataDir, "agents"), source: "global" },
|
|
14971
|
+
{ dir: path43.join(process.cwd(), ".deepseeker-code", "agents"), source: "project" }
|
|
14594
14972
|
];
|
|
14595
14973
|
parseAgentAt = async (file, dir, source) => {
|
|
14596
14974
|
let raw;
|
|
14597
14975
|
try {
|
|
14598
|
-
raw = await
|
|
14976
|
+
raw = await fs41.readFile(file, "utf-8");
|
|
14599
14977
|
} catch {
|
|
14600
14978
|
return null;
|
|
14601
14979
|
}
|
|
@@ -14630,7 +15008,7 @@ var init_loader6 = __esm({
|
|
|
14630
15008
|
const known = new Set(into.map((t) => t.function.name));
|
|
14631
15009
|
const picked = await scanSources(
|
|
14632
15010
|
filterSources(SOURCES3, includeProject),
|
|
14633
|
-
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ?
|
|
15011
|
+
(e, dir) => e.isFile() && e.name.endsWith(".agent.md") ? path43.join(dir, e.name) : void 0,
|
|
14634
15012
|
parseAgentAt
|
|
14635
15013
|
);
|
|
14636
15014
|
for (const { item: m, file, source } of picked) {
|
|
@@ -14667,8 +15045,8 @@ var init_registry7 = __esm({
|
|
|
14667
15045
|
});
|
|
14668
15046
|
|
|
14669
15047
|
// ../core/src/commands/loader.ts
|
|
14670
|
-
import
|
|
14671
|
-
import
|
|
15048
|
+
import fs42 from "fs/promises";
|
|
15049
|
+
import path44 from "path";
|
|
14672
15050
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
14673
15051
|
var BUILTIN_DIR3, SOURCES4, MAX_COMMAND_BODY_BYTES, parseCommandAt, loadCommands, initCommands;
|
|
14674
15052
|
var init_loader7 = __esm({
|
|
@@ -14678,17 +15056,17 @@ var init_loader7 = __esm({
|
|
|
14678
15056
|
init_frontmatter();
|
|
14679
15057
|
init_registry7();
|
|
14680
15058
|
init_registry2();
|
|
14681
|
-
BUILTIN_DIR3 =
|
|
15059
|
+
BUILTIN_DIR3 = path44.join(path44.dirname(fileURLToPath4(import.meta.url)), "builtin");
|
|
14682
15060
|
SOURCES4 = [
|
|
14683
15061
|
{ dir: BUILTIN_DIR3, source: "builtin" },
|
|
14684
|
-
{ dir:
|
|
14685
|
-
{ dir:
|
|
15062
|
+
{ dir: path44.join(appConfig.dataDir, "commands"), source: "global" },
|
|
15063
|
+
{ dir: path44.join(process.cwd(), ".deepseeker-code", "commands"), source: "project" }
|
|
14686
15064
|
];
|
|
14687
15065
|
MAX_COMMAND_BODY_BYTES = 64 * 1024;
|
|
14688
15066
|
parseCommandAt = async (file, _dir, source) => {
|
|
14689
15067
|
let raw;
|
|
14690
15068
|
try {
|
|
14691
|
-
raw = await
|
|
15069
|
+
raw = await fs42.readFile(file, "utf-8");
|
|
14692
15070
|
} catch {
|
|
14693
15071
|
return null;
|
|
14694
15072
|
}
|
|
@@ -14699,7 +15077,7 @@ var init_loader7 = __esm({
|
|
|
14699
15077
|
}
|
|
14700
15078
|
const name = parsed.frontmatter.name;
|
|
14701
15079
|
const description = parsed.frontmatter.description;
|
|
14702
|
-
const fallbackName =
|
|
15080
|
+
const fallbackName = path44.basename(file, ".md");
|
|
14703
15081
|
const finalName = name || fallbackName;
|
|
14704
15082
|
if (!description) {
|
|
14705
15083
|
console.warn(`\u26A0\uFE0F [commands] \u7F3A\u5C11 description\uFF08${file}\uFF09\uFF0C\u5DF2\u8DF3\u8FC7`);
|
|
@@ -14725,7 +15103,7 @@ var init_loader7 = __esm({
|
|
|
14725
15103
|
loadCommands = async (includeProject) => {
|
|
14726
15104
|
const picked = await scanSources(
|
|
14727
15105
|
filterSources(SOURCES4, includeProject),
|
|
14728
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
15106
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path44.join(dir, e.name) : void 0,
|
|
14729
15107
|
parseCommandAt
|
|
14730
15108
|
);
|
|
14731
15109
|
for (const { item } of picked) registerCommand(item);
|
|
@@ -14743,8 +15121,8 @@ var init_loader7 = __esm({
|
|
|
14743
15121
|
});
|
|
14744
15122
|
|
|
14745
15123
|
// ../core/src/outputStyles/loader.ts
|
|
14746
|
-
import
|
|
14747
|
-
import
|
|
15124
|
+
import fs43 from "fs/promises";
|
|
15125
|
+
import path45 from "path";
|
|
14748
15126
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
14749
15127
|
var BUILTIN_DIR4, MAX_STYLE_BODY_BYTES, SOURCES5, parseStyleAt, loadOutputStyles, initOutputStyles;
|
|
14750
15128
|
var init_loader8 = __esm({
|
|
@@ -14754,17 +15132,17 @@ var init_loader8 = __esm({
|
|
|
14754
15132
|
init_frontmatter();
|
|
14755
15133
|
init_registry5();
|
|
14756
15134
|
init_registry2();
|
|
14757
|
-
BUILTIN_DIR4 =
|
|
15135
|
+
BUILTIN_DIR4 = path45.join(path45.dirname(fileURLToPath5(import.meta.url)), "builtin");
|
|
14758
15136
|
MAX_STYLE_BODY_BYTES = 64 * 1024;
|
|
14759
15137
|
SOURCES5 = [
|
|
14760
15138
|
{ dir: BUILTIN_DIR4, source: "builtin" },
|
|
14761
|
-
{ dir:
|
|
14762
|
-
{ dir:
|
|
15139
|
+
{ dir: path45.join(appConfig.dataDir, "output-styles"), source: "global" },
|
|
15140
|
+
{ dir: path45.join(process.cwd(), ".deepseeker-code", "output-styles"), source: "project" }
|
|
14763
15141
|
];
|
|
14764
15142
|
parseStyleAt = async (file, _dir, source) => {
|
|
14765
15143
|
let raw;
|
|
14766
15144
|
try {
|
|
14767
|
-
raw = await
|
|
15145
|
+
raw = await fs43.readFile(file, "utf-8");
|
|
14768
15146
|
} catch {
|
|
14769
15147
|
return null;
|
|
14770
15148
|
}
|
|
@@ -14796,7 +15174,7 @@ var init_loader8 = __esm({
|
|
|
14796
15174
|
loadOutputStyles = async (includeProject) => {
|
|
14797
15175
|
const picked = await scanSources(
|
|
14798
15176
|
filterSources(SOURCES5, includeProject),
|
|
14799
|
-
(e, dir) => e.isFile() && e.name.endsWith(".md") ?
|
|
15177
|
+
(e, dir) => e.isFile() && e.name.endsWith(".md") ? path45.join(dir, e.name) : void 0,
|
|
14800
15178
|
parseStyleAt
|
|
14801
15179
|
);
|
|
14802
15180
|
for (const { item } of picked) registerOutputStyle(item);
|
|
@@ -14877,8 +15255,8 @@ var init_bootstrap = __esm({
|
|
|
14877
15255
|
});
|
|
14878
15256
|
|
|
14879
15257
|
// ../core/src/statusLine/config.ts
|
|
14880
|
-
import
|
|
14881
|
-
import
|
|
15258
|
+
import fs44 from "fs/promises";
|
|
15259
|
+
import path46 from "path";
|
|
14882
15260
|
var parseBlock, readStatusLineConfig;
|
|
14883
15261
|
var init_config2 = __esm({
|
|
14884
15262
|
"../core/src/statusLine/config.ts"() {
|
|
@@ -14894,16 +15272,16 @@ var init_config2 = __esm({
|
|
|
14894
15272
|
};
|
|
14895
15273
|
readStatusLineConfig = async (includeProject) => {
|
|
14896
15274
|
const paths = [
|
|
14897
|
-
|
|
15275
|
+
path46.join(appConfig.dataDir, "settings.json"),
|
|
14898
15276
|
// 全局用户级
|
|
14899
|
-
...includeProject ? [
|
|
15277
|
+
...includeProject ? [path46.join(process.cwd(), ".deepseeker-code", "settings.json")] : []
|
|
14900
15278
|
// 项目级(覆盖);未信任时省略
|
|
14901
15279
|
];
|
|
14902
15280
|
let result = null;
|
|
14903
15281
|
for (const configPath of paths) {
|
|
14904
15282
|
let raw;
|
|
14905
15283
|
try {
|
|
14906
|
-
raw = await
|
|
15284
|
+
raw = await fs44.readFile(configPath, "utf-8");
|
|
14907
15285
|
} catch {
|
|
14908
15286
|
continue;
|
|
14909
15287
|
}
|
|
@@ -14923,8 +15301,8 @@ var init_config2 = __esm({
|
|
|
14923
15301
|
|
|
14924
15302
|
// ../core/src/statusLine/runner.ts
|
|
14925
15303
|
import { spawn as spawn5 } from "child_process";
|
|
14926
|
-
import
|
|
14927
|
-
import
|
|
15304
|
+
import fs45 from "fs";
|
|
15305
|
+
import path47 from "path";
|
|
14928
15306
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
14929
15307
|
var STATUSLINE_TIMEOUT_MS, cachedVersion, runStatusLine;
|
|
14930
15308
|
var init_runner = __esm({
|
|
@@ -14933,16 +15311,16 @@ var init_runner = __esm({
|
|
|
14933
15311
|
init_guard();
|
|
14934
15312
|
STATUSLINE_TIMEOUT_MS = 3e3;
|
|
14935
15313
|
try {
|
|
14936
|
-
const here =
|
|
15314
|
+
const here = path47.dirname(fileURLToPath6(import.meta.url));
|
|
14937
15315
|
const candidates = [
|
|
14938
|
-
|
|
15316
|
+
path47.join(here, "../../../package.json"),
|
|
14939
15317
|
// src/core/package.json
|
|
14940
|
-
|
|
15318
|
+
path47.join(here, "../../../../package.json")
|
|
14941
15319
|
// 仓库根 package.json
|
|
14942
15320
|
];
|
|
14943
15321
|
for (const p of candidates) {
|
|
14944
15322
|
try {
|
|
14945
|
-
const pkg = JSON.parse(
|
|
15323
|
+
const pkg = JSON.parse(fs45.readFileSync(p, "utf-8"));
|
|
14946
15324
|
if (typeof pkg.version === "string" && pkg.version) {
|
|
14947
15325
|
cachedVersion = pkg.version;
|
|
14948
15326
|
break;
|
|
@@ -14992,222 +15370,6 @@ var init_runner = __esm({
|
|
|
14992
15370
|
}
|
|
14993
15371
|
});
|
|
14994
15372
|
|
|
14995
|
-
// ../core/src/observability/store.ts
|
|
14996
|
-
import path46 from "path";
|
|
14997
|
-
import fs44 from "fs/promises";
|
|
14998
|
-
var getTraceDirPath, getTracePath, tracePathCache, ensuredTraceDirs, ensureTraceDir, getGlobalClockPath, getTraceStorePath;
|
|
14999
|
-
var init_store3 = __esm({
|
|
15000
|
-
"../core/src/observability/store.ts"() {
|
|
15001
|
-
"use strict";
|
|
15002
|
-
init_config();
|
|
15003
|
-
init_traceCalculate();
|
|
15004
|
-
init_common();
|
|
15005
|
-
getTraceDirPath = (mainTraceId) => {
|
|
15006
|
-
assertSafeSessionId(mainTraceId, "traceId");
|
|
15007
|
-
return path46.join(appConfig.dataDir, "trace", appConfig.userWorkspaceDir, getFileName(mainTraceId));
|
|
15008
|
-
};
|
|
15009
|
-
getTracePath = () => {
|
|
15010
|
-
return path46.join(appConfig.dataDir, "trace");
|
|
15011
|
-
};
|
|
15012
|
-
tracePathCache = /* @__PURE__ */ new Map();
|
|
15013
|
-
ensuredTraceDirs = /* @__PURE__ */ new Set();
|
|
15014
|
-
ensureTraceDir = async (mainTraceId) => {
|
|
15015
|
-
const dir = getTraceDirPath(mainTraceId);
|
|
15016
|
-
if (ensuredTraceDirs.has(dir)) return;
|
|
15017
|
-
await fs44.mkdir(dir, { recursive: true });
|
|
15018
|
-
ensuredTraceDirs.add(dir);
|
|
15019
|
-
};
|
|
15020
|
-
getGlobalClockPath = () => {
|
|
15021
|
-
return path46.join(getTracePath(), "trace-cleanup-clock.json");
|
|
15022
|
-
};
|
|
15023
|
-
getTraceStorePath = async (mainTraceId) => {
|
|
15024
|
-
assertSafeSessionId(mainTraceId, "traceId");
|
|
15025
|
-
const rootId = getFileName(mainTraceId);
|
|
15026
|
-
const cached2 = tracePathCache.get(rootId);
|
|
15027
|
-
if (cached2) return cached2;
|
|
15028
|
-
await ensureTraceDir(rootId);
|
|
15029
|
-
const dir = getTraceDirPath(rootId);
|
|
15030
|
-
const files = await fs44.readdir(dir);
|
|
15031
|
-
const existedFile = files.find((f) => f.endsWith(`__${rootId}.jsonl`));
|
|
15032
|
-
let fileName = "";
|
|
15033
|
-
if (existedFile) {
|
|
15034
|
-
fileName = existedFile;
|
|
15035
|
-
} else {
|
|
15036
|
-
const todayStr = getTodayDateString();
|
|
15037
|
-
fileName = `trace-${todayStr}__${rootId}.jsonl`;
|
|
15038
|
-
}
|
|
15039
|
-
const resolved = path46.join(dir, fileName);
|
|
15040
|
-
tracePathCache.set(rootId, resolved);
|
|
15041
|
-
return resolved;
|
|
15042
|
-
};
|
|
15043
|
-
}
|
|
15044
|
-
});
|
|
15045
|
-
|
|
15046
|
-
// ../core/src/observability/trace.ts
|
|
15047
|
-
import fs45 from "fs/promises";
|
|
15048
|
-
import path47 from "path";
|
|
15049
|
-
async function emitTrace(base) {
|
|
15050
|
-
const event = {
|
|
15051
|
-
sessionId: base.sessionId,
|
|
15052
|
-
parentId: base.parentId,
|
|
15053
|
-
eventType: base.eventType,
|
|
15054
|
-
timestamp: base.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
15055
|
-
usage: base.usage,
|
|
15056
|
-
payload: base.payload,
|
|
15057
|
-
metadata: {
|
|
15058
|
-
...base.metadata || {}
|
|
15059
|
-
}
|
|
15060
|
-
};
|
|
15061
|
-
try {
|
|
15062
|
-
await appendTraceEvent(event);
|
|
15063
|
-
} catch (error) {
|
|
15064
|
-
console.warn("\u26A0\uFE0F [Trace] \u4E8B\u4EF6\u843D\u76D8\u5931\u8D25\uFF0C\u5DF2\u9632\u5FA1\u6027\u8DF3\u8FC7\uFF08\u4E0D\u5F71\u54CD\u4E3B\u4E1A\u52A1\uFF09:", error);
|
|
15065
|
-
}
|
|
15066
|
-
}
|
|
15067
|
-
async function appendTraceEvent(event) {
|
|
15068
|
-
const p = await getTraceStorePath(event.sessionId);
|
|
15069
|
-
const line = JSON.stringify(event) + "\n";
|
|
15070
|
-
await fs45.appendFile(p, line, "utf-8");
|
|
15071
|
-
if (workspaceTraceBytes < 0) {
|
|
15072
|
-
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
15073
|
-
}
|
|
15074
|
-
workspaceTraceBytes += Buffer.byteLength(line, "utf-8");
|
|
15075
|
-
void maybeCleanupAfterAppend(event.sessionId);
|
|
15076
|
-
}
|
|
15077
|
-
async function maybeCleanupAfterAppend(sessionId) {
|
|
15078
|
-
if (cleanupInProgress2) return;
|
|
15079
|
-
cleanupInProgress2 = true;
|
|
15080
|
-
try {
|
|
15081
|
-
await ensureClockLoaded2();
|
|
15082
|
-
const now = Date.now();
|
|
15083
|
-
const isTimeExpired = now - diskLastCleanupAt2 > CLEANUP_INTERVAL_MS2;
|
|
15084
|
-
const isSizeOverflow = workspaceTraceBytes > MAX_TRACE_FOLDER_BYTES;
|
|
15085
|
-
if (!isTimeExpired && !isSizeOverflow) return;
|
|
15086
|
-
if (isSizeOverflow && !isTimeExpired && now - lastSizeCleanupAt2 < SIZE_CLEANUP_COOLDOWN_MS2) {
|
|
15087
|
-
return;
|
|
15088
|
-
}
|
|
15089
|
-
const reason = isTimeExpired && isSizeOverflow ? "\u5BB9\u91CF+\u65F6\u95F4\u53CC\u95F8" : isSizeOverflow ? "\u5BB9\u91CF\u8D8A\u8FC750MB\u5927\u95F8" : "3\u5929\u51B7\u5374\u5468\u671F\u5DF2\u6EE1";
|
|
15090
|
-
console.log(`\u{1F9F9} [Trace\u8FD0\u7EF4] \u89E6\u53D1\u81EA\u9002\u5E94\u6E05\u7406\uFF08\u539F\u56E0: ${reason}\uFF09`);
|
|
15091
|
-
let deletedCount = 0;
|
|
15092
|
-
deletedCount += await cleanupOldTraceFiles();
|
|
15093
|
-
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
15094
|
-
if (workspaceTraceBytes > MAX_TRACE_FOLDER_BYTES) {
|
|
15095
|
-
const targetBytes = Math.floor(MAX_TRACE_FOLDER_BYTES * SIZE_RECLAIM_TARGET_RATIO2);
|
|
15096
|
-
deletedCount += await evictOldestForSize2(targetBytes);
|
|
15097
|
-
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
15098
|
-
}
|
|
15099
|
-
lastSizeCleanupAt2 = now;
|
|
15100
|
-
diskLastCleanupAt2 = now;
|
|
15101
|
-
const clockPath = getGlobalClockPath();
|
|
15102
|
-
await fs45.mkdir(path47.dirname(clockPath), { recursive: true });
|
|
15103
|
-
await fs45.writeFile(clockPath, JSON.stringify({ lastCleanupAt: now, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
15104
|
-
if (deletedCount > 0) {
|
|
15105
|
-
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`);
|
|
15106
|
-
}
|
|
15107
|
-
} catch (error) {
|
|
15108
|
-
console.warn("\u26A0\uFE0F [Trace\u8FD0\u7EF4] \u81EA\u52A8\u6E05\u7406\u53D1\u751F\u8F7B\u5FAE\u5F02\u5E38\uFF0C\u5DF2\u9632\u5FA1\u6027\u8DF3\u8FC7:", error);
|
|
15109
|
-
} finally {
|
|
15110
|
-
cleanupInProgress2 = false;
|
|
15111
|
-
}
|
|
15112
|
-
}
|
|
15113
|
-
async function cleanupOldTraceFiles() {
|
|
15114
|
-
const dir = getTracePath();
|
|
15115
|
-
const retentionDays = Math.max(1, appConfig.traceRetentionDays || 7);
|
|
15116
|
-
const cutoff = /* @__PURE__ */ new Date();
|
|
15117
|
-
cutoff.setHours(0, 0, 0, 0);
|
|
15118
|
-
cutoff.setDate(cutoff.getDate() - retentionDays);
|
|
15119
|
-
const now = Date.now();
|
|
15120
|
-
let deleted = 0;
|
|
15121
|
-
let relativePaths;
|
|
15122
|
-
try {
|
|
15123
|
-
relativePaths = await fs45.readdir(dir, { recursive: true });
|
|
15124
|
-
} catch {
|
|
15125
|
-
return 0;
|
|
15126
|
-
}
|
|
15127
|
-
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
15128
|
-
for (const relativePath of relativePaths) {
|
|
15129
|
-
const fileName = path47.basename(relativePath);
|
|
15130
|
-
const m = fileName.match(re);
|
|
15131
|
-
if (!m) continue;
|
|
15132
|
-
const fileBornDay = /* @__PURE__ */ new Date(`${m[1]}T00:00:00`);
|
|
15133
|
-
if (fileBornDay >= cutoff) continue;
|
|
15134
|
-
const fullPath = path47.join(dir, relativePath);
|
|
15135
|
-
try {
|
|
15136
|
-
const st = await fs45.stat(fullPath);
|
|
15137
|
-
if (now - st.mtimeMs < ACTIVE_GRACE_MS2) continue;
|
|
15138
|
-
await fs45.unlink(fullPath);
|
|
15139
|
-
deleted += 1;
|
|
15140
|
-
} catch {
|
|
15141
|
-
}
|
|
15142
|
-
}
|
|
15143
|
-
return deleted;
|
|
15144
|
-
}
|
|
15145
|
-
async function evictOldestForSize2(targetBytes) {
|
|
15146
|
-
const dir = getTracePath();
|
|
15147
|
-
let relativePaths;
|
|
15148
|
-
try {
|
|
15149
|
-
relativePaths = await fs45.readdir(dir, { recursive: true });
|
|
15150
|
-
} catch {
|
|
15151
|
-
return 0;
|
|
15152
|
-
}
|
|
15153
|
-
const re = /^trace-(\d{4}-\d{2}-\d{2})__([\w-]+)\.jsonl$/;
|
|
15154
|
-
const candidates = [];
|
|
15155
|
-
for (const relativePath of relativePaths) {
|
|
15156
|
-
const fileName = path47.basename(relativePath);
|
|
15157
|
-
if (!re.test(fileName)) continue;
|
|
15158
|
-
try {
|
|
15159
|
-
const st = await fs45.stat(path47.join(dir, relativePath));
|
|
15160
|
-
candidates.push({ mtime: st.mtimeMs, fullPath: path47.join(dir, relativePath), size: st.size });
|
|
15161
|
-
} catch {
|
|
15162
|
-
}
|
|
15163
|
-
}
|
|
15164
|
-
candidates.sort((a, b) => a.mtime - b.mtime);
|
|
15165
|
-
let totalBytes = candidates.reduce((sum, c) => sum + c.size, 0);
|
|
15166
|
-
let deleted = 0;
|
|
15167
|
-
for (const c of candidates) {
|
|
15168
|
-
if (totalBytes <= targetBytes) break;
|
|
15169
|
-
try {
|
|
15170
|
-
await fs45.unlink(c.fullPath);
|
|
15171
|
-
totalBytes -= c.size;
|
|
15172
|
-
deleted += 1;
|
|
15173
|
-
} catch {
|
|
15174
|
-
}
|
|
15175
|
-
}
|
|
15176
|
-
if (deleted > 0) {
|
|
15177
|
-
console.warn(`\u26A0\uFE0F [Trace\u8FD0\u7EF4] \u5BB9\u91CF\u786C\u9A71\u9010\uFF1A\u8D8A\u8FC7\u6D3B\u8DC3\u4FDD\u62A4\u5F3A\u5220 ${deleted} \u4E2A\u6700\u65E7 trace \u6587\u4EF6\uFF08\u78C1\u76D8\u538B\u529B\u515C\u5E95\uFF09\u3002`);
|
|
15178
|
-
}
|
|
15179
|
-
return deleted;
|
|
15180
|
-
}
|
|
15181
|
-
var CLEANUP_INTERVAL_MS2, ACTIVE_GRACE_MS2, MAX_TRACE_FOLDER_BYTES, SIZE_RECLAIM_TARGET_RATIO2, SIZE_CLEANUP_COOLDOWN_MS2, workspaceTraceBytes, diskLastCleanupAt2, clockLoaded2, lastSizeCleanupAt2, cleanupInProgress2, ensureClockLoaded2;
|
|
15182
|
-
var init_trace = __esm({
|
|
15183
|
-
"../core/src/observability/trace.ts"() {
|
|
15184
|
-
"use strict";
|
|
15185
|
-
init_config();
|
|
15186
|
-
init_store3();
|
|
15187
|
-
init_traceCalculate();
|
|
15188
|
-
CLEANUP_INTERVAL_MS2 = 3 * 24 * 60 * 60 * 1e3;
|
|
15189
|
-
ACTIVE_GRACE_MS2 = 24 * 60 * 60 * 1e3;
|
|
15190
|
-
MAX_TRACE_FOLDER_BYTES = 50 * 1024 * 1024;
|
|
15191
|
-
SIZE_RECLAIM_TARGET_RATIO2 = 0.8;
|
|
15192
|
-
SIZE_CLEANUP_COOLDOWN_MS2 = 60 * 1e3;
|
|
15193
|
-
workspaceTraceBytes = -1;
|
|
15194
|
-
diskLastCleanupAt2 = 0;
|
|
15195
|
-
clockLoaded2 = false;
|
|
15196
|
-
lastSizeCleanupAt2 = 0;
|
|
15197
|
-
cleanupInProgress2 = false;
|
|
15198
|
-
ensureClockLoaded2 = async () => {
|
|
15199
|
-
if (clockLoaded2) return;
|
|
15200
|
-
clockLoaded2 = true;
|
|
15201
|
-
try {
|
|
15202
|
-
const rawClock = await fs45.readFile(getGlobalClockPath(), "utf-8");
|
|
15203
|
-
diskLastCleanupAt2 = JSON.parse(rawClock).lastCleanupAt || 0;
|
|
15204
|
-
} catch {
|
|
15205
|
-
diskLastCleanupAt2 = 0;
|
|
15206
|
-
}
|
|
15207
|
-
};
|
|
15208
|
-
}
|
|
15209
|
-
});
|
|
15210
|
-
|
|
15211
15373
|
// ../core/src/tool/approvalGate.ts
|
|
15212
15374
|
var approvalGate_exports = {};
|
|
15213
15375
|
__export(approvalGate_exports, {
|
|
@@ -16923,7 +17085,7 @@ var init_StreamingCursor = __esm({
|
|
|
16923
17085
|
// src/components/MessageBlock.tsx
|
|
16924
17086
|
import { Box, Text as Text3 } from "ink";
|
|
16925
17087
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
16926
|
-
var UsageFooter, listPrefix, AssistantLine,
|
|
17088
|
+
var UsageFooter, listPrefix, AssistantLine, fenceLen, isMdRow, isMdSep, mdCells, parseBlocks, fitCell, tableWidths, buildVLines, AssistantVLine, MessageBlock;
|
|
16927
17089
|
var init_MessageBlock = __esm({
|
|
16928
17090
|
"src/components/MessageBlock.tsx"() {
|
|
16929
17091
|
"use strict";
|
|
@@ -16962,7 +17124,10 @@ var init_MessageBlock = __esm({
|
|
|
16962
17124
|
}
|
|
16963
17125
|
return /* @__PURE__ */ jsx3(RichText, { text: line });
|
|
16964
17126
|
};
|
|
16965
|
-
|
|
17127
|
+
fenceLen = (l, bareOnly) => {
|
|
17128
|
+
const m = l.match(/^\s*(`{3,})([a-z0-9_-]*)\s*$/);
|
|
17129
|
+
return m && (!bareOnly || !m[2]) ? m[1].length : 0;
|
|
17130
|
+
};
|
|
16966
17131
|
isMdRow = (l) => l.includes("|");
|
|
16967
17132
|
isMdSep = (l) => /^[ \t|:-]+$/.test(l) && l.includes("-") && l.includes("|");
|
|
16968
17133
|
mdCells = (l) => l.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim());
|
|
@@ -16971,10 +17136,11 @@ var init_MessageBlock = __esm({
|
|
|
16971
17136
|
const blocks = [];
|
|
16972
17137
|
let i = 0;
|
|
16973
17138
|
while (i < src.length) {
|
|
16974
|
-
|
|
17139
|
+
const openLen = fenceLen(src[i], false);
|
|
17140
|
+
if (openLen) {
|
|
16975
17141
|
const body = [];
|
|
16976
17142
|
i++;
|
|
16977
|
-
while (i < src.length &&
|
|
17143
|
+
while (i < src.length && fenceLen(src[i], true) < openLen) body.push(src[i++]);
|
|
16978
17144
|
if (i < src.length) i++;
|
|
16979
17145
|
blocks.push({ kind: "fence", lines: body });
|
|
16980
17146
|
continue;
|