deepseeker-code 1.0.63 → 1.0.64
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 +416 -182
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1531,27 +1531,29 @@ var init_client = __esm({
|
|
|
1531
1531
|
});
|
|
1532
1532
|
|
|
1533
1533
|
// ../core/src/llm/providers/deepseek/stream.ts
|
|
1534
|
-
var STREAM_IDLE_TIMEOUT_MS, stripHistoricalReasoning, streamChat;
|
|
1534
|
+
var STREAM_IDLE_TIMEOUT_MS, isEmptyAssistantMsg, stripHistoricalReasoning, streamChat;
|
|
1535
1535
|
var init_stream = __esm({
|
|
1536
1536
|
"../core/src/llm/providers/deepseek/stream.ts"() {
|
|
1537
1537
|
"use strict";
|
|
1538
1538
|
init_client();
|
|
1539
1539
|
STREAM_IDLE_TIMEOUT_MS = Number(process.env.DEEP_SEEK_STREAM_IDLE_TIMEOUT_MS) || 12e4;
|
|
1540
|
+
isEmptyAssistantMsg = (m) => m?.role === "assistant" && !(typeof m.content === "string" && m.content.length > 0) && !(Array.isArray(m.tool_calls) && m.tool_calls.length > 0);
|
|
1540
1541
|
stripHistoricalReasoning = (messages) => {
|
|
1541
|
-
|
|
1542
|
+
const wire = messages.some(isEmptyAssistantMsg) ? messages.filter((m) => !isEmptyAssistantMsg(m)) : messages;
|
|
1543
|
+
if (process.env.DEEP_SEEK_REASONING_PASSTHROUGH === "1") return wire;
|
|
1542
1544
|
let lastNonSystem = null;
|
|
1543
|
-
for (let i =
|
|
1544
|
-
if (
|
|
1545
|
-
lastNonSystem =
|
|
1545
|
+
for (let i = wire.length - 1; i >= 0; i--) {
|
|
1546
|
+
if (wire[i]?.role !== "system") {
|
|
1547
|
+
lastNonSystem = wire[i];
|
|
1546
1548
|
break;
|
|
1547
1549
|
}
|
|
1548
1550
|
}
|
|
1549
|
-
const hasSplitToolTurn =
|
|
1550
|
-
if (lastNonSystem?.role === "assistant" || hasSplitToolTurn) return
|
|
1551
|
-
return
|
|
1552
|
-
const
|
|
1553
|
-
if (
|
|
1554
|
-
const copy = { ...
|
|
1551
|
+
const hasSplitToolTurn = wire.some((m, i) => i > 0 && m?.role === "assistant" && wire[i - 1]?.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0);
|
|
1552
|
+
if (lastNonSystem?.role === "assistant" || hasSplitToolTurn) return wire;
|
|
1553
|
+
return wire.map((m) => {
|
|
1554
|
+
const w = m;
|
|
1555
|
+
if (w?.role !== "assistant" || typeof w.reasoning_content !== "string") return m;
|
|
1556
|
+
const copy = { ...w };
|
|
1555
1557
|
delete copy.reasoning_content;
|
|
1556
1558
|
return copy;
|
|
1557
1559
|
});
|
|
@@ -2601,13 +2603,17 @@ var init_transcript = __esm({
|
|
|
2601
2603
|
console.warn(`\u26A0\uFE0F [transcript] \u6D88\u606F\u542B ${fffdCount} \u4E2A\u4E71\u7801\u5B57\u7B26\uFF08U+FFFD\uFF09\uFF0C\u5DF2\u539F\u6837\u5199\u5165\u5386\u53F2\u3002\u6765\u6E90\u53EF\u80FD\u662F GBK \u5B50\u8FDB\u7A0B\u8F93\u51FA\u6216\u4E71\u7801\u7C98\u8D34\u3002`);
|
|
2602
2604
|
}
|
|
2603
2605
|
await appendLineWithRetry(p, payload);
|
|
2606
|
+
return true;
|
|
2604
2607
|
} catch (e) {
|
|
2605
2608
|
console.warn(`\u26A0\uFE0F \u6D88\u606F\u843D\u76D8\u5931\u8D25\uFF08\u5DF2\u91CD\u8BD5 3 \u6B21\uFF0C\u5185\u5B58\u4E0E\u78C1\u76D8\u8F6C\u5F55\u53EF\u80FD\u4E0D\u4E00\u81F4\uFF09:`, e);
|
|
2609
|
+
return false;
|
|
2606
2610
|
}
|
|
2607
2611
|
};
|
|
2608
2612
|
appendMessages = async (sessionId, entries) => {
|
|
2609
|
-
if (entries.length === 0) return;
|
|
2610
|
-
if (entries.length === 1)
|
|
2613
|
+
if (entries.length === 0) return { written: 0, failed: 0 };
|
|
2614
|
+
if (entries.length === 1) {
|
|
2615
|
+
return await appendMessage(entries[0]) ? { written: 1, failed: 0 } : { written: 0, failed: 1 };
|
|
2616
|
+
}
|
|
2611
2617
|
try {
|
|
2612
2618
|
await ensureSessionsDir(sessionId);
|
|
2613
2619
|
const p = getTranscriptPath(sessionId);
|
|
@@ -2620,28 +2626,35 @@ var init_transcript = __esm({
|
|
|
2620
2626
|
if (fffdTotal > 0) console.warn(`[transcript] \u6279\u91CF\u6D88\u606F\u542B ${fffdTotal} \u4E2A\u4E71\u7801\u5B57\u7B26\uFF08U+FFFD\uFF09\uFF0C\u5DF2\u539F\u6837\u5199\u5165\u5386\u53F2\u3002\u6765\u6E90\u53EF\u80FD\u662F GBK \u5B50\u8FDB\u7A0B\u8F93\u51FA\u6216\u4E71\u7801\u7C98\u8D34\u3002`);
|
|
2621
2627
|
let handle = null;
|
|
2622
2628
|
let i = 0;
|
|
2629
|
+
let failed = 0;
|
|
2623
2630
|
try {
|
|
2624
2631
|
handle = await fs9.open(p, "a");
|
|
2625
2632
|
for (; i < payloads.length; i++) await appendLineWithRetry(p, payloads[i], handle);
|
|
2626
2633
|
} catch (e) {
|
|
2627
2634
|
console.warn(`[transcript] \u6279\u91CF\u843D\u76D8\u7B2C ${i + 1}/${payloads.length} \u6761\u5931\u8D25\uFF0C\u8BE5\u6761\u8D77\u56DE\u843D\u9010\u6761\u65E7\u8DEF\u5F84:`, e instanceof Error ? e.message : e);
|
|
2628
|
-
for (; i < entries.length; i++)
|
|
2635
|
+
for (; i < entries.length; i++) {
|
|
2636
|
+
if (!await appendMessage(entries[i])) failed++;
|
|
2637
|
+
}
|
|
2629
2638
|
} finally {
|
|
2630
2639
|
if (handle) await handle.close().catch(() => {
|
|
2631
2640
|
});
|
|
2632
2641
|
}
|
|
2642
|
+
return { written: entries.length - failed, failed };
|
|
2633
2643
|
} catch (e) {
|
|
2634
2644
|
console.warn(`\u6279\u91CF\u6D88\u606F\u843D\u76D8\u5931\u8D25\uFF08\u5185\u5B58\u4E0E\u78C1\u76D8\u8F6C\u5F55\u53EF\u80FD\u4E0D\u4E00\u81F4\uFF09:`, e);
|
|
2645
|
+
return { written: 0, failed: entries.length };
|
|
2635
2646
|
}
|
|
2636
2647
|
};
|
|
2637
2648
|
appendEvent = async (sessionId, ev) => {
|
|
2638
|
-
if (!appConfig.transcriptEvents) return;
|
|
2649
|
+
if (!appConfig.transcriptEvents) return true;
|
|
2639
2650
|
try {
|
|
2640
2651
|
await ensureSessionsDir(sessionId);
|
|
2641
2652
|
const line = { id: createUUID(), ts: (/* @__PURE__ */ new Date()).toISOString(), ...ev };
|
|
2642
2653
|
await appendLineWithRetry(getTranscriptPath(sessionId), JSON.stringify(line) + "\n");
|
|
2654
|
+
return true;
|
|
2643
2655
|
} catch (e) {
|
|
2644
2656
|
console.warn(`\u26A0\uFE0F [transcript] \u4E8B\u4EF6\u884C\u843D\u76D8\u5931\u8D25\uFF08${ev.dscEvent}\uFF0C\u6062\u590D/\u5206\u53C9\u5C06\u56DE\u9000\u542F\u53D1\u5F0F\uFF09:`, e);
|
|
2657
|
+
return false;
|
|
2645
2658
|
}
|
|
2646
2659
|
};
|
|
2647
2660
|
}
|
|
@@ -2667,8 +2680,8 @@ var init_recovery = __esm({
|
|
|
2667
2680
|
if (!sawEvents || !lastStart) return { kind: "legacy" };
|
|
2668
2681
|
return closed.has(lastStart.runId) ? { kind: "clean" } : { kind: "crashed", runId: lastStart.runId };
|
|
2669
2682
|
};
|
|
2670
|
-
repairOrphanToolCalls = (msgs,
|
|
2671
|
-
const placeholder =
|
|
2683
|
+
repairOrphanToolCalls = (msgs, confirmedUnclosed) => {
|
|
2684
|
+
const placeholder = confirmedUnclosed ? "\uFF08\u4E0A\u6B21\u4F1A\u8BDD\u7684\u8FD9\u6B21\u5DE5\u5177\u8C03\u7528\u672A\u5B8C\u6210\uFF08run \u672A\u95ED\u5408\uFF09\uFF0C\u5DF2\u8DF3\u8FC7\u3002\uFF09" : "\uFF08\u8BE5\u5DE5\u5177\u8C03\u7528\u56E0\u4E0A\u6B21\u4F1A\u8BDD\u5F02\u5E38\u4E2D\u65AD\u672A\u7559\u4E0B\u7ED3\u679C\uFF0C\u5DF2\u8DF3\u8FC7\u3002\uFF09";
|
|
2672
2685
|
const out = [];
|
|
2673
2686
|
const repairedToolCallIds = [];
|
|
2674
2687
|
for (let i = 0; i < msgs.length; i++) {
|
|
@@ -2689,7 +2702,7 @@ var init_recovery = __esm({
|
|
|
2689
2702
|
}
|
|
2690
2703
|
}
|
|
2691
2704
|
}
|
|
2692
|
-
return { msgs: out, repairedToolCallIds,
|
|
2705
|
+
return { msgs: out, repairedToolCallIds, confirmedUnclosed };
|
|
2693
2706
|
};
|
|
2694
2707
|
reconcileCompaction = (state, lines) => {
|
|
2695
2708
|
let last;
|
|
@@ -2713,9 +2726,9 @@ var init_recovery = __esm({
|
|
|
2713
2726
|
await appendEvent(sessionId, {
|
|
2714
2727
|
dscEvent: "run.abandoned",
|
|
2715
2728
|
runId: interruption.runId,
|
|
2716
|
-
reason: "
|
|
2729
|
+
reason: "unclosed (cause unknown)"
|
|
2717
2730
|
});
|
|
2718
|
-
console.warn(`\u27E6recovery\u27E7 \u68C0\u6D4B\u5230\u672A\u95ED\u5408 run\uFF08${interruption.runId.slice(0, 8)}\u2026\uFF09\u2192 \u5DF2\u8865 run.abandoned \u95ED\u5893\u6807\u8BB0\uFF1B\u5B64\u513F\u4FEE\u590D\u6309\u300C\
|
|
2731
|
+
console.warn(`\u27E6recovery\u27E7 \u68C0\u6D4B\u5230\u672A\u95ED\u5408 run\uFF08${interruption.runId.slice(0, 8)}\u2026\uFF09\u2192 \u5DF2\u8865 run.abandoned \u95ED\u5893\u6807\u8BB0\uFF1B\u5B64\u513F\u4FEE\u590D\u6309\u300C\u672A\u95ED\u5408\u300D\u6863\u6267\u884C\u3002`);
|
|
2719
2732
|
}
|
|
2720
2733
|
const state = precomputed?.state ?? await getRollingState(sessionId);
|
|
2721
2734
|
const compaction = reconcileCompaction(
|
|
@@ -3545,19 +3558,63 @@ ${lines}
|
|
|
3545
3558
|
const hitRate = event.lastRealPromptTokens && event.lastCachedTokens != null && event.lastRealPromptTokens > 0 ? event.lastCachedTokens / event.lastRealPromptTokens : null;
|
|
3546
3559
|
const cacheFactor = hitRate == null ? 1 : Math.min(1.1, Math.max(0.9, 0.9 + hitRate * 0.2));
|
|
3547
3560
|
const effectiveRatio = Math.min(event.compactRatio * cacheFactor, 0.82);
|
|
3548
|
-
|
|
3561
|
+
const thresholdAtCheck = Math.round(event.modelWindow * effectiveRatio);
|
|
3562
|
+
const reportCheck = (decision, decayed2) => {
|
|
3563
|
+
event.onWindowCheck?.({
|
|
3564
|
+
estReal: Math.round(estReal(event.messageArr)),
|
|
3565
|
+
threshold: thresholdAtCheck,
|
|
3566
|
+
correctionRatio,
|
|
3567
|
+
toolsTokens,
|
|
3568
|
+
hitRate,
|
|
3569
|
+
cacheFactor,
|
|
3570
|
+
decision,
|
|
3571
|
+
...decayed2 === void 0 ? {} : { decayed: decayed2 }
|
|
3572
|
+
});
|
|
3573
|
+
};
|
|
3574
|
+
const estRealAtTrigger = Math.round(estReal(event.messageArr));
|
|
3575
|
+
const emitCheckEvent = (decision) => {
|
|
3576
|
+
event.events({
|
|
3577
|
+
sessionId: event.sessionId,
|
|
3578
|
+
eventType: "context.check",
|
|
3579
|
+
metadata: {
|
|
3580
|
+
depth: event.depth,
|
|
3581
|
+
decisionSource: "summary",
|
|
3582
|
+
ok: true,
|
|
3583
|
+
estReal: estRealAtTrigger,
|
|
3584
|
+
thresholdAtSend: thresholdAtCheck,
|
|
3585
|
+
correctionRatioUsed: correctionRatio,
|
|
3586
|
+
hitRateAtCheck: hitRate,
|
|
3587
|
+
cacheFactorAtCheck: cacheFactor,
|
|
3588
|
+
windowDecision: decision
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
};
|
|
3592
|
+
if (!event.forceCompact && estReal(event.messageArr) <= event.modelWindow * effectiveRatio) {
|
|
3593
|
+
reportCheck("noop");
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3549
3596
|
const preDecaySize = estReal(event.messageArr);
|
|
3550
3597
|
const decayedArr = decayOldToolResults(event.messageArr);
|
|
3551
|
-
|
|
3598
|
+
const decayed = decayedArr !== event.messageArr;
|
|
3599
|
+
if (decayed) {
|
|
3552
3600
|
event.messageArr.length = 0;
|
|
3553
3601
|
event.messageArr.push(...decayedArr);
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3602
|
+
event.events({
|
|
3603
|
+
sessionId: event.sessionId,
|
|
3604
|
+
eventType: "context.decay",
|
|
3605
|
+
metadata: {
|
|
3606
|
+
depth: event.depth,
|
|
3607
|
+
decisionSource: "summary",
|
|
3608
|
+
ok: true,
|
|
3609
|
+
decayTokensBefore: Math.round(preDecaySize),
|
|
3610
|
+
decayTokensAfter: Math.round(estReal(event.messageArr))
|
|
3611
|
+
}
|
|
3612
|
+
});
|
|
3558
3613
|
}
|
|
3559
3614
|
const tokensThreshold = Math.round(event.modelWindow * effectiveRatio);
|
|
3615
|
+
let preCompactSent = false;
|
|
3560
3616
|
await dispatch("PreCompact", { sessionId: event.sessionId, depth: event.depth, tokensBefore: Math.round(estReal(event.messageArr)), tokensThreshold });
|
|
3617
|
+
preCompactSent = true;
|
|
3561
3618
|
const systemMsg = event.messageArr[0];
|
|
3562
3619
|
const summaryMsg = event.messageArr[1];
|
|
3563
3620
|
let keep = event.keepRecentUnits;
|
|
@@ -3565,102 +3622,113 @@ ${lines}
|
|
|
3565
3622
|
const preCompactSize = Math.round(lastSize);
|
|
3566
3623
|
const startTime = performance.now();
|
|
3567
3624
|
let round = 0;
|
|
3568
|
-
let
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3625
|
+
let compactDecision = "noop";
|
|
3626
|
+
let forcedPass = event.forceCompact === true || decayed;
|
|
3627
|
+
try {
|
|
3628
|
+
while (forcedPass || lastSize > event.modelWindow * effectiveRatio) {
|
|
3629
|
+
forcedPass = false;
|
|
3630
|
+
if (event.signal?.aborted) {
|
|
3631
|
+
return;
|
|
3632
|
+
}
|
|
3633
|
+
;
|
|
3634
|
+
const active = event.messageArr.slice(2);
|
|
3635
|
+
const { toCompact, keepRecent } = splitUntils(active, keep);
|
|
3636
|
+
try {
|
|
3637
|
+
if (toCompact.length > 0) {
|
|
3638
|
+
summaryMsg.content = mergeSummarySlot(summaryMsg?.content || "", "", extractArchiveEntities(toCompact));
|
|
3639
|
+
const batches = splitIntoBatches(toCompact);
|
|
3640
|
+
summaryMsg.content = batches.length === 1 ? await synthesizeSlotNarrativeFromBatch(summaryMsg.content, batches[0], event.signal, event.onAuxUsage) : await synthesizeSlotNarrative(summaryMsg.content, await compactBatches(batches, event.signal, event.depth === 0 ? event.onUIEvent : void 0, event.onAuxUsage), event.signal, event.onAuxUsage);
|
|
3641
|
+
const slotNotes = parseSummarySlot(typeof summaryMsg?.content === "string" ? summaryMsg.content : "").notes;
|
|
3642
|
+
if (estimateTokens([{ role: summaryMsg?.role ?? "system", content: slotNotes }]) > SUMMARY_SELF_COMPACT_THRESHOLD) {
|
|
3643
|
+
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal, event.onAuxUsage);
|
|
3644
|
+
}
|
|
3645
|
+
const endTime = performance.now();
|
|
3646
|
+
event.messageArr.length = 0;
|
|
3647
|
+
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
3648
|
+
event.events({
|
|
3649
|
+
sessionId: event.sessionId,
|
|
3650
|
+
eventType: "session.summary",
|
|
3651
|
+
metadata: {
|
|
3652
|
+
depth: event.depth,
|
|
3653
|
+
decisionSource: "summary",
|
|
3654
|
+
ok: true,
|
|
3655
|
+
durationMs: endTime - startTime,
|
|
3656
|
+
round: round++
|
|
3657
|
+
},
|
|
3658
|
+
usage: {
|
|
3659
|
+
prompt_tokens: lastSize,
|
|
3660
|
+
compress_tokens: estReal(event.messageArr)
|
|
3661
|
+
}
|
|
3662
|
+
});
|
|
3663
|
+
const store = await getRollingState(event.sessionId);
|
|
3664
|
+
store.archivedMessageCount = (store.archivedMessageCount || 0) + toCompact.length;
|
|
3665
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
3666
|
+
compactDecision = "compact";
|
|
3667
|
+
} else if (keep > 1) {
|
|
3668
|
+
keep--;
|
|
3669
|
+
continue;
|
|
3670
|
+
} else if (summaryMsg?.content) {
|
|
3583
3671
|
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal, event.onAuxUsage);
|
|
3672
|
+
compactDecision = "selfCompact";
|
|
3673
|
+
event.messageArr.length = 0;
|
|
3674
|
+
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
3675
|
+
const store = await getRollingState(event.sessionId);
|
|
3676
|
+
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
3677
|
+
} else {
|
|
3678
|
+
break;
|
|
3584
3679
|
}
|
|
3680
|
+
} catch (error) {
|
|
3681
|
+
if (event.signal?.aborted) return;
|
|
3682
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
3683
|
+
console.warn("\u26A0\uFE0F \u672C\u8F6E\u538B\u7F29\u5931\u8D25\uFF0C\u8DF3\u8FC7:", err.message);
|
|
3684
|
+
const store = await getRollingState(event.sessionId);
|
|
3685
|
+
const nextFailures = (store.consecutiveFailures || 0) + 1;
|
|
3686
|
+
await setRollingState(event.sessionId, {
|
|
3687
|
+
archivedMessageCount: store.archivedMessageCount || 0,
|
|
3688
|
+
rollingSummary: summaryMsg?.content || "",
|
|
3689
|
+
consecutiveFailures: nextFailures
|
|
3690
|
+
// 👈 同步落盘
|
|
3691
|
+
});
|
|
3585
3692
|
const endTime = performance.now();
|
|
3586
|
-
event.messageArr.length = 0;
|
|
3587
|
-
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
3588
3693
|
event.events({
|
|
3589
3694
|
sessionId: event.sessionId,
|
|
3695
|
+
parentId: event.depth > 0 ? event.sessionId : "",
|
|
3590
3696
|
eventType: "session.summary",
|
|
3591
3697
|
metadata: {
|
|
3592
3698
|
depth: event.depth,
|
|
3699
|
+
messageId: summaryMsg?.id ?? "(rolling-summary-slot)",
|
|
3593
3700
|
decisionSource: "summary",
|
|
3594
|
-
ok:
|
|
3701
|
+
ok: false,
|
|
3595
3702
|
durationMs: endTime - startTime,
|
|
3596
|
-
|
|
3703
|
+
attempt: nextFailures
|
|
3597
3704
|
},
|
|
3598
3705
|
usage: {
|
|
3599
3706
|
prompt_tokens: lastSize,
|
|
3600
|
-
compress_tokens:
|
|
3707
|
+
compress_tokens: estimateTokens(event.messageArr)
|
|
3708
|
+
},
|
|
3709
|
+
payload: {
|
|
3710
|
+
output: err.message
|
|
3601
3711
|
}
|
|
3602
3712
|
});
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
continue;
|
|
3609
|
-
} else if (summaryMsg?.content) {
|
|
3610
|
-
summaryMsg.content = await compactSlotNarrative(summaryMsg.content, event.modelWindow, event.signal, event.onAuxUsage);
|
|
3611
|
-
event.messageArr.length = 0;
|
|
3612
|
-
event.messageArr.push(systemMsg, summaryMsg, ...keepRecent);
|
|
3613
|
-
const store = await getRollingState(event.sessionId);
|
|
3614
|
-
await persistCompaction(event.sessionId, store.archivedMessageCount, summaryMsg.content);
|
|
3615
|
-
} else {
|
|
3713
|
+
if (nextFailures >= 3) {
|
|
3714
|
+
throw new Error(
|
|
3715
|
+
`\u274C [\u538B\u7F29\u7194\u65AD] \u4E0A\u4E0B\u6587\u538B\u7F29\u8FDE\u7EED ${nextFailures} \u6B21\u5931\u8D25\uFF0C\u4E3A\u9632\u5929\u4EF7\u8D26\u5355\u6B7B\u5FAA\u73AF\u5DF2\u6682\u505C\u81EA\u52A8\u538B\u7F29\u3002\u5E38\u89C1\u6839\u56E0\uFF1A\u6458\u8981\u8F85\u52A9\u6A21\u578B\u670D\u52A1\u5F02\u5E38\u6216\u7F51\u7EDC\u4E0D\u901A\uFF08\u53EF\u67E5 DEEP_SEEK_AUX_MODEL \u670D\u52A1\u53EF\u7528\u6027\uFF1B\u8D85\u957F\u5DE5\u5177\u7ED3\u679C\u5DF2\u7531\u7CFB\u7EDF\u81EA\u52A8\u9884\u622A\u65AD\uFF0C\u4E00\u822C\u4E0D\u518D\u662F\u4E3B\u56E0\uFF09\u3002\u81EA\u6108\uFF1A\u76F4\u63A5\u91CD\u53D1\u6D88\u606F\u5373\u53EF\u91CD\u8BD5\uFF08\u6210\u529F\u538B\u7F29\u4E00\u6B21\u8BA1\u6570\u5373\u6E05\u96F6\uFF09\uFF1B\u6216 /fork \u5206\u53C9\u7EED\u63A5\u3001/new \u5F00\u65B0\u4F1A\u8BDD\u3002`
|
|
3716
|
+
);
|
|
3717
|
+
}
|
|
3616
3718
|
break;
|
|
3617
3719
|
}
|
|
3618
|
-
|
|
3619
|
-
if (
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
await
|
|
3625
|
-
archivedMessageCount: store.archivedMessageCount || 0,
|
|
3626
|
-
rollingSummary: summaryMsg?.content || "",
|
|
3627
|
-
consecutiveFailures: nextFailures
|
|
3628
|
-
// 👈 同步落盘
|
|
3629
|
-
});
|
|
3630
|
-
const endTime = performance.now();
|
|
3631
|
-
event.events({
|
|
3632
|
-
sessionId: event.sessionId,
|
|
3633
|
-
parentId: event.depth > 0 ? event.sessionId : "",
|
|
3634
|
-
eventType: "session.summary",
|
|
3635
|
-
metadata: {
|
|
3636
|
-
depth: event.depth,
|
|
3637
|
-
messageId: summaryMsg?.id ?? "(rolling-summary-slot)",
|
|
3638
|
-
decisionSource: "summary",
|
|
3639
|
-
ok: false,
|
|
3640
|
-
durationMs: endTime - startTime,
|
|
3641
|
-
attempt: nextFailures
|
|
3642
|
-
},
|
|
3643
|
-
usage: {
|
|
3644
|
-
prompt_tokens: lastSize,
|
|
3645
|
-
compress_tokens: estimateTokens(event.messageArr)
|
|
3646
|
-
},
|
|
3647
|
-
payload: {
|
|
3648
|
-
output: err.message
|
|
3649
|
-
}
|
|
3720
|
+
const newSize = estReal(event.messageArr);
|
|
3721
|
+
if (newSize >= lastSize) break;
|
|
3722
|
+
lastSize = newSize;
|
|
3723
|
+
}
|
|
3724
|
+
} finally {
|
|
3725
|
+
if (preCompactSent) {
|
|
3726
|
+
await dispatch("PostCompact", { sessionId: event.sessionId, depth: event.depth, tokensBefore: Math.round(lastSize), tokensAfter: Math.round(estReal(event.messageArr)) }).catch(() => {
|
|
3650
3727
|
});
|
|
3651
|
-
if (nextFailures >= 3) {
|
|
3652
|
-
throw new Error(
|
|
3653
|
-
`\u274C [\u538B\u7F29\u7194\u65AD] \u4E0A\u4E0B\u6587\u538B\u7F29\u8FDE\u7EED ${nextFailures} \u6B21\u5931\u8D25\uFF0C\u4E3A\u9632\u5929\u4EF7\u8D26\u5355\u6B7B\u5FAA\u73AF\u5DF2\u6682\u505C\u81EA\u52A8\u538B\u7F29\u3002\u5E38\u89C1\u6839\u56E0\uFF1A\u6458\u8981\u8F85\u52A9\u6A21\u578B\u670D\u52A1\u5F02\u5E38\u6216\u7F51\u7EDC\u4E0D\u901A\uFF08\u53EF\u67E5 DEEP_SEEK_AUX_MODEL \u670D\u52A1\u53EF\u7528\u6027\uFF1B\u8D85\u957F\u5DE5\u5177\u7ED3\u679C\u5DF2\u7531\u7CFB\u7EDF\u81EA\u52A8\u9884\u622A\u65AD\uFF0C\u4E00\u822C\u4E0D\u518D\u662F\u4E3B\u56E0\uFF09\u3002\u81EA\u6108\uFF1A\u76F4\u63A5\u91CD\u53D1\u6D88\u606F\u5373\u53EF\u91CD\u8BD5\uFF08\u6210\u529F\u538B\u7F29\u4E00\u6B21\u8BA1\u6570\u5373\u6E05\u96F6\uFF09\uFF1B\u6216 /fork \u5206\u53C9\u7EED\u63A5\u3001/new \u5F00\u65B0\u4F1A\u8BDD\u3002`
|
|
3654
|
-
);
|
|
3655
|
-
}
|
|
3656
|
-
break;
|
|
3657
3728
|
}
|
|
3658
|
-
const newSize = estReal(event.messageArr);
|
|
3659
|
-
if (newSize >= lastSize) break;
|
|
3660
|
-
lastSize = newSize;
|
|
3661
3729
|
}
|
|
3662
|
-
|
|
3663
|
-
|
|
3730
|
+
reportCheck(compactDecision, decayed);
|
|
3731
|
+
if (compactDecision !== "noop") emitCheckEvent(compactDecision);
|
|
3664
3732
|
if (event.onUIEvent && event.depth === 0) {
|
|
3665
3733
|
const afterSize = Math.round(estReal(event.messageArr));
|
|
3666
3734
|
if (preCompactSize - afterSize > 0) {
|
|
@@ -4242,13 +4310,19 @@ var init_inbox = __esm({
|
|
|
4242
4310
|
};
|
|
4243
4311
|
flushLeftoverToTranscript = async (sessionId) => {
|
|
4244
4312
|
const texts = claimSessionInbox(sessionId);
|
|
4313
|
+
let failed = 0;
|
|
4245
4314
|
for (const t of texts) {
|
|
4246
|
-
await appendMessage({ sessionId, role: "user", content: t });
|
|
4315
|
+
const ok = await appendMessage({ sessionId, role: "user", content: t });
|
|
4316
|
+
if (!ok) failed++;
|
|
4247
4317
|
}
|
|
4248
4318
|
if (texts.length > 0) {
|
|
4249
|
-
|
|
4319
|
+
if (failed > 0) {
|
|
4320
|
+
console.warn(`[inbox] \u4F1A\u8BDD ${sessionId} \u7ED3\u675F\u65F6 ${failed}/${texts.length} \u6761\u8865\u5145\u8F93\u5165\u843D\u76D8\u5931\u8D25\uFF08transcript \u4FA7\u6545\u969C\uFF0C\u4E0B\u8F6E\u65E0\u6CD5\u5E26\u5165\uFF09`);
|
|
4321
|
+
} else {
|
|
4322
|
+
console.warn(`[inbox] \u4F1A\u8BDD ${sessionId} \u7ED3\u675F\u65F6 ${texts.length} \u6761\u8865\u5145\u8F93\u5165\u672A\u8BA4\u9886\uFF0C\u5DF2\u5199\u5165 transcript\uFF08\u4E0B\u8F6E\u81EA\u52A8\u5E26\u5165\uFF09`);
|
|
4323
|
+
}
|
|
4250
4324
|
}
|
|
4251
|
-
return texts.length;
|
|
4325
|
+
return { flushed: texts.length - failed, failed };
|
|
4252
4326
|
};
|
|
4253
4327
|
}
|
|
4254
4328
|
});
|
|
@@ -6134,7 +6208,7 @@ var init_registry6 = __esm({
|
|
|
6134
6208
|
});
|
|
6135
6209
|
|
|
6136
6210
|
// ../core/src/memory/inject.ts
|
|
6137
|
-
var MEMORY_FENCE, MEMORY_MARKER, injectMemory;
|
|
6211
|
+
var MEMORY_FENCE, MEMORY_MARKER, memorySnapshots, injectMemory, clearMemorySnapshot;
|
|
6138
6212
|
var init_inject5 = __esm({
|
|
6139
6213
|
"../core/src/memory/inject.ts"() {
|
|
6140
6214
|
"use strict";
|
|
@@ -6142,12 +6216,24 @@ var init_inject5 = __esm({
|
|
|
6142
6216
|
init_registry6();
|
|
6143
6217
|
MEMORY_FENCE = "\u27E6DSC:MEMORY\u27E7";
|
|
6144
6218
|
MEMORY_MARKER = "\u3010\u8BB0\u5FC6\u7D22\u5F15\u3011";
|
|
6145
|
-
|
|
6146
|
-
|
|
6219
|
+
memorySnapshots = /* @__PURE__ */ new Map();
|
|
6220
|
+
injectMemory = (message, sessionId) => {
|
|
6221
|
+
let index;
|
|
6222
|
+
if (sessionId === void 0) {
|
|
6223
|
+
index = getMemoryIndex();
|
|
6224
|
+
} else {
|
|
6225
|
+
if (!memorySnapshots.has(sessionId)) {
|
|
6226
|
+
memorySnapshots.set(sessionId, getMemoryIndex());
|
|
6227
|
+
}
|
|
6228
|
+
index = memorySnapshots.get(sessionId) ?? null;
|
|
6229
|
+
}
|
|
6147
6230
|
if (!index) return;
|
|
6148
6231
|
injectMarkedBlock(message, MEMORY_FENCE, `${MEMORY_MARKER}
|
|
6149
6232
|
${index}`);
|
|
6150
6233
|
};
|
|
6234
|
+
clearMemorySnapshot = (sessionId) => {
|
|
6235
|
+
memorySnapshots.delete(sessionId);
|
|
6236
|
+
};
|
|
6151
6237
|
}
|
|
6152
6238
|
});
|
|
6153
6239
|
|
|
@@ -6226,7 +6312,7 @@ var init_systemInjections = __esm({
|
|
|
6226
6312
|
injectSkillCatalog(message);
|
|
6227
6313
|
injectAgentCatalog(message);
|
|
6228
6314
|
injectProjectGuide(message);
|
|
6229
|
-
injectMemory(message);
|
|
6315
|
+
injectMemory(message, options.sessionId);
|
|
6230
6316
|
return { rawTools, cleanedToolSchemas, toolsTokens };
|
|
6231
6317
|
};
|
|
6232
6318
|
}
|
|
@@ -12866,13 +12952,21 @@ var init_toolScheduling = __esm({
|
|
|
12866
12952
|
scheduleToolCalls = async function* (assistantMessage, message, ctx) {
|
|
12867
12953
|
const { sessionId, signal, rawTools } = ctx;
|
|
12868
12954
|
let abortedDuringTools = false;
|
|
12955
|
+
const degraded = [];
|
|
12956
|
+
const markDegraded = (name) => {
|
|
12957
|
+
if (!degraded.includes(name)) degraded.push(name);
|
|
12958
|
+
};
|
|
12959
|
+
const noteWrite = (ok, name) => {
|
|
12960
|
+
if (!ok) markDegraded(name);
|
|
12961
|
+
};
|
|
12962
|
+
const degradedField = () => degraded.length > 0 ? { degraded: [...degraded] } : {};
|
|
12869
12963
|
const pendingImages = [];
|
|
12870
12964
|
const fillRestPlaceholders = async (fromIdx) => {
|
|
12871
12965
|
const tcs2 = assistantMessage.tool_calls;
|
|
12872
12966
|
for (let j = fromIdx + 1; j < tcs2.length; j++) {
|
|
12873
12967
|
const ph = "\uFF08\u5DF2\u8DF3\u8FC7\uFF1A\u7EC8\u7ED3\u7C7B\u5DE5\u5177\u4E4B\u540E\u7684\u5E76\u884C\u8C03\u7528\u672A\u6267\u884C\uFF09";
|
|
12874
12968
|
message.push({ role: "tool", tool_call_id: tcs2[j].id, content: ph });
|
|
12875
|
-
await appendMessage({ sessionId, role: "tool", tool_call_id: tcs2[j].id, content: ph });
|
|
12969
|
+
noteWrite(await appendMessage({ sessionId, role: "tool", tool_call_id: tcs2[j].id, content: ph }), "appendMessage(placeholder)");
|
|
12876
12970
|
}
|
|
12877
12971
|
};
|
|
12878
12972
|
const parallelSafeToolsEnabled = appConfig.parallelSafeTools;
|
|
@@ -12911,7 +13005,7 @@ var init_toolScheduling = __esm({
|
|
|
12911
13005
|
for (let j = idx; j < tcs.length; j++) {
|
|
12912
13006
|
const ph = "\uFF08\u5DF2\u4E2D\u6B62\uFF0C\u672A\u6267\u884C\uFF09";
|
|
12913
13007
|
message.push({ role: "tool", tool_call_id: tcs[j].id, content: ph });
|
|
12914
|
-
await appendMessage({ sessionId, role: "tool", tool_call_id: tcs[j].id, content: ph });
|
|
13008
|
+
noteWrite(await appendMessage({ sessionId, role: "tool", tool_call_id: tcs[j].id, content: ph }), "appendMessage(placeholder)");
|
|
12915
13009
|
}
|
|
12916
13010
|
break;
|
|
12917
13011
|
}
|
|
@@ -12957,7 +13051,8 @@ var init_toolScheduling = __esm({
|
|
|
12957
13051
|
if (oc.imageAttachments?.length) pendingImages.push(...oc.imageAttachments);
|
|
12958
13052
|
if (oc.aborted) abortedDuringTools = true;
|
|
12959
13053
|
}
|
|
12960
|
-
await appendMessages(sessionId, batchEntries);
|
|
13054
|
+
const batchWrite = await appendMessages(sessionId, batchEntries);
|
|
13055
|
+
if (batchWrite.failed > 0) markDegraded("appendMessages(tool-results)");
|
|
12961
13056
|
if (budget) {
|
|
12962
13057
|
try {
|
|
12963
13058
|
const tokensAfter = estimateTokens(message);
|
|
@@ -12991,22 +13086,22 @@ var init_toolScheduling = __esm({
|
|
|
12991
13086
|
const oc = await processToolCall(tc, ctx);
|
|
12992
13087
|
if (oc.terminal) {
|
|
12993
13088
|
message.push({ role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel });
|
|
12994
|
-
await appendMessage({ sessionId, role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel });
|
|
13089
|
+
noteWrite(await appendMessage({ sessionId, role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel }), "appendMessage(tool-result)");
|
|
12995
13090
|
await fillRestPlaceholders(idx);
|
|
12996
13091
|
yield { type: "tool.end", toolCallId: oc.toolCallId, toolName: oc.calledName, result: oc.resultForUser, ok: oc.ok };
|
|
12997
13092
|
if (oc.terminal.kind === "exit_plan_mode") {
|
|
12998
13093
|
yield { type: "plan.proposed", plan: oc.terminal.plan || "" };
|
|
12999
|
-
return { kind: "terminal", terminalText: oc.terminal.plan || oc.resultForUser };
|
|
13094
|
+
return { kind: "terminal", terminalText: oc.terminal.plan || oc.resultForUser, ...degradedField() };
|
|
13000
13095
|
} else if (oc.terminal.kind === "enter_plan_mode") {
|
|
13001
13096
|
yield { type: "plan.enterRequested", reason: oc.terminal.reason || "" };
|
|
13002
|
-
return { kind: "terminal", terminalText: oc.terminal.reason ? `\u{1F4CB} \u6A21\u578B\u8BF7\u6C42\u8FDB\u5165\u8BA1\u5212\u6A21\u5F0F\uFF1A${oc.terminal.reason}` : oc.resultForUser };
|
|
13097
|
+
return { kind: "terminal", terminalText: oc.terminal.reason ? `\u{1F4CB} \u6A21\u578B\u8BF7\u6C42\u8FDB\u5165\u8BA1\u5212\u6A21\u5F0F\uFF1A${oc.terminal.reason}` : oc.resultForUser, ...degradedField() };
|
|
13003
13098
|
} else {
|
|
13004
|
-
return { kind: "terminal", terminalText: oc.resultForUser };
|
|
13099
|
+
return { kind: "terminal", terminalText: oc.resultForUser, ...degradedField() };
|
|
13005
13100
|
}
|
|
13006
13101
|
}
|
|
13007
13102
|
yield { type: "tool.end", toolCallId: oc.toolCallId, toolName: oc.calledName, result: oc.resultForUser, ok: oc.ok };
|
|
13008
13103
|
message.push({ role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel });
|
|
13009
|
-
await appendMessage({ sessionId, role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel });
|
|
13104
|
+
noteWrite(await appendMessage({ sessionId, role: "tool", tool_call_id: oc.toolCallId, content: oc.resultForModel }), "appendMessage(tool-result)");
|
|
13010
13105
|
if (oc.imageAttachments?.length) pendingImages.push(...oc.imageAttachments);
|
|
13011
13106
|
if (oc.aborted) abortedDuringTools = true;
|
|
13012
13107
|
idx++;
|
|
@@ -13015,17 +13110,17 @@ var init_toolScheduling = __esm({
|
|
|
13015
13110
|
if (!abortedDuringTools && pendingImages.length > 0) {
|
|
13016
13111
|
const parts = buildImageFollowUpParts(pendingImages);
|
|
13017
13112
|
message.push({ role: "user", content: parts });
|
|
13018
|
-
await appendMessage({ sessionId, role: "user", content: parts });
|
|
13113
|
+
noteWrite(await appendMessage({ sessionId, role: "user", content: parts }), "appendMessage(image-followup)");
|
|
13019
13114
|
}
|
|
13020
|
-
if (abortedDuringTools) return { kind: "aborted" };
|
|
13021
|
-
return { kind: "completed" };
|
|
13115
|
+
if (abortedDuringTools) return { kind: "aborted", ...degradedField() };
|
|
13116
|
+
return { kind: "completed", ...degradedField() };
|
|
13022
13117
|
};
|
|
13023
13118
|
}
|
|
13024
13119
|
});
|
|
13025
13120
|
|
|
13026
13121
|
// ../core/src/agent/streamInference.ts
|
|
13027
13122
|
import { createHash as createHash2 } from "node:crypto";
|
|
13028
|
-
var sha1short, toolsFingerprintCache, RETRY_BACKOFF_CAP_MS, extractRetryAfterMs, withNudgeTail, streamInference;
|
|
13123
|
+
var sha1short, toolsFingerprintCache, buildPrefixFingerprint, RETRY_BACKOFF_CAP_MS, extractRetryAfterMs, withNudgeTail, streamInference;
|
|
13029
13124
|
var init_streamInference = __esm({
|
|
13030
13125
|
"../core/src/agent/streamInference.ts"() {
|
|
13031
13126
|
"use strict";
|
|
@@ -13038,6 +13133,19 @@ var init_streamInference = __esm({
|
|
|
13038
13133
|
init_createModel();
|
|
13039
13134
|
sha1short = (s) => createHash2("sha1").update(s).digest("hex").slice(0, 10);
|
|
13040
13135
|
toolsFingerprintCache = /* @__PURE__ */ new WeakMap();
|
|
13136
|
+
buildPrefixFingerprint = (message, cleanedToolSchemas) => ({
|
|
13137
|
+
toolsHash: (() => {
|
|
13138
|
+
let h = toolsFingerprintCache.get(cleanedToolSchemas);
|
|
13139
|
+
if (h === void 0) {
|
|
13140
|
+
h = sha1short(JSON.stringify(cleanedToolSchemas));
|
|
13141
|
+
toolsFingerprintCache.set(cleanedToolSchemas, h);
|
|
13142
|
+
}
|
|
13143
|
+
return h;
|
|
13144
|
+
})(),
|
|
13145
|
+
sysHash: sha1short(String(message[0]?.content ?? "")),
|
|
13146
|
+
sumHash: sha1short(String(message[1]?.content ?? "")),
|
|
13147
|
+
msgCount: message.length
|
|
13148
|
+
});
|
|
13041
13149
|
RETRY_BACKOFF_CAP_MS = 3e4;
|
|
13042
13150
|
extractRetryAfterMs = (e) => {
|
|
13043
13151
|
try {
|
|
@@ -13081,28 +13189,32 @@ var init_streamInference = __esm({
|
|
|
13081
13189
|
keepRecentUnits,
|
|
13082
13190
|
compactRatio,
|
|
13083
13191
|
modelWindow,
|
|
13084
|
-
toolsTokens = 0
|
|
13192
|
+
toolsTokens = 0,
|
|
13193
|
+
windowCheck
|
|
13085
13194
|
} = ctx;
|
|
13086
13195
|
let inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
13087
13196
|
let assistantMessage = { role: "assistant", content: null };
|
|
13088
13197
|
try {
|
|
13089
|
-
const prefixFingerprint =
|
|
13090
|
-
|
|
13091
|
-
let h = toolsFingerprintCache.get(cleanedToolSchemas);
|
|
13092
|
-
if (h === void 0) {
|
|
13093
|
-
h = sha1short(JSON.stringify(cleanedToolSchemas));
|
|
13094
|
-
toolsFingerprintCache.set(cleanedToolSchemas, h);
|
|
13095
|
-
}
|
|
13096
|
-
return h;
|
|
13097
|
-
})(),
|
|
13098
|
-
sysHash: sha1short(String(message[0]?.content ?? "")),
|
|
13099
|
-
sumHash: sha1short(String(message[1]?.content ?? "")),
|
|
13100
|
-
msgCount: message.length
|
|
13101
|
-
};
|
|
13198
|
+
const prefixFingerprint = buildPrefixFingerprint(message, cleanedToolSchemas);
|
|
13199
|
+
const wc = windowCheck;
|
|
13102
13200
|
events({
|
|
13103
13201
|
sessionId,
|
|
13104
13202
|
eventType: "llm.request",
|
|
13105
|
-
metadata: {
|
|
13203
|
+
metadata: {
|
|
13204
|
+
depth,
|
|
13205
|
+
decisionSource: userDecisionSource,
|
|
13206
|
+
ok: true,
|
|
13207
|
+
durationMs: performance.now() - startTime,
|
|
13208
|
+
round,
|
|
13209
|
+
model,
|
|
13210
|
+
...prefixFingerprint,
|
|
13211
|
+
...wc ? {
|
|
13212
|
+
estReal: wc.estReal,
|
|
13213
|
+
thresholdAtSend: wc.threshold,
|
|
13214
|
+
correctionRatioUsed: wc.correctionRatio,
|
|
13215
|
+
windowDecision: wc.decision
|
|
13216
|
+
} : {}
|
|
13217
|
+
},
|
|
13106
13218
|
// ★ P2 口径:估算加上工具 schema 常数项(与 API 真实 prompt_tokens 同口径,trace 里 est/real 才可比)
|
|
13107
13219
|
usage: { prompt_tokens: estimateTokens(inferenceMessages) + toolsTokens },
|
|
13108
13220
|
payload: { input: msgText(message[message.length - 1].content) }
|
|
@@ -13150,6 +13262,16 @@ var init_streamInference = __esm({
|
|
|
13150
13262
|
break;
|
|
13151
13263
|
}
|
|
13152
13264
|
}
|
|
13265
|
+
if (!signal?.aborted && !contentBuf && toolCallsBuf.size === 0 && !lastUsage && idleRetries < MAX_STREAM_RETRIES) {
|
|
13266
|
+
idleRetries++;
|
|
13267
|
+
if (reasoningBuf) yield { type: "text.reset" };
|
|
13268
|
+
console.warn(`\u26A0\uFE0F \u6D41\u7A7A\u7ED3\u675F\uFF080 \u5185\u5BB9 0 usage\uFF0C\u7591\u4F3C\u670D\u52A1\u7AEF\u65AD\u6D41\uFF09\uFF0C\u7B2C ${idleRetries}/${MAX_STREAM_RETRIES} \u6B21\u91CD\u8BD5...`);
|
|
13269
|
+
contentBuf = "";
|
|
13270
|
+
reasoningBuf = "";
|
|
13271
|
+
toolCallsBuf.clear();
|
|
13272
|
+
lastUsage = void 0;
|
|
13273
|
+
continue;
|
|
13274
|
+
}
|
|
13153
13275
|
break;
|
|
13154
13276
|
} catch (streamErr) {
|
|
13155
13277
|
if (signal?.aborted) throw streamErr;
|
|
@@ -13219,6 +13341,19 @@ var init_streamInference = __esm({
|
|
|
13219
13341
|
onUIEvent: ctx.onUIEvent,
|
|
13220
13342
|
onAuxUsage: ctx.onAuxUsage
|
|
13221
13343
|
});
|
|
13344
|
+
events({
|
|
13345
|
+
sessionId,
|
|
13346
|
+
eventType: "llm.contextDowngraded",
|
|
13347
|
+
metadata: {
|
|
13348
|
+
depth,
|
|
13349
|
+
decisionSource: llmDecisionSource,
|
|
13350
|
+
ok: true,
|
|
13351
|
+
round,
|
|
13352
|
+
model,
|
|
13353
|
+
estReal: estimateTokens(withNudgeTail(message, nudgeMsg)) + (toolsTokens ?? 0)
|
|
13354
|
+
},
|
|
13355
|
+
payload: { output: streamErr instanceof Error ? streamErr.message : String(streamErr) }
|
|
13356
|
+
});
|
|
13222
13357
|
inferenceMessages = withNudgeTail(message, nudgeMsg);
|
|
13223
13358
|
compactedThisRound = true;
|
|
13224
13359
|
contentBuf = "";
|
|
@@ -13266,7 +13401,17 @@ var init_streamInference = __esm({
|
|
|
13266
13401
|
events({
|
|
13267
13402
|
sessionId,
|
|
13268
13403
|
eventType: "llm.response",
|
|
13269
|
-
|
|
13404
|
+
// ★ emptyStream 标记:0 内容 0 usage 的退化完成(重试耗尽仍空)——修复前该形态记 ok:true
|
|
13405
|
+
// 无任何异常痕迹(0d245bd0 取证时 trace 里完全看不出 round 13 是空流),此处如实回报。
|
|
13406
|
+
metadata: {
|
|
13407
|
+
depth,
|
|
13408
|
+
decisionSource: llmDecisionSource,
|
|
13409
|
+
ok: true,
|
|
13410
|
+
durationMs: performance.now() - startTime,
|
|
13411
|
+
round,
|
|
13412
|
+
model,
|
|
13413
|
+
...!contentBuf && toolCallsBuf.size === 0 && !lastUsage ? { emptyStream: true } : {}
|
|
13414
|
+
},
|
|
13270
13415
|
usage: {
|
|
13271
13416
|
prompt_tokens: lastUsage?.prompt_tokens,
|
|
13272
13417
|
completion_tokens: lastUsage?.completion_tokens,
|
|
@@ -13745,7 +13890,7 @@ var init_usageLog = __esm({
|
|
|
13745
13890
|
ensuredDir = null;
|
|
13746
13891
|
getUsageLogPath = (month) => path37.join(usageDir(), `usage-${month}.jsonl`);
|
|
13747
13892
|
recordUsageRun = async (rec) => {
|
|
13748
|
-
if (USAGE_DISABLED) return;
|
|
13893
|
+
if (USAGE_DISABLED) return true;
|
|
13749
13894
|
try {
|
|
13750
13895
|
const full = { workspace: appConfig.userWorkspaceDir, ...rec };
|
|
13751
13896
|
const month = (full.ts || (/* @__PURE__ */ new Date()).toISOString()).slice(0, 7);
|
|
@@ -13755,8 +13900,10 @@ var init_usageLog = __esm({
|
|
|
13755
13900
|
ensuredDir = dir;
|
|
13756
13901
|
}
|
|
13757
13902
|
await fs34.appendFile(getUsageLogPath(month), JSON.stringify(full) + "\n", "utf-8");
|
|
13903
|
+
return true;
|
|
13758
13904
|
} catch (e) {
|
|
13759
13905
|
console.warn("\u26A0\uFE0F [usageLog] \u4F7F\u7528\u65E5\u5FD7\u843D\u76D8\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u4E3B\u4E1A\u52A1\uFF09:", e instanceof Error ? e.message : e);
|
|
13906
|
+
return false;
|
|
13760
13907
|
}
|
|
13761
13908
|
};
|
|
13762
13909
|
USAGE_FILE_RE = /^usage-\d{4}-\d{2}\.jsonl$/;
|
|
@@ -14034,7 +14181,7 @@ async function evictOldestForSize2(targetBytes) {
|
|
|
14034
14181
|
}
|
|
14035
14182
|
return deleted;
|
|
14036
14183
|
}
|
|
14037
|
-
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;
|
|
14184
|
+
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, droppedBatches, traceTimers, cleanupTriggerCount, needImmediateFlush, scheduleTraceTimer, flushChains, runSerialized, flushTraceBuffer, ensureClockLoaded2, tracePayloadMaxChars, truncateTracePayload;
|
|
14038
14185
|
var init_trace = __esm({
|
|
14039
14186
|
"../core/src/observability/trace.ts"() {
|
|
14040
14187
|
"use strict";
|
|
@@ -14054,6 +14201,7 @@ var init_trace = __esm({
|
|
|
14054
14201
|
TRACE_BATCH_LINES = 50;
|
|
14055
14202
|
TRACE_BATCH_MS = 200;
|
|
14056
14203
|
traceBuf = /* @__PURE__ */ new Map();
|
|
14204
|
+
droppedBatches = /* @__PURE__ */ new Map();
|
|
14057
14205
|
traceTimers = /* @__PURE__ */ new Map();
|
|
14058
14206
|
cleanupTriggerCount = 0;
|
|
14059
14207
|
needImmediateFlush = (ev) => ev.metadata?.ok === false || ev.eventType === "user.aborted" || ev.eventType === "tool.repeat_break" || ev.eventType === "session.end";
|
|
@@ -14066,34 +14214,55 @@ var init_trace = __esm({
|
|
|
14066
14214
|
t.unref?.();
|
|
14067
14215
|
traceTimers.set(sessionId, t);
|
|
14068
14216
|
};
|
|
14217
|
+
flushChains = /* @__PURE__ */ new Map();
|
|
14218
|
+
runSerialized = (id, fn) => {
|
|
14219
|
+
const prev = flushChains.get(id) ?? Promise.resolve();
|
|
14220
|
+
const next = prev.then(fn, fn);
|
|
14221
|
+
flushChains.set(id, next.catch(() => void 0));
|
|
14222
|
+
return next;
|
|
14223
|
+
};
|
|
14069
14224
|
flushTraceBuffer = async (sessionId) => {
|
|
14070
|
-
const
|
|
14225
|
+
const reportSticky = sessionId === void 0;
|
|
14226
|
+
const ids = sessionId !== void 0 ? [sessionId] : [.../* @__PURE__ */ new Set([...traceBuf.keys(), ...droppedBatches.keys()])];
|
|
14227
|
+
let failedSessions = 0;
|
|
14071
14228
|
for (const id of ids) {
|
|
14072
|
-
const
|
|
14073
|
-
|
|
14074
|
-
|
|
14075
|
-
|
|
14076
|
-
|
|
14077
|
-
traceBuf.set(id, []);
|
|
14078
|
-
const timer = traceTimers.get(id);
|
|
14079
|
-
if (timer) {
|
|
14080
|
-
clearTimeout(timer);
|
|
14081
|
-
traceTimers.delete(id);
|
|
14082
|
-
}
|
|
14083
|
-
try {
|
|
14084
|
-
const joined = arr.join("");
|
|
14085
|
-
const p = await getTraceStorePath(id);
|
|
14086
|
-
await fs36.appendFile(p, joined, "utf-8");
|
|
14087
|
-
if (workspaceTraceBytes < 0) {
|
|
14088
|
-
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
14229
|
+
const degraded = await runSerialized(id, async () => {
|
|
14230
|
+
let bad = false;
|
|
14231
|
+
if (reportSticky && droppedBatches.has(id)) {
|
|
14232
|
+
droppedBatches.delete(id);
|
|
14233
|
+
bad = true;
|
|
14089
14234
|
}
|
|
14090
|
-
|
|
14091
|
-
|
|
14092
|
-
|
|
14093
|
-
|
|
14094
|
-
|
|
14095
|
-
|
|
14235
|
+
const arr = traceBuf.get(id);
|
|
14236
|
+
if (!arr || arr.length === 0) {
|
|
14237
|
+
traceBuf.delete(id);
|
|
14238
|
+
return bad;
|
|
14239
|
+
}
|
|
14240
|
+
traceBuf.set(id, []);
|
|
14241
|
+
const timer = traceTimers.get(id);
|
|
14242
|
+
if (timer) {
|
|
14243
|
+
clearTimeout(timer);
|
|
14244
|
+
traceTimers.delete(id);
|
|
14245
|
+
}
|
|
14246
|
+
try {
|
|
14247
|
+
const joined = arr.join("");
|
|
14248
|
+
const p = await getTraceStorePath(id);
|
|
14249
|
+
await fs36.appendFile(p, joined, "utf-8");
|
|
14250
|
+
if (workspaceTraceBytes < 0) {
|
|
14251
|
+
workspaceTraceBytes = await getDirBytes(getTracePath());
|
|
14252
|
+
}
|
|
14253
|
+
workspaceTraceBytes += Buffer.byteLength(joined, "utf-8");
|
|
14254
|
+
cleanupTriggerCount++;
|
|
14255
|
+
void maybeCleanupAfterAppend(id);
|
|
14256
|
+
} catch (error) {
|
|
14257
|
+
bad = true;
|
|
14258
|
+
if (!reportSticky) droppedBatches.set(id, (droppedBatches.get(id) ?? 0) + 1);
|
|
14259
|
+
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);
|
|
14260
|
+
}
|
|
14261
|
+
return bad;
|
|
14262
|
+
});
|
|
14263
|
+
if (degraded) failedSessions++;
|
|
14096
14264
|
}
|
|
14265
|
+
return failedSessions;
|
|
14097
14266
|
};
|
|
14098
14267
|
ensureClockLoaded2 = async () => {
|
|
14099
14268
|
if (clockLoaded2) return;
|
|
@@ -14180,7 +14349,16 @@ async function* runAgent(message, options) {
|
|
|
14180
14349
|
const inheritedBudgetCheck = options.budgetCheck ?? (depth === 0 ? ledger.overHardLimit : void 0);
|
|
14181
14350
|
let planWriteRej = 0;
|
|
14182
14351
|
const toolCounts = {};
|
|
14183
|
-
|
|
14352
|
+
const degraded = [];
|
|
14353
|
+
const markDegraded = (name) => {
|
|
14354
|
+
if (!degraded.includes(name)) degraded.push(name);
|
|
14355
|
+
};
|
|
14356
|
+
try {
|
|
14357
|
+
const ok = await appendEvent(sessionId, { dscEvent: "run.start", runId, depth });
|
|
14358
|
+
if (!ok) markDegraded("appendEvent(run.start)");
|
|
14359
|
+
} catch {
|
|
14360
|
+
markDegraded("appendEvent(run.start)");
|
|
14361
|
+
}
|
|
14184
14362
|
try {
|
|
14185
14363
|
while (true) {
|
|
14186
14364
|
round++;
|
|
@@ -14227,11 +14405,17 @@ async function* runAgent(message, options) {
|
|
|
14227
14405
|
clearQueuedWake(sessionId);
|
|
14228
14406
|
for (const t of inboxTexts) {
|
|
14229
14407
|
message.push({ role: "user", content: t });
|
|
14230
|
-
|
|
14408
|
+
try {
|
|
14409
|
+
const ok = await appendMessage({ sessionId, role: "user", content: t });
|
|
14410
|
+
if (!ok) markDegraded("appendMessage(user)");
|
|
14411
|
+
} catch {
|
|
14412
|
+
markDegraded("appendMessage(user)");
|
|
14413
|
+
}
|
|
14231
14414
|
}
|
|
14232
14415
|
yield { type: "inbox.claimed", texts: inboxTexts };
|
|
14233
14416
|
}
|
|
14234
14417
|
yield { type: "round.start", round };
|
|
14418
|
+
let lastWindowCheck;
|
|
14235
14419
|
try {
|
|
14236
14420
|
await ensureFitsWindow(
|
|
14237
14421
|
{
|
|
@@ -14253,6 +14437,10 @@ async function* runAgent(message, options) {
|
|
|
14253
14437
|
onUIEvent: (evt) => {
|
|
14254
14438
|
if (evt.type === "compact.done") runCompactCount++;
|
|
14255
14439
|
options.onUIEvent?.(evt);
|
|
14440
|
+
},
|
|
14441
|
+
// ★ M1:判定快照出口(含 noop;抛异常路径不回调——那轮推理本就不发生)
|
|
14442
|
+
onWindowCheck: (check) => {
|
|
14443
|
+
lastWindowCheck = check;
|
|
14256
14444
|
}
|
|
14257
14445
|
}
|
|
14258
14446
|
);
|
|
@@ -14288,7 +14476,8 @@ async function* runAgent(message, options) {
|
|
|
14288
14476
|
modelWindow,
|
|
14289
14477
|
toolsTokens,
|
|
14290
14478
|
onUIEvent: options.onUIEvent,
|
|
14291
|
-
onAuxUsage: reportAuxUsage
|
|
14479
|
+
onAuxUsage: reportAuxUsage,
|
|
14480
|
+
windowCheck: lastWindowCheck
|
|
14292
14481
|
});
|
|
14293
14482
|
if (infResult.kind === "aborted") {
|
|
14294
14483
|
yield { type: "final", text: infResult.partialText || lastContent || "\uFF08\u5DF2\u4E2D\u6B62\uFF09" };
|
|
@@ -14310,13 +14499,28 @@ async function* runAgent(message, options) {
|
|
|
14310
14499
|
}
|
|
14311
14500
|
ledger.addUsage(infResult.usage);
|
|
14312
14501
|
const assistantMessage = infResult.assistantMessage;
|
|
14313
|
-
|
|
14314
|
-
|
|
14315
|
-
|
|
14316
|
-
|
|
14502
|
+
const emptyAssistant = !(typeof assistantMessage.content === "string" && assistantMessage.content.length > 0) && !(Array.isArray(assistantMessage.tool_calls) && assistantMessage.tool_calls.length > 0);
|
|
14503
|
+
if (emptyAssistant) {
|
|
14504
|
+
markDegraded("emptyAssistantSkip");
|
|
14505
|
+
} else {
|
|
14506
|
+
message.push(assistantMessage);
|
|
14507
|
+
try {
|
|
14508
|
+
const ok = await appendMessage({ ...assistantMessage, sessionId });
|
|
14509
|
+
if (!ok) markDegraded("appendMessage(assistant)");
|
|
14510
|
+
} catch {
|
|
14511
|
+
markDegraded("appendMessage(assistant)");
|
|
14512
|
+
}
|
|
14513
|
+
if (typeof assistantMessage.content === "string" && assistantMessage.content) {
|
|
14514
|
+
lastContent = assistantMessage.content;
|
|
14515
|
+
}
|
|
14317
14516
|
}
|
|
14318
14517
|
if (!assistantMessage.tool_calls || assistantMessage.tool_calls.length === 0) {
|
|
14319
|
-
|
|
14518
|
+
try {
|
|
14519
|
+
const ok = await appendEvent(sessionId, { dscEvent: "round.end", runId, round, usage: infResult.usage });
|
|
14520
|
+
if (!ok) markDegraded("appendEvent(round.end)");
|
|
14521
|
+
} catch {
|
|
14522
|
+
markDegraded("appendEvent(round.end)");
|
|
14523
|
+
}
|
|
14320
14524
|
emitContextUsage();
|
|
14321
14525
|
ledger.flushRelay();
|
|
14322
14526
|
const finalText = (typeof assistantMessage.content === "string" ? assistantMessage.content : "") || "";
|
|
@@ -14337,7 +14541,12 @@ async function* runAgent(message, options) {
|
|
|
14337
14541
|
const ph = "\uFF08\u91CD\u590D\u8C03\u7528\u7194\u65AD\uFF0C\u672A\u6267\u884C\uFF09";
|
|
14338
14542
|
message.push({ role: "tool", tool_call_id: tc.id, content: ph });
|
|
14339
14543
|
}
|
|
14340
|
-
|
|
14544
|
+
try {
|
|
14545
|
+
const phWrite = await appendMessages(sessionId, assistantMessage.tool_calls.map((tc) => ({ sessionId, role: "tool", tool_call_id: tc.id, content: "\uFF08\u91CD\u590D\u8C03\u7528\u7194\u65AD\uFF0C\u672A\u6267\u884C\uFF09" })));
|
|
14546
|
+
if (phWrite.failed > 0) markDegraded("appendMessages(repeat-placeholder)");
|
|
14547
|
+
} catch {
|
|
14548
|
+
markDegraded("appendMessages(repeat-placeholder)");
|
|
14549
|
+
}
|
|
14341
14550
|
yield { type: "final", text: repeatVerdict.text };
|
|
14342
14551
|
return;
|
|
14343
14552
|
}
|
|
@@ -14388,6 +14597,7 @@ async function* runAgent(message, options) {
|
|
|
14388
14597
|
batchBudgetChars: void 0
|
|
14389
14598
|
};
|
|
14390
14599
|
const scheduleResult = yield* scheduleToolCalls(assistantMessage, message, toolCallCtx);
|
|
14600
|
+
if (scheduleResult.degraded) for (const name of scheduleResult.degraded) markDegraded(name);
|
|
14391
14601
|
if (scheduleResult.kind === "aborted") {
|
|
14392
14602
|
yield { type: "final", text: lastContent || "\uFF08\u5DF2\u4E2D\u6B62\uFF09" };
|
|
14393
14603
|
return;
|
|
@@ -14396,7 +14606,12 @@ async function* runAgent(message, options) {
|
|
|
14396
14606
|
yield { type: "final", text: scheduleResult.terminalText };
|
|
14397
14607
|
return;
|
|
14398
14608
|
}
|
|
14399
|
-
|
|
14609
|
+
try {
|
|
14610
|
+
const ok = await appendEvent(sessionId, { dscEvent: "round.end", runId, round, usage: infResult.usage });
|
|
14611
|
+
if (!ok) markDegraded("appendEvent(round.end)");
|
|
14612
|
+
} catch {
|
|
14613
|
+
markDegraded("appendEvent(round.end)");
|
|
14614
|
+
}
|
|
14400
14615
|
emitContextUsage();
|
|
14401
14616
|
ledger.flushRelay();
|
|
14402
14617
|
if (options.planMode && planWriteRej >= PLAN_REJECT_FORCE_AT) {
|
|
@@ -14418,20 +14633,26 @@ async function* runAgent(message, options) {
|
|
|
14418
14633
|
return;
|
|
14419
14634
|
} finally {
|
|
14420
14635
|
try {
|
|
14421
|
-
await flushLeftoverToTranscript(sessionId);
|
|
14636
|
+
const flushResult = await flushLeftoverToTranscript(sessionId);
|
|
14637
|
+
if (flushResult.failed > 0) markDegraded("flushLeftoverToTranscript");
|
|
14422
14638
|
} catch {
|
|
14639
|
+
markDegraded("flushLeftoverToTranscript");
|
|
14423
14640
|
}
|
|
14424
14641
|
try {
|
|
14425
|
-
await appendEvent(sessionId, { dscEvent: "run.end", runId, stopReason: signal?.aborted ? "aborted" : stopReason, rounds: round, usage: ledger.usageSummary() });
|
|
14642
|
+
const ok = await appendEvent(sessionId, { dscEvent: "run.end", runId, stopReason: signal?.aborted ? "aborted" : stopReason, rounds: round, usage: ledger.usageSummary() });
|
|
14643
|
+
if (!ok) markDegraded("appendEvent(run.end)");
|
|
14426
14644
|
} catch {
|
|
14645
|
+
markDegraded("appendEvent(run.end)");
|
|
14427
14646
|
}
|
|
14428
14647
|
try {
|
|
14429
|
-
await flushTraceBuffer();
|
|
14648
|
+
const failedSessions = await flushTraceBuffer();
|
|
14649
|
+
if (failedSessions > 0) markDegraded("flushTraceBuffer");
|
|
14430
14650
|
} catch {
|
|
14651
|
+
markDegraded("flushTraceBuffer");
|
|
14431
14652
|
}
|
|
14432
14653
|
try {
|
|
14433
14654
|
const us = ledger.usageSummary();
|
|
14434
|
-
|
|
14655
|
+
const ok = await recordUsageRun({
|
|
14435
14656
|
v: 1,
|
|
14436
14657
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14437
14658
|
sessionId,
|
|
@@ -14449,11 +14670,20 @@ async function* runAgent(message, options) {
|
|
|
14449
14670
|
// costYuan/toolCostYuan/auxCostYuan(口径与舍入在 runLedger)
|
|
14450
14671
|
tools: toolCounts
|
|
14451
14672
|
});
|
|
14673
|
+
if (!ok) markDegraded("recordUsageRun");
|
|
14452
14674
|
} catch {
|
|
14675
|
+
markDegraded("recordUsageRun");
|
|
14453
14676
|
}
|
|
14454
14677
|
try {
|
|
14455
14678
|
ledger.flushRelay();
|
|
14456
14679
|
} catch {
|
|
14680
|
+
markDegraded("ledger.flushRelay");
|
|
14681
|
+
}
|
|
14682
|
+
try {
|
|
14683
|
+
await updateCalibration(sessionId, effectiveModel, { calibRatio, lastRealPromptTokens, lastCachedTokens });
|
|
14684
|
+
} catch (e) {
|
|
14685
|
+
markDegraded("updateCalibration");
|
|
14686
|
+
console.warn("\u26A0\uFE0F \u538B\u7F29\u6821\u51C6\u72B6\u6001\u843D\u76D8\u5931\u8D25\uFF08\u4E0B run \u6821\u51C6\u91CD\u96F6\uFF0C\u7F13\u5B58\u611F\u77E5\u538B\u7F29\u9000\u5316\u56DE\u7F3A\u7701 1.4\uFF09:", e instanceof Error ? e.message : e);
|
|
14457
14687
|
}
|
|
14458
14688
|
try {
|
|
14459
14689
|
const us = ledger.usageSummary();
|
|
@@ -14469,22 +14699,24 @@ async function* runAgent(message, options) {
|
|
|
14469
14699
|
...ledger.receiptFields(),
|
|
14470
14700
|
// costYuan(null=无价)/toolCostYuan/auxCostYuan/subCostYuan(口径与舍入在 runLedger)
|
|
14471
14701
|
durationMs: Math.round(performance.now() - startTime),
|
|
14472
|
-
budgetTruncated: budgetTruncated || void 0
|
|
14702
|
+
budgetTruncated: budgetTruncated || void 0,
|
|
14473
14703
|
// 预算截断标注(E2;undefined 自动省略)
|
|
14704
|
+
degraded: degraded.length > 0 ? [...degraded] : void 0
|
|
14705
|
+
// D5:结算单发出前已降级的旁路快照(边界=updateCalibration 之后、Stop hook 之前;undefined 自动省略)
|
|
14474
14706
|
});
|
|
14475
14707
|
}
|
|
14476
14708
|
} catch {
|
|
14709
|
+
markDegraded("run.receipt");
|
|
14477
14710
|
}
|
|
14478
14711
|
try {
|
|
14479
14712
|
const reason = signal?.aborted ? "aborted" : stopReason;
|
|
14480
14713
|
await dispatch("Stop", { sessionId, cwd, lastText: lastContent || "", reason });
|
|
14481
14714
|
} catch (e) {
|
|
14715
|
+
markDegraded("Stop-hook");
|
|
14482
14716
|
console.warn("\u26A0\uFE0F Stop hook \u5916\u5C42\u515C\u5E95\uFF08dispatch \u5185\u90E8\u5BB9\u9519\u5931\u6548\uFF0C\u5C5E\u5F02\u5E38\u4FE1\u53F7\uFF09:", e instanceof Error ? e.message : e);
|
|
14483
14717
|
}
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
} catch (e) {
|
|
14487
|
-
console.warn("\u26A0\uFE0F \u538B\u7F29\u6821\u51C6\u72B6\u6001\u843D\u76D8\u5931\u8D25\uFF08\u4E0B run \u6821\u51C6\u91CD\u96F6\uFF0C\u7F13\u5B58\u611F\u77E5\u538B\u7F29\u9000\u5316\u56DE\u7F3A\u7701 1.4\uFF09:", e instanceof Error ? e.message : e);
|
|
14718
|
+
if (degraded.length > 0) {
|
|
14719
|
+
console.warn(`\u26A0\uFE0F [run \u964D\u7EA7] ${degraded.length} \u9879\uFF08\u4E0D\u5F71\u54CD\u4E3B\u6D41\u7A0B\uFF1B\u5177\u4F53\u540E\u679C\u89C1\u7EC4\u4EF6\u540D\uFF09: ${degraded.join(", ")}`);
|
|
14488
14720
|
}
|
|
14489
14721
|
}
|
|
14490
14722
|
}
|
|
@@ -15862,6 +16094,7 @@ var init_chatProcessing = __esm({
|
|
|
15862
16094
|
init_systemPrompt();
|
|
15863
16095
|
init_model();
|
|
15864
16096
|
init_agentWake();
|
|
16097
|
+
init_inject5();
|
|
15865
16098
|
handleUnifiedChat = async (inbound, sendOutbound, sseWrite, abortSignal, opts) => {
|
|
15866
16099
|
let busyKey = typeof inbound.sessionId === "string" && inbound.sessionId ? inbound.sessionId : "";
|
|
15867
16100
|
markRunStart(busyKey);
|
|
@@ -16029,6 +16262,7 @@ ${envLines.join("\n")}`;
|
|
|
16029
16262
|
}
|
|
16030
16263
|
await dispatch("SessionEnd", { sessionId, cwd: process.cwd() }).catch(() => {
|
|
16031
16264
|
});
|
|
16265
|
+
clearMemorySnapshot(sessionId);
|
|
16032
16266
|
await emitTrace({
|
|
16033
16267
|
sessionId,
|
|
16034
16268
|
eventType: "session.end",
|