@draht/coding-agent 2026.3.14 → 2026.3.25-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/README.md +45 -30
- package/dist/bun/cli.d.ts +3 -0
- package/dist/bun/cli.d.ts.map +1 -0
- package/dist/bun/cli.js +7 -0
- package/dist/bun/cli.js.map +1 -0
- package/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/bun/register-bedrock.d.ts.map +1 -0
- package/dist/bun/register-bedrock.js +4 -0
- package/dist/bun/register-bedrock.js.map +1 -0
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -6
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +4 -0
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +18 -0
- package/dist/cli/initial-message.d.ts.map +1 -0
- package/dist/cli/initial-message.js +22 -0
- package/dist/cli/initial-message.js.map +1 -0
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +2 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -3
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +38 -5
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +201 -73
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts +6 -7
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +8 -107
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -0
- 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 +2 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +7 -3
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +2 -2
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +7 -6
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/template.css +43 -13
- package/dist/core/export-html/template.html +1 -0
- package/dist/core/export-html/template.js +107 -0
- package/dist/core/export-html/tool-renderer.d.ts +2 -2
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +41 -16
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/index.d.ts +4 -3
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +16 -6
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +9 -9
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +89 -71
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +49 -13
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts +4 -11
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js +6 -86
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +13 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +155 -37
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +270 -50
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +222 -134
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +49 -23
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +6 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +41 -17
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/output-guard.d.ts +6 -0
- package/dist/core/output-guard.d.ts.map +1 -0
- package/dist/core/output-guard.js +59 -0
- package/dist/core/output-guard.js.map +1 -0
- package/dist/core/package-manager.d.ts +22 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +373 -53
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/prompt-templates.d.ts +2 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +39 -39
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +43 -8
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +6 -7
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +141 -118
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +4 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +6 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +9 -10
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +8 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +5 -3
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +54 -9
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts +2 -3
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +3 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/source-info.d.ts +18 -0
- package/dist/core/source-info.d.ts.map +1 -0
- package/dist/core/source-info.js +19 -0
- package/dist/core/source-info.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +17 -60
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +24 -6
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +210 -110
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +1 -0
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +14 -2
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +95 -23
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
- package/dist/core/tools/file-mutation-queue.js +37 -0
- package/dist/core/tools/file-mutation-queue.js.map +1 -0
- package/dist/core/tools/find.d.ts +11 -4
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +82 -30
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +15 -4
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +83 -29
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +58 -19
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +51 -26
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +9 -3
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +67 -13
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts +10 -3
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +110 -51
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +21 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -0
- package/dist/core/tools/render-utils.js +49 -0
- package/dist/core/tools/render-utils.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.js +30 -0
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
- package/dist/core/tools/write.d.ts +9 -3
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +168 -30
- package/dist/core/tools/write.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +105 -226
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +0 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +22 -9
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +1 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +2 -2
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +2 -2
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +8 -8
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +6 -6
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +9 -9
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +5 -5
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +8 -8
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +3 -36
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +5 -44
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +6 -6
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +13 -9
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +6 -6
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +4 -4
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +32 -35
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +5 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +5 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +2 -2
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +5 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +5 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +16 -34
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +128 -636
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +27 -16
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +6 -6
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +2 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -11
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +353 -214
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +3 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +63 -37
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +5 -11
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +27 -17
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +3 -4
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/child-process.d.ts +11 -0
- package/dist/utils/child-process.d.ts.map +1 -0
- package/dist/utils/child-process.js +78 -0
- package/dist/utils/child-process.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +94 -11
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +27 -16
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/utils/exif-orientation.d.ts.map +1 -0
- package/dist/utils/exif-orientation.js +158 -0
- package/dist/utils/exif-orientation.js.map +1 -0
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js +5 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-resize.d.ts +5 -5
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +51 -95
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +5 -4
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/custom-provider.md +6 -2
- package/docs/extensions.md +108 -21
- package/docs/keybindings.md +103 -112
- package/docs/models.md +39 -1
- package/docs/packages.md +9 -0
- package/docs/providers.md +7 -0
- package/docs/rpc.md +15 -6
- package/docs/sdk.md +2 -2
- package/docs/settings.md +9 -0
- package/docs/terminal-setup.md +11 -0
- package/docs/tui.md +2 -2
- package/examples/extensions/README.md +2 -2
- package/examples/extensions/antigravity-image-gen.ts +5 -3
- package/examples/extensions/built-in-tool-renderer.ts +8 -8
- package/examples/extensions/commands.ts +3 -3
- package/examples/extensions/minimal-mode.ts +14 -14
- package/examples/extensions/question.ts +2 -2
- package/examples/extensions/questionnaire.ts +2 -2
- package/examples/extensions/subagent/index.ts +30 -8
- package/examples/extensions/titlebar-spinner.ts +2 -2
- package/examples/extensions/todo.ts +2 -2
- package/examples/extensions/tool-override.ts +9 -7
- package/examples/extensions/truncated-tool.ts +8 -5
- package/examples/sdk/04-skills.ts +8 -2
- package/examples/sdk/08-prompt-templates.ts +8 -2
- package/examples/sdk/12-full-control.ts +0 -1
- package/examples/sdk/README.md +1 -1
- package/package.json +4 -4
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Modes use this class and add their own I/O layer on top.
|
|
14
14
|
*/
|
|
15
|
-
import { readFileSync } from "node:fs";
|
|
16
|
-
import { basename, dirname, join } from "node:path";
|
|
15
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
17
17
|
import { isContextOverflow, modelsAreEqual, resetApiProviders, supportsXhigh } from "@draht/ai";
|
|
18
18
|
import { getDocsPath } from "../config.js";
|
|
19
19
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
@@ -24,12 +24,13 @@ import { calculateContextTokens, collectEntriesForBranchSummary, compact, estima
|
|
|
24
24
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
25
25
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
26
26
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
27
|
-
import { ExtensionRunner, wrapRegisteredTools,
|
|
27
|
+
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
28
28
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
29
|
-
import { getLatestCompactionEntry } from "./session-manager.js";
|
|
30
|
-
import {
|
|
29
|
+
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
30
|
+
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
31
31
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
32
|
-
import {
|
|
32
|
+
import { createAllToolDefinitions } from "./tools/index.js";
|
|
33
|
+
import { createToolDefinitionFromAgentTool, wrapToolDefinition } from "./tools/tool-definition-wrapper.js";
|
|
33
34
|
/**
|
|
34
35
|
* Parse a skill block from message text.
|
|
35
36
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -89,7 +90,7 @@ export class AgentSession {
|
|
|
89
90
|
_turnIndex = 0;
|
|
90
91
|
_resourceLoader;
|
|
91
92
|
_customTools;
|
|
92
|
-
|
|
93
|
+
_baseToolDefinitions = new Map();
|
|
93
94
|
_cwd;
|
|
94
95
|
_extensionRunnerRef;
|
|
95
96
|
_initialActiveToolNames;
|
|
@@ -103,6 +104,7 @@ export class AgentSession {
|
|
|
103
104
|
_modelRegistry;
|
|
104
105
|
// Tool registry for extension getTools/setTools
|
|
105
106
|
_toolRegistry = new Map();
|
|
107
|
+
_toolDefinitions = new Map();
|
|
106
108
|
_toolPromptSnippets = new Map();
|
|
107
109
|
_toolPromptGuidelines = new Map();
|
|
108
110
|
// Base system prompt (without extension appends) - used to apply fresh appends each turn
|
|
@@ -122,6 +124,7 @@ export class AgentSession {
|
|
|
122
124
|
// Always subscribe to agent events for internal handling
|
|
123
125
|
// (session persistence, extensions, auto-compaction, retry logic)
|
|
124
126
|
this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
|
|
127
|
+
this._installAgentToolHooks();
|
|
125
128
|
this._buildRuntime({
|
|
126
129
|
activeToolNames: this._initialActiveToolNames,
|
|
127
130
|
includeAllExtensionTools: true,
|
|
@@ -131,6 +134,59 @@ export class AgentSession {
|
|
|
131
134
|
get modelRegistry() {
|
|
132
135
|
return this._modelRegistry;
|
|
133
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Install tool hooks once on the Agent instance.
|
|
139
|
+
*
|
|
140
|
+
* The callbacks read `this._extensionRunner` at execution time, so extension reload swaps in the
|
|
141
|
+
* new runner without reinstalling hooks. Extension-specific tool wrappers are still used to adapt
|
|
142
|
+
* registered tool execution to the extension context. Tool call and tool result interception now
|
|
143
|
+
* happens here instead of in wrappers.
|
|
144
|
+
*/
|
|
145
|
+
_installAgentToolHooks() {
|
|
146
|
+
this.agent.setBeforeToolCall(async ({ toolCall, args }) => {
|
|
147
|
+
const runner = this._extensionRunner;
|
|
148
|
+
if (!runner?.hasHandlers("tool_call")) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
await this._agentEventQueue;
|
|
152
|
+
try {
|
|
153
|
+
return await runner.emitToolCall({
|
|
154
|
+
type: "tool_call",
|
|
155
|
+
toolName: toolCall.name,
|
|
156
|
+
toolCallId: toolCall.id,
|
|
157
|
+
input: args,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
if (err instanceof Error) {
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
164
|
+
throw new Error(`Extension failed, blocking execution: ${String(err)}`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
this.agent.setAfterToolCall(async ({ toolCall, args, result, isError }) => {
|
|
168
|
+
const runner = this._extensionRunner;
|
|
169
|
+
if (!runner?.hasHandlers("tool_result")) {
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
const hookResult = await runner.emitToolResult({
|
|
173
|
+
type: "tool_result",
|
|
174
|
+
toolName: toolCall.name,
|
|
175
|
+
toolCallId: toolCall.id,
|
|
176
|
+
input: args,
|
|
177
|
+
content: result.content,
|
|
178
|
+
details: isError ? undefined : result.details,
|
|
179
|
+
isError,
|
|
180
|
+
});
|
|
181
|
+
if (!hookResult || isError) {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
content: hookResult.content,
|
|
186
|
+
details: hookResult.details,
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|
|
134
190
|
// =========================================================================
|
|
135
191
|
// Event Subscription
|
|
136
192
|
// =========================================================================
|
|
@@ -234,7 +290,6 @@ export class AgentSession {
|
|
|
234
290
|
attempt: this._retryAttempt,
|
|
235
291
|
});
|
|
236
292
|
this._retryAttempt = 0;
|
|
237
|
-
this._resolveRetry();
|
|
238
293
|
}
|
|
239
294
|
}
|
|
240
295
|
}
|
|
@@ -248,6 +303,7 @@ export class AgentSession {
|
|
|
248
303
|
if (didRetry)
|
|
249
304
|
return; // Retry was initiated, don't proceed to compaction
|
|
250
305
|
}
|
|
306
|
+
this._resolveRetry();
|
|
251
307
|
await this._checkCompaction(msg);
|
|
252
308
|
}
|
|
253
309
|
}
|
|
@@ -439,15 +495,19 @@ export class AgentSession {
|
|
|
439
495
|
return this.agent.state.tools.map((t) => t.name);
|
|
440
496
|
}
|
|
441
497
|
/**
|
|
442
|
-
* Get all configured tools with name, description, and
|
|
498
|
+
* Get all configured tools with name, description, parameter schema, and source metadata.
|
|
443
499
|
*/
|
|
444
500
|
getAllTools() {
|
|
445
|
-
return Array.from(this.
|
|
446
|
-
name:
|
|
447
|
-
description:
|
|
448
|
-
parameters:
|
|
501
|
+
return Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({
|
|
502
|
+
name: definition.name,
|
|
503
|
+
description: definition.description,
|
|
504
|
+
parameters: definition.parameters,
|
|
505
|
+
sourceInfo,
|
|
449
506
|
}));
|
|
450
507
|
}
|
|
508
|
+
getToolDefinition(name) {
|
|
509
|
+
return this._toolDefinitions.get(name)?.definition;
|
|
510
|
+
}
|
|
451
511
|
/**
|
|
452
512
|
* Set active tools by name.
|
|
453
513
|
* Only tools in the registry can be enabled. Unknown tool names are ignored.
|
|
@@ -748,8 +808,9 @@ export class AgentSession {
|
|
|
748
808
|
}
|
|
749
809
|
}
|
|
750
810
|
/**
|
|
751
|
-
* Queue a steering message
|
|
752
|
-
* Delivered after current
|
|
811
|
+
* Queue a steering message while the agent is running.
|
|
812
|
+
* Delivered after the current assistant turn finishes executing its tool calls,
|
|
813
|
+
* before the next LLM call.
|
|
753
814
|
* Expands skill commands and prompt templates. Errors on extension commands.
|
|
754
815
|
* @param images Optional image attachments to include with the message
|
|
755
816
|
* @throws Error if text is an extension command
|
|
@@ -1371,19 +1432,9 @@ export class AgentSession {
|
|
|
1371
1432
|
// This ensures sessions that hit persistent API errors (e.g. 529) can still compact.
|
|
1372
1433
|
let contextTokens;
|
|
1373
1434
|
if (assistantMessage.stopReason === "error") {
|
|
1374
|
-
const
|
|
1375
|
-
const estimate = estimateContextTokens(messages);
|
|
1435
|
+
const estimate = estimateContextTokens(this.agent.state.messages);
|
|
1376
1436
|
if (estimate.lastUsageIndex === null)
|
|
1377
1437
|
return; // No usage data at all
|
|
1378
|
-
// Verify the usage source is post-compaction. Kept pre-compaction messages
|
|
1379
|
-
// have stale usage reflecting the old (larger) context and would falsely
|
|
1380
|
-
// trigger compaction right after one just finished.
|
|
1381
|
-
const usageMsg = messages[estimate.lastUsageIndex];
|
|
1382
|
-
if (compactionEntry &&
|
|
1383
|
-
usageMsg.role === "assistant" &&
|
|
1384
|
-
usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
|
|
1385
|
-
return;
|
|
1386
|
-
}
|
|
1387
1438
|
contextTokens = estimate.tokens;
|
|
1388
1439
|
}
|
|
1389
1440
|
else {
|
|
@@ -1589,37 +1640,36 @@ export class AgentSession {
|
|
|
1589
1640
|
? runner.onError(this._extensionErrorListener)
|
|
1590
1641
|
: undefined;
|
|
1591
1642
|
}
|
|
1643
|
+
_refreshCurrentModelFromRegistry() {
|
|
1644
|
+
const currentModel = this.model;
|
|
1645
|
+
if (!currentModel) {
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
const refreshedModel = this._modelRegistry.find(currentModel.provider, currentModel.id);
|
|
1649
|
+
if (!refreshedModel || refreshedModel === currentModel) {
|
|
1650
|
+
return;
|
|
1651
|
+
}
|
|
1652
|
+
this.agent.setModel(refreshedModel);
|
|
1653
|
+
}
|
|
1592
1654
|
_bindExtensionCore(runner) {
|
|
1593
|
-
const normalizeLocation = (source) => {
|
|
1594
|
-
if (source === "user" || source === "project" || source === "path") {
|
|
1595
|
-
return source;
|
|
1596
|
-
}
|
|
1597
|
-
return undefined;
|
|
1598
|
-
};
|
|
1599
|
-
const reservedBuiltins = new Set(BUILTIN_SLASH_COMMANDS.map((command) => command.name));
|
|
1600
1655
|
const getCommands = () => {
|
|
1601
|
-
const extensionCommands = runner
|
|
1602
|
-
.
|
|
1603
|
-
.filter(({ command }) => !reservedBuiltins.has(command.name))
|
|
1604
|
-
.map(({ command, extensionPath }) => ({
|
|
1605
|
-
name: command.name,
|
|
1656
|
+
const extensionCommands = runner.getRegisteredCommands().map((command) => ({
|
|
1657
|
+
name: command.invocationName,
|
|
1606
1658
|
description: command.description,
|
|
1607
1659
|
source: "extension",
|
|
1608
|
-
|
|
1660
|
+
sourceInfo: command.sourceInfo,
|
|
1609
1661
|
}));
|
|
1610
1662
|
const templates = this.promptTemplates.map((template) => ({
|
|
1611
1663
|
name: template.name,
|
|
1612
1664
|
description: template.description,
|
|
1613
1665
|
source: "prompt",
|
|
1614
|
-
|
|
1615
|
-
path: template.filePath,
|
|
1666
|
+
sourceInfo: template.sourceInfo,
|
|
1616
1667
|
}));
|
|
1617
1668
|
const skills = this._resourceLoader.getSkills().skills.map((skill) => ({
|
|
1618
1669
|
name: `skill:${skill.name}`,
|
|
1619
1670
|
description: skill.description,
|
|
1620
1671
|
source: "skill",
|
|
1621
|
-
|
|
1622
|
-
path: skill.filePath,
|
|
1672
|
+
sourceInfo: skill.sourceInfo,
|
|
1623
1673
|
}));
|
|
1624
1674
|
return [...extensionCommands, ...templates, ...skills];
|
|
1625
1675
|
};
|
|
@@ -1690,6 +1740,15 @@ export class AgentSession {
|
|
|
1690
1740
|
})();
|
|
1691
1741
|
},
|
|
1692
1742
|
getSystemPrompt: () => this.systemPrompt,
|
|
1743
|
+
}, {
|
|
1744
|
+
registerProvider: (name, config) => {
|
|
1745
|
+
this._modelRegistry.registerProvider(name, config);
|
|
1746
|
+
this._refreshCurrentModelFromRegistry();
|
|
1747
|
+
},
|
|
1748
|
+
unregisterProvider: (name) => {
|
|
1749
|
+
this._modelRegistry.unregisterProvider(name);
|
|
1750
|
+
this._refreshCurrentModelFromRegistry();
|
|
1751
|
+
},
|
|
1693
1752
|
});
|
|
1694
1753
|
}
|
|
1695
1754
|
_refreshToolRegistry(options) {
|
|
@@ -1698,34 +1757,48 @@ export class AgentSession {
|
|
|
1698
1757
|
const registeredTools = this._extensionRunner?.getAllRegisteredTools() ?? [];
|
|
1699
1758
|
const allCustomTools = [
|
|
1700
1759
|
...registeredTools,
|
|
1701
|
-
...this._customTools.map((
|
|
1760
|
+
...this._customTools.map((definition) => ({
|
|
1761
|
+
definition,
|
|
1762
|
+
sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" }),
|
|
1763
|
+
})),
|
|
1702
1764
|
];
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1765
|
+
const definitionRegistry = new Map(Array.from(this._baseToolDefinitions.entries()).map(([name, definition]) => [
|
|
1766
|
+
name,
|
|
1767
|
+
{
|
|
1768
|
+
definition,
|
|
1769
|
+
sourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: "builtin" }),
|
|
1770
|
+
},
|
|
1771
|
+
]));
|
|
1772
|
+
for (const tool of allCustomTools) {
|
|
1773
|
+
definitionRegistry.set(tool.definition.name, {
|
|
1774
|
+
definition: tool.definition,
|
|
1775
|
+
sourceInfo: tool.sourceInfo,
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
this._toolDefinitions = definitionRegistry;
|
|
1779
|
+
this._toolPromptSnippets = new Map(Array.from(definitionRegistry.values())
|
|
1780
|
+
.map(({ definition }) => {
|
|
1781
|
+
const snippet = this._normalizePromptSnippet(definition.promptSnippet);
|
|
1782
|
+
return snippet ? [definition.name, snippet] : undefined;
|
|
1707
1783
|
})
|
|
1708
1784
|
.filter((entry) => entry !== undefined));
|
|
1709
|
-
this._toolPromptGuidelines = new Map(
|
|
1710
|
-
.map((
|
|
1711
|
-
const guidelines = this._normalizePromptGuidelines(
|
|
1712
|
-
return guidelines.length > 0 ? [
|
|
1785
|
+
this._toolPromptGuidelines = new Map(Array.from(definitionRegistry.values())
|
|
1786
|
+
.map(({ definition }) => {
|
|
1787
|
+
const guidelines = this._normalizePromptGuidelines(definition.promptGuidelines);
|
|
1788
|
+
return guidelines.length > 0 ? [definition.name, guidelines] : undefined;
|
|
1713
1789
|
})
|
|
1714
1790
|
.filter((entry) => entry !== undefined));
|
|
1715
1791
|
const wrappedExtensionTools = this._extensionRunner
|
|
1716
1792
|
? wrapRegisteredTools(allCustomTools, this._extensionRunner)
|
|
1717
1793
|
: [];
|
|
1718
|
-
const toolRegistry = new Map(this.
|
|
1794
|
+
const toolRegistry = new Map(Array.from(this._baseToolDefinitions.values()).map((definition) => [
|
|
1795
|
+
definition.name,
|
|
1796
|
+
wrapToolDefinition(definition),
|
|
1797
|
+
]));
|
|
1719
1798
|
for (const tool of wrappedExtensionTools) {
|
|
1720
1799
|
toolRegistry.set(tool.name, tool);
|
|
1721
1800
|
}
|
|
1722
|
-
|
|
1723
|
-
const wrappedAllTools = wrapToolsWithExtensions(Array.from(toolRegistry.values()), this._extensionRunner);
|
|
1724
|
-
this._toolRegistry = new Map(wrappedAllTools.map((tool) => [tool.name, tool]));
|
|
1725
|
-
}
|
|
1726
|
-
else {
|
|
1727
|
-
this._toolRegistry = toolRegistry;
|
|
1728
|
-
}
|
|
1801
|
+
this._toolRegistry = toolRegistry;
|
|
1729
1802
|
const nextActiveToolNames = options?.activeToolNames
|
|
1730
1803
|
? [...options.activeToolNames]
|
|
1731
1804
|
: [...previousActiveToolNames];
|
|
@@ -1746,13 +1819,16 @@ export class AgentSession {
|
|
|
1746
1819
|
_buildRuntime(options) {
|
|
1747
1820
|
const autoResizeImages = this.settingsManager.getImageAutoResize();
|
|
1748
1821
|
const shellCommandPrefix = this.settingsManager.getShellCommandPrefix();
|
|
1749
|
-
const
|
|
1750
|
-
? this._baseToolsOverride
|
|
1751
|
-
|
|
1822
|
+
const baseToolDefinitions = this._baseToolsOverride
|
|
1823
|
+
? Object.fromEntries(Object.entries(this._baseToolsOverride).map(([name, tool]) => [
|
|
1824
|
+
name,
|
|
1825
|
+
createToolDefinitionFromAgentTool(tool),
|
|
1826
|
+
]))
|
|
1827
|
+
: createAllToolDefinitions(this._cwd, {
|
|
1752
1828
|
read: { autoResizeImages },
|
|
1753
1829
|
bash: { commandPrefix: shellCommandPrefix },
|
|
1754
1830
|
});
|
|
1755
|
-
this.
|
|
1831
|
+
this._baseToolDefinitions = new Map(Object.entries(baseToolDefinitions).map(([name, tool]) => [name, tool]));
|
|
1756
1832
|
const extensionsResult = this._resourceLoader.getExtensions();
|
|
1757
1833
|
if (options.flagValues) {
|
|
1758
1834
|
for (const [name, value] of options.flagValues) {
|
|
@@ -1816,8 +1892,8 @@ export class AgentSession {
|
|
|
1816
1892
|
if (isContextOverflow(message, contextWindow))
|
|
1817
1893
|
return false;
|
|
1818
1894
|
const err = message.errorMessage;
|
|
1819
|
-
// Match: overloaded_error, rate limit, 429, 500, 502, 503, 504, service unavailable, connection errors, fetch failed, terminated, retry delay exceeded
|
|
1820
|
-
return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server
|
|
1895
|
+
// Match: overloaded_error, provider returned error, rate limit, 429, 500, 502, 503, 504, service unavailable, network/connection errors, fetch failed, terminated, retry delay exceeded
|
|
1896
|
+
return /overloaded|provider.?returned.?error|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|network.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|socket hang up|timed? out|timeout|terminated|retry delay/i.test(err);
|
|
1821
1897
|
}
|
|
1822
1898
|
/**
|
|
1823
1899
|
* Handle retryable errors with exponential backoff.
|
|
@@ -2380,6 +2456,7 @@ export class AgentSession {
|
|
|
2380
2456
|
total: totalInput + totalOutput + totalCacheRead + totalCacheWrite,
|
|
2381
2457
|
},
|
|
2382
2458
|
cost: totalCost,
|
|
2459
|
+
contextUsage: this.getContextUsage(),
|
|
2383
2460
|
};
|
|
2384
2461
|
}
|
|
2385
2462
|
getContextUsage() {
|
|
@@ -2431,19 +2508,70 @@ export class AgentSession {
|
|
|
2431
2508
|
async exportToHtml(outputPath) {
|
|
2432
2509
|
const themeName = this.settingsManager.getTheme();
|
|
2433
2510
|
// Create tool renderer if we have an extension runner (for custom tool HTML rendering)
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
theme,
|
|
2439
|
-
});
|
|
2440
|
-
}
|
|
2511
|
+
const toolRenderer = createToolHtmlRenderer({
|
|
2512
|
+
getToolDefinition: (name) => this.getToolDefinition(name),
|
|
2513
|
+
theme,
|
|
2514
|
+
});
|
|
2441
2515
|
return await exportSessionToHtml(this.sessionManager, this.state, {
|
|
2442
2516
|
outputPath,
|
|
2443
2517
|
themeName,
|
|
2444
2518
|
toolRenderer,
|
|
2445
2519
|
});
|
|
2446
2520
|
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Export the current session branch to a JSONL file.
|
|
2523
|
+
* Writes the session header followed by all entries on the current branch path.
|
|
2524
|
+
* @param outputPath Target file path. If omitted, generates a timestamped file in cwd.
|
|
2525
|
+
* @returns The resolved output file path.
|
|
2526
|
+
*/
|
|
2527
|
+
exportToJsonl(outputPath) {
|
|
2528
|
+
const filePath = resolve(outputPath ?? `session-${new Date().toISOString().replace(/[:.]/g, "-")}.jsonl`);
|
|
2529
|
+
const dir = dirname(filePath);
|
|
2530
|
+
if (!existsSync(dir)) {
|
|
2531
|
+
mkdirSync(dir, { recursive: true });
|
|
2532
|
+
}
|
|
2533
|
+
const header = {
|
|
2534
|
+
type: "session",
|
|
2535
|
+
version: CURRENT_SESSION_VERSION,
|
|
2536
|
+
id: this.sessionManager.getSessionId(),
|
|
2537
|
+
timestamp: new Date().toISOString(),
|
|
2538
|
+
cwd: this.sessionManager.getCwd(),
|
|
2539
|
+
};
|
|
2540
|
+
const branchEntries = this.sessionManager.getBranch();
|
|
2541
|
+
const lines = [JSON.stringify(header)];
|
|
2542
|
+
// Re-chain parentIds to form a linear sequence
|
|
2543
|
+
let prevId = null;
|
|
2544
|
+
for (const entry of branchEntries) {
|
|
2545
|
+
const linear = { ...entry, parentId: prevId };
|
|
2546
|
+
lines.push(JSON.stringify(linear));
|
|
2547
|
+
prevId = entry.id;
|
|
2548
|
+
}
|
|
2549
|
+
writeFileSync(filePath, `${lines.join("\n")}\n`);
|
|
2550
|
+
return filePath;
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* Import a JSONL session file.
|
|
2554
|
+
* Copies the file into the session directory and switches to it (like /resume).
|
|
2555
|
+
* @param inputPath Path to the JSONL file to import.
|
|
2556
|
+
* @returns true if the session was switched successfully.
|
|
2557
|
+
*/
|
|
2558
|
+
async importFromJsonl(inputPath) {
|
|
2559
|
+
const resolved = resolve(inputPath);
|
|
2560
|
+
if (!existsSync(resolved)) {
|
|
2561
|
+
throw new Error(`File not found: ${resolved}`);
|
|
2562
|
+
}
|
|
2563
|
+
// Copy into the session directory so we don't modify the original
|
|
2564
|
+
const sessionDir = this.sessionManager.getSessionDir();
|
|
2565
|
+
if (!existsSync(sessionDir)) {
|
|
2566
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
2567
|
+
}
|
|
2568
|
+
const destPath = join(sessionDir, basename(resolved));
|
|
2569
|
+
// Avoid overwriting if source and destination are the same file
|
|
2570
|
+
if (resolve(destPath) !== resolved) {
|
|
2571
|
+
copyFileSync(resolved, destPath);
|
|
2572
|
+
}
|
|
2573
|
+
return this.switchSession(destPath);
|
|
2574
|
+
}
|
|
2447
2575
|
// =========================================================================
|
|
2448
2576
|
// Utilities
|
|
2449
2577
|
// =========================================================================
|