nolo-cli 0.67.0 → 0.68.0-alpha.1
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/{_executeModel-C5K4UL5I.js → _executeModel-XCNYHC6S.js} +13 -13
- package/{agentDeleteCommand-7RESZDRC.js → agentDeleteCommand-Z3DTLQEG.js} +5 -5
- package/{agentEmailCommands-KES5FG2E.js → agentEmailCommands-DFK2MIXR.js} +14 -14
- package/{agentListCommands-VFBLREFU.js → agentListCommands-FSX7RY7U.js} +5 -5
- package/{agentMachineCommands-UJ77TKWZ.js → agentMachineCommands-FYPV45TJ.js} +6 -6
- package/{agentRecordCommands-MZBPYUGL.js → agentRecordCommands-SXOCVBX7.js} +14 -14
- package/{agentRunCommand-R3RWG53B.js → agentRunCommand-XISX4ICI.js} +14 -14
- package/{agentRuntimeLocal-BD7R3OJL.js → agentRuntimeLocal-2ENB2B2Z.js} +5 -5
- package/{agentSlice-UP66DIC2.js → agentSlice-QLZWET7H.js} +1 -1
- package/{appDeleteCommands-X3UF4ZHF.js → appDeleteCommands-XKAUWKUI.js} +5 -5
- package/{appDeployCommands-MFHLJIYZ.js → appDeployCommands-SNXZY5IX.js} +5 -5
- package/{appDeployStatusCommands-BGXSUHY6.js → appDeployStatusCommands-NXUJ6LXS.js} +5 -5
- package/{appGetCommands-KEA6FZTF.js → appGetCommands-DNRYKGOK.js} +5 -5
- package/{appListCommands-CZGMZW3L.js → appListCommands-URESGUKU.js} +5 -5
- package/{chatQueueReduxAdapter-VVXE2NXW.js → chatQueueReduxAdapter-FNXZNIAT.js} +4 -4
- package/{chunk-HQ3ZLBSI.js → chunk-2XENHR3P.js} +96 -0
- package/{chunk-TDTSQVDX.js → chunk-3E67YXGD.js} +85 -88
- package/{chunk-RCNQCXPM.js → chunk-5JTJG4OG.js} +115 -121
- package/{chunk-MN2XJEWL.js → chunk-7NG5APVZ.js} +16 -133
- package/{chunk-UZXOOSHF.js → chunk-AUA5DTWI.js} +15 -14
- package/{chunk-HPRMNGAM.js → chunk-IX6H4NKR.js} +1 -1
- package/{chunk-UBWLW3KY.js → chunk-IY2BLZKO.js} +3 -3
- package/{chunk-5DUAG5G7.js → chunk-K4326DRU.js} +202 -11729
- package/{chunk-AVJQ4TDL.js → chunk-K5YS7FAN.js} +1 -1
- package/{chunk-TTTW4DIT.js → chunk-LNOW66U4.js} +6 -6
- package/{chunk-NFTTUZ3L.js → chunk-LTLZPAO7.js} +1 -1
- package/{chunk-QPXRNDI3.js → chunk-MIN5X7GI.js} +2 -2
- package/{chunk-OHJWIXXW.js → chunk-RLZ6HZSX.js} +3 -3
- package/{chunk-BG7ZGBKH.js → chunk-SM4ED2LZ.js} +4 -4
- package/{chunk-FPT2E44F.js → chunk-VHADFQCI.js} +2 -2
- package/{chunk-UNAVSDC5.js → chunk-XHNOCBUU.js} +4 -2
- package/chunk-XNO3T6RB.js +18504 -0
- package/chunk-Z6S2JBE4.js +2471 -0
- package/{chunk-M3HN7RBV.js → chunk-ZCVO2HLZ.js} +1 -1
- package/{contentThunks-BHML6O7K.js → contentThunks-6K4RZXKH.js} +5 -5
- package/{createAgentAutomationAction-K5YJO4IA.js → createAgentAutomationAction-6XYIZ3GS.js} +5 -5
- package/{createDialogAction-SFMZLPS4.js → createDialogAction-TJWDXAKL.js} +6 -6
- package/{createPageAction-UD7BSFQS.js → createPageAction-EZ2LPB6K.js} +5 -5
- package/{dialogCommands-2ABSL4ND.js → dialogCommands-ULXMRIAM.js} +5 -5
- package/{dialogSlice-DEC5GV6X.js → dialogSlice-5DRM6AQQ.js} +4 -4
- package/{docCreateCommands-2QZCW4HZ.js → docCreateCommands-PPHO6KUM.js} +5 -5
- package/{docDeleteCommands-WKZKQAKM.js → docDeleteCommands-U2GVGQPR.js} +5 -5
- package/{docReadCommands-WMKJCR4Q.js → docReadCommands-CYY3DJXY.js} +5 -5
- package/{docStore-IBPCRTTX.js → docStore-OJXM46BB.js} +1 -1
- package/{docUpdateCommands-KPLM63NK.js → docUpdateCommands-B5UVFLJU.js} +5 -5
- package/{handleSendMessageAction-C7CZNGMB.js → handleSendMessageAction-EWY3J2AV.js} +4 -4
- package/index.js +41 -41
- package/{machineCommands-6BG3AHT5.js → machineCommands-B76BYAJF.js} +14 -14
- package/{machineWsRunDispatch-G2KJ6NQF.js → machineWsRunDispatch-LN6274EL.js} +14 -14
- package/package.json +1 -1
- package/{readlineWorkspace-5LZ3EDIQ.js → readlineWorkspace-UFHEJIDS.js} +77 -18
- package/{runAgentClientLoop-CICP3O2T.js → runAgentClientLoop-MAER6Y5K.js} +11 -11
- package/{spaceCommands-NQOIERT6.js → spaceCommands-2YT7C56D.js} +5 -5
- package/{streamAgentChatTurn-QUD4FY5I.js → streamAgentChatTurn-AKUDQL5W.js} +14 -14
- package/{tools-MAP6O2YZ.js → tools-NM36O7ZG.js} +8 -8
- package/{tuiSummaryLlmCaller-VL5RDGLT.js → tuiSummaryLlmCaller-ZGATEM35.js} +2 -2
- package/{updateDialogTitleAction-L6CCRVUK.js → updateDialogTitleAction-RHH353JB.js} +5 -5
- package/chunk-CLZYOOI3.js +0 -4463
- package/chunk-IF6UQNAK.js +0 -5062
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
readSseFrames,
|
|
9
9
|
streamSseDataValues,
|
|
10
10
|
throwIfChatCompletionStreamFailed
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZCVO2HLZ.js";
|
|
12
12
|
import {
|
|
13
13
|
clipToolText,
|
|
14
14
|
hasImageInRuntimeMessages,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
requiresBareImageUrl,
|
|
40
40
|
resolveToolGuidedSections,
|
|
41
41
|
toBareImageUrlMessages
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-K5YS7FAN.js";
|
|
43
43
|
import {
|
|
44
44
|
convertMessagesToResponsesInput,
|
|
45
45
|
extractReasoningFromResponseOutput,
|
|
@@ -80,16 +80,16 @@ import {
|
|
|
80
80
|
EMPTY_ASSISTANT_REPAIR_PROMPT,
|
|
81
81
|
getModelContextWindow,
|
|
82
82
|
hasAssistantVisibleOutput,
|
|
83
|
+
normalizeUsage,
|
|
83
84
|
readCacheCreationInputTokens,
|
|
84
85
|
readCacheReadInputTokens,
|
|
85
86
|
resolveEmptyAssistantFallbackMessage,
|
|
86
87
|
resolveEmptyAssistantOutcome,
|
|
87
88
|
resolveTruncatedReasoningTailLog
|
|
88
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-2XENHR3P.js";
|
|
89
90
|
import {
|
|
90
91
|
COMPACTION_SUMMARY_SCHEMA_VERSION,
|
|
91
92
|
COMPACTION_SUMMARY_SYSTEM_PROMPT,
|
|
92
|
-
TOOL_STUB_TEXT,
|
|
93
93
|
buildCompactionMetricsFromPlan,
|
|
94
94
|
buildCompactionUserContent,
|
|
95
95
|
clipCompactText,
|
|
@@ -102,8 +102,10 @@ import {
|
|
|
102
102
|
observeMeaningfulProviderResponse,
|
|
103
103
|
planCompression,
|
|
104
104
|
planContextUsage,
|
|
105
|
+
resolveCompressionTriggerRatio,
|
|
106
|
+
truncateToolOutputForContext,
|
|
105
107
|
withProviderCallTimingFields
|
|
106
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-3E67YXGD.js";
|
|
107
109
|
import {
|
|
108
110
|
estimateTokenCount
|
|
109
111
|
} from "./chunk-PSCNXBYA.js";
|
|
@@ -12404,35 +12406,10 @@ function projectHistoryWithSummary(args2) {
|
|
|
12404
12406
|
const found = bridged.findIndex((m) => m.id === args2.summarizedBeforeId);
|
|
12405
12407
|
if (found !== -1) startIndex = found + 1;
|
|
12406
12408
|
}
|
|
12407
|
-
|
|
12408
|
-
if (args2.stubbedBeforeId) {
|
|
12409
|
-
const found = bridged.findIndex((m) => m.id === args2.stubbedBeforeId);
|
|
12410
|
-
if (found !== -1) stubEndIndex = found;
|
|
12411
|
-
}
|
|
12412
|
-
const projected = args2.history.slice(startIndex).map((message, i) => {
|
|
12413
|
-
const absIndex = startIndex + i;
|
|
12414
|
-
if (stubEndIndex !== -1 && message.role === "tool" && absIndex <= stubEndIndex) {
|
|
12415
|
-
const content = typeof message.content === "string" ? TOOL_STUB_TEXT : Array.isArray(message.content) ? [{ type: "text", text: TOOL_STUB_TEXT }] : TOOL_STUB_TEXT;
|
|
12416
|
-
return { ...message, content };
|
|
12417
|
-
}
|
|
12418
|
-
return message;
|
|
12419
|
-
});
|
|
12409
|
+
const projected = args2.history.slice(startIndex);
|
|
12420
12410
|
const summaryMsg = args2.summary.trim().length > 0 ? [buildLocalSummaryHistoryMessage(args2.summary)] : [];
|
|
12421
12411
|
return [...summaryMsg, ...projected];
|
|
12422
12412
|
}
|
|
12423
|
-
function applyStoredStubToHistory(history, stubbedBeforeId) {
|
|
12424
|
-
if (!stubbedBeforeId) return history;
|
|
12425
|
-
const bridged = toPlanCompressionMessages(history);
|
|
12426
|
-
const stubEndIndex = bridged.findIndex((m) => m.id === stubbedBeforeId);
|
|
12427
|
-
if (stubEndIndex === -1) return history;
|
|
12428
|
-
return history.map((message, i) => {
|
|
12429
|
-
if (i <= stubEndIndex && message.role === "tool") {
|
|
12430
|
-
const content = typeof message.content === "string" ? TOOL_STUB_TEXT : Array.isArray(message.content) ? [{ type: "text", text: TOOL_STUB_TEXT }] : TOOL_STUB_TEXT;
|
|
12431
|
-
return { ...message, content };
|
|
12432
|
-
}
|
|
12433
|
-
return message;
|
|
12434
|
-
});
|
|
12435
|
-
}
|
|
12436
12413
|
var COLD_RESUME_IDLE_MS = 60 * 60 * 1e3;
|
|
12437
12414
|
function isColdResume(history, nowMs) {
|
|
12438
12415
|
for (let i = history.length - 1; i >= 0; i -= 1) {
|
|
@@ -12482,31 +12459,24 @@ async function maybeAutoCompactLocalHistory(args2) {
|
|
|
12482
12459
|
}
|
|
12483
12460
|
const existingSummary = typeof stored?.summary === "string" ? stored.summary : "";
|
|
12484
12461
|
const summarizedBeforeId = typeof stored?.summarizedBeforeId === "string" ? stored.summarizedBeforeId : void 0;
|
|
12485
|
-
const storedStubbedBeforeId = typeof stored?.stubbedBeforeId === "string" && stored.stubbedBeforeId ? stored.stubbedBeforeId : void 0;
|
|
12486
12462
|
const contextWindow = typeof args2.contextWindow === "number" && Number.isFinite(args2.contextWindow) && args2.contextWindow > 0 ? args2.contextWindow : getModelContextWindow(args2.model ?? "");
|
|
12487
|
-
const allMsgs = toPlanCompressionMessages(
|
|
12488
|
-
applyStoredStubToHistory(history, storedStubbedBeforeId)
|
|
12489
|
-
);
|
|
12463
|
+
const allMsgs = toPlanCompressionMessages(history);
|
|
12490
12464
|
const coldResume = isColdResume(history, args2.now?.() ?? Date.now());
|
|
12491
12465
|
const plan = planCompression({
|
|
12492
12466
|
allMsgs,
|
|
12493
12467
|
summarizedBeforeId,
|
|
12494
12468
|
summary: existingSummary,
|
|
12495
12469
|
contextWindow,
|
|
12496
|
-
|
|
12497
|
-
// totalUsed 比 summary 本身增长超过 minNewTokens,不重复触发。
|
|
12498
|
-
lastCompactedTokenCount: existingSummary ? estimateTokenCount(existingSummary) : void 0,
|
|
12499
|
-
...coldResume ? { force: true, reason: "context_budget" } : {},
|
|
12470
|
+
...coldResume ? { coldResume: true, reason: "cold_resume" } : {},
|
|
12500
12471
|
...args2.realContextUsagePercent !== void 0 ? { realContextUsagePercent: args2.realContextUsagePercent } : {}
|
|
12501
12472
|
});
|
|
12502
12473
|
const projectExisting = () => {
|
|
12503
|
-
if (!existingSummary.trim()
|
|
12474
|
+
if (!existingSummary.trim()) return unchanged();
|
|
12504
12475
|
return {
|
|
12505
12476
|
history: projectHistoryWithSummary({
|
|
12506
12477
|
history,
|
|
12507
12478
|
summary: existingSummary,
|
|
12508
|
-
summarizedBeforeId
|
|
12509
|
-
stubbedBeforeId: storedStubbedBeforeId
|
|
12479
|
+
summarizedBeforeId
|
|
12510
12480
|
}),
|
|
12511
12481
|
compressed: true,
|
|
12512
12482
|
summaryGenerated: false
|
|
@@ -12515,49 +12485,6 @@ async function maybeAutoCompactLocalHistory(args2) {
|
|
|
12515
12485
|
if (!plan.shouldCompress) {
|
|
12516
12486
|
return projectExisting();
|
|
12517
12487
|
}
|
|
12518
|
-
if (plan.stub) {
|
|
12519
|
-
const nextStubbedBeforeId = plan.stub.beforeId;
|
|
12520
|
-
const changed = nextStubbedBeforeId !== storedStubbedBeforeId;
|
|
12521
|
-
if (changed) {
|
|
12522
|
-
try {
|
|
12523
|
-
await adapter.saveDialogSummary({
|
|
12524
|
-
dialogId,
|
|
12525
|
-
summary: existingSummary,
|
|
12526
|
-
summarizedBeforeId,
|
|
12527
|
-
stubbedBeforeId: nextStubbedBeforeId,
|
|
12528
|
-
// stub 档不改锚点切片 → 透传源校验字段保持读写对称
|
|
12529
|
-
sourceHash: stored?.sourceHash,
|
|
12530
|
-
sourceCount: stored?.sourceCount,
|
|
12531
|
-
schemaVersion: COMPACTION_SUMMARY_SCHEMA_VERSION
|
|
12532
|
-
});
|
|
12533
|
-
} catch (error) {
|
|
12534
|
-
console.warn("[localLoop] saveDialogSummary (stub) failed:", error);
|
|
12535
|
-
}
|
|
12536
|
-
}
|
|
12537
|
-
const metrics = buildCompactionMetricsFromPlan({
|
|
12538
|
-
reason: "tool_stub",
|
|
12539
|
-
previousSummary: existingSummary,
|
|
12540
|
-
plan,
|
|
12541
|
-
newSummary: existingSummary
|
|
12542
|
-
});
|
|
12543
|
-
console.log(formatCompactionMetricsLog(metrics));
|
|
12544
|
-
return {
|
|
12545
|
-
history: projectHistoryWithSummary({
|
|
12546
|
-
history,
|
|
12547
|
-
summary: existingSummary,
|
|
12548
|
-
summarizedBeforeId,
|
|
12549
|
-
stubbedBeforeId: nextStubbedBeforeId
|
|
12550
|
-
}),
|
|
12551
|
-
compressed: true,
|
|
12552
|
-
summaryGenerated: false,
|
|
12553
|
-
metrics,
|
|
12554
|
-
reason: "tool_stub",
|
|
12555
|
-
savedTokens: plan.stub.savedTokens,
|
|
12556
|
-
stubbedCount: plan.stub.stubbedCount,
|
|
12557
|
-
beforeTokens: metrics.previousSummaryTokens + metrics.compressedTokens,
|
|
12558
|
-
afterTokens: metrics.newSummaryTokens + metrics.retainedTokens
|
|
12559
|
-
};
|
|
12560
|
-
}
|
|
12561
12488
|
try {
|
|
12562
12489
|
const provider = await args2.resolveProvider();
|
|
12563
12490
|
const msgsToCompress = plan.msgsToCompress;
|
|
@@ -12580,14 +12507,15 @@ async function maybeAutoCompactLocalHistory(args2) {
|
|
|
12580
12507
|
console.warn(
|
|
12581
12508
|
"[localLoop] auto-compaction produced empty summary; keeping prior projection"
|
|
12582
12509
|
);
|
|
12583
|
-
return
|
|
12510
|
+
return {
|
|
12511
|
+
...projectExisting(),
|
|
12512
|
+
failureMessage: "summary model returned empty content"
|
|
12513
|
+
};
|
|
12584
12514
|
}
|
|
12585
12515
|
await adapter.saveDialogSummary({
|
|
12586
12516
|
dialogId,
|
|
12587
12517
|
summary: newSummary,
|
|
12588
12518
|
summarizedBeforeId: plan.newSummarizedBeforeId,
|
|
12589
|
-
// 新摘要已覆盖 stub 区间 → 清空 stubbedBeforeId
|
|
12590
|
-
stubbedBeforeId: void 0,
|
|
12591
12519
|
// 内容寻址失效检测:存锚点切片哈希与长度,供下轮载入校验。
|
|
12592
12520
|
sourceHash: hashSummarySourceSlice(history, plan.newSummarizedBeforeId),
|
|
12593
12521
|
sourceCount: (() => {
|
|
@@ -12622,7 +12550,8 @@ async function maybeAutoCompactLocalHistory(args2) {
|
|
|
12622
12550
|
};
|
|
12623
12551
|
} catch (error) {
|
|
12624
12552
|
console.warn("[localLoop] auto-compaction failed:", error);
|
|
12625
|
-
|
|
12553
|
+
const failureMessage = error instanceof Error && error.message ? error.message.slice(0, 200) : String(error).slice(0, 200);
|
|
12554
|
+
return { ...projectExisting(), failureMessage };
|
|
12626
12555
|
}
|
|
12627
12556
|
}
|
|
12628
12557
|
|
|
@@ -13572,6 +13501,7 @@ async function runLocalAgentTurn(input) {
|
|
|
13572
13501
|
throw error;
|
|
13573
13502
|
}
|
|
13574
13503
|
loopTimingMark("loadDialogHistory", 0);
|
|
13504
|
+
const canonicalHistory = history;
|
|
13575
13505
|
const identityBlock = buildIdentityBlock({
|
|
13576
13506
|
agentName: agentConfig.name,
|
|
13577
13507
|
agentId: agentConfig.key,
|
|
@@ -13609,6 +13539,8 @@ async function runLocalAgentTurn(input) {
|
|
|
13609
13539
|
}
|
|
13610
13540
|
return resolvedProvider;
|
|
13611
13541
|
};
|
|
13542
|
+
const contextWindow = getModelContextWindow(agentConfig.model ?? "");
|
|
13543
|
+
const compressionTriggerRatio = resolveCompressionTriggerRatio(contextWindow);
|
|
13612
13544
|
let realContextUsagePercent;
|
|
13613
13545
|
if (input.continueDialogId && typeof input.adapter.loadLastContextUsage === "function") {
|
|
13614
13546
|
try {
|
|
@@ -13616,7 +13548,6 @@ async function runLocalAgentTurn(input) {
|
|
|
13616
13548
|
input.continueDialogId
|
|
13617
13549
|
);
|
|
13618
13550
|
const inputTokens = usage?.inputTokens;
|
|
13619
|
-
const contextWindow = getModelContextWindow(agentConfig.model);
|
|
13620
13551
|
if (typeof inputTokens === "number" && Number.isFinite(inputTokens) && inputTokens > 0 && typeof contextWindow === "number" && Number.isFinite(contextWindow) && contextWindow > 0) {
|
|
13621
13552
|
realContextUsagePercent = Math.min(
|
|
13622
13553
|
1,
|
|
@@ -13628,6 +13559,21 @@ async function runLocalAgentTurn(input) {
|
|
|
13628
13559
|
}
|
|
13629
13560
|
}
|
|
13630
13561
|
let compactionUsage;
|
|
13562
|
+
const emitCompactionObservation = (compacted) => {
|
|
13563
|
+
if (compacted.compressed || compacted.summaryGenerated || compacted.failureMessage) {
|
|
13564
|
+
emitLoopEvent(observationBoundary, {
|
|
13565
|
+
kind: "compaction",
|
|
13566
|
+
atMs: Date.now(),
|
|
13567
|
+
reason: compacted.reason ?? "context_budget",
|
|
13568
|
+
summaryGenerated: compacted.summaryGenerated,
|
|
13569
|
+
compressed: compacted.compressed,
|
|
13570
|
+
...compacted.failureMessage ? { failed: true, detail: compacted.failureMessage } : {},
|
|
13571
|
+
...compacted.beforeTokens !== void 0 ? { beforeTokens: compacted.beforeTokens } : {},
|
|
13572
|
+
...compacted.afterTokens !== void 0 ? { afterTokens: compacted.afterTokens } : {},
|
|
13573
|
+
...compacted.savedTokens !== void 0 ? { savedTokens: compacted.savedTokens } : {}
|
|
13574
|
+
});
|
|
13575
|
+
}
|
|
13576
|
+
};
|
|
13631
13577
|
try {
|
|
13632
13578
|
const compacted = await maybeAutoCompactLocalHistory({
|
|
13633
13579
|
adapter: input.adapter,
|
|
@@ -13639,19 +13585,7 @@ async function runLocalAgentTurn(input) {
|
|
|
13639
13585
|
});
|
|
13640
13586
|
history = compacted.history;
|
|
13641
13587
|
compactionUsage = compacted.usage;
|
|
13642
|
-
|
|
13643
|
-
emitLoopEvent(observationBoundary, {
|
|
13644
|
-
kind: "compaction",
|
|
13645
|
-
atMs: Date.now(),
|
|
13646
|
-
reason: compacted.reason ?? "context_budget",
|
|
13647
|
-
summaryGenerated: compacted.summaryGenerated,
|
|
13648
|
-
compressed: compacted.compressed,
|
|
13649
|
-
...compacted.beforeTokens !== void 0 ? { beforeTokens: compacted.beforeTokens } : {},
|
|
13650
|
-
...compacted.afterTokens !== void 0 ? { afterTokens: compacted.afterTokens } : {},
|
|
13651
|
-
...compacted.savedTokens !== void 0 ? { savedTokens: compacted.savedTokens } : {},
|
|
13652
|
-
...compacted.stubbedCount !== void 0 ? { stubbedCount: compacted.stubbedCount } : {}
|
|
13653
|
-
});
|
|
13654
|
-
}
|
|
13588
|
+
emitCompactionObservation(compacted);
|
|
13655
13589
|
} catch (error) {
|
|
13656
13590
|
console.warn("[localLoop] auto-compaction unexpected error:", error);
|
|
13657
13591
|
}
|
|
@@ -13663,7 +13597,6 @@ async function runLocalAgentTurn(input) {
|
|
|
13663
13597
|
loopTimingMark("trimHistoryToContextBudget", 0);
|
|
13664
13598
|
const hasContextBlocks = callerScopes.some((block) => block.content.trim()) || mergedContextBlockScopes.some((block) => block.content.trim());
|
|
13665
13599
|
const promptMessageCount = agentConfig.prompt?.trim() || hasContextBlocks ? 1 : 0;
|
|
13666
|
-
const turnStartIndex = promptMessageCount + history.length;
|
|
13667
13600
|
const builtMessages = buildMessages({
|
|
13668
13601
|
prompt: agentConfig.prompt,
|
|
13669
13602
|
contextBlockScopes: mergedContextBlockScopes,
|
|
@@ -13694,6 +13627,17 @@ async function runLocalAgentTurn(input) {
|
|
|
13694
13627
|
atMs: Date.now()
|
|
13695
13628
|
});
|
|
13696
13629
|
}
|
|
13630
|
+
const rawTurnMessages = messages.slice(
|
|
13631
|
+
promptMessageCount + history.length
|
|
13632
|
+
);
|
|
13633
|
+
const pushMessage = (msg) => {
|
|
13634
|
+
messages.push(msg);
|
|
13635
|
+
rawTurnMessages.push(msg);
|
|
13636
|
+
};
|
|
13637
|
+
const capToolMessage = (msg) => msg.role === "tool" && typeof msg.content === "string" ? {
|
|
13638
|
+
...msg,
|
|
13639
|
+
content: truncateToolOutputForContext(msg.content, contextWindow)
|
|
13640
|
+
} : msg;
|
|
13697
13641
|
const userInputText = extractUserInputText(input.input);
|
|
13698
13642
|
let toolCallCount = 0;
|
|
13699
13643
|
let result4;
|
|
@@ -13708,6 +13652,50 @@ async function runLocalAgentTurn(input) {
|
|
|
13708
13652
|
let skipFinalAppend = false;
|
|
13709
13653
|
let partialContent = "";
|
|
13710
13654
|
const progressGuard = createLocalLoopProgressGuard(input.progressGuardConfig);
|
|
13655
|
+
const maybeCompactInLoop = async () => {
|
|
13656
|
+
if (!input.continueDialogId) return;
|
|
13657
|
+
if (!contextUsage) return;
|
|
13658
|
+
const inputTokens = normalizeUsage(contextUsage).input_tokens;
|
|
13659
|
+
if (!inputTokens || inputTokens <= 0) return;
|
|
13660
|
+
const ratio = Math.min(1, inputTokens / contextWindow);
|
|
13661
|
+
if (ratio < compressionTriggerRatio) return;
|
|
13662
|
+
try {
|
|
13663
|
+
const compacted = await maybeAutoCompactLocalHistory({
|
|
13664
|
+
adapter: input.adapter,
|
|
13665
|
+
dialogId: input.continueDialogId,
|
|
13666
|
+
// canonical 坐标:store 全量历史 + 本轮消息的「持久化形态」
|
|
13667
|
+
// (applyPersistedTurnInput 会把首条 user 消息换成 paste 展开形态)。
|
|
13668
|
+
// 锚点与 sourceHash 都必须按持久化形态计算——否则下轮从 store
|
|
13669
|
+
// 重载后重算 hash 必不匹配,摘要被判无效、白付一次摘要调用。
|
|
13670
|
+
history: [
|
|
13671
|
+
...canonicalHistory,
|
|
13672
|
+
...applyPersistedTurnInput(
|
|
13673
|
+
rawTurnMessages,
|
|
13674
|
+
input.persistedInput,
|
|
13675
|
+
input.persistedInputReference
|
|
13676
|
+
)
|
|
13677
|
+
],
|
|
13678
|
+
model: agentConfig.model,
|
|
13679
|
+
resolveProvider: resolveProviderOnce,
|
|
13680
|
+
realContextUsagePercent: ratio
|
|
13681
|
+
});
|
|
13682
|
+
if (compacted.usage) {
|
|
13683
|
+
compactionUsage = addOutOfBandUsage(compactionUsage, compacted.usage);
|
|
13684
|
+
}
|
|
13685
|
+
if (compacted.compressed) {
|
|
13686
|
+
messages = downgradeUnparsableToolCalls([
|
|
13687
|
+
...messages.slice(0, promptMessageCount),
|
|
13688
|
+
...prepareHistoryForNextTurn(
|
|
13689
|
+
compacted.history,
|
|
13690
|
+
input.adapter.host === "cli" ? input.contextReferenceResolver : void 0
|
|
13691
|
+
)
|
|
13692
|
+
]).messages;
|
|
13693
|
+
}
|
|
13694
|
+
emitCompactionObservation(compacted);
|
|
13695
|
+
} catch (error) {
|
|
13696
|
+
console.warn("[localLoop] in-loop auto-compaction failed:", error);
|
|
13697
|
+
}
|
|
13698
|
+
};
|
|
13711
13699
|
try {
|
|
13712
13700
|
const provider = await resolveProviderOnce();
|
|
13713
13701
|
const applyPendingInjections = () => {
|
|
@@ -13722,7 +13710,7 @@ async function runLocalAgentTurn(input) {
|
|
|
13722
13710
|
let injected = false;
|
|
13723
13711
|
for (const text of pending) {
|
|
13724
13712
|
if (typeof text !== "string" || !text.trim()) continue;
|
|
13725
|
-
|
|
13713
|
+
pushMessage({ role: "user", content: text });
|
|
13726
13714
|
injected = true;
|
|
13727
13715
|
}
|
|
13728
13716
|
return injected;
|
|
@@ -13904,13 +13892,14 @@ ${reasoningTailLog}
|
|
|
13904
13892
|
content: result4.content,
|
|
13905
13893
|
...result4.reasoning_content ? { reasoning_content: result4.reasoning_content } : {}
|
|
13906
13894
|
};
|
|
13907
|
-
|
|
13895
|
+
pushMessage(assistantMessage);
|
|
13908
13896
|
if (applyPendingInjections()) {
|
|
13909
13897
|
loopTimingMark("roundEnd", round);
|
|
13910
13898
|
round += 1;
|
|
13911
13899
|
continue;
|
|
13912
13900
|
}
|
|
13913
13901
|
messages.pop();
|
|
13902
|
+
rawTurnMessages.pop();
|
|
13914
13903
|
}
|
|
13915
13904
|
break;
|
|
13916
13905
|
}
|
|
@@ -13930,7 +13919,9 @@ ${reasoningTailLog}
|
|
|
13930
13919
|
}
|
|
13931
13920
|
}
|
|
13932
13921
|
if (hasInlineExecutedTools) {
|
|
13933
|
-
|
|
13922
|
+
for (const blockMsg of blocksToOpenAiMessages(outputBlocks)) {
|
|
13923
|
+
pushMessage(capToolMessage(blockMsg));
|
|
13924
|
+
}
|
|
13934
13925
|
skipFinalAppend = true;
|
|
13935
13926
|
break;
|
|
13936
13927
|
}
|
|
@@ -13938,7 +13929,7 @@ ${reasoningTailLog}
|
|
|
13938
13929
|
continue;
|
|
13939
13930
|
}
|
|
13940
13931
|
toolCallCount += toolCalls.length;
|
|
13941
|
-
|
|
13932
|
+
pushMessage({
|
|
13942
13933
|
role: "assistant",
|
|
13943
13934
|
content: result4.content || null,
|
|
13944
13935
|
...result4.reasoning_content ? { reasoning_content: result4.reasoning_content } : {},
|
|
@@ -14114,17 +14105,19 @@ ${reasoningTailLog}
|
|
|
14114
14105
|
metadata: toolResult.metadata
|
|
14115
14106
|
});
|
|
14116
14107
|
loopTimingMark("toolResultFormat", round);
|
|
14117
|
-
|
|
14118
|
-
|
|
14119
|
-
|
|
14108
|
+
pushMessage(
|
|
14109
|
+
capToolMessage({
|
|
14110
|
+
role: "tool",
|
|
14111
|
+
content: formatToolMessageContent({
|
|
14112
|
+
toolName,
|
|
14113
|
+
content: toolResult.content,
|
|
14114
|
+
metadata: observedMetadata
|
|
14115
|
+
}),
|
|
14116
|
+
tool_call_id: toolCall.id,
|
|
14120
14117
|
toolName,
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
tool_call_id: toolCall.id,
|
|
14125
|
-
toolName,
|
|
14126
|
-
...observedMetadata ? { tool_result_metadata: observedMetadata } : {}
|
|
14127
|
-
});
|
|
14118
|
+
...observedMetadata ? { tool_result_metadata: observedMetadata } : {}
|
|
14119
|
+
})
|
|
14120
|
+
);
|
|
14128
14121
|
}
|
|
14129
14122
|
const toolExecutionGuardVerdict = progressGuard.observeToolExecution(
|
|
14130
14123
|
toolCalls,
|
|
@@ -14146,6 +14139,7 @@ ${reasoningTailLog}
|
|
|
14146
14139
|
};
|
|
14147
14140
|
break;
|
|
14148
14141
|
}
|
|
14142
|
+
await maybeCompactInLoop();
|
|
14149
14143
|
loopTimingMark("roundEnd", round);
|
|
14150
14144
|
round += 1;
|
|
14151
14145
|
}
|
|
@@ -14154,7 +14148,7 @@ ${reasoningTailLog}
|
|
|
14154
14148
|
}
|
|
14155
14149
|
if (loopError) {
|
|
14156
14150
|
const turnMessages2 = applyPersistedTurnInput(
|
|
14157
|
-
|
|
14151
|
+
rawTurnMessages,
|
|
14158
14152
|
input.persistedInput,
|
|
14159
14153
|
input.persistedInputReference
|
|
14160
14154
|
);
|
|
@@ -14192,7 +14186,7 @@ ${reasoningTailLog}
|
|
|
14192
14186
|
result4.emptyAssistantFallbackReason,
|
|
14193
14187
|
result4.reasoning_content
|
|
14194
14188
|
);
|
|
14195
|
-
|
|
14189
|
+
pushMessage({
|
|
14196
14190
|
role: "assistant",
|
|
14197
14191
|
content: result4.content,
|
|
14198
14192
|
// 与中间轮(:561)一致带上 reasoning_content,让 saveTurn 持久化思维链,
|
|
@@ -14202,7 +14196,7 @@ ${reasoningTailLog}
|
|
|
14202
14196
|
});
|
|
14203
14197
|
}
|
|
14204
14198
|
const turnMessages = applyPersistedTurnInput(
|
|
14205
|
-
|
|
14199
|
+
rawTurnMessages,
|
|
14206
14200
|
input.persistedInput,
|
|
14207
14201
|
input.persistedInputReference
|
|
14208
14202
|
);
|