@runtypelabs/sdk 1.8.0 → 1.8.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/dist/index.cjs +613 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -1
- package/dist/index.d.ts +85 -1
- package/dist/index.js +613 -95
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3038,7 +3038,11 @@ var designPhase = {
|
|
|
3038
3038
|
buildTransitionSummary(_state, _nextPhaseName) {
|
|
3039
3039
|
return [
|
|
3040
3040
|
"Automatic phase transition: design \u2192 build.",
|
|
3041
|
-
"Requirements understood. Build the game and deploy it using deploy_sandbox
|
|
3041
|
+
"Requirements understood. Build the game and deploy it using deploy_sandbox.",
|
|
3042
|
+
"",
|
|
3043
|
+
"MANDATORY: Use the `files` parameter for ALL game HTML/JS/CSS.",
|
|
3044
|
+
"code = minimal Express static server (~4 lines), files = game assets.",
|
|
3045
|
+
"NEVER embed HTML inside res.send() template literals."
|
|
3042
3046
|
].join("\n");
|
|
3043
3047
|
},
|
|
3044
3048
|
interceptToolCall(toolName, _args, _ctx) {
|
|
@@ -3098,7 +3102,32 @@ var buildPhase = {
|
|
|
3098
3102
|
" 4. If the deploy fails, read the error output, fix the code, and call deploy_sandbox again.",
|
|
3099
3103
|
" 5. The sandbox is persistent \u2014 subsequent calls reuse the same sandbox.",
|
|
3100
3104
|
" 6. Load game libraries from CDN in your HTML (e.g., Three.js from unpkg/cdnjs) OR include them in packageJson.",
|
|
3101
|
-
" 7. Make the game fullscreen by default (width: 100vw, height: 100vh, no margin/padding on body)."
|
|
3105
|
+
" 7. Make the game fullscreen by default (width: 100vw, height: 100vh, no margin/padding on body).",
|
|
3106
|
+
"",
|
|
3107
|
+
"STARTER TEMPLATES \u2014 Copy and customize based on the game type:",
|
|
3108
|
+
"",
|
|
3109
|
+
"ALL templates use this server code:",
|
|
3110
|
+
' code: `const express = require("express"); const app = express(); app.use(express.static("public")); app.listen(3000, () => console.log("Game server running on port 3000"));`',
|
|
3111
|
+
' packageJson: { "dependencies": { "express": "^4.18.2" } }',
|
|
3112
|
+
' language: "javascript"',
|
|
3113
|
+
"",
|
|
3114
|
+
"THREE.JS (3D games \u2014 racing, flying, FPS, etc.):",
|
|
3115
|
+
" files: {",
|
|
3116
|
+
' "public/index.html": HTML with <script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js"}}</script> and <script type="module" src="game.js"></script>',
|
|
3117
|
+
' "public/game.js": Import three, create scene/camera/renderer, game loop with requestAnimationFrame',
|
|
3118
|
+
" }",
|
|
3119
|
+
"",
|
|
3120
|
+
"PHASER (2D games \u2014 platformers, shooters, puzzles):",
|
|
3121
|
+
" files: {",
|
|
3122
|
+
' "public/index.html": HTML with <script src="https://cdn.jsdelivr.net/npm/phaser@3.80.1/dist/phaser.min.js"></script> and <script src="game.js"></script>',
|
|
3123
|
+
' "public/game.js": Phaser.Game config with scenes, preload/create/update lifecycle',
|
|
3124
|
+
" }",
|
|
3125
|
+
"",
|
|
3126
|
+
"CANVAS 2D (simple games \u2014 pong, snake, breakout):",
|
|
3127
|
+
" files: {",
|
|
3128
|
+
' "public/index.html": HTML with <canvas id="game" width="800" height="600"></canvas> and <script src="game.js"></script>',
|
|
3129
|
+
' "public/game.js": Get canvas context, game loop with requestAnimationFrame, draw calls',
|
|
3130
|
+
" }"
|
|
3102
3131
|
].join("\n");
|
|
3103
3132
|
},
|
|
3104
3133
|
buildToolGuidance(_state) {
|
|
@@ -3112,8 +3141,23 @@ var buildPhase = {
|
|
|
3112
3141
|
isComplete() {
|
|
3113
3142
|
return false;
|
|
3114
3143
|
},
|
|
3115
|
-
interceptToolCall(toolName,
|
|
3116
|
-
|
|
3144
|
+
interceptToolCall(toolName, args, _ctx) {
|
|
3145
|
+
const localBlock = blockLocalTools(toolName);
|
|
3146
|
+
if (localBlock) return localBlock;
|
|
3147
|
+
if (toolName === "deploy_sandbox" && args) {
|
|
3148
|
+
const hasFiles = args.files && typeof args.files === "object" && Object.keys(args.files).length > 0;
|
|
3149
|
+
const codeStr = typeof args.code === "string" ? args.code : "";
|
|
3150
|
+
const embedsHtml = /res\.send\s*\(/.test(codeStr) && /<html|<body|<script/i.test(codeStr);
|
|
3151
|
+
if (!hasFiles && embedsHtml) {
|
|
3152
|
+
return [
|
|
3153
|
+
"Blocked: You are embedding HTML inside res.send() \u2014 this will break due to nested template literals.",
|
|
3154
|
+
"You MUST use the `files` parameter. Put your game HTML/JS/CSS in files and use a minimal Express static server for code.",
|
|
3155
|
+
'Example: code: `const express = require("express"); const app = express(); app.use(express.static("public")); app.listen(3000);`',
|
|
3156
|
+
'files: { "public/index.html": "<!DOCTYPE html>...", "public/game.js": "// game code" }'
|
|
3157
|
+
].join("\n");
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
return void 0;
|
|
3117
3161
|
},
|
|
3118
3162
|
canAcceptCompletion(_state, trace) {
|
|
3119
3163
|
return trace.entries.some((entry) => entry.startsWith("deploy_sandbox"));
|
|
@@ -5409,6 +5453,8 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5409
5453
|
this.updateWorkflowPhase(state, this.createEmptyToolTrace(), workflow);
|
|
5410
5454
|
let recordId;
|
|
5411
5455
|
const localToolNames = options.localTools ? Object.keys(options.localTools) : void 0;
|
|
5456
|
+
const builtinToolSchemas = await this.loadBuiltinToolSchemas(options.toolIds);
|
|
5457
|
+
const compactInstructions = this.resolveCompactInstructions(options.compactInstructions, agent);
|
|
5412
5458
|
if (!options.previousMessages) {
|
|
5413
5459
|
if (workflow.generateBootstrapContext) {
|
|
5414
5460
|
state.bootstrapContext = await workflow.generateBootstrapContext(
|
|
@@ -5442,7 +5488,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5442
5488
|
if (session === 0 && !options.previousMessages) {
|
|
5443
5489
|
state.originalMessage = options.message;
|
|
5444
5490
|
}
|
|
5445
|
-
const
|
|
5491
|
+
const preparedSession = await this.prepareSessionContext(
|
|
5446
5492
|
options.message,
|
|
5447
5493
|
state,
|
|
5448
5494
|
session,
|
|
@@ -5450,61 +5496,93 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5450
5496
|
localToolNames,
|
|
5451
5497
|
continuationContext,
|
|
5452
5498
|
workflow,
|
|
5453
|
-
options.toolIds
|
|
5499
|
+
options.toolIds,
|
|
5500
|
+
{
|
|
5501
|
+
autoCompactTokenThreshold: options.autoCompactTokenThreshold,
|
|
5502
|
+
contextLimitTokens: options.contextLimitTokens,
|
|
5503
|
+
model: options.model,
|
|
5504
|
+
compactStrategy: options.compactStrategy,
|
|
5505
|
+
compactInstructions,
|
|
5506
|
+
localTools: options.localTools,
|
|
5507
|
+
builtinToolSchemas,
|
|
5508
|
+
onContextCompaction: options.onContextCompaction,
|
|
5509
|
+
onContextNotice: options.onContextNotice
|
|
5510
|
+
}
|
|
5454
5511
|
);
|
|
5512
|
+
const {
|
|
5513
|
+
messages,
|
|
5514
|
+
requestContextManagement,
|
|
5515
|
+
pendingNativeCompactionEvent
|
|
5516
|
+
} = preparedSession;
|
|
5455
5517
|
let sessionResult;
|
|
5456
5518
|
const sessionData = {
|
|
5457
5519
|
messages,
|
|
5458
5520
|
debugMode: options.debugMode,
|
|
5459
5521
|
model: options.model,
|
|
5460
|
-
...options.toolIds?.length ? { tools: { toolIds: options.toolIds } } : {}
|
|
5522
|
+
...options.toolIds?.length ? { tools: { toolIds: options.toolIds } } : {},
|
|
5523
|
+
...requestContextManagement ? { contextManagement: requestContextManagement } : {}
|
|
5461
5524
|
};
|
|
5462
5525
|
let sessionToolMessages = [];
|
|
5463
|
-
if (
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5526
|
+
if (pendingNativeCompactionEvent) {
|
|
5527
|
+
await this.emitContextCompactionEvent(options.onContextCompaction, {
|
|
5528
|
+
phase: "start",
|
|
5529
|
+
...pendingNativeCompactionEvent
|
|
5530
|
+
});
|
|
5531
|
+
}
|
|
5532
|
+
try {
|
|
5533
|
+
if (useStream && options.localTools) {
|
|
5534
|
+
const localToolResult = await this.executeWithLocalTools(
|
|
5535
|
+
id,
|
|
5536
|
+
sessionData,
|
|
5537
|
+
sessionLocalTools || options.localTools,
|
|
5538
|
+
sessionCallbacks,
|
|
5539
|
+
{
|
|
5540
|
+
onLocalToolResult: this.createLocalToolLoopGuard(state, sessionTrace, workflow)
|
|
5541
|
+
},
|
|
5542
|
+
state.taskName
|
|
5543
|
+
);
|
|
5544
|
+
if (!localToolResult) {
|
|
5545
|
+
throw new Error("Agent stream ended without a complete event");
|
|
5546
|
+
}
|
|
5547
|
+
const { completeEvent, toolMessages: captured } = localToolResult;
|
|
5548
|
+
sessionToolMessages = captured;
|
|
5549
|
+
sessionResult = {
|
|
5550
|
+
success: completeEvent.success,
|
|
5551
|
+
result: completeEvent.finalOutput || "",
|
|
5552
|
+
iterations: completeEvent.iterations,
|
|
5553
|
+
totalCost: completeEvent.totalCost || 0,
|
|
5554
|
+
totalTokens: completeEvent.totalTokens,
|
|
5555
|
+
stopReason: completeEvent.stopReason,
|
|
5556
|
+
error: completeEvent.error
|
|
5557
|
+
};
|
|
5558
|
+
} else if (useStream && options.streamCallbacks) {
|
|
5559
|
+
const completeEvent = await this.executeWithCallbacks(
|
|
5560
|
+
id,
|
|
5561
|
+
sessionData,
|
|
5562
|
+
sessionCallbacks || options.streamCallbacks
|
|
5563
|
+
);
|
|
5564
|
+
if (!completeEvent) {
|
|
5565
|
+
throw new Error("Agent stream ended without a complete event");
|
|
5566
|
+
}
|
|
5567
|
+
sessionResult = {
|
|
5568
|
+
success: completeEvent.success,
|
|
5569
|
+
result: completeEvent.finalOutput || "",
|
|
5570
|
+
iterations: completeEvent.iterations,
|
|
5571
|
+
totalCost: completeEvent.totalCost || 0,
|
|
5572
|
+
totalTokens: completeEvent.totalTokens,
|
|
5573
|
+
stopReason: completeEvent.stopReason,
|
|
5574
|
+
error: completeEvent.error
|
|
5575
|
+
};
|
|
5576
|
+
} else {
|
|
5577
|
+
sessionResult = await this.execute(id, sessionData);
|
|
5476
5578
|
}
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
totalCost: completeEvent.totalCost || 0,
|
|
5484
|
-
totalTokens: completeEvent.totalTokens,
|
|
5485
|
-
stopReason: completeEvent.stopReason,
|
|
5486
|
-
error: completeEvent.error
|
|
5487
|
-
};
|
|
5488
|
-
} else if (useStream && options.streamCallbacks) {
|
|
5489
|
-
const completeEvent = await this.executeWithCallbacks(
|
|
5490
|
-
id,
|
|
5491
|
-
sessionData,
|
|
5492
|
-
sessionCallbacks || options.streamCallbacks
|
|
5493
|
-
);
|
|
5494
|
-
if (!completeEvent) {
|
|
5495
|
-
throw new Error("Agent stream ended without a complete event");
|
|
5579
|
+
} finally {
|
|
5580
|
+
if (pendingNativeCompactionEvent) {
|
|
5581
|
+
await this.emitContextCompactionEvent(options.onContextCompaction, {
|
|
5582
|
+
phase: "complete",
|
|
5583
|
+
...pendingNativeCompactionEvent
|
|
5584
|
+
});
|
|
5496
5585
|
}
|
|
5497
|
-
sessionResult = {
|
|
5498
|
-
success: completeEvent.success,
|
|
5499
|
-
result: completeEvent.finalOutput || "",
|
|
5500
|
-
iterations: completeEvent.iterations,
|
|
5501
|
-
totalCost: completeEvent.totalCost || 0,
|
|
5502
|
-
totalTokens: completeEvent.totalTokens,
|
|
5503
|
-
stopReason: completeEvent.stopReason,
|
|
5504
|
-
error: completeEvent.error
|
|
5505
|
-
};
|
|
5506
|
-
} else {
|
|
5507
|
-
sessionResult = await this.execute(id, sessionData);
|
|
5508
5586
|
}
|
|
5509
5587
|
const toolTraceSummary = this.buildToolTraceSummary(sessionTrace);
|
|
5510
5588
|
const effectiveSessionOutput = this.buildEffectiveSessionOutput(
|
|
@@ -5591,7 +5669,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5591
5669
|
}
|
|
5592
5670
|
}
|
|
5593
5671
|
if (!state.messages) state.messages = [];
|
|
5594
|
-
if (
|
|
5672
|
+
if (this.isCompactHistoryMessageSet(messages)) {
|
|
5673
|
+
state.messages = [...messages];
|
|
5674
|
+
} else if (state.messages.length > 0 && messages.length > state.messages.length) {
|
|
5595
5675
|
const newMessages = messages.slice(state.messages.length);
|
|
5596
5676
|
state.messages.push(...newMessages);
|
|
5597
5677
|
} else {
|
|
@@ -5656,41 +5736,379 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5656
5736
|
const upper = output.toUpperCase();
|
|
5657
5737
|
return _AgentsEndpoint.STOP_PHRASES.some((phrase) => upper.includes(phrase.toUpperCase()));
|
|
5658
5738
|
}
|
|
5739
|
+
resolveReservedOutputTokens(contextLimitTokens) {
|
|
5740
|
+
if (typeof contextLimitTokens !== "number" || !Number.isFinite(contextLimitTokens) || contextLimitTokens <= 0) {
|
|
5741
|
+
return void 0;
|
|
5742
|
+
}
|
|
5743
|
+
return Math.max(8e3, Math.min(64e3, Math.floor(contextLimitTokens * 0.15)));
|
|
5744
|
+
}
|
|
5745
|
+
resolveEffectiveInputBudgetTokens(contextLimitTokens) {
|
|
5746
|
+
if (typeof contextLimitTokens !== "number" || !Number.isFinite(contextLimitTokens) || contextLimitTokens <= 0) {
|
|
5747
|
+
return void 0;
|
|
5748
|
+
}
|
|
5749
|
+
const reservedOutputTokens = this.resolveReservedOutputTokens(contextLimitTokens) ?? 0;
|
|
5750
|
+
return Math.max(1, contextLimitTokens - reservedOutputTokens);
|
|
5751
|
+
}
|
|
5752
|
+
resolveCompactStrategy(strategy, modelId) {
|
|
5753
|
+
if (strategy === "summary_fallback") {
|
|
5754
|
+
return "summary_fallback";
|
|
5755
|
+
}
|
|
5756
|
+
const normalizedModelId = modelId?.trim().toLowerCase() ?? "";
|
|
5757
|
+
const supportsAnthropicNativeCompaction = normalizedModelId.includes("claude") || normalizedModelId.includes("anthropic");
|
|
5758
|
+
if (strategy === "provider_native") {
|
|
5759
|
+
return supportsAnthropicNativeCompaction ? "provider_native" : "summary_fallback";
|
|
5760
|
+
}
|
|
5761
|
+
return supportsAnthropicNativeCompaction ? "provider_native" : "summary_fallback";
|
|
5762
|
+
}
|
|
5763
|
+
estimateTextTokens(text) {
|
|
5764
|
+
if (!text) return 0;
|
|
5765
|
+
return Math.ceil(text.length / 4);
|
|
5766
|
+
}
|
|
5767
|
+
estimateUnknownTokens(value) {
|
|
5768
|
+
if (typeof value === "string") return this.estimateTextTokens(value);
|
|
5769
|
+
try {
|
|
5770
|
+
return this.estimateTextTokens(JSON.stringify(value));
|
|
5771
|
+
} catch {
|
|
5772
|
+
return 0;
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5775
|
+
estimateMessageContentTokens(content) {
|
|
5776
|
+
if (typeof content === "string") return this.estimateTextTokens(content);
|
|
5777
|
+
return content.reduce((total, part) => {
|
|
5778
|
+
if (typeof part.text === "string") total += this.estimateTextTokens(part.text);
|
|
5779
|
+
if (typeof part.image === "string") total += 85;
|
|
5780
|
+
if (typeof part.data === "string") {
|
|
5781
|
+
total += Math.min(200, this.estimateTextTokens(part.data));
|
|
5782
|
+
}
|
|
5783
|
+
return total + 4;
|
|
5784
|
+
}, 0);
|
|
5785
|
+
}
|
|
5786
|
+
estimateToolCallTokens(toolCalls) {
|
|
5787
|
+
if (!toolCalls || toolCalls.length === 0) return 0;
|
|
5788
|
+
return toolCalls.reduce(
|
|
5789
|
+
(sum, toolCall) => sum + 12 + this.estimateTextTokens(toolCall.toolName) + this.estimateUnknownTokens(toolCall.args),
|
|
5790
|
+
0
|
|
5791
|
+
);
|
|
5792
|
+
}
|
|
5793
|
+
estimateToolResultTokens(toolResults) {
|
|
5794
|
+
if (!toolResults || toolResults.length === 0) return 0;
|
|
5795
|
+
return toolResults.reduce(
|
|
5796
|
+
(sum, toolResult) => sum + 12 + this.estimateTextTokens(toolResult.toolName) + this.estimateUnknownTokens(toolResult.result),
|
|
5797
|
+
0
|
|
5798
|
+
);
|
|
5799
|
+
}
|
|
5800
|
+
estimateMessageTokens(message) {
|
|
5801
|
+
return 6 + this.estimateMessageContentTokens(message.content) + this.estimateToolCallTokens(message.toolCalls) + this.estimateToolResultTokens(message.toolResults);
|
|
5802
|
+
}
|
|
5803
|
+
estimateConversationTokens(messages) {
|
|
5804
|
+
return messages.reduce((sum, message) => sum + this.estimateMessageTokens(message), 0);
|
|
5805
|
+
}
|
|
5806
|
+
estimateConversationBreakdown(messages) {
|
|
5807
|
+
let historyTokens = 0;
|
|
5808
|
+
let toolOutputTokens = 0;
|
|
5809
|
+
for (const message of messages) {
|
|
5810
|
+
const contentTokens = this.estimateMessageContentTokens(message.content);
|
|
5811
|
+
const toolCallTokens = this.estimateToolCallTokens(message.toolCalls);
|
|
5812
|
+
const toolResultTokens = this.estimateToolResultTokens(message.toolResults);
|
|
5813
|
+
const messageTotal = 6 + contentTokens + toolCallTokens + toolResultTokens;
|
|
5814
|
+
if (message.role === "tool") {
|
|
5815
|
+
toolOutputTokens += messageTotal;
|
|
5816
|
+
} else {
|
|
5817
|
+
historyTokens += 6 + contentTokens + toolCallTokens;
|
|
5818
|
+
toolOutputTokens += toolResultTokens;
|
|
5819
|
+
}
|
|
5820
|
+
}
|
|
5821
|
+
return {
|
|
5822
|
+
historyTokens,
|
|
5823
|
+
toolOutputTokens,
|
|
5824
|
+
estimatedInputTokens: historyTokens + toolOutputTokens
|
|
5825
|
+
};
|
|
5826
|
+
}
|
|
5827
|
+
estimateToolDefinitionTokens(localTools, builtinToolSchemas) {
|
|
5828
|
+
const localToolDefinitions = Object.entries(localTools || {}).map(([name, definition]) => ({
|
|
5829
|
+
name,
|
|
5830
|
+
description: definition.description,
|
|
5831
|
+
parametersSchema: definition.parametersSchema
|
|
5832
|
+
}));
|
|
5833
|
+
const payload = [...localToolDefinitions, ...builtinToolSchemas];
|
|
5834
|
+
if (payload.length === 0) return 0;
|
|
5835
|
+
return this.estimateUnknownTokens(payload);
|
|
5836
|
+
}
|
|
5837
|
+
async loadBuiltinToolSchemas(toolIds) {
|
|
5838
|
+
if (!toolIds || toolIds.length === 0) return [];
|
|
5839
|
+
try {
|
|
5840
|
+
const schemas = await this.client.get("/tools/schema", { toolIds });
|
|
5841
|
+
return Array.isArray(schemas) ? schemas : [];
|
|
5842
|
+
} catch {
|
|
5843
|
+
return [];
|
|
5844
|
+
}
|
|
5845
|
+
}
|
|
5846
|
+
buildDefaultCompactInstructions() {
|
|
5847
|
+
return [
|
|
5848
|
+
"Preserve changed files or best candidate paths.",
|
|
5849
|
+
"Preserve verification or test results.",
|
|
5850
|
+
"Preserve the current workflow phase and remaining work.",
|
|
5851
|
+
"Preserve unresolved blockers or follow-up risks.",
|
|
5852
|
+
"Preserve artifact references and offloaded tool outputs."
|
|
5853
|
+
].join(" ");
|
|
5854
|
+
}
|
|
5855
|
+
resolveCompactInstructions(optionInstructions, agent) {
|
|
5856
|
+
if (typeof optionInstructions === "string" && optionInstructions.trim()) {
|
|
5857
|
+
return optionInstructions.trim();
|
|
5858
|
+
}
|
|
5859
|
+
const config = agent.config;
|
|
5860
|
+
if (!config || typeof config !== "object") {
|
|
5861
|
+
return void 0;
|
|
5862
|
+
}
|
|
5863
|
+
const compactInstructions = config.compactInstructions;
|
|
5864
|
+
return typeof compactInstructions === "string" && compactInstructions.trim() ? compactInstructions.trim() : void 0;
|
|
5865
|
+
}
|
|
5866
|
+
extractArtifactReferences(state) {
|
|
5867
|
+
const references = /* @__PURE__ */ new Set();
|
|
5868
|
+
const offloadPrefix = "[Output saved to ";
|
|
5869
|
+
for (const message of state.messages ?? []) {
|
|
5870
|
+
if (!message.toolResults) continue;
|
|
5871
|
+
for (const toolResult of message.toolResults) {
|
|
5872
|
+
if (typeof toolResult.result !== "string") continue;
|
|
5873
|
+
let startIndex = 0;
|
|
5874
|
+
while (startIndex < toolResult.result.length) {
|
|
5875
|
+
const prefixIndex = toolResult.result.indexOf(offloadPrefix, startIndex);
|
|
5876
|
+
if (prefixIndex === -1) break;
|
|
5877
|
+
const pathStart = prefixIndex + offloadPrefix.length;
|
|
5878
|
+
const closingBracket = toolResult.result.indexOf("]", pathStart);
|
|
5879
|
+
if (closingBracket === -1) break;
|
|
5880
|
+
const bracketContent = toolResult.result.slice(pathStart, closingBracket);
|
|
5881
|
+
const separatorIndex = bracketContent.indexOf(" \u2014 ");
|
|
5882
|
+
const pathText = separatorIndex === -1 ? bracketContent.trim() : bracketContent.slice(0, separatorIndex).trim();
|
|
5883
|
+
if (pathText) {
|
|
5884
|
+
references.add(pathText);
|
|
5885
|
+
}
|
|
5886
|
+
startIndex = closingBracket + 1;
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
}
|
|
5890
|
+
if (state.planPath) {
|
|
5891
|
+
references.add(state.planPath);
|
|
5892
|
+
}
|
|
5893
|
+
return [...references].slice(0, 8);
|
|
5894
|
+
}
|
|
5895
|
+
buildContextBudgetBreakdown(details) {
|
|
5896
|
+
const conversationBreakdown = this.estimateConversationBreakdown(details.historyMessages);
|
|
5897
|
+
const currentTurnTokens = this.estimateTextTokens(details.currentTurnContent);
|
|
5898
|
+
const toolDefinitionTokens = this.estimateToolDefinitionTokens(
|
|
5899
|
+
details.localTools,
|
|
5900
|
+
details.builtinToolSchemas
|
|
5901
|
+
);
|
|
5902
|
+
const reservedOutputTokens = this.resolveReservedOutputTokens(details.contextLimitTokens);
|
|
5903
|
+
const effectiveInputBudgetTokens = this.resolveEffectiveInputBudgetTokens(details.contextLimitTokens);
|
|
5904
|
+
const summaryTokens = details.summaryText ? this.estimateTextTokens(
|
|
5905
|
+
`${_AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX}
|
|
5906
|
+
|
|
5907
|
+
${details.summaryText}
|
|
5908
|
+
|
|
5909
|
+
Do NOT redo any of the above work.`
|
|
5910
|
+
) : void 0;
|
|
5911
|
+
return {
|
|
5912
|
+
historyTokens: conversationBreakdown.historyTokens,
|
|
5913
|
+
toolOutputTokens: conversationBreakdown.toolOutputTokens,
|
|
5914
|
+
currentTurnTokens,
|
|
5915
|
+
toolDefinitionTokens,
|
|
5916
|
+
...summaryTokens ? { summaryTokens } : {},
|
|
5917
|
+
...reservedOutputTokens ? { reservedOutputTokens } : {},
|
|
5918
|
+
...effectiveInputBudgetTokens ? { effectiveInputBudgetTokens } : {},
|
|
5919
|
+
estimatedInputTokens: conversationBreakdown.estimatedInputTokens + currentTurnTokens + toolDefinitionTokens
|
|
5920
|
+
};
|
|
5921
|
+
}
|
|
5922
|
+
async emitContextCompactionEvent(onContextCompaction, event) {
|
|
5923
|
+
if (!onContextCompaction) return;
|
|
5924
|
+
try {
|
|
5925
|
+
await onContextCompaction(event);
|
|
5926
|
+
} catch {
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5929
|
+
async emitContextNotice(onContextNotice, event) {
|
|
5930
|
+
if (!onContextNotice) return;
|
|
5931
|
+
try {
|
|
5932
|
+
await onContextNotice(event);
|
|
5933
|
+
} catch {
|
|
5934
|
+
}
|
|
5935
|
+
}
|
|
5936
|
+
async buildCompactHistoryMessagesWithLifecycle(state, userContent, sessionIndex, details) {
|
|
5937
|
+
const baseEvent = {
|
|
5938
|
+
mode: details.mode,
|
|
5939
|
+
strategy: details.strategy,
|
|
5940
|
+
sessionIndex: sessionIndex + 1,
|
|
5941
|
+
model: details.model,
|
|
5942
|
+
estimatedTokens: details.beforeTokens,
|
|
5943
|
+
thresholdTokens: details.thresholdTokens,
|
|
5944
|
+
contextLimitTokens: details.contextLimitTokens,
|
|
5945
|
+
effectiveInputBudgetTokens: details.effectiveInputBudgetTokens,
|
|
5946
|
+
reservedOutputTokens: details.reservedOutputTokens,
|
|
5947
|
+
beforeTokens: details.beforeTokens,
|
|
5948
|
+
afterTokens: details.afterTokens,
|
|
5949
|
+
breakdown: details.breakdown
|
|
5950
|
+
};
|
|
5951
|
+
await this.emitContextCompactionEvent(details.onContextCompaction, {
|
|
5952
|
+
phase: "start",
|
|
5953
|
+
...baseEvent
|
|
5954
|
+
});
|
|
5955
|
+
const compactMessages = this.buildCompactHistoryMessages(
|
|
5956
|
+
state,
|
|
5957
|
+
userContent,
|
|
5958
|
+
details.compactInstructions,
|
|
5959
|
+
details.mode
|
|
5960
|
+
);
|
|
5961
|
+
await this.emitContextCompactionEvent(details.onContextCompaction, {
|
|
5962
|
+
phase: "complete",
|
|
5963
|
+
...baseEvent
|
|
5964
|
+
});
|
|
5965
|
+
return compactMessages;
|
|
5966
|
+
}
|
|
5967
|
+
buildCompactHistoryMessages(state, userContent, compactInstructions, mode = "auto") {
|
|
5968
|
+
const summary = this.generateCompactSummary(state, compactInstructions);
|
|
5969
|
+
const prefix = mode === "forced" ? _AgentsEndpoint.FORCED_COMPACT_SUMMARY_PREFIX : _AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX;
|
|
5970
|
+
return [
|
|
5971
|
+
{
|
|
5972
|
+
role: "system",
|
|
5973
|
+
content: `${prefix}
|
|
5974
|
+
|
|
5975
|
+
${summary}
|
|
5976
|
+
|
|
5977
|
+
Do NOT redo any of the above work.`
|
|
5978
|
+
},
|
|
5979
|
+
{
|
|
5980
|
+
role: "user",
|
|
5981
|
+
content: userContent
|
|
5982
|
+
}
|
|
5983
|
+
];
|
|
5984
|
+
}
|
|
5985
|
+
isCompactHistoryMessageSet(messages) {
|
|
5986
|
+
if (messages.length === 0) return false;
|
|
5987
|
+
const firstMessage = messages[0];
|
|
5988
|
+
return firstMessage?.role === "system" && typeof firstMessage.content === "string" && (firstMessage.content.startsWith(_AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX) || firstMessage.content.startsWith(_AgentsEndpoint.FORCED_COMPACT_SUMMARY_PREFIX));
|
|
5989
|
+
}
|
|
5659
5990
|
/**
|
|
5660
5991
|
* Generate a compact summary of prior work for continuation context.
|
|
5661
5992
|
* Used when compact mode is enabled to keep token usage low.
|
|
5662
5993
|
*/
|
|
5663
|
-
generateCompactSummary(state) {
|
|
5664
|
-
const
|
|
5665
|
-
|
|
5994
|
+
generateCompactSummary(state, compactInstructions) {
|
|
5995
|
+
const recentSessions = (state.sessions ?? []).slice(-5);
|
|
5996
|
+
const sessionSummaries = recentSessions.map(
|
|
5997
|
+
(session) => `- Session ${session.index}: ${session.stopReason} ($${session.cost.toFixed(4)}) ${session.outputPreview.slice(0, 160)}`
|
|
5666
5998
|
).join("\n");
|
|
5999
|
+
const candidatePaths = Array.from(
|
|
6000
|
+
new Set(
|
|
6001
|
+
[
|
|
6002
|
+
...state.bestCandidatePath ? [state.bestCandidatePath] : [],
|
|
6003
|
+
...state.candidatePaths ?? []
|
|
6004
|
+
].filter(Boolean)
|
|
6005
|
+
)
|
|
6006
|
+
).slice(0, 8);
|
|
6007
|
+
const verificationSummary = state.bestCandidateVerified ? "Latest candidate verified." : state.bestCandidateNeedsVerification ? "Latest candidate still needs verification." : state.lastVerificationPassed ? "Latest verification passed." : state.verificationRequired ? "Verification is still required." : "No verification requirement recorded.";
|
|
6008
|
+
const artifactReferences = this.extractArtifactReferences(state);
|
|
6009
|
+
const pendingNextStep = state.lastStopReason === "complete" ? "Confirm nothing else remains before declaring the task complete." : `Continue the ${state.workflowPhase || "research"} phase without redoing prior work.`;
|
|
6010
|
+
const instructions = compactInstructions || this.buildDefaultCompactInstructions();
|
|
5667
6011
|
return [
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
...
|
|
6012
|
+
"Task + Phase",
|
|
6013
|
+
`- Task: ${state.taskName}`,
|
|
6014
|
+
`- Status: ${state.status}`,
|
|
6015
|
+
`- Workflow phase: ${state.workflowPhase || "research"}`,
|
|
6016
|
+
`- Sessions completed: ${state.sessionCount}`,
|
|
6017
|
+
`- Total cost: $${state.totalCost.toFixed(4)}`,
|
|
6018
|
+
"",
|
|
6019
|
+
"Completed Work",
|
|
6020
|
+
...sessionSummaries ? [sessionSummaries] : ["- No completed session summaries recorded yet."],
|
|
6021
|
+
"",
|
|
6022
|
+
"Changed Files / Candidate Paths",
|
|
6023
|
+
...candidatePaths.length > 0 ? candidatePaths.map((candidatePath) => `- ${candidatePath}`) : ["- No candidate paths recorded yet."],
|
|
6024
|
+
...state.planPath ? [`- Plan path: ${state.planPath}`] : [],
|
|
6025
|
+
...state.planWritten ? ["- Planning artifact has been written."] : [],
|
|
6026
|
+
...state.bestCandidateReason ? [`- Best candidate rationale: ${state.bestCandidateReason}`] : [],
|
|
6027
|
+
"",
|
|
6028
|
+
"Verification Status",
|
|
6029
|
+
`- ${verificationSummary}`,
|
|
6030
|
+
...state.lastError ? [`- Last error: ${state.lastError}`] : [],
|
|
6031
|
+
"",
|
|
6032
|
+
"Pending Next Step",
|
|
6033
|
+
`- ${pendingNextStep}`,
|
|
5680
6034
|
"",
|
|
5681
|
-
"
|
|
5682
|
-
|
|
6035
|
+
"Artifact / Tool Output References",
|
|
6036
|
+
...artifactReferences.length > 0 ? artifactReferences.map((reference) => `- ${reference}`) : ["- No offloaded artifacts recorded."],
|
|
5683
6037
|
"",
|
|
5684
|
-
"
|
|
5685
|
-
|
|
6038
|
+
"Compaction Instructions",
|
|
6039
|
+
`- ${instructions}`,
|
|
6040
|
+
"",
|
|
6041
|
+
"Last Output (truncated)",
|
|
6042
|
+
(state.lastOutput || "").slice(0, 1800) || "- No final output recorded yet."
|
|
5686
6043
|
].join("\n");
|
|
5687
6044
|
}
|
|
5688
6045
|
/**
|
|
5689
6046
|
* Build messages for a session, injecting progress context for continuation sessions.
|
|
5690
6047
|
* Optionally accepts continuation context for marathon resume scenarios.
|
|
5691
6048
|
*/
|
|
5692
|
-
buildSessionMessages(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext, workflow, builtinToolIds) {
|
|
6049
|
+
async buildSessionMessages(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext, workflow, builtinToolIds, compactionOptions) {
|
|
6050
|
+
const prepared = await this.prepareSessionContext(
|
|
6051
|
+
originalMessage,
|
|
6052
|
+
state,
|
|
6053
|
+
sessionIndex,
|
|
6054
|
+
maxSessions,
|
|
6055
|
+
localToolNames,
|
|
6056
|
+
continuationContext,
|
|
6057
|
+
workflow,
|
|
6058
|
+
builtinToolIds,
|
|
6059
|
+
compactionOptions
|
|
6060
|
+
);
|
|
6061
|
+
return prepared.messages;
|
|
6062
|
+
}
|
|
6063
|
+
async prepareSessionContext(originalMessage, state, sessionIndex, maxSessions, localToolNames, continuationContext, workflow, builtinToolIds, compactionOptions) {
|
|
5693
6064
|
const wf = workflow ?? defaultWorkflow;
|
|
6065
|
+
const compactInstructions = compactionOptions?.compactInstructions;
|
|
6066
|
+
const resolvedStrategy = continuationContext?.compact ? "summary_fallback" : this.resolveCompactStrategy(compactionOptions?.compactStrategy, compactionOptions?.model);
|
|
6067
|
+
const requestContextManagement = resolvedStrategy === "provider_native" && typeof compactionOptions?.autoCompactTokenThreshold === "number" && compactionOptions.autoCompactTokenThreshold > 0 ? {
|
|
6068
|
+
compactStrategy: resolvedStrategy,
|
|
6069
|
+
...compactInstructions ? { compactInstructions } : {},
|
|
6070
|
+
nativeCompaction: {
|
|
6071
|
+
provider: "anthropic",
|
|
6072
|
+
thresholdTokens: compactionOptions.autoCompactTokenThreshold
|
|
6073
|
+
}
|
|
6074
|
+
} : void 0;
|
|
6075
|
+
const maybeEmitToolDefinitionWarning = async (breakdown) => {
|
|
6076
|
+
if (sessionIndex !== 0) return;
|
|
6077
|
+
if (typeof compactionOptions?.contextLimitTokens !== "number" || compactionOptions.contextLimitTokens <= 0) {
|
|
6078
|
+
return;
|
|
6079
|
+
}
|
|
6080
|
+
if (breakdown.toolDefinitionTokens <= 0) return;
|
|
6081
|
+
const ratio = breakdown.toolDefinitionTokens / compactionOptions.contextLimitTokens;
|
|
6082
|
+
if (ratio < 0.1) return;
|
|
6083
|
+
await this.emitContextNotice(compactionOptions?.onContextNotice, {
|
|
6084
|
+
kind: "tool_definitions_warning",
|
|
6085
|
+
sessionIndex: sessionIndex + 1,
|
|
6086
|
+
model: compactionOptions?.model,
|
|
6087
|
+
message: `Tool definitions consume about ${(ratio * 100).toFixed(1)}% of the ${compactionOptions.contextLimitTokens.toLocaleString()} token context window. Reduce the enabled tool set if context pressure remains high.`,
|
|
6088
|
+
estimatedTokens: breakdown.toolDefinitionTokens,
|
|
6089
|
+
contextLimitTokens: compactionOptions.contextLimitTokens,
|
|
6090
|
+
effectiveInputBudgetTokens: breakdown.effectiveInputBudgetTokens,
|
|
6091
|
+
reservedOutputTokens: breakdown.reservedOutputTokens
|
|
6092
|
+
});
|
|
6093
|
+
};
|
|
6094
|
+
const buildNativeCompactionEvent = (mode, breakdown) => {
|
|
6095
|
+
if (resolvedStrategy !== "provider_native" || typeof compactionOptions?.autoCompactTokenThreshold !== "number" || compactionOptions.autoCompactTokenThreshold <= 0 || breakdown.estimatedInputTokens < compactionOptions.autoCompactTokenThreshold) {
|
|
6096
|
+
return void 0;
|
|
6097
|
+
}
|
|
6098
|
+
return {
|
|
6099
|
+
mode,
|
|
6100
|
+
strategy: resolvedStrategy,
|
|
6101
|
+
sessionIndex: sessionIndex + 1,
|
|
6102
|
+
model: compactionOptions?.model,
|
|
6103
|
+
estimatedTokens: breakdown.estimatedInputTokens,
|
|
6104
|
+
thresholdTokens: compactionOptions.autoCompactTokenThreshold,
|
|
6105
|
+
contextLimitTokens: compactionOptions.contextLimitTokens,
|
|
6106
|
+
effectiveInputBudgetTokens: breakdown.effectiveInputBudgetTokens,
|
|
6107
|
+
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
6108
|
+
beforeTokens: breakdown.estimatedInputTokens,
|
|
6109
|
+
breakdown
|
|
6110
|
+
};
|
|
6111
|
+
};
|
|
5694
6112
|
const currentPhase = wf.phases.find((p) => p.name === state.workflowPhase);
|
|
5695
6113
|
const toolGuidanceLines = currentPhase?.buildToolGuidance(state) ?? [];
|
|
5696
6114
|
const isDeployWorkflow = wf.name === "deploy";
|
|
@@ -5719,25 +6137,16 @@ var _AgentsEndpoint = class _AgentsEndpoint {
|
|
|
5719
6137
|
if (continuationContext && sessionIndex === 0) {
|
|
5720
6138
|
const defaultContinueMessage = "Continue the task. Review your prior work above and proceed with any remaining work. If everything is already complete, respond with TASK_COMPLETE.";
|
|
5721
6139
|
const userMessage = continuationContext.newUserMessage || defaultContinueMessage;
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
},
|
|
5733
|
-
{
|
|
5734
|
-
role: "user",
|
|
5735
|
-
content: [userMessage, phaseBlock, toolsBlock, bootstrapBlock, candidateBlock, "", multiSessionInstruction].join("\n")
|
|
5736
|
-
}
|
|
5737
|
-
];
|
|
5738
|
-
return messages2;
|
|
5739
|
-
}
|
|
5740
|
-
const messages = [
|
|
6140
|
+
const userContent = [
|
|
6141
|
+
userMessage,
|
|
6142
|
+
phaseBlock,
|
|
6143
|
+
toolsBlock,
|
|
6144
|
+
bootstrapBlock,
|
|
6145
|
+
candidateBlock,
|
|
6146
|
+
"",
|
|
6147
|
+
multiSessionInstruction
|
|
6148
|
+
].join("\n");
|
|
6149
|
+
const fullHistoryMessages = [
|
|
5741
6150
|
...continuationContext.previousMessages,
|
|
5742
6151
|
{
|
|
5743
6152
|
role: "system",
|
|
@@ -5745,14 +6154,79 @@ Do NOT redo any of the above work.`
|
|
|
5745
6154
|
},
|
|
5746
6155
|
{
|
|
5747
6156
|
role: "user",
|
|
5748
|
-
content:
|
|
6157
|
+
content: userContent
|
|
5749
6158
|
}
|
|
5750
6159
|
];
|
|
5751
|
-
|
|
6160
|
+
const summaryText = this.generateCompactSummary(state, compactInstructions);
|
|
6161
|
+
const breakdown = this.buildContextBudgetBreakdown({
|
|
6162
|
+
historyMessages: continuationContext.previousMessages,
|
|
6163
|
+
currentTurnContent: userContent,
|
|
6164
|
+
localTools: compactionOptions?.localTools,
|
|
6165
|
+
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
6166
|
+
summaryText,
|
|
6167
|
+
contextLimitTokens: compactionOptions?.contextLimitTokens
|
|
6168
|
+
});
|
|
6169
|
+
await maybeEmitToolDefinitionWarning(breakdown);
|
|
6170
|
+
if (continuationContext.compact) {
|
|
6171
|
+
return {
|
|
6172
|
+
messages: await this.buildCompactHistoryMessagesWithLifecycle(
|
|
6173
|
+
state,
|
|
6174
|
+
userContent,
|
|
6175
|
+
sessionIndex,
|
|
6176
|
+
{
|
|
6177
|
+
mode: "forced",
|
|
6178
|
+
strategy: "summary_fallback",
|
|
6179
|
+
model: compactionOptions?.model,
|
|
6180
|
+
beforeTokens: breakdown.estimatedInputTokens,
|
|
6181
|
+
afterTokens: (breakdown.summaryTokens || 0) + breakdown.currentTurnTokens + breakdown.toolDefinitionTokens,
|
|
6182
|
+
thresholdTokens: compactionOptions?.autoCompactTokenThreshold,
|
|
6183
|
+
contextLimitTokens: compactionOptions?.contextLimitTokens,
|
|
6184
|
+
effectiveInputBudgetTokens: breakdown.effectiveInputBudgetTokens,
|
|
6185
|
+
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
6186
|
+
breakdown,
|
|
6187
|
+
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
6188
|
+
compactInstructions
|
|
6189
|
+
}
|
|
6190
|
+
),
|
|
6191
|
+
requestContextManagement
|
|
6192
|
+
};
|
|
6193
|
+
}
|
|
6194
|
+
if (resolvedStrategy === "summary_fallback" && typeof compactionOptions?.autoCompactTokenThreshold === "number" && compactionOptions.autoCompactTokenThreshold > 0 && breakdown.estimatedInputTokens >= compactionOptions.autoCompactTokenThreshold) {
|
|
6195
|
+
return {
|
|
6196
|
+
messages: await this.buildCompactHistoryMessagesWithLifecycle(
|
|
6197
|
+
state,
|
|
6198
|
+
userContent,
|
|
6199
|
+
sessionIndex,
|
|
6200
|
+
{
|
|
6201
|
+
mode: "auto",
|
|
6202
|
+
strategy: "summary_fallback",
|
|
6203
|
+
model: compactionOptions?.model,
|
|
6204
|
+
beforeTokens: breakdown.estimatedInputTokens,
|
|
6205
|
+
afterTokens: (breakdown.summaryTokens || 0) + breakdown.currentTurnTokens + breakdown.toolDefinitionTokens,
|
|
6206
|
+
thresholdTokens: compactionOptions?.autoCompactTokenThreshold,
|
|
6207
|
+
contextLimitTokens: compactionOptions?.contextLimitTokens,
|
|
6208
|
+
effectiveInputBudgetTokens: breakdown.effectiveInputBudgetTokens,
|
|
6209
|
+
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
6210
|
+
breakdown,
|
|
6211
|
+
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
6212
|
+
compactInstructions
|
|
6213
|
+
}
|
|
6214
|
+
),
|
|
6215
|
+
requestContextManagement
|
|
6216
|
+
};
|
|
6217
|
+
}
|
|
6218
|
+
return {
|
|
6219
|
+
messages: fullHistoryMessages,
|
|
6220
|
+
requestContextManagement,
|
|
6221
|
+
pendingNativeCompactionEvent: buildNativeCompactionEvent("auto", breakdown)
|
|
6222
|
+
};
|
|
5752
6223
|
}
|
|
5753
6224
|
if (sessionIndex === 0) {
|
|
5754
6225
|
const content2 = [originalMessage, phaseBlock, toolsBlock, bootstrapBlock, candidateBlock, "", multiSessionInstruction].join("\n");
|
|
5755
|
-
return
|
|
6226
|
+
return {
|
|
6227
|
+
messages: [{ role: "user", content: content2 }],
|
|
6228
|
+
requestContextManagement
|
|
6229
|
+
};
|
|
5756
6230
|
}
|
|
5757
6231
|
const recentSessions = state.sessions.slice(-5);
|
|
5758
6232
|
const progressSummary = recentSessions.map(
|
|
@@ -5786,10 +6260,49 @@ Do NOT redo any of the above work.`
|
|
|
5786
6260
|
...historyMessages.slice(-MAX_HISTORY_MESSAGES)
|
|
5787
6261
|
];
|
|
5788
6262
|
}
|
|
5789
|
-
|
|
6263
|
+
const summaryText = this.generateCompactSummary(state, compactInstructions);
|
|
6264
|
+
const breakdown = this.buildContextBudgetBreakdown({
|
|
6265
|
+
historyMessages,
|
|
6266
|
+
currentTurnContent: continuationContent,
|
|
6267
|
+
localTools: compactionOptions?.localTools,
|
|
6268
|
+
builtinToolSchemas: compactionOptions?.builtinToolSchemas || [],
|
|
6269
|
+
summaryText,
|
|
6270
|
+
contextLimitTokens: compactionOptions?.contextLimitTokens
|
|
6271
|
+
});
|
|
6272
|
+
await maybeEmitToolDefinitionWarning(breakdown);
|
|
6273
|
+
const messages = [
|
|
5790
6274
|
...historyMessages,
|
|
5791
6275
|
{ role: "user", content: continuationContent }
|
|
5792
6276
|
];
|
|
6277
|
+
if (resolvedStrategy === "summary_fallback" && typeof compactionOptions?.autoCompactTokenThreshold === "number" && compactionOptions.autoCompactTokenThreshold > 0 && breakdown.estimatedInputTokens >= compactionOptions.autoCompactTokenThreshold) {
|
|
6278
|
+
return {
|
|
6279
|
+
messages: await this.buildCompactHistoryMessagesWithLifecycle(
|
|
6280
|
+
state,
|
|
6281
|
+
continuationContent,
|
|
6282
|
+
sessionIndex,
|
|
6283
|
+
{
|
|
6284
|
+
mode: "auto",
|
|
6285
|
+
strategy: "summary_fallback",
|
|
6286
|
+
model: compactionOptions?.model,
|
|
6287
|
+
beforeTokens: breakdown.estimatedInputTokens,
|
|
6288
|
+
afterTokens: (breakdown.summaryTokens || 0) + breakdown.currentTurnTokens + breakdown.toolDefinitionTokens,
|
|
6289
|
+
thresholdTokens: compactionOptions?.autoCompactTokenThreshold,
|
|
6290
|
+
contextLimitTokens: compactionOptions?.contextLimitTokens,
|
|
6291
|
+
effectiveInputBudgetTokens: breakdown.effectiveInputBudgetTokens,
|
|
6292
|
+
reservedOutputTokens: breakdown.reservedOutputTokens,
|
|
6293
|
+
breakdown,
|
|
6294
|
+
onContextCompaction: compactionOptions?.onContextCompaction,
|
|
6295
|
+
compactInstructions
|
|
6296
|
+
}
|
|
6297
|
+
),
|
|
6298
|
+
requestContextManagement
|
|
6299
|
+
};
|
|
6300
|
+
}
|
|
6301
|
+
return {
|
|
6302
|
+
messages,
|
|
6303
|
+
requestContextManagement,
|
|
6304
|
+
pendingNativeCompactionEvent: buildNativeCompactionEvent("auto", breakdown)
|
|
6305
|
+
};
|
|
5793
6306
|
}
|
|
5794
6307
|
const recoveryMessage = this.buildStuckTurnRecoveryMessage(state, wf);
|
|
5795
6308
|
const content = [
|
|
@@ -5809,7 +6322,10 @@ Do NOT redo any of the above work.`
|
|
|
5809
6322
|
"",
|
|
5810
6323
|
"Continue where you left off. Do not redo previous work. If the task is already complete, respond with TASK_COMPLETE."
|
|
5811
6324
|
].join("\n");
|
|
5812
|
-
return
|
|
6325
|
+
return {
|
|
6326
|
+
messages: [{ role: "user", content }],
|
|
6327
|
+
requestContextManagement
|
|
6328
|
+
};
|
|
5813
6329
|
}
|
|
5814
6330
|
/**
|
|
5815
6331
|
* Upsert a record to sync long-task progress to the dashboard.
|
|
@@ -5859,6 +6375,8 @@ Do NOT redo any of the above work.`
|
|
|
5859
6375
|
}
|
|
5860
6376
|
}
|
|
5861
6377
|
};
|
|
6378
|
+
_AgentsEndpoint.AUTO_COMPACT_SUMMARY_PREFIX = "You are continuing a long-running task. Here is a compact summary of prior work:";
|
|
6379
|
+
_AgentsEndpoint.FORCED_COMPACT_SUMMARY_PREFIX = "You are continuing a previously completed task. Here is a summary of prior work:";
|
|
5862
6380
|
/** Stop phrases that indicate the agent considers its task complete. */
|
|
5863
6381
|
_AgentsEndpoint.STOP_PHRASES = [
|
|
5864
6382
|
"DONE:",
|