@astralyn/pi 1.0.4 → 1.1.0
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 +53 -0
- package/dist/bundle/chunks/{anthropic-messages-YIOJIMVL.js → anthropic-messages-3K3DWVY6.js} +1 -1
- package/dist/bundle/chunks/anthropic.js +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-LDW4FGAQ.js → azure-openai-responses-CH74HGP4.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
- package/dist/bundle/chunks/{chunk-UCXU7KLO.js → chunk-3MMB5I7J.js} +1 -1
- package/dist/bundle/chunks/{chunk-GIG5IHES.js → chunk-5KJH3GGH.js} +1 -1
- package/dist/bundle/chunks/chunk-6VYRLG5F.js +2 -0
- package/dist/bundle/chunks/{chunk-73WG7F7N.js → chunk-C2ARIVS3.js} +1 -1
- package/dist/bundle/chunks/{chunk-23OTKHCH.js → chunk-D3XW5X3Z.js} +490 -260
- package/dist/bundle/chunks/{chunk-IFELM7MW.js → chunk-EJEOEBSJ.js} +1 -1
- package/dist/bundle/chunks/chunk-H35KWBT5.js +11 -0
- package/dist/bundle/chunks/chunk-KAC2YPTW.js +2 -0
- package/dist/bundle/chunks/chunk-MAC4N3BW.js +2 -0
- package/dist/bundle/chunks/chunk-QLU3LESZ.js +2 -0
- package/dist/bundle/chunks/{chunk-A6ALEEY5.js → chunk-TEAAYBTS.js} +1 -1
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XO45ZT3V.js +2 -0
- package/dist/bundle/chunks/codemode-worker.js +101 -5
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/{google-generative-ai-S5A5IBU4.js → google-generative-ai-VVO64ZRQ.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-UBRQFDB4.js → google-vertex-LKS5NUHA.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{llama-cpp-classify-R7DQLTQN.js → llama-cpp-classify-H3IZDR5O.js} +2 -2
- package/dist/bundle/chunks/{mistral-conversations-A2N5FSOV.js → mistral-conversations-NJUOG4ET.js} +2 -2
- package/dist/bundle/chunks/openai-chatgpt.js +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-Q6JHCWLE.js → openai-codex-responses-TZWBTTYM.js} +2 -2
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/{openai-completions-H4VMO7AU.js → openai-completions-7HTTU6FH.js} +1 -1
- package/dist/bundle/chunks/openai-decisions-776H4VDZ.js +5 -0
- package/dist/bundle/chunks/{openai-responses-G4PGNM2H.js → openai-responses-7A6BAQ5X.js} +1 -1
- package/dist/bundle/chunks/{openrouter-images-YP3YVB54.js → openrouter-images-TDLJV5N4.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-HZZ7GEEW.js → pi-messages-ZXNERWJG.js} +1 -1
- package/dist/bundle/chunks/typesafe-system-one-2DQLG4R2.js +2 -0
- package/dist/bundle/chunks/{virtual-modules-IJTAY26N.js → virtual-modules-2NHGQRS6.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts +2 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +24 -5
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +38 -10
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +190 -186
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +40 -45
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/context-snapshot.d.ts +4 -1
- package/dist/core/context-snapshot.d.ts.map +1 -1
- package/dist/core/context-snapshot.js +45 -0
- package/dist/core/context-snapshot.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +2 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/types.d.ts +13 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/mcp-servers.d.ts +8 -0
- package/dist/core/mcp-servers.d.ts.map +1 -1
- package/dist/core/mcp-servers.js +30 -7
- package/dist/core/mcp-servers.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +2 -1
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/nested-tool-calls.d.ts +1 -0
- package/dist/core/nested-tool-calls.d.ts.map +1 -1
- package/dist/core/nested-tool-calls.js +1 -0
- package/dist/core/nested-tool-calls.js.map +1 -1
- package/dist/core/resource-loader.d.ts +3 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -3
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +13 -4
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +19 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +13 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +37 -13
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +4 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +6 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/system-prompt.d.ts +6 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +9 -4
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/session.d.ts +9 -0
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +21 -0
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tools/read.d.ts +13 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +18 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/renderers/bash.d.ts.map +1 -1
- package/dist/core/tools/renderers/bash.js +8 -3
- package/dist/core/tools/renderers/bash.js.map +1 -1
- package/dist/core/tools/renderers/edit.js +1 -1
- package/dist/core/tools/renderers/edit.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +65 -8
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/index.d.ts.map +1 -1
- package/dist/extensions/codemode/index.js +1 -0
- package/dist/extensions/codemode/index.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts +9 -2
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +14 -6
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/index.js +2 -2
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +34 -11
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/mcp/cli.js +17 -23
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +165 -64
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts +5 -3
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +36 -10
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/resources.d.ts +3 -4
- package/dist/extensions/mcp/resources.d.ts.map +1 -1
- package/dist/extensions/mcp/resources.js +3 -4
- package/dist/extensions/mcp/resources.js.map +1 -1
- package/dist/extensions/mcp/runtime.d.ts +4 -1
- package/dist/extensions/mcp/runtime.d.ts.map +1 -1
- package/dist/extensions/mcp/runtime.js +22 -5
- package/dist/extensions/mcp/runtime.js.map +1 -1
- package/dist/extensions/mcp/tools.d.ts +2 -1
- package/dist/extensions/mcp/tools.d.ts.map +1 -1
- package/dist/extensions/mcp/tools.js +2 -1
- package/dist/extensions/mcp/tools.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts +3 -3
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +10 -2
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/extensions/search/code-search.d.ts +29 -0
- package/dist/extensions/search/code-search.d.ts.map +1 -0
- package/dist/extensions/search/code-search.js +120 -0
- package/dist/extensions/search/code-search.js.map +1 -0
- package/dist/extensions/search/command.d.ts +5 -0
- package/dist/extensions/search/command.d.ts.map +1 -0
- package/dist/extensions/search/command.js +69 -0
- package/dist/extensions/search/command.js.map +1 -0
- package/dist/extensions/search/credential.d.ts +25 -0
- package/dist/extensions/search/credential.d.ts.map +1 -0
- package/dist/extensions/search/credential.js +117 -0
- package/dist/extensions/search/credential.js.map +1 -0
- package/dist/extensions/search/devin.d.ts +34 -0
- package/dist/extensions/search/devin.d.ts.map +1 -0
- package/dist/extensions/search/devin.js +210 -0
- package/dist/extensions/search/devin.js.map +1 -0
- package/dist/extensions/search/index.d.ts +5 -0
- package/dist/extensions/search/index.d.ts.map +1 -0
- package/dist/extensions/search/index.js +110 -0
- package/dist/extensions/search/index.js.map +1 -0
- package/dist/extensions/search/panel.d.ts +53 -0
- package/dist/extensions/search/panel.d.ts.map +1 -0
- package/dist/extensions/search/panel.js +157 -0
- package/dist/extensions/search/panel.js.map +1 -0
- package/dist/extensions/search/prompt.d.ts +14 -0
- package/dist/extensions/search/prompt.d.ts.map +1 -0
- package/dist/extensions/search/prompt.js +221 -0
- package/dist/extensions/search/prompt.js.map +1 -0
- package/dist/extensions/search/render.d.ts +28 -0
- package/dist/extensions/search/render.d.ts.map +1 -0
- package/dist/extensions/search/render.js +86 -0
- package/dist/extensions/search/render.js.map +1 -0
- package/dist/extensions/search/workspace.d.ts +38 -0
- package/dist/extensions/search/workspace.d.ts.map +1 -0
- package/dist/extensions/search/workspace.js +245 -0
- package/dist/extensions/search/workspace.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +14 -14
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -2
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +7 -2
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +52 -59
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/program-status-reporter.d.ts +34 -0
- package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
- package/dist/modes/interactive/program-status-reporter.js +107 -0
- package/dist/modes/interactive/program-status-reporter.js.map +1 -0
- package/dist/modes/interactive/tasks/host-hooks.d.ts +14 -0
- package/dist/modes/interactive/tasks/host-hooks.d.ts.map +1 -0
- package/dist/modes/interactive/tasks/host-hooks.js +31 -0
- package/dist/modes/interactive/tasks/host-hooks.js.map +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +1 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/tool-view/tool-execution.d.ts +5 -0
- package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/tool-view/tool-execution.js +7 -0
- package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +24 -0
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/ansi.d.ts +8 -0
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +30 -11
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +12 -11
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +12 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +5 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +9 -10
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +6 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/docs/bundled/README.md +1 -1
- package/docs/bundled/extensions/provider.md +1 -1
- package/docs/bundled/extensions/question.md +1 -1
- package/docs/bundled/extensions/search.md +50 -0
- package/docs/bundled/extensions/statusline.md +15 -41
- package/docs/codemode.md +26 -5
- package/docs/docs.json +0 -4
- package/docs/environment-variables.md +1 -0
- package/docs/extensions.md +6 -2
- package/docs/json.md +2 -2
- package/docs/llama-cpp.md +8 -1
- package/docs/mcp.md +3 -1
- package/docs/models.md +4 -1
- package/docs/providers.md +17 -0
- package/docs/rpc.md +6 -3
- package/docs/session-format.md +1 -0
- package/docs/settings.md +4 -4
- package/docs/terminal-setup.md +14 -0
- package/docs/usage.md +19 -5
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +54 -54
- package/package.json +13 -11
- package/dist/bundle/chunks/chunk-57XI7YJH.js +0 -2
- package/dist/bundle/chunks/chunk-JI4WGISU.js +0 -2
- package/dist/bundle/chunks/chunk-TCQ4HHQD.js +0 -2
- package/dist/bundle/chunks/chunk-TXJO4AJ7.js +0 -11
- package/dist/bundle/chunks/cloudflare-workers-ai-system-one-OWU5SM6J.js +0 -2
- package/dist/bundle/chunks/typesafe-system-one-KYKKNU3E.js +0 -2
- package/dist/extensions/web-search/auth.d.ts +0 -12
- package/dist/extensions/web-search/auth.d.ts.map +0 -1
- package/dist/extensions/web-search/auth.js +0 -90
- package/dist/extensions/web-search/auth.js.map +0 -1
- package/dist/extensions/web-search/constants.d.ts +0 -13
- package/dist/extensions/web-search/constants.d.ts.map +0 -1
- package/dist/extensions/web-search/constants.js +0 -26
- package/dist/extensions/web-search/constants.js.map +0 -1
- package/dist/extensions/web-search/execute.d.ts +0 -9
- package/dist/extensions/web-search/execute.d.ts.map +0 -1
- package/dist/extensions/web-search/execute.js +0 -96
- package/dist/extensions/web-search/execute.js.map +0 -1
- package/dist/extensions/web-search/format.d.ts +0 -21
- package/dist/extensions/web-search/format.d.ts.map +0 -1
- package/dist/extensions/web-search/format.js +0 -117
- package/dist/extensions/web-search/format.js.map +0 -1
- package/dist/extensions/web-search/index.d.ts +0 -6
- package/dist/extensions/web-search/index.d.ts.map +0 -1
- package/dist/extensions/web-search/index.js +0 -50
- package/dist/extensions/web-search/index.js.map +0 -1
- package/dist/extensions/web-search/providers/deepseek.d.ts +0 -13
- package/dist/extensions/web-search/providers/deepseek.d.ts.map +0 -1
- package/dist/extensions/web-search/providers/deepseek.js +0 -110
- package/dist/extensions/web-search/providers/deepseek.js.map +0 -1
- package/dist/extensions/web-search/providers/http.d.ts +0 -4
- package/dist/extensions/web-search/providers/http.d.ts.map +0 -1
- package/dist/extensions/web-search/providers/http.js +0 -42
- package/dist/extensions/web-search/providers/http.js.map +0 -1
- package/dist/extensions/web-search/providers/minimax.d.ts +0 -12
- package/dist/extensions/web-search/providers/minimax.d.ts.map +0 -1
- package/dist/extensions/web-search/providers/minimax.js +0 -61
- package/dist/extensions/web-search/providers/minimax.js.map +0 -1
- package/dist/extensions/web-search/render.d.ts +0 -15
- package/dist/extensions/web-search/render.d.ts.map +0 -1
- package/dist/extensions/web-search/render.js +0 -142
- package/dist/extensions/web-search/render.js.map +0 -1
- package/dist/extensions/web-search/results.d.ts +0 -35
- package/dist/extensions/web-search/results.d.ts.map +0 -1
- package/dist/extensions/web-search/results.js +0 -167
- package/dist/extensions/web-search/results.js.map +0 -1
- package/dist/extensions/web-search/schema.d.ts +0 -10
- package/dist/extensions/web-search/schema.d.ts.map +0 -1
- package/dist/extensions/web-search/schema.js +0 -36
- package/dist/extensions/web-search/schema.js.map +0 -1
- package/dist/extensions/web-search/types.d.ts +0 -51
- package/dist/extensions/web-search/types.d.ts.map +0 -1
- package/dist/extensions/web-search/types.js +0 -5
- package/dist/extensions/web-search/types.js.map +0 -1
- package/docs/bundled/extensions/web-search.md +0 -46
|
@@ -16,7 +16,7 @@ import { createTasksToolDefinition } from "./tools/tasks.js";
|
|
|
16
16
|
import { readFileSync } from "node:fs";
|
|
17
17
|
import { basename, dirname } from "node:path";
|
|
18
18
|
import { runToolCall, } from "@earendil-works/pi-agent-core";
|
|
19
|
-
import { contentText, getCurrentSystemMessage,
|
|
19
|
+
import { contentText, getCurrentSystemMessage, retryDelayMs } from "@earendil-works/pi-ai";
|
|
20
20
|
import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
|
|
21
21
|
import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
|
|
22
22
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
@@ -27,18 +27,20 @@ import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth
|
|
|
27
27
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
28
28
|
import { generateBugReportSummary } from "./bug-report.js";
|
|
29
29
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
30
|
+
import { captureContextSnapshot } from "./context-snapshot.js";
|
|
30
31
|
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
|
|
31
32
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
32
33
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
33
34
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
34
35
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
36
|
+
import { createToolNameMatcher, isMcpToolName } from "./mcp-servers.js";
|
|
35
37
|
import { convertToLlm } from "./messages.js";
|
|
36
38
|
import { ModelRegistry } from "./model-registry.js";
|
|
37
39
|
import { NestedToolCallRunner } from "./nested-tool-calls.js";
|
|
38
40
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
39
41
|
import { exportSessionToJsonl } from "./session-export.js";
|
|
40
42
|
import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
|
|
41
|
-
import { DEFAULT_TOOL_NAMES } from "./settings-manager.js";
|
|
43
|
+
import { applyToolModifiers, DEFAULT_TOOL_NAMES, } from "./settings-manager.js";
|
|
42
44
|
import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
|
|
43
45
|
import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
|
|
44
46
|
import { TaskSession } from "./tasks/session.js";
|
|
@@ -121,6 +123,11 @@ export class AgentSession {
|
|
|
121
123
|
* `setActiveToolsByName()` deactivates a tool or the next agent run starts.
|
|
122
124
|
*/
|
|
123
125
|
this._pendingToolNames = new Set();
|
|
126
|
+
/**
|
|
127
|
+
* Whether the allowlist filters MCP tools: it is empty (`--no-tools`) or names an MCP tool
|
|
128
|
+
* (`mcp__*`). Otherwise it keeps MCP tools registered for codemode and tool_search.
|
|
129
|
+
*/
|
|
130
|
+
this._allowlistFiltersMcp = false;
|
|
124
131
|
this._extensionMode = "print";
|
|
125
132
|
// Tool registry for extension getTools/setTools
|
|
126
133
|
this._toolRegistry = new Map();
|
|
@@ -261,8 +268,13 @@ export class AgentSession {
|
|
|
261
268
|
this._extensionRunnerRef = config.extensionRunnerRef;
|
|
262
269
|
this._initialActiveToolNames = config.initialActiveToolNames;
|
|
263
270
|
this._usesDefaultTools = config.usesDefaultTools ?? false;
|
|
264
|
-
this.
|
|
265
|
-
|
|
271
|
+
this._defaultToolModifiers = config.defaultToolModifiers ?? [];
|
|
272
|
+
if (config.allowedToolNames) {
|
|
273
|
+
this._allowedTools = createToolNameMatcher(config.allowedToolNames);
|
|
274
|
+
this._allowlistFiltersMcp =
|
|
275
|
+
config.allowedToolNames.length === 0 || config.allowedToolNames.some((entry) => entry.startsWith("mcp__"));
|
|
276
|
+
}
|
|
277
|
+
this._excludedTools = config.excludedToolNames ? createToolNameMatcher(config.excludedToolNames) : undefined;
|
|
266
278
|
this._baseToolsOverride = config.baseToolsOverride;
|
|
267
279
|
this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
|
|
268
280
|
// Always subscribe to agent events for internal handling
|
|
@@ -287,6 +299,10 @@ export class AgentSession {
|
|
|
287
299
|
get quarantinedTaskSettlements() {
|
|
288
300
|
return this._tasksHost.quarantinedSettlements;
|
|
289
301
|
}
|
|
302
|
+
/** Running tasks that navigating to `targetId` would cancel, so a host can confirm first. */
|
|
303
|
+
tasksStoppedByTreeNavigation(targetId) {
|
|
304
|
+
return this._tasksHost.stoppedByTreeNavigation(targetId);
|
|
305
|
+
}
|
|
290
306
|
/** Pause delivery across asynchronous lifecycle/preflight gaps. Nestable. */
|
|
291
307
|
pauseTaskNotifications() {
|
|
292
308
|
return this._tasksHost.delivery.pause();
|
|
@@ -312,48 +328,8 @@ export class AgentSession {
|
|
|
312
328
|
return this._modelRuntime;
|
|
313
329
|
}
|
|
314
330
|
/** Capture stable state before any asynchronous context preparation. Never includes a partial stream. */
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if (!model)
|
|
318
|
-
throw new Error("No model selected");
|
|
319
|
-
const requestOptions = {
|
|
320
|
-
sessionId: this.agent.sessionId ?? this.sessionManager.getSessionId(),
|
|
321
|
-
transport: this.agent.transport,
|
|
322
|
-
thinkingBudgets: structuredClone(this.agent.thinkingBudgets),
|
|
323
|
-
maxRetryDelayMs: this.agent.maxRetryDelayMs,
|
|
324
|
-
onPayload: this.agent.onPayload,
|
|
325
|
-
onResponse: this.agent.onResponse,
|
|
326
|
-
};
|
|
327
|
-
const snapshot = {
|
|
328
|
-
capturedAt: Date.now(),
|
|
329
|
-
sessionId: this.sessionManager.getSessionId(),
|
|
330
|
-
leafId: this.sessionManager.getLeafId(),
|
|
331
|
-
model: structuredClone(model),
|
|
332
|
-
thinkingLevel: this.thinkingLevel,
|
|
333
|
-
tools: this.agent.state.tools.map(({ name, description, parameters, constrainedSampling }) => ({
|
|
334
|
-
name,
|
|
335
|
-
description,
|
|
336
|
-
parameters: structuredClone(parameters),
|
|
337
|
-
...(constrainedSampling === undefined ? {} : { constrainedSampling: structuredClone(constrainedSampling) }),
|
|
338
|
-
})),
|
|
339
|
-
streamOptions: this._contextSource?.resolveStreamOptions(model, requestOptions) ?? requestOptions,
|
|
340
|
-
};
|
|
341
|
-
const currentSystemPrompt = this.systemPrompt;
|
|
342
|
-
// The canonical projection is what the next request converts; the inspection cache may lag it.
|
|
343
|
-
const messages = structuredClone(this.sessionManager.buildSessionProjection().messages);
|
|
344
|
-
const convert = this.agent.convertToLlm;
|
|
345
|
-
const transform = this.agent.transformContext;
|
|
346
|
-
const prepared = this._contextSource
|
|
347
|
-
? await this._contextSource.prepareMessages(messages)
|
|
348
|
-
: await convert(transform ? await transform(messages) : messages);
|
|
349
|
-
// The prepared transcript declares the prompt the provider received, including a forced
|
|
350
|
-
// prompt projected for the last request; before the first request there is none yet.
|
|
351
|
-
const declared = getCurrentSystemMessage(prepared);
|
|
352
|
-
return {
|
|
353
|
-
...snapshot,
|
|
354
|
-
systemPrompt: declared ? getSystemMessageText(declared) : currentSystemPrompt,
|
|
355
|
-
messages: structuredClone(prepared),
|
|
356
|
-
};
|
|
331
|
+
getContextSnapshot() {
|
|
332
|
+
return captureContextSnapshot(this, this._contextSource);
|
|
357
333
|
}
|
|
358
334
|
async _getRequiredRequestAuth(model, signal) {
|
|
359
335
|
let result;
|
|
@@ -831,8 +807,9 @@ export class AgentSession {
|
|
|
831
807
|
this._isAgentRunActive = false;
|
|
832
808
|
this._isEmittingAgentSettled = true;
|
|
833
809
|
try {
|
|
834
|
-
|
|
835
|
-
this.
|
|
810
|
+
const aborted = this._agentRunAbortRequested;
|
|
811
|
+
await this._extensionRunner.emit({ type: "agent_settled", aborted });
|
|
812
|
+
this._emit({ type: "agent_settled", aborted });
|
|
836
813
|
}
|
|
837
814
|
finally {
|
|
838
815
|
this._isEmittingAgentSettled = false;
|
|
@@ -1026,6 +1003,7 @@ export class AgentSession {
|
|
|
1026
1003
|
toolName: event.toolName,
|
|
1027
1004
|
result: event.result,
|
|
1028
1005
|
isError: event.isError,
|
|
1006
|
+
...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),
|
|
1029
1007
|
};
|
|
1030
1008
|
await this._extensionRunner.emit(extensionEvent);
|
|
1031
1009
|
}
|
|
@@ -1179,8 +1157,27 @@ export class AgentSession {
|
|
|
1179
1157
|
this._pendingToolNames.delete(tool.name);
|
|
1180
1158
|
this._rebuildSystemPrompt(tools.map((tool) => tool.name));
|
|
1181
1159
|
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Whether `--tools` and `--exclude-tools` keep the tool registered. MCP tools stay registered
|
|
1162
|
+
* unless the allowlist filters them (see `_allowlistFiltersMcp`).
|
|
1163
|
+
*/
|
|
1182
1164
|
_isAllowedTool(name) {
|
|
1183
|
-
|
|
1165
|
+
if (this._excludedTools?.(name))
|
|
1166
|
+
return false;
|
|
1167
|
+
if (!this._allowedTools || this._allowedTools(name))
|
|
1168
|
+
return true;
|
|
1169
|
+
return !this._allowlistFiltersMcp && isMcpToolName(name);
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Whether the tool may be active, which declares it to the model. MCP tools the allowlist keeps
|
|
1173
|
+
* without matching them are only for codemode and tool_search: they may be declared only when
|
|
1174
|
+
* tool_search can load them (non-`direct` exposure and tool_search registered). This also applies
|
|
1175
|
+
* to tools restored from the transcript or set by extensions.
|
|
1176
|
+
*/
|
|
1177
|
+
_isActivatable(name) {
|
|
1178
|
+
if (!this._allowedTools || this._allowedTools(name) || !isMcpToolName(name))
|
|
1179
|
+
return true;
|
|
1180
|
+
return this._getToolExposure(name) !== "direct" && this._toolRegistry.has("tool_search");
|
|
1184
1181
|
}
|
|
1185
1182
|
_getToolExposure(name) {
|
|
1186
1183
|
return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
|
|
@@ -1204,7 +1201,7 @@ export class AgentSession {
|
|
|
1204
1201
|
_applyToolLoadout(toolNames) {
|
|
1205
1202
|
const tools = [...new Set(toolNames)].flatMap((name) => {
|
|
1206
1203
|
const tool = this._toolRegistry.get(name);
|
|
1207
|
-
return tool && this._getToolExposure(name) !== "hidden" ? [tool] : [];
|
|
1204
|
+
return tool && this._getToolExposure(name) !== "hidden" && this._isActivatable(name) ? [tool] : [];
|
|
1208
1205
|
});
|
|
1209
1206
|
const hooks = tools.flatMap((tool) => {
|
|
1210
1207
|
const entry = this._toolDefinitions.get(tool.name);
|
|
@@ -1219,6 +1216,7 @@ export class AgentSession {
|
|
|
1219
1216
|
registered: [...this._toolRegistry.values()],
|
|
1220
1217
|
getExposure: (name) => this._getToolExposure(name),
|
|
1221
1218
|
getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
|
|
1219
|
+
getPromptGuidelines: (name) => this._toolPromptGuidelines.get(name) ?? [],
|
|
1222
1220
|
};
|
|
1223
1221
|
const descriptions = new Map();
|
|
1224
1222
|
for (const { definition, sourceInfo } of hooks) {
|
|
@@ -1317,8 +1315,8 @@ export class AgentSession {
|
|
|
1317
1315
|
const toolSnippets = {};
|
|
1318
1316
|
for (const name of this._toolRegistry.keys()) {
|
|
1319
1317
|
const snippet = this._toolPromptSnippets.get(name);
|
|
1320
|
-
// Tools without a snippet are not listed.
|
|
1321
|
-
if (snippet
|
|
1318
|
+
// Tools without a snippet are not listed.
|
|
1319
|
+
if (snippet)
|
|
1322
1320
|
toolSnippets[name] = snippet;
|
|
1323
1321
|
}
|
|
1324
1322
|
const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
|
|
@@ -1333,6 +1331,7 @@ export class AgentSession {
|
|
|
1333
1331
|
customPrompt: loaderSystemPrompt,
|
|
1334
1332
|
appendSystemPrompt,
|
|
1335
1333
|
selectedTools: validToolNames,
|
|
1334
|
+
hiddenTools: [...this._hiddenDeclarations],
|
|
1336
1335
|
toolSnippets,
|
|
1337
1336
|
toolGuidelines: Object.fromEntries(this._toolPromptGuidelines),
|
|
1338
1337
|
});
|
|
@@ -1349,8 +1348,8 @@ export class AgentSession {
|
|
|
1349
1348
|
*/
|
|
1350
1349
|
_preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
|
|
1351
1350
|
options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
|
|
1352
|
-
// The tool list must match the declarations the request carries
|
|
1353
|
-
options.
|
|
1351
|
+
// The tool list and rules must match the declarations the request carries.
|
|
1352
|
+
options.hiddenTools = [...this._hiddenDeclarations];
|
|
1354
1353
|
const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
|
|
1355
1354
|
return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
|
|
1356
1355
|
}
|
|
@@ -1562,131 +1561,147 @@ export class AgentSession {
|
|
|
1562
1561
|
* @throws Error if no model selected or no API key available (when not streaming)
|
|
1563
1562
|
*/
|
|
1564
1563
|
async prompt(text, options) {
|
|
1564
|
+
// A deferred prompt re-enters here after the settled handlers finish.
|
|
1565
|
+
if (this._isEmittingAgentSettled)
|
|
1566
|
+
return this._promptBody(text, options);
|
|
1567
|
+
// A user-initiated prompt is the recovery point for failed completion deliveries.
|
|
1568
|
+
this.retryTaskNotifications();
|
|
1569
|
+
// Extension commands may stay open indefinitely; only model input holds the preflight pause,
|
|
1570
|
+
// released once the prompt is handled, queued, or started.
|
|
1571
|
+
if (this._isExtensionCommandPrompt(text, options))
|
|
1572
|
+
return this._promptBody(text, options);
|
|
1573
|
+
const resumeBackground = this.pauseTaskNotifications();
|
|
1574
|
+
try {
|
|
1575
|
+
await this._promptBody(text, {
|
|
1576
|
+
...options,
|
|
1577
|
+
preflightResult: (result) => {
|
|
1578
|
+
resumeBackground();
|
|
1579
|
+
options?.preflightResult?.(result);
|
|
1580
|
+
},
|
|
1581
|
+
});
|
|
1582
|
+
}
|
|
1583
|
+
finally {
|
|
1584
|
+
resumeBackground();
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
_isExtensionCommandPrompt(text, options) {
|
|
1588
|
+
if (!(options?.expandPromptTemplates ?? true) || !text.startsWith("/"))
|
|
1589
|
+
return false;
|
|
1590
|
+
const spaceIndex = text.indexOf(" ");
|
|
1591
|
+
return (this._extensionRunner.getCommand(spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex)) !== undefined);
|
|
1592
|
+
}
|
|
1593
|
+
async _promptBody(text, options) {
|
|
1565
1594
|
if (this._isEmittingAgentSettled) {
|
|
1566
1595
|
this._deferredSettledActions.push(async () => await this.prompt(text, options));
|
|
1567
1596
|
return;
|
|
1568
1597
|
}
|
|
1569
|
-
// A user-initiated prompt is the recovery point for failed completion deliveries.
|
|
1570
|
-
this.retryTaskNotifications();
|
|
1571
1598
|
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1572
1599
|
const preflightResult = options?.preflightResult;
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
const handled = await this._tryExecuteExtensionCommand(text);
|
|
1580
|
-
if (handled) {
|
|
1581
|
-
// Extension command executed, no prompt to send
|
|
1582
|
-
preflightResult?.("handled");
|
|
1583
|
-
return;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
// Observer commands above may stay open indefinitely; only real model input owns
|
|
1587
|
-
// the preflight pause, released once the user message is established.
|
|
1588
|
-
resumeBackground = this.pauseTaskNotifications();
|
|
1589
|
-
if (this._compactionAbortController !== undefined) {
|
|
1590
|
-
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1591
|
-
}
|
|
1592
|
-
// Emit input event for extension interception (before skill/template expansion)
|
|
1593
|
-
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1594
|
-
if (!processedInput) {
|
|
1600
|
+
// Handle extension commands first (execute immediately, even during streaming)
|
|
1601
|
+
// Extension commands manage their own LLM interaction via pi.sendMessage()
|
|
1602
|
+
if (expandPromptTemplates && text.startsWith("/")) {
|
|
1603
|
+
const handled = await this._tryExecuteExtensionCommand(text);
|
|
1604
|
+
if (handled) {
|
|
1605
|
+
// Extension command executed, no prompt to send
|
|
1595
1606
|
preflightResult?.("handled");
|
|
1596
1607
|
return;
|
|
1597
1608
|
}
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1609
|
+
}
|
|
1610
|
+
if (this._compactionAbortController !== undefined) {
|
|
1611
|
+
throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
|
|
1612
|
+
}
|
|
1613
|
+
// Emit input event for extension interception (before skill/template expansion)
|
|
1614
|
+
const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1615
|
+
if (!processedInput) {
|
|
1616
|
+
preflightResult?.("handled");
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
const { text: currentText, images: currentImages } = processedInput;
|
|
1620
|
+
// Expand skill commands (/skill:name args) and prompt templates (/template args)
|
|
1621
|
+
let expandedText = currentText;
|
|
1622
|
+
if (expandPromptTemplates) {
|
|
1623
|
+
expandedText = this._expandSkillCommand(expandedText);
|
|
1624
|
+
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1625
|
+
}
|
|
1626
|
+
// If streaming, queue via steer() or followUp() based on option
|
|
1627
|
+
if (this.isStreaming) {
|
|
1628
|
+
if (!options?.streamingBehavior) {
|
|
1629
|
+
throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
|
|
1618
1630
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
this._flushPendingCustomMessages();
|
|
1622
|
-
// Validate model
|
|
1623
|
-
if (!this.model) {
|
|
1624
|
-
throw new Error(formatNoModelSelectedMessage());
|
|
1631
|
+
if (options.streamingBehavior === "followUp") {
|
|
1632
|
+
await this._queueFollowUp(expandedText, currentImages);
|
|
1625
1633
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1634
|
+
else {
|
|
1635
|
+
await this._queueSteer(expandedText, currentImages);
|
|
1636
|
+
}
|
|
1637
|
+
preflightResult?.("queued");
|
|
1638
|
+
return;
|
|
1639
|
+
}
|
|
1640
|
+
// Flush any pending bash and custom messages before the new prompt
|
|
1641
|
+
this._flushPendingBashMessages();
|
|
1642
|
+
this._flushPendingCustomMessages();
|
|
1643
|
+
// Validate model
|
|
1644
|
+
if (!this.model) {
|
|
1645
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1646
|
+
}
|
|
1647
|
+
const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
|
|
1648
|
+
(await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
|
|
1649
|
+
if (!hasConfiguredAuth) {
|
|
1650
|
+
const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
|
|
1651
|
+
if (isOAuth) {
|
|
1652
|
+
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1653
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
1654
|
+
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1655
|
+
}
|
|
1656
|
+
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1657
|
+
}
|
|
1658
|
+
// Check if we need to compact before sending (catches aborted responses).
|
|
1659
|
+
// The user's new prompt is sent below, so do not call agent.continue() here.
|
|
1660
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
1661
|
+
if (lastAssistant) {
|
|
1662
|
+
await this._checkCompaction(lastAssistant, false);
|
|
1663
|
+
}
|
|
1664
|
+
// Emit before_agent_start before normalizing images so extension-driven model
|
|
1665
|
+
// selection determines the resize profile used for the request and history.
|
|
1666
|
+
const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
|
|
1667
|
+
const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
|
|
1668
|
+
// Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
|
|
1669
|
+
// which updates the live loadout instead. An explicit edit wins; otherwise the live
|
|
1670
|
+
// loadout is authoritative, so a setActiveTools() call is not undone here.
|
|
1671
|
+
const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
|
|
1672
|
+
result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
|
|
1673
|
+
if (!handlerEditedTools)
|
|
1674
|
+
result.systemPromptOptions.selectedTools = this.getActiveToolNames();
|
|
1675
|
+
const normalized = await this._normalizePromptImages(currentImages);
|
|
1676
|
+
const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
|
|
1677
|
+
// Build messages only after hooks and image normalization have completed.
|
|
1678
|
+
const messages = [];
|
|
1679
|
+
const userContent = [{ type: "text", text: userText }];
|
|
1680
|
+
userContent.push(...normalized.images);
|
|
1681
|
+
messages.push({
|
|
1682
|
+
role: "user",
|
|
1683
|
+
content: userContent,
|
|
1684
|
+
timestamp: Date.now(),
|
|
1685
|
+
});
|
|
1686
|
+
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1687
|
+
for (const msg of this._pendingNextTurnMessages) {
|
|
1688
|
+
messages.push(msg);
|
|
1689
|
+
}
|
|
1690
|
+
for (const msg of result.messages) {
|
|
1660
1691
|
messages.push({
|
|
1661
|
-
role: "
|
|
1662
|
-
|
|
1692
|
+
role: "custom",
|
|
1693
|
+
customType: msg.customType,
|
|
1694
|
+
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1695
|
+
content: msg.content ?? [],
|
|
1696
|
+
display: msg.display,
|
|
1697
|
+
details: msg.details,
|
|
1663
1698
|
timestamp: Date.now(),
|
|
1664
1699
|
});
|
|
1665
|
-
// Inject any pending "nextTurn" messages as context alongside the user message
|
|
1666
|
-
for (const msg of this._pendingNextTurnMessages) {
|
|
1667
|
-
messages.push(msg);
|
|
1668
|
-
}
|
|
1669
|
-
for (const msg of result.messages) {
|
|
1670
|
-
messages.push({
|
|
1671
|
-
role: "custom",
|
|
1672
|
-
customType: msg.customType,
|
|
1673
|
-
// Untyped extensions can pass null/missing content; normalize at ingestion.
|
|
1674
|
-
content: msg.content ?? [],
|
|
1675
|
-
display: msg.display,
|
|
1676
|
-
details: msg.details,
|
|
1677
|
-
timestamp: Date.now(),
|
|
1678
|
-
});
|
|
1679
|
-
}
|
|
1680
|
-
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1681
|
-
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1682
|
-
if (updateMessage)
|
|
1683
|
-
messages.unshift(updateMessage);
|
|
1684
1700
|
}
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
return;
|
|
1701
|
+
const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
|
|
1702
|
+
this._runSystemPromptOptions = result.systemPromptOptions;
|
|
1703
|
+
if (updateMessage)
|
|
1704
|
+
messages.unshift(updateMessage);
|
|
1690
1705
|
preflightResult?.("started");
|
|
1691
1706
|
await this._runAgentPrompt(messages);
|
|
1692
1707
|
}
|
|
@@ -2889,7 +2904,7 @@ export class AgentSession {
|
|
|
2889
2904
|
// `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
|
|
2890
2905
|
const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
|
|
2891
2906
|
const previousActiveToolNames = this.getActiveToolNames();
|
|
2892
|
-
const
|
|
2907
|
+
const allowedTools = this._allowedTools;
|
|
2893
2908
|
const registeredTools = this._extensionRunner.getAllRegisteredTools();
|
|
2894
2909
|
const allCustomTools = [
|
|
2895
2910
|
...registeredTools,
|
|
@@ -2942,10 +2957,11 @@ export class AgentSession {
|
|
|
2942
2957
|
}
|
|
2943
2958
|
this._toolRegistry = toolRegistry;
|
|
2944
2959
|
const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => this._isAllowedTool(name));
|
|
2945
|
-
if (
|
|
2960
|
+
if (allowedTools) {
|
|
2946
2961
|
for (const toolName of this._toolRegistry.keys()) {
|
|
2947
|
-
// Naming a tool activates it even when it is not active by default.
|
|
2948
|
-
|
|
2962
|
+
// Naming or matching a tool activates it even when it is not active by default. MCP tools
|
|
2963
|
+
// kept registered without being named stay inactive.
|
|
2964
|
+
if (allowedTools(toolName) && this._isDeclarable(toolName)) {
|
|
2949
2965
|
nextActiveToolNames.push(toolName);
|
|
2950
2966
|
}
|
|
2951
2967
|
}
|
|
@@ -3027,7 +3043,10 @@ export class AgentSession {
|
|
|
3027
3043
|
await Promise.all([this.tasks.shutdown(), this.abort()]);
|
|
3028
3044
|
await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
|
|
3029
3045
|
oldRunner.invalidate();
|
|
3030
|
-
const
|
|
3046
|
+
const getDefaultTools = () => this._usesDefaultTools
|
|
3047
|
+
? applyToolModifiers(this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES, this._defaultToolModifiers)
|
|
3048
|
+
: [];
|
|
3049
|
+
const previousDefaultTools = new Set(getDefaultTools());
|
|
3031
3050
|
await this.settingsManager.reload();
|
|
3032
3051
|
this.syncQueueModesFromSettings();
|
|
3033
3052
|
resetApiProviders();
|
|
@@ -3035,9 +3054,7 @@ export class AgentSession {
|
|
|
3035
3054
|
this._tasksHost.replaceService();
|
|
3036
3055
|
// Activate tools newly added to defaultTools. Removed ones stay active, and tools disabled
|
|
3037
3056
|
// during the session stay disabled unless the setting newly adds them.
|
|
3038
|
-
const addedDefaultTools =
|
|
3039
|
-
? (this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES).filter((name) => !previousDefaultTools.has(name))
|
|
3040
|
-
: [];
|
|
3057
|
+
const addedDefaultTools = getDefaultTools().filter((name) => !previousDefaultTools.has(name));
|
|
3041
3058
|
// Tools the new extensions register later, such as MCP tools, are pending until then.
|
|
3042
3059
|
for (const name of this.getActiveToolNames())
|
|
3043
3060
|
this._pendingToolNames.add(name);
|
|
@@ -3286,19 +3303,6 @@ export class AgentSession {
|
|
|
3286
3303
|
* @param options.label Label to attach to the branch summary entry
|
|
3287
3304
|
* @returns Result with editorText (if user message) and cancelled status
|
|
3288
3305
|
*/
|
|
3289
|
-
/**
|
|
3290
|
-
* Running tasks that navigating to `targetId` would cancel, so a host can confirm first.
|
|
3291
|
-
* Mirrors navigateTree's destination: selecting a user or custom message moves the leaf to its parent.
|
|
3292
|
-
*/
|
|
3293
|
-
tasksStoppedByTreeNavigation(targetId) {
|
|
3294
|
-
const target = this.sessionManager.getEntry(targetId);
|
|
3295
|
-
if (!target)
|
|
3296
|
-
return [];
|
|
3297
|
-
const leafId = (target.type === "message" && target.message.role === "user") || target.type === "custom_message"
|
|
3298
|
-
? target.parentId
|
|
3299
|
-
: targetId;
|
|
3300
|
-
return this.tasks.activeOutsideBranch(new Set(leafId === null ? [] : this.sessionManager.getBranch(leafId).map((entry) => entry.id)));
|
|
3301
|
-
}
|
|
3302
3306
|
async navigateTree(targetId, options = {}) {
|
|
3303
3307
|
if (this.isStreaming) {
|
|
3304
3308
|
throw new Error("Wait for the current response to finish before navigating the session tree.");
|
|
@@ -3418,7 +3422,7 @@ export class AgentSession {
|
|
|
3418
3422
|
// Non-user message: leaf = selected node
|
|
3419
3423
|
newLeafId = targetId;
|
|
3420
3424
|
}
|
|
3421
|
-
await this.
|
|
3425
|
+
await this._tasksHost.cancelOutsideBranch(newLeafId);
|
|
3422
3426
|
// Switch leaf (with or without summary)
|
|
3423
3427
|
// Summary is attached at the navigation target position (newLeafId), not the old branch
|
|
3424
3428
|
let summaryEntry;
|