@bastani/atomic 0.8.26-alpha.6 → 0.8.26-alpha.8
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/CHANGELOG.md +29 -0
- package/README.md +5 -5
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +12 -0
- package/dist/builtin/subagents/agents/codebase-online-researcher.md +9 -9
- package/dist/builtin/subagents/agents/debugger.md +6 -6
- package/dist/builtin/subagents/package.json +4 -4
- package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/builtin/subagents/skills/browser/EXAMPLES.md +151 -0
- package/dist/builtin/subagents/skills/browser/LICENSE.txt +21 -0
- package/dist/builtin/subagents/skills/browser/REFERENCE.md +451 -0
- package/dist/builtin/subagents/skills/browser/SKILL.md +170 -0
- package/dist/builtin/subagents/skills/subagent/SKILL.md +4 -4
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +17 -0
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +4 -1
- package/dist/builtin/workflows/builtin/goal.ts +127 -99
- package/dist/builtin/workflows/builtin/open-claude-design.ts +224 -147
- package/dist/builtin/workflows/builtin/ralph.ts +160 -197
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/skills/research-codebase/SKILL.md +1 -1
- package/dist/builtin/workflows/src/extension/wiring.ts +13 -1
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +12 -6
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +2 -2
- package/dist/builtin/workflows/src/shared/authoring-contract.d.ts +2 -2
- package/dist/builtin/workflows/src/shared/types.ts +3 -3
- package/dist/builtin/workflows/src/tui/stage-chat-view.ts +2 -1
- package/dist/core/agent-session.d.ts +33 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +155 -182
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +1 -1
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +6 -3
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +23 -10
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/context-compaction.d.ts +61 -0
- package/dist/core/compaction/context-compaction.d.ts.map +1 -0
- package/dist/core/compaction/context-compaction.js +602 -0
- package/dist/core/compaction/context-compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +1 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +1 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/extensions/types.d.ts +3 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/session-manager.d.ts +41 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +146 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +1 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host.js +17 -0
- package/dist/modes/interactive/components/chat-session-host.js.map +1 -1
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts +17 -0
- package/dist/modes/interactive/components/context-compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/context-compaction-summary-message.js +83 -0
- package/dist/modes/interactive/components/context-compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +72 -8
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +13 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +8 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +4 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +14 -3
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/compaction.md +89 -37
- package/docs/custom-provider.md +11 -9
- package/docs/extensions.md +44 -40
- package/docs/index.md +2 -9
- package/docs/json.md +15 -12
- package/docs/packages.md +2 -0
- package/docs/providers.md +4 -1
- package/docs/quickstart.md +5 -12
- package/docs/rpc.md +38 -23
- package/docs/sdk.md +3 -10
- package/docs/session-format.md +26 -13
- package/docs/sessions.md +3 -3
- package/docs/settings.md +2 -2
- package/docs/skills.md +1 -15
- package/docs/termux.md +9 -10
- package/docs/themes.md +2 -2
- package/docs/tmux.md +3 -3
- package/docs/tui.md +19 -32
- package/docs/usage.md +2 -2
- package/docs/workflows.md +44 -2
- package/package.json +4 -12
- package/dist/builtin/subagents/skills/browser-use/SKILL.md +0 -234
- package/dist/builtin/subagents/skills/browser-use/references/cdp-python.md +0 -76
- package/dist/builtin/subagents/skills/browser-use/references/multi-session.md +0 -92
- package/node_modules/@earendil-works/pi-tui/README.md +0 -779
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts +0 -54
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js +0 -632
- package/node_modules/@earendil-works/pi-tui/dist/autocomplete.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts +0 -22
- package/node_modules/@earendil-works/pi-tui/dist/components/box.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js +0 -104
- package/node_modules/@earendil-works/pi-tui/dist/components/box.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts +0 -22
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js +0 -35
- package/node_modules/@earendil-works/pi-tui/dist/components/cancellable-loader.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +0 -249
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +0 -1857
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts +0 -28
- package/node_modules/@earendil-works/pi-tui/dist/components/image.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js +0 -89
- package/node_modules/@earendil-works/pi-tui/dist/components/image.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts +0 -37
- package/node_modules/@earendil-works/pi-tui/dist/components/input.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js +0 -378
- package/node_modules/@earendil-works/pi-tui/dist/components/input.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts +0 -31
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js +0 -69
- package/node_modules/@earendil-works/pi-tui/dist/components/loader.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +0 -96
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +0 -644
- package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts +0 -50
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js +0 -159
- package/node_modules/@earendil-works/pi-tui/dist/components/select-list.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts +0 -50
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js +0 -185
- package/node_modules/@earendil-works/pi-tui/dist/components/settings-list.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts +0 -12
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js +0 -23
- package/node_modules/@earendil-works/pi-tui/dist/components/spacer.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts +0 -19
- package/node_modules/@earendil-works/pi-tui/dist/components/text.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js +0 -89
- package/node_modules/@earendil-works/pi-tui/dist/components/text.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts +0 -13
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js +0 -51
- package/node_modules/@earendil-works/pi-tui/dist/components/truncated-text.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts +0 -39
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js +0 -2
- package/node_modules/@earendil-works/pi-tui/dist/editor-component.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +0 -16
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +0 -110
- package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +0 -23
- package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/index.js +0 -32
- package/node_modules/@earendil-works/pi-tui/dist/index.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts +0 -193
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js +0 -174
- package/node_modules/@earendil-works/pi-tui/dist/keybindings.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts +0 -184
- package/node_modules/@earendil-works/pi-tui/dist/keys.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/keys.js +0 -1173
- package/node_modules/@earendil-works/pi-tui/dist/keys.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts +0 -28
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js +0 -44
- package/node_modules/@earendil-works/pi-tui/dist/kill-ring.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts +0 -3
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js +0 -53
- package/node_modules/@earendil-works/pi-tui/dist/native-modifiers.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +0 -50
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +0 -361
- package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts +0 -90
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js +0 -366
- package/node_modules/@earendil-works/pi-tui/dist/terminal-image.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +0 -113
- package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js +0 -472
- package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +0 -227
- package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/tui.js +0 -1106
- package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts +0 -17
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js +0 -25
- package/node_modules/@earendil-works/pi-tui/dist/undo-stack.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts +0 -84
- package/node_modules/@earendil-works/pi-tui/dist/utils.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/utils.js +0 -1029
- package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts +0 -25
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js +0 -96
- package/node_modules/@earendil-works/pi-tui/dist/word-navigation.js.map +0 -1
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
- package/node_modules/@earendil-works/pi-tui/package.json +0 -47
- package/node_modules/get-east-asian-width/index.d.ts +0 -60
- package/node_modules/get-east-asian-width/index.js +0 -30
- package/node_modules/get-east-asian-width/license +0 -9
- package/node_modules/get-east-asian-width/lookup-data.js +0 -21
- package/node_modules/get-east-asian-width/lookup.js +0 -138
- package/node_modules/get-east-asian-width/package.json +0 -71
- package/node_modules/get-east-asian-width/readme.md +0 -65
- package/node_modules/get-east-asian-width/utilities.js +0 -24
- package/node_modules/marked/LICENSE.md +0 -44
- package/node_modules/marked/README.md +0 -106
- package/node_modules/marked/bin/main.js +0 -282
- package/node_modules/marked/bin/marked.js +0 -15
- package/node_modules/marked/lib/marked.cjs +0 -2211
- package/node_modules/marked/lib/marked.cjs.map +0 -7
- package/node_modules/marked/lib/marked.d.cts +0 -728
- package/node_modules/marked/lib/marked.d.ts +0 -728
- package/node_modules/marked/lib/marked.esm.js +0 -2189
- package/node_modules/marked/lib/marked.esm.js.map +0 -7
- package/node_modules/marked/lib/marked.umd.js +0 -2213
- package/node_modules/marked/lib/marked.umd.js.map +0 -7
- package/node_modules/marked/man/marked.1 +0 -111
- package/node_modules/marked/man/marked.1.md +0 -92
- package/node_modules/marked/marked.min.js +0 -69
- package/node_modules/marked/package.json +0 -111
|
@@ -22,14 +22,14 @@ import { sleep } from "../utils/sleep.js";
|
|
|
22
22
|
import { ATOMIC_GUIDE_COMMAND_NAME, ATOMIC_GUIDE_HELP_CHOICES, atomicGuideModeForChoice, getAtomicGuideMessage, isAtomicGuideHelpChoice, normalizeAtomicGuideMode, } from "./atomic-guide-command.js";
|
|
23
23
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
24
24
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
25
|
-
import { calculateContextTokens, collectEntriesForBranchSummary,
|
|
25
|
+
import { calculateContextTokens, collectEntriesForBranchSummary, contextCompact as runContextCompact, estimateContextTokens, generateBranchSummary, prepareContextCompaction, shouldCompact, } from "./compaction/index.js";
|
|
26
26
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
27
27
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
28
28
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
29
29
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
30
30
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
31
31
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
32
|
-
import { CURRENT_SESSION_VERSION,
|
|
32
|
+
import { CURRENT_SESSION_VERSION, getLatestCompactionBoundaryEntry } from "./session-manager.js";
|
|
33
33
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
34
34
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
35
35
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
@@ -1476,11 +1476,41 @@ export class AgentSession {
|
|
|
1476
1476
|
// Compaction
|
|
1477
1477
|
// =========================================================================
|
|
1478
1478
|
/**
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
|
|
1479
|
+
* Apply validated logical deletions and rebuild active agent context.
|
|
1480
|
+
* Retained transcript entries/content blocks stay verbatim.
|
|
1481
|
+
*/
|
|
1482
|
+
async _applyContextVerbatimCompaction(options) {
|
|
1483
|
+
if (!this.model) {
|
|
1484
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1485
|
+
}
|
|
1486
|
+
const pathEntries = this.sessionManager.getBranch();
|
|
1487
|
+
const settings = this.settingsManager.getCompactionSettings();
|
|
1488
|
+
const preparation = prepareContextCompaction(pathEntries, settings);
|
|
1489
|
+
if (!preparation) {
|
|
1490
|
+
return undefined;
|
|
1491
|
+
}
|
|
1492
|
+
const validated = await runContextCompact(preparation, this.model, options.apiKey, options.headers, options.abortController.signal, this.thinkingLevel);
|
|
1493
|
+
if (options.abortController.signal.aborted) {
|
|
1494
|
+
throw new Error("Compaction cancelled");
|
|
1495
|
+
}
|
|
1496
|
+
const backupPath = this.sessionManager.writeBackupSnapshot(options.backupLabel);
|
|
1497
|
+
this.sessionManager.appendContextCompaction(validated.deletedTargets, validated.protectedEntryIds, validated.stats, backupPath);
|
|
1498
|
+
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1499
|
+
this.agent.state.messages = sessionContext.messages;
|
|
1500
|
+
return {
|
|
1501
|
+
...validated,
|
|
1502
|
+
promptVersion: 1,
|
|
1503
|
+
...(backupPath ? { backupPath } : {}),
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* Manually compact the session context using deletion-only verbatim context compaction.
|
|
1508
|
+
* Aborts current agent operation first. Custom summary instructions are not accepted.
|
|
1482
1509
|
*/
|
|
1483
1510
|
async compact(customInstructions) {
|
|
1511
|
+
if (customInstructions?.trim()) {
|
|
1512
|
+
throw new Error("Custom compaction instructions are not supported; use /compact without arguments");
|
|
1513
|
+
}
|
|
1484
1514
|
this._disconnectFromAgent();
|
|
1485
1515
|
await this.abort();
|
|
1486
1516
|
this._compactionAbortController = new AbortController();
|
|
@@ -1490,84 +1520,23 @@ export class AgentSession {
|
|
|
1490
1520
|
throw new Error(formatNoModelSelectedMessage());
|
|
1491
1521
|
}
|
|
1492
1522
|
const { apiKey, headers } = await this._getRequiredRequestAuth(this.model);
|
|
1493
|
-
const
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
throw new Error("Already compacted");
|
|
1501
|
-
}
|
|
1523
|
+
const result = await this._applyContextVerbatimCompaction({
|
|
1524
|
+
apiKey,
|
|
1525
|
+
headers,
|
|
1526
|
+
abortController: this._compactionAbortController,
|
|
1527
|
+
backupLabel: "compact",
|
|
1528
|
+
});
|
|
1529
|
+
if (!result) {
|
|
1502
1530
|
throw new Error("Nothing to compact (session too small)");
|
|
1503
1531
|
}
|
|
1504
|
-
let extensionCompaction;
|
|
1505
|
-
let fromExtension = false;
|
|
1506
|
-
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1507
|
-
const result = (await this._extensionRunner.emit({
|
|
1508
|
-
type: "session_before_compact",
|
|
1509
|
-
preparation,
|
|
1510
|
-
branchEntries: pathEntries,
|
|
1511
|
-
customInstructions,
|
|
1512
|
-
signal: this._compactionAbortController.signal,
|
|
1513
|
-
}));
|
|
1514
|
-
if (result?.cancel) {
|
|
1515
|
-
throw new Error("Compaction cancelled");
|
|
1516
|
-
}
|
|
1517
|
-
if (result?.compaction) {
|
|
1518
|
-
extensionCompaction = result.compaction;
|
|
1519
|
-
fromExtension = true;
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
let summary;
|
|
1523
|
-
let firstKeptEntryId;
|
|
1524
|
-
let tokensBefore;
|
|
1525
|
-
let details;
|
|
1526
|
-
if (extensionCompaction) {
|
|
1527
|
-
// Extension provided compaction content
|
|
1528
|
-
summary = extensionCompaction.summary;
|
|
1529
|
-
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1530
|
-
tokensBefore = extensionCompaction.tokensBefore;
|
|
1531
|
-
details = extensionCompaction.details;
|
|
1532
|
-
}
|
|
1533
|
-
else {
|
|
1534
|
-
// Generate compaction result
|
|
1535
|
-
const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel);
|
|
1536
|
-
summary = result.summary;
|
|
1537
|
-
firstKeptEntryId = result.firstKeptEntryId;
|
|
1538
|
-
tokensBefore = result.tokensBefore;
|
|
1539
|
-
details = result.details;
|
|
1540
|
-
}
|
|
1541
|
-
if (this._compactionAbortController.signal.aborted) {
|
|
1542
|
-
throw new Error("Compaction cancelled");
|
|
1543
|
-
}
|
|
1544
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1545
|
-
const newEntries = this.sessionManager.getEntries();
|
|
1546
|
-
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1547
|
-
this.agent.state.messages = sessionContext.messages;
|
|
1548
|
-
// Get the saved compaction entry for the extension event
|
|
1549
|
-
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
1550
|
-
if (this._extensionRunner && savedCompactionEntry) {
|
|
1551
|
-
await this._extensionRunner.emit({
|
|
1552
|
-
type: "session_compact",
|
|
1553
|
-
compactionEntry: savedCompactionEntry,
|
|
1554
|
-
fromExtension,
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
const compactionResult = {
|
|
1558
|
-
summary,
|
|
1559
|
-
firstKeptEntryId,
|
|
1560
|
-
tokensBefore,
|
|
1561
|
-
details,
|
|
1562
|
-
};
|
|
1563
1532
|
this._emit({
|
|
1564
1533
|
type: "compaction_end",
|
|
1565
1534
|
reason: "manual",
|
|
1566
|
-
result
|
|
1535
|
+
result,
|
|
1567
1536
|
aborted: false,
|
|
1568
1537
|
willRetry: false,
|
|
1569
1538
|
});
|
|
1570
|
-
return
|
|
1539
|
+
return result;
|
|
1571
1540
|
}
|
|
1572
1541
|
catch (error) {
|
|
1573
1542
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1587,6 +1556,56 @@ export class AgentSession {
|
|
|
1587
1556
|
this._reconnectToAgent();
|
|
1588
1557
|
}
|
|
1589
1558
|
}
|
|
1559
|
+
/**
|
|
1560
|
+
* Manually compact the session context by applying validated logical deletions.
|
|
1561
|
+
* Retained transcript entries/content blocks stay verbatim; no user prompt text is accepted.
|
|
1562
|
+
*/
|
|
1563
|
+
async contextCompact() {
|
|
1564
|
+
this._disconnectFromAgent();
|
|
1565
|
+
await this.abort();
|
|
1566
|
+
this._compactionAbortController = new AbortController();
|
|
1567
|
+
this._emit({ type: "context_compaction_start", reason: "manual" });
|
|
1568
|
+
try {
|
|
1569
|
+
if (!this.model) {
|
|
1570
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1571
|
+
}
|
|
1572
|
+
const { apiKey, headers } = await this._getRequiredRequestAuth(this.model);
|
|
1573
|
+
const result = await this._applyContextVerbatimCompaction({
|
|
1574
|
+
apiKey,
|
|
1575
|
+
headers,
|
|
1576
|
+
abortController: this._compactionAbortController,
|
|
1577
|
+
backupLabel: "context-compact",
|
|
1578
|
+
});
|
|
1579
|
+
if (!result) {
|
|
1580
|
+
throw new Error("Nothing to context-compact (session too small)");
|
|
1581
|
+
}
|
|
1582
|
+
this._emit({
|
|
1583
|
+
type: "context_compaction_end",
|
|
1584
|
+
reason: "manual",
|
|
1585
|
+
result,
|
|
1586
|
+
aborted: false,
|
|
1587
|
+
willRetry: false,
|
|
1588
|
+
});
|
|
1589
|
+
return result;
|
|
1590
|
+
}
|
|
1591
|
+
catch (error) {
|
|
1592
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1593
|
+
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1594
|
+
this._emit({
|
|
1595
|
+
type: "context_compaction_end",
|
|
1596
|
+
reason: "manual",
|
|
1597
|
+
result: undefined,
|
|
1598
|
+
aborted,
|
|
1599
|
+
willRetry: false,
|
|
1600
|
+
errorMessage: aborted ? undefined : `Context compaction failed: ${message}`,
|
|
1601
|
+
});
|
|
1602
|
+
throw error;
|
|
1603
|
+
}
|
|
1604
|
+
finally {
|
|
1605
|
+
this._compactionAbortController = undefined;
|
|
1606
|
+
this._reconnectToAgent();
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1590
1609
|
/**
|
|
1591
1610
|
* Cancel in-progress compaction (manual or auto).
|
|
1592
1611
|
*/
|
|
@@ -1606,7 +1625,7 @@ export class AgentSession {
|
|
|
1606
1625
|
*
|
|
1607
1626
|
* Two cases:
|
|
1608
1627
|
* 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry
|
|
1609
|
-
* 2. Threshold: Context over threshold, compact,
|
|
1628
|
+
* 2. Threshold: Context over threshold, compact, resume queued active-turn work if present; otherwise wait for user
|
|
1610
1629
|
*
|
|
1611
1630
|
* @param assistantMessage The assistant message to check
|
|
1612
1631
|
* @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
|
|
@@ -1627,9 +1646,10 @@ export class AgentSession {
|
|
|
1627
1646
|
// Skip compaction checks if this assistant message is older than the latest
|
|
1628
1647
|
// compaction boundary. This prevents a stale pre-compaction usage/error
|
|
1629
1648
|
// from retriggering compaction on the first prompt after compaction.
|
|
1630
|
-
const
|
|
1631
|
-
const
|
|
1632
|
-
|
|
1649
|
+
const compactionBoundaryEntry = getLatestCompactionBoundaryEntry(this.sessionManager.getBranch());
|
|
1650
|
+
const assistantIsFromBeforeCompactionBoundary = compactionBoundaryEntry !== null &&
|
|
1651
|
+
assistantMessage.timestamp <= new Date(compactionBoundaryEntry.timestamp).getTime();
|
|
1652
|
+
if (assistantIsFromBeforeCompactionBoundary) {
|
|
1633
1653
|
return;
|
|
1634
1654
|
}
|
|
1635
1655
|
// Case 1: Overflow - LLM returned context overflow error
|
|
@@ -1668,9 +1688,9 @@ export class AgentSession {
|
|
|
1668
1688
|
// have stale usage reflecting the old (larger) context and would falsely
|
|
1669
1689
|
// trigger compaction right after one just finished.
|
|
1670
1690
|
const usageMsg = messages[estimate.lastUsageIndex];
|
|
1671
|
-
if (
|
|
1691
|
+
if (compactionBoundaryEntry &&
|
|
1672
1692
|
usageMsg.role === "assistant" &&
|
|
1673
|
-
usageMsg.timestamp <= new Date(
|
|
1693
|
+
usageMsg.timestamp <= new Date(compactionBoundaryEntry.timestamp).getTime()) {
|
|
1674
1694
|
return;
|
|
1675
1695
|
}
|
|
1676
1696
|
contextTokens = estimate.tokens;
|
|
@@ -1682,11 +1702,44 @@ export class AgentSession {
|
|
|
1682
1702
|
await this._runAutoCompaction("threshold", false);
|
|
1683
1703
|
}
|
|
1684
1704
|
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Internal: remove the trailing overflow error from retry context if it is still present.
|
|
1707
|
+
*/
|
|
1708
|
+
_dropTrailingOverflowAssistantErrorIfPresent() {
|
|
1709
|
+
const messages = this.agent.state.messages;
|
|
1710
|
+
const lastMsg = messages[messages.length - 1];
|
|
1711
|
+
if (lastMsg?.role === "assistant" && lastMsg.stopReason === "error") {
|
|
1712
|
+
this.agent.state.messages = messages.slice(0, -1);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Internal: schedule a live post-event continuation probe after compaction_end listeners can flush queues.
|
|
1717
|
+
*/
|
|
1718
|
+
_schedulePostAutoCompactionContinuationProbe(reason, willRetry) {
|
|
1719
|
+
setTimeout(() => {
|
|
1720
|
+
if (this.isCompacting || this.isStreaming) {
|
|
1721
|
+
return;
|
|
1722
|
+
}
|
|
1723
|
+
if (reason === "overflow" && willRetry) {
|
|
1724
|
+
this._resumeAfterAutoCompaction();
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
if (!this.agent.hasQueuedMessages()) {
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
this._resumeAfterAutoCompaction();
|
|
1731
|
+
}, 100);
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Internal: resume generation after successful auto-compaction only when active work remains.
|
|
1735
|
+
*/
|
|
1736
|
+
_resumeAfterAutoCompaction() {
|
|
1737
|
+
this.agent.continue().catch(() => { });
|
|
1738
|
+
}
|
|
1685
1739
|
/**
|
|
1686
1740
|
* Internal: Run auto-compaction with events.
|
|
1687
1741
|
*/
|
|
1688
1742
|
async _runAutoCompaction(reason, willRetry) {
|
|
1689
|
-
const settings = this.settingsManager.getCompactionSettings();
|
|
1690
1743
|
this._emit({ type: "compaction_start", reason });
|
|
1691
1744
|
this._autoCompactionAbortController = new AbortController();
|
|
1692
1745
|
try {
|
|
@@ -1711,10 +1764,13 @@ export class AgentSession {
|
|
|
1711
1764
|
});
|
|
1712
1765
|
return;
|
|
1713
1766
|
}
|
|
1714
|
-
const
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1767
|
+
const result = await this._applyContextVerbatimCompaction({
|
|
1768
|
+
apiKey: authResult.apiKey,
|
|
1769
|
+
headers: authResult.headers,
|
|
1770
|
+
abortController: this._autoCompactionAbortController,
|
|
1771
|
+
backupLabel: reason === "overflow" ? "overflow-auto-compact" : "auto-compact",
|
|
1772
|
+
});
|
|
1773
|
+
if (!result) {
|
|
1718
1774
|
this._emit({
|
|
1719
1775
|
type: "compaction_end",
|
|
1720
1776
|
reason,
|
|
@@ -1724,109 +1780,26 @@ export class AgentSession {
|
|
|
1724
1780
|
});
|
|
1725
1781
|
return;
|
|
1726
1782
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1730
|
-
const extensionResult = (await this._extensionRunner.emit({
|
|
1731
|
-
type: "session_before_compact",
|
|
1732
|
-
preparation,
|
|
1733
|
-
branchEntries: pathEntries,
|
|
1734
|
-
customInstructions: undefined,
|
|
1735
|
-
signal: this._autoCompactionAbortController.signal,
|
|
1736
|
-
}));
|
|
1737
|
-
if (extensionResult?.cancel) {
|
|
1738
|
-
this._emit({
|
|
1739
|
-
type: "compaction_end",
|
|
1740
|
-
reason,
|
|
1741
|
-
result: undefined,
|
|
1742
|
-
aborted: true,
|
|
1743
|
-
willRetry: false,
|
|
1744
|
-
});
|
|
1745
|
-
return;
|
|
1746
|
-
}
|
|
1747
|
-
if (extensionResult?.compaction) {
|
|
1748
|
-
extensionCompaction = extensionResult.compaction;
|
|
1749
|
-
fromExtension = true;
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
let summary;
|
|
1753
|
-
let firstKeptEntryId;
|
|
1754
|
-
let tokensBefore;
|
|
1755
|
-
let details;
|
|
1756
|
-
if (extensionCompaction) {
|
|
1757
|
-
// Extension provided compaction content
|
|
1758
|
-
summary = extensionCompaction.summary;
|
|
1759
|
-
firstKeptEntryId = extensionCompaction.firstKeptEntryId;
|
|
1760
|
-
tokensBefore = extensionCompaction.tokensBefore;
|
|
1761
|
-
details = extensionCompaction.details;
|
|
1783
|
+
if (reason === "overflow" && willRetry) {
|
|
1784
|
+
this._dropTrailingOverflowAssistantErrorIfPresent();
|
|
1762
1785
|
}
|
|
1763
|
-
else {
|
|
1764
|
-
// Generate compaction result
|
|
1765
|
-
const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel);
|
|
1766
|
-
summary = compactResult.summary;
|
|
1767
|
-
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1768
|
-
tokensBefore = compactResult.tokensBefore;
|
|
1769
|
-
details = compactResult.details;
|
|
1770
|
-
}
|
|
1771
|
-
if (this._autoCompactionAbortController.signal.aborted) {
|
|
1772
|
-
this._emit({
|
|
1773
|
-
type: "compaction_end",
|
|
1774
|
-
reason,
|
|
1775
|
-
result: undefined,
|
|
1776
|
-
aborted: true,
|
|
1777
|
-
willRetry: false,
|
|
1778
|
-
});
|
|
1779
|
-
return;
|
|
1780
|
-
}
|
|
1781
|
-
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension);
|
|
1782
|
-
const newEntries = this.sessionManager.getEntries();
|
|
1783
|
-
const sessionContext = this.sessionManager.buildSessionContext();
|
|
1784
|
-
this.agent.state.messages = sessionContext.messages;
|
|
1785
|
-
// Get the saved compaction entry for the extension event
|
|
1786
|
-
const savedCompactionEntry = newEntries.find((e) => e.type === "compaction" && e.summary === summary);
|
|
1787
|
-
if (this._extensionRunner && savedCompactionEntry) {
|
|
1788
|
-
await this._extensionRunner.emit({
|
|
1789
|
-
type: "session_compact",
|
|
1790
|
-
compactionEntry: savedCompactionEntry,
|
|
1791
|
-
fromExtension,
|
|
1792
|
-
});
|
|
1793
|
-
}
|
|
1794
|
-
const result = {
|
|
1795
|
-
summary,
|
|
1796
|
-
firstKeptEntryId,
|
|
1797
|
-
tokensBefore,
|
|
1798
|
-
details,
|
|
1799
|
-
};
|
|
1800
1786
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry });
|
|
1801
|
-
|
|
1802
|
-
const messages = this.agent.state.messages;
|
|
1803
|
-
const lastMsg = messages[messages.length - 1];
|
|
1804
|
-
if (lastMsg?.role === "assistant" && lastMsg.stopReason === "error") {
|
|
1805
|
-
this.agent.state.messages = messages.slice(0, -1);
|
|
1806
|
-
}
|
|
1807
|
-
setTimeout(() => {
|
|
1808
|
-
this.agent.continue().catch(() => { });
|
|
1809
|
-
}, 100);
|
|
1810
|
-
}
|
|
1811
|
-
else if (this.agent.hasQueuedMessages()) {
|
|
1812
|
-
// Auto-compaction can complete while follow-up/steering/custom messages are waiting.
|
|
1813
|
-
// Kick the loop so queued messages are actually delivered.
|
|
1814
|
-
setTimeout(() => {
|
|
1815
|
-
this.agent.continue().catch(() => { });
|
|
1816
|
-
}, 100);
|
|
1817
|
-
}
|
|
1787
|
+
this._schedulePostAutoCompactionContinuationProbe(reason, willRetry);
|
|
1818
1788
|
}
|
|
1819
1789
|
catch (error) {
|
|
1820
1790
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1791
|
+
const aborted = errorMessage === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
1821
1792
|
this._emit({
|
|
1822
1793
|
type: "compaction_end",
|
|
1823
1794
|
reason,
|
|
1824
1795
|
result: undefined,
|
|
1825
|
-
aborted
|
|
1796
|
+
aborted,
|
|
1826
1797
|
willRetry: false,
|
|
1827
|
-
errorMessage:
|
|
1828
|
-
?
|
|
1829
|
-
:
|
|
1798
|
+
errorMessage: aborted
|
|
1799
|
+
? undefined
|
|
1800
|
+
: reason === "overflow"
|
|
1801
|
+
? `Context overflow recovery failed: ${errorMessage}`
|
|
1802
|
+
: `Auto-compaction failed: ${errorMessage}`,
|
|
1830
1803
|
});
|
|
1831
1804
|
}
|
|
1832
1805
|
finally {
|
|
@@ -2633,10 +2606,10 @@ export class AgentSession {
|
|
|
2633
2606
|
// We can only trust usage from an assistant that responded after the latest compaction.
|
|
2634
2607
|
// If no such assistant exists, context token count is unknown until the next LLM response.
|
|
2635
2608
|
const branchEntries = this.sessionManager.getBranch();
|
|
2636
|
-
const
|
|
2637
|
-
if (
|
|
2609
|
+
const latestCompactionBoundary = getLatestCompactionBoundaryEntry(branchEntries);
|
|
2610
|
+
if (latestCompactionBoundary) {
|
|
2638
2611
|
// Check if there's a valid assistant usage after the compaction boundary
|
|
2639
|
-
const compactionIndex = branchEntries.lastIndexOf(
|
|
2612
|
+
const compactionIndex = branchEntries.lastIndexOf(latestCompactionBoundary);
|
|
2640
2613
|
let hasPostCompactionUsage = false;
|
|
2641
2614
|
for (let i = branchEntries.length - 1; i > compactionIndex; i--) {
|
|
2642
2615
|
const entry = branchEntries[i];
|