@ai-agent-forge/agent-forge 0.88.2 → 0.88.4
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 +33 -0
- package/README.md +1 -1
- package/bundled-plugins/agent-loop-policy/agent-forge.json +1 -1
- package/bundled-plugins/agent-loop-policy/plugin.json +1 -1
- package/bundled-plugins/coding-tools/agent-forge.json +1 -1
- package/bundled-plugins/coding-tools/plugin.json +1 -1
- package/bundled-plugins/compaction-policy/agent-forge.json +1 -1
- package/bundled-plugins/compaction-policy/plugin.json +1 -1
- package/bundled-plugins/overflow-policy/agent-forge.json +1 -1
- package/bundled-plugins/overflow-policy/plugin.json +1 -1
- package/bundled-plugins/provider-failover/agent-forge.json +1 -1
- package/bundled-plugins/provider-failover/plugin.json +1 -1
- package/bundled-plugins/retry-policy/agent-forge.json +1 -1
- package/bundled-plugins/retry-policy/plugin.json +1 -1
- package/dist/artifacts/paged-read.d.ts +6 -1
- package/dist/artifacts/paged-read.d.ts.map +1 -1
- package/dist/artifacts/paged-read.js.map +1 -1
- package/dist/bundle/.build-manifest.json +244 -234
- package/dist/bundle/chunks/{anthropic-messages-PLAKXR73.js → anthropic-messages-3FJHRAJL.js} +2 -2
- package/dist/bundle/chunks/anthropic.js +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-OUWQ2AZD.js → azure-openai-responses-GCL47IDS.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-6F5JWGKE.js → chunk-32YDZI4J.js} +1 -1
- package/dist/bundle/chunks/{chunk-LSP24WNH.js → chunk-755VNWIF.js} +12 -12
- package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-BVVSHK6W.js} +1 -1
- package/dist/bundle/chunks/{chunk-HTC5K5SM.js → chunk-HEL6TAWE.js} +95 -90
- package/dist/bundle/chunks/{chunk-6R7UI4IY.js → chunk-QDLOMKF6.js} +1 -1
- package/dist/bundle/chunks/{chunk-44I47ACN.js → chunk-V3ACW7VD.js} +1 -1
- package/dist/bundle/chunks/{google-generative-ai-DLII6DAT.js → google-generative-ai-6BMXWA44.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-G7BZL7GM.js → google-vertex-6H7NLRTK.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +1 -1
- package/dist/bundle/chunks/{mistral-conversations-JXUK24ID.js → mistral-conversations-IXUHSFSJ.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-5GSGFIPG.js → openai-codex-responses-YHUAEVCM.js} +1 -1
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/{openai-completions-EI2I6DTG.js → openai-completions-ULQCFC72.js} +1 -1
- package/dist/bundle/chunks/openai-responses-NLLAJDPS.js +2 -0
- package/dist/bundle/chunks/{openrouter-images-G4GQRUSG.js → openrouter-images-GZZQZXMS.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +1 -1
- package/dist/bundle/chunks/{pi-messages-PWU2VJMR.js → pi-messages-EJTI2EJ3.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-TQWEGNNZ.js +5 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts +0 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/experimental/cli.d.ts +3 -3
- package/dist/cli/experimental/cli.d.ts.map +1 -1
- package/dist/cli/experimental/cli.js +2 -2
- package/dist/cli/experimental/cli.js.map +1 -1
- package/dist/cli/experimental/commands/agent-forge.d.ts +15 -0
- package/dist/cli/experimental/commands/agent-forge.d.ts.map +1 -0
- package/dist/cli/experimental/commands/{pi.js → agent-forge.js} +4 -4
- package/dist/cli/experimental/commands/agent-forge.js.map +1 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -7
- package/dist/config.js.map +1 -1
- package/dist/core/agent-forge-manifest.d.ts +7 -0
- package/dist/core/agent-forge-manifest.d.ts.map +1 -0
- package/dist/core/{pi-manifest.js → agent-forge-manifest.js} +4 -4
- package/dist/core/agent-forge-manifest.js.map +1 -0
- package/dist/core/agent-session-compaction.d.ts +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +3 -3
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-lifecycle.d.ts.map +1 -1
- package/dist/core/agent-session-lifecycle.js +12 -1
- package/dist/core/agent-session-lifecycle.js.map +1 -1
- package/dist/core/agent-session-projection.d.ts.map +1 -1
- package/dist/core/agent-session-projection.js +3 -3
- package/dist/core/agent-session-projection.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +1 -3
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
- package/dist/core/extensions/capability-plugin.js +15 -8
- package/dist/core/extensions/capability-plugin.js.map +1 -1
- package/dist/core/extensions/capability-runtime-store.d.ts +20 -1
- package/dist/core/extensions/capability-runtime-store.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-store.js +67 -0
- package/dist/core/extensions/capability-runtime-store.js.map +1 -1
- package/dist/core/extensions/capability-runtime-types.d.ts +14 -0
- package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-types.js +7 -1
- package/dist/core/extensions/capability-runtime-types.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +144 -42
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/virtual-modules.js +12 -4
- package/dist/core/extensions/virtual-modules.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +1 -1
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js +3 -3
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +2 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-resource-collection.d.ts.map +1 -1
- package/dist/core/package-resource-collection.js +5 -5
- package/dist/core/package-resource-collection.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +3 -3
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +6 -7
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -4
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +5 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +1 -3
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition.d.ts +1 -1
- package/dist/core/tools/tool-definition.d.ts.map +1 -1
- package/dist/core/tools/tool-definition.js.map +1 -1
- package/dist/core/trace-retention.d.ts +16 -1
- package/dist/core/trace-retention.d.ts.map +1 -1
- package/dist/core/trace-retention.js +43 -20
- package/dist/core/trace-retention.js.map +1 -1
- package/dist/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/export-html/ansi-to-html.js.map +1 -0
- package/dist/{core/export-html → export-html}/index.d.ts +1 -1
- package/dist/export-html/index.d.ts.map +1 -0
- package/dist/{core/export-html → export-html}/index.js +5 -5
- package/dist/export-html/index.js.map +1 -0
- package/dist/{core/export-html → export-html}/tool-renderer.d.ts +2 -2
- package/dist/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/export-html/tool-renderer.js.map +1 -0
- package/dist/{modes/interactive → host}/model-catalog-refresh.d.ts +1 -1
- package/dist/host/model-catalog-refresh.d.ts.map +1 -0
- package/dist/{modes/interactive → host}/model-catalog-refresh.js +1 -1
- package/dist/host/model-catalog-refresh.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +25 -14
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/agents-view.js +1 -1
- package/dist/modes/interactive/components/agents-view.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +3 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +83 -24
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +1 -1
- 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 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.js +1 -1
- package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
- package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-input.js +1 -1
- package/dist/modes/interactive/components/dialog-input.js.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.js +1 -1
- package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +1 -1
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -2
- 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 +1 -1
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.js +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.js +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -1
- package/dist/modes/interactive/components/render-types.d.ts +1 -1
- package/dist/modes/interactive/components/render-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/render-types.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 +1 -1
- 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 +2 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.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/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js +1 -1
- package/dist/modes/interactive/components/settings-submenu.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 +1 -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 +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +1 -1
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +1 -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 +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +96 -4
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.js +1 -1
- package/dist/modes/interactive/components/tool-run-group.js.map +1 -1
- package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-list.js +1 -1
- package/dist/modes/interactive/components/tree-list.js.map +1 -1
- package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-render.js +1 -1
- package/dist/modes/interactive/components/tree-render.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/workflow-view.js +1 -1
- package/dist/modes/interactive/components/workflow-view.js.map +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth.js +1 -1
- package/dist/modes/interactive/interactive-auth.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts +123 -6
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +691 -4
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-events.d.ts +174 -0
- package/dist/modes/interactive/interactive-events.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-events.js +704 -0
- package/dist/modes/interactive/interactive-events.js.map +1 -0
- package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-format.js +1 -1
- package/dist/modes/interactive/interactive-format.js.map +1 -1
- package/dist/modes/interactive/interactive-lifecycle.d.ts +94 -0
- package/dist/modes/interactive/interactive-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-lifecycle.js +177 -0
- package/dist/modes/interactive/interactive-lifecycle.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +240 -133
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +251 -2159
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-queues.d.ts +96 -0
- package/dist/modes/interactive/interactive-queues.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-queues.js +183 -0
- package/dist/modes/interactive/interactive-queues.js.map +1 -0
- package/dist/modes/interactive/interactive-selectors.d.ts +95 -5
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +517 -6
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/startup-services.d.ts +31 -0
- package/dist/modes/interactive/startup-services.d.ts.map +1 -0
- package/dist/modes/interactive/startup-services.js +123 -0
- package/dist/modes/interactive/startup-services.js.map +1 -0
- package/dist/modes/memory-preheat.d.ts +11 -0
- package/dist/modes/memory-preheat.d.ts.map +1 -0
- package/dist/modes/memory-preheat.js +20 -0
- package/dist/modes/memory-preheat.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts +9 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +79 -0
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/remote/server-assembly.d.ts.map +1 -1
- package/dist/remote/server-assembly.js +7 -2
- package/dist/remote/server-assembly.js.map +1 -1
- package/dist/suites/builtin-suites.d.ts.map +1 -0
- package/dist/suites/builtin-suites.js.map +1 -0
- package/dist/suites/resolved-agent-profile.d.ts.map +1 -0
- package/dist/suites/resolved-agent-profile.js.map +1 -0
- package/dist/suites/suite-lifecycle.d.ts.map +1 -0
- package/dist/suites/suite-lifecycle.js.map +1 -0
- package/dist/suites/suite-loader.d.ts.map +1 -0
- package/dist/suites/suite-loader.js.map +1 -0
- package/dist/{modes/interactive/theme → theme}/dark.json +1 -1
- package/dist/{modes/interactive/theme → theme}/light.json +1 -1
- package/dist/{modes/interactive/theme → theme}/theme-controller.d.ts +1 -1
- package/dist/theme/theme-controller.d.ts.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme-controller.js +1 -1
- package/dist/theme/theme-controller.js.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme.d.ts +1 -1
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme.js +5 -5
- package/dist/theme/theme.js.map +1 -0
- package/docs/compaction.md +7 -7
- package/docs/environment-variables.md +10 -4
- package/docs/keybindings.md +3 -3
- package/docs/models.md +17 -17
- package/docs/packages.md +1 -1
- package/docs/prompt-templates.md +1 -1
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +5 -5
- package/docs/session-format.md +3 -3
- package/docs/settings.md +15 -1
- package/docs/shell-aliases.md +1 -1
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +17 -17
- package/docs/themes.md +5 -5
- package/docs/tmux.md +4 -4
- package/docs/tui.md +1 -1
- package/docs/usage.md +292 -292
- package/docs/windows.md +1 -1
- package/examples/extensions/bash-spawn-hook/index.ts +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/mcp-stdio/index.d.ts +64 -0
- package/examples/extensions/mcp-stdio/index.d.ts.map +1 -0
- package/examples/extensions/mcp-stdio/index.js +292 -0
- package/examples/extensions/mcp-stdio/index.js.map +1 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -6
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/package.json +2 -2
- package/dist/bundle/chunks/openai-responses-AUJQ3NWT.js +0 -2
- package/dist/bundle/chunks/virtual-modules-MRXD3RWG.js +0 -5
- package/dist/cli/experimental/commands/pi.d.ts +0 -15
- package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
- package/dist/cli/experimental/commands/pi.js.map +0 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
- package/dist/core/export-html/ansi-to-html.js.map +0 -1
- package/dist/core/export-html/index.d.ts.map +0 -1
- package/dist/core/export-html/index.js.map +0 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
- package/dist/core/export-html/tool-renderer.js.map +0 -1
- package/dist/core/pi-manifest.d.ts +0 -7
- package/dist/core/pi-manifest.d.ts.map +0 -1
- package/dist/core/pi-manifest.js.map +0 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +0 -1
- package/dist/modes/interactive/model-catalog-refresh.js.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme.js.map +0 -1
- package/dist/profiles/builtin-suites.d.ts.map +0 -1
- package/dist/profiles/builtin-suites.js.map +0 -1
- package/dist/profiles/resolved-agent-profile.d.ts.map +0 -1
- package/dist/profiles/resolved-agent-profile.js.map +0 -1
- package/dist/profiles/suite-lifecycle.d.ts.map +0 -1
- package/dist/profiles/suite-lifecycle.js.map +0 -1
- package/dist/profiles/suite-loader.d.ts.map +0 -1
- package/dist/profiles/suite-loader.js.map +0 -1
- package/dist/utils/deprecation.d.ts +0 -4
- package/dist/utils/deprecation.d.ts.map +0 -1
- package/dist/utils/deprecation.js +0 -13
- package/dist/utils/deprecation.js.map +0 -1
- /package/dist/{core/export-html → export-html}/ansi-to-html.d.ts +0 -0
- /package/dist/{core/export-html → export-html}/ansi-to-html.js +0 -0
- /package/dist/{core/export-html → export-html}/template.css +0 -0
- /package/dist/{core/export-html → export-html}/template.html +0 -0
- /package/dist/{core/export-html → export-html}/template.js +0 -0
- /package/dist/{core/export-html → export-html}/tool-renderer.js +0 -0
- /package/dist/{core/export-html → export-html}/vendor/highlight.min.js +0 -0
- /package/dist/{core/export-html → export-html}/vendor/marked.min.js +0 -0
- /package/dist/{profiles → suites}/builtin-suites.d.ts +0 -0
- /package/dist/{profiles → suites}/builtin-suites.js +0 -0
- /package/dist/{profiles → suites}/resolved-agent-profile.d.ts +0 -0
- /package/dist/{profiles → suites}/resolved-agent-profile.js +0 -0
- /package/dist/{profiles → suites}/suite-lifecycle.d.ts +0 -0
- /package/dist/{profiles → suites}/suite-lifecycle.js +0 -0
- /package/dist/{profiles → suites}/suite-loader.d.ts +0 -0
- /package/dist/{profiles → suites}/suite-loader.js +0 -0
- /package/dist/{modes/interactive/theme → theme}/theme-schema.json +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-services.js","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, CredentialStore, Model } from \"@agent-forge/ai\";\nimport { CONFIG_DIR_NAME, getAgentDir, VERSION } from \"../config.ts\";\nimport type { HostFactsV1 } from \"../plugins/ecosystem/types.ts\";\nimport type { ObservabilityPlugin } from \"../plugins/observability-types.ts\";\nimport type {\n\tBuiltinPluginManifestOverridesV1,\n\tBuiltinPluginProfileIdV1,\n\tBuiltinPluginProfileResolutionV1,\n} from \"../profile/plugin-profiles.ts\";\nimport type { VerifiedToolPluginV1 } from \"../profile/profile-assembly.ts\";\nimport type { SuiteDefinition } from \"../profiles/builtin-suites.ts\";\nimport { createSuiteAssembly, resolveSuiteId, SUITE_ENV_VAR } from \"../profiles/suite-loader.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./extensions/index.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport {\n\tDefaultResourceLoader,\n\ttype DefaultResourceLoaderOptions,\n\ttype ResourceLoader,\n\ttype ResourceLoaderReloadOptions,\n} from \"./resource-loader.ts\";\nimport {\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\tcreateAgentSession,\n\ttype InstalledCapabilityPluginV1,\n} from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport type { SessionStartMetadata } from \"./session-start.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport type { ToolDefinition } from \"./tools/tool-definition.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tsettingsManager?: SettingsManager;\n\tmodelRuntime?: ModelRuntime;\n\t/**\n\t * Credential storage used by the default model runtime (D-067 phase 1):\n\t * forwarded to `ModelRuntime.create` when `modelRuntime` is omitted.\n\t * Ignored when an explicit `modelRuntime` is supplied. Defaults to the\n\t * file at `<agentDir>/auth.json`.\n\t */\n\tcredentials?: CredentialStore;\n\tmodelRuntimeSignal?: AbortSignal;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresourceLoaderReloadOptions?: ResourceLoaderReloadOptions;\n\t/**\n\t * Explicit suite id (highest resolution priority, 设计 §9). Without it the\n\t * suite resolves via AGENT_FORGE_SUITE, then settings, then \"coding\".\n\t */\n\tsuite?: string;\n\t/**\n\t * Wire the full suite assembly (agents.md three-level chain, system prompt\n\t * gate, skill/extension association filters, MCP registration pool) into\n\t * these services' DefaultResourceLoader. Default false: services built\n\t * without it keep the plain loader behavior (evals and testkit\n\t * determinism). When true, the suite id is resolved exactly once here and\n\t * exposed as AgentSessionServices.suiteId so session creation reuses it\n\t * instead of resolving again. The MCP pool (设计 §4/§5) additionally reads\n\t * the mcp.json config surface, filters it by associations.mcp, and\n\t * materializes the injected servers as capability-plugin manifests\n\t * (AgentSessionServices.mcpCapabilityPluginPaths).\n\t */\n\tsuiteAssembly?: boolean;\n\t/** Optional domain plugin profile selected for this suite. */\n\tpluginProfileId?: BuiltinPluginProfileIdV1;\n\t/** Optional subset of plugins from the selected builtin Profile. */\n\tselectedPluginIds?: readonly string[];\n\t/** Optional plugin IDs disabled within the selected builtin Profile. */\n\tdisabledPluginIds?: readonly string[];\n\tpluginHost?: HostFactsV1;\n\tverifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-owned active installed manifests; never discovered implicitly. */\n\tmanifestOverrides?: BuiltinPluginManifestOverridesV1;\n\t/**\n\t * Verified active installations (D-075 S2 installed-code-loading) from the\n\t * host's active-binding resolution; forwarded to session creation so their\n\t * plugin.json paths enter the sdk's candidate pool for profile members.\n\t */\n\tinstalledCapabilityPlugins?: readonly InstalledCapabilityPluginV1[];\n\t/** Host diagnostics from active-install resolution; no package data is retained. */\n\tpluginBindingDiagnostics?: readonly AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartMetadata;\n\t/** --rebind-suite: adopt a drifted suite binding on resume (forwarded to createAgentSession). */\n\tallowSuiteRebind?: boolean;\n\tmodel?: Model<Api>;\n\tstreamFn?: CreateAgentSessionOptions[\"streamFn\"];\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcapabilityMode?: CreateAgentSessionOptions[\"capabilityMode\"];\n\tdiscoverCapabilityPlugins?: CreateAgentSessionOptions[\"discoverCapabilityPlugins\"];\n\t/**\n\t * Session trace collection (设计 §4.4/§6), forwarded to createAgentSession.\n\t * Omitted keeps the sdk default (tracing on); hosts pass `false` for\n\t * `--no-trace`.\n\t */\n\ttraceEnabled?: CreateAgentSessionOptions[\"traceEnabled\"];\n\t/**\n\t * Host-process logger forwarded to createAgentSession (设计 §5). Omitted\n\t * keeps the sdk's explicit no-logging contract (instrumentation no-ops).\n\t */\n\thostLogger?: CreateAgentSessionOptions[\"hostLogger\"];\n\tcapabilityPluginPaths?: CreateAgentSessionOptions[\"capabilityPluginPaths\"];\n\tcontextStrategyName?: CreateAgentSessionOptions[\"contextStrategyName\"];\n\tretryPolicyName?: CreateAgentSessionOptions[\"retryPolicyName\"];\n\tcompactionPolicyName?: CreateAgentSessionOptions[\"compactionPolicyName\"];\n\toverflowPolicyName?: CreateAgentSessionOptions[\"overflowPolicyName\"];\n\tbranchSummaryPolicyName?: CreateAgentSessionOptions[\"branchSummaryPolicyName\"];\n\t/** Host adapter for cancellable interaction tasks, forwarded to createAgentSession. */\n\tinteractionHost?: CreateAgentSessionOptions[\"interactionHost\"];\n\t/**\n\t * 覆盖 services 自带 loader。pooled runner 的叶子会话用它注入子任务档案的\n\t * `systemPromptAppend`(追加语义,不替换继承内容);缺省沿用 services 的 loader。\n\t */\n\tresourceLoader?: CreateAgentSessionOptions[\"resourceLoader\"];\n\t/**\n\t * Forwarded to createAgentSession. Headless subagent runners pass `false` so a\n\t * runner task session stays a leaf (no nested agent tasks; D-045 increment 2b).\n\t */\n\tenableAgentTasks?: CreateAgentSessionOptions[\"enableAgentTasks\"];\n\tcustomTools?: ToolDefinition[];\n\t/**\n\t * Explicit suite id forwarded to createAgentSession. When omitted, the\n\t * services' resolved suiteId (suiteAssembly: true) is used; without either,\n\t * createAgentSession resolves the suite itself.\n\t */\n\tsuite?: string;\n\t/**\n\t * Wire the suite's capability surface (方案系统 M3) onto the created\n\t * sessions. Default: on when the services ran the suite assembly\n\t * (suiteAssembly: true, so first-party entries get the builtin capability\n\t * whitelist and plugin-pool filtering); otherwise off, matching the sdk's\n\t * caller-supplied-loader assembly boundary.\n\t */\n\tsuiteCapabilityWiring?: boolean;\n\t/**\n\t * 子代理通信面的宿主接线(D-060 S5 pooled parity):pooled runner 的叶子会话\n\t * 用它注入 post/drainInbox 闭包(身份绑定到叶子会话,信箱为文件承载、跨进程)。\n\t */\n\tsubagentCommunicationWiring?: CreateAgentSessionOptions[\"subagentCommunicationWiring\"];\n\t/**\n\t * 承载退役切片 1(生产 CLI 默认 pooled):转发 createAgentSession 的\n\t * self-invocation 自动池化声明。仅真实 CLI 装配传 true。\n\t */\n\tsubagentPoolFromSelfInvocation?: CreateAgentSessionOptions[\"subagentPoolFromSelfInvocation\"];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\t/**\n\t * /metrics 命令的数据源共享 ref(observability 插件工厂创建时写入\n\t * plugin.getMetrics、dispose 时置空;宿主装配完成后读取接进命令 options)。\n\t * 空 = 插件未挂载(/metrics 显示未装配警告)。\n\t */\n\tobservabilityGetMetricsRef?: { current?: ObservabilityPlugin[\"getMetrics\"] };\n\tagentDir: string;\n\tmodelRuntime: ModelRuntime;\n\tsettingsManager: SettingsManager;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\t/**\n\t * Suite id resolved for these services when `suiteAssembly` was requested;\n\t * undefined when assembly was off (no suite filtering was applied here).\n\t */\n\tsuiteId?: string;\n\tpluginProfile?: BuiltinPluginProfileResolutionV1;\n\tpluginProfileId?: BuiltinPluginProfileIdV1;\n\t/**\n\t * Verified active installations (D-075 S2) forwarded from the services\n\t * options; createAgentSessionFromServices passes them to the sdk's\n\t * installed-code-loading candidate pool.\n\t */\n\tinstalledCapabilityPlugins?: readonly InstalledCapabilityPluginV1[];\n\t/**\n\t * Capability-plugin manifest paths materialized for the suite's MCP\n\t * registration pool (M4, 设计 §4/§5). Defined only when `suiteAssembly`\n\t * injected at least one associated mcp.json server;\n\t * createAgentSessionFromServices appends them to the created session's\n\t * capabilityPluginPaths.\n\t */\n\tmcpCapabilityPluginPaths?: readonly string[];\n\t/**\n\t * Plugin ids of the MCP pool servers configured with `deferredTools: true`.\n\t * Their tools register normally but stay out of the default active set; the\n\t * session's tool_search tool discovers and activates them on demand.\n\t */\n\tmcpDeferredToolPluginIds?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Suite MCP registration pool (方案系统 M4: MCP 配置面, 设计 §4/§5)\n// ---------------------------------------------------------------------------\n\n/** User-level MCP config file directly inside the agent dir. */\nconst MCP_CONFIG_FILENAME = \"mcp.json\";\n/** Generated per-server capability-plugin manifests live below this agentDir dir. */\nconst MCP_POOL_DIR = \"mcp/pool\";\n/** Shared stdio bridge module inside the pool dir (leading \"_\" keeps server names distinct). */\nconst MCP_POOL_BRIDGE_DIR = \"_bridge\";\n/** Server names are associations keys and pool directory names; \"_\" is reserved for the bridge. */\nconst MCP_SERVER_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n/** One MCP server resolved from an mcp.json configuration file. */\nexport interface SuiteMcpServerV1 {\n\t/** Server name: the associations.mcp match key and the pool directory name. */\n\treadonly name: string;\n\t/** stdio launch command; undefined for remote HTTP servers (`url` set). */\n\treadonly command?: string;\n\treadonly args: readonly string[];\n\t/** Remote HTTP endpoint; undefined for stdio servers (`command` set). */\n\treadonly url?: string;\n\t/**\n\t * Custom request headers sent with every request to a remote HTTP server;\n\t * undefined for stdio servers (`headers` there only contributes a\n\t * diagnostic and is never forwarded).\n\t */\n\treadonly headers?: Readonly<Record<string, string>>;\n\t/**\n\t * Config layer the server came from. \"project\" (`<cwd>/.agent-forge/mcp.json`)\n\t * is the third layer (设计 §4) and always passes; \"user\"\n\t * (`<agentDir>/mcp.json`) injects only when associated.\n\t */\n\treadonly scope: \"user\" | \"project\";\n\t/** Generated capability-plugin manifest path for this server. */\n\treadonly manifestPath: string;\n\t/** Whether the server's tools stay out of the default active set until tool_search activates them. */\n\treadonly deferred: boolean;\n}\n\nexport interface SuiteMcpPoolV1 {\n\t/** Injected servers in deterministic order (project first, then user). */\n\treadonly servers: readonly SuiteMcpServerV1[];\n\t/** Manifest paths ready for the session's capabilityPluginPaths channel. */\n\treadonly manifestPaths: readonly string[];\n\t/** Plugin ids whose tools are registered but excluded from the default active set. */\n\treadonly deferredPluginIds: readonly string[];\n\t/**\n\t * Diagnostics: unreadable/invalid config files, filtered non-associated\n\t * servers, project-overridden duplicates, and dangling associations.\n\t * Reported, never thrown (设计 §11.3).\n\t */\n\treadonly diagnostics: readonly string[];\n}\n\ninterface McpServerConfigV1 {\n\treadonly command?: string;\n\treadonly args: readonly string[];\n\treadonly url?: string;\n\t/** Custom request headers for remote HTTP servers; ignored (with a diagnostic) on stdio entries. */\n\treadonly headers?: Readonly<Record<string, string>>;\n\treadonly deferredTools?: boolean;\n}\n\n/**\n * Remote MCP URLs accept only http/https; any other protocol or unparseable\n * value is a configuration error, not a fallback path.\n */\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst protocol = new URL(value).protocol;\n\t\treturn protocol === \"http:\" || protocol === \"https:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Reads one mcp.json (`{ \"mcpServers\": { \"<name>\": { \"command\", \"args\" } } }`\n * for stdio servers, or `{ \"url\" }` for remote HTTP servers). Each entry must\n * carry exactly one of \"command\" and \"url\". Corruption tolerance: a missing\n * file is an empty config; an unreadable or malformed file, and invalid\n * per-server entries, contribute a diagnostic and are skipped — never thrown.\n */\nfunction parseMcpConfig(path: string): {\n\tservers: Map<string, McpServerConfigV1>;\n\tdiagnostics: string[];\n} {\n\tconst servers = new Map<string, McpServerConfigV1>();\n\tconst diagnostics: string[] = [];\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(readFileSync(path, \"utf8\"));\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { servers, diagnostics };\n\t\tdiagnostics.push(\n\t\t\t`MCP config at ${path} is unreadable; ignoring it. Errors: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t\treturn { servers, diagnostics };\n\t}\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tdiagnostics.push(`MCP config at ${path} must be an object with an \"mcpServers\" map; ignoring it.`);\n\t\treturn { servers, diagnostics };\n\t}\n\tconst mcpServers = (value as Record<string, unknown>).mcpServers;\n\tif (mcpServers === undefined) return { servers, diagnostics };\n\tif (typeof mcpServers !== \"object\" || mcpServers === null || Array.isArray(mcpServers)) {\n\t\tdiagnostics.push(`MCP config at ${path} must carry an \"mcpServers\" object; ignoring it.`);\n\t\treturn { servers, diagnostics };\n\t}\n\tfor (const [name, entry] of Object.entries(mcpServers as Record<string, unknown>)) {\n\t\tif (!MCP_SERVER_NAME_PATTERN.test(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server name \"${name}\" in ${path} is invalid (must match ${MCP_SERVER_NAME_PATTERN.source}); ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} must be an object with a \"command\" or \"url\"; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst config = entry as Record<string, unknown>;\n\t\tif (config.url !== undefined && (typeof config.url !== \"string\" || config.url.trim().length === 0)) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"url\" to be a non-empty string; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst hasCommand = typeof config.command === \"string\" && config.command.trim().length > 0;\n\t\tconst hasUrl = typeof config.url === \"string\" && config.url.trim().length > 0;\n\t\tif (hasCommand && hasUrl) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} accepts either \"command\" (stdio server) or \"url\" (remote HTTP server), not both; ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!hasCommand && !hasUrl) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} requires a non-empty string \"command\" (stdio server) or \"url\" (remote HTTP server); ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (hasUrl && !isHttpUrl(config.url as string)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} requires \"url\" to be a valid http:// or https:// URL; ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tconfig.args !== undefined &&\n\t\t\t(!Array.isArray(config.args) || !config.args.every((arg) => typeof arg === \"string\"))\n\t\t) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"args\" to be a string array; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (config.deferredTools !== undefined && typeof config.deferredTools !== \"boolean\") {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"deferredTools\" to be a boolean; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (config.headers !== undefined) {\n\t\t\tif (hasCommand) {\n\t\t\t\t// Same acceptance style as a url entry carrying args: the entry\n\t\t\t\t// loads, but the field belongs to the other transport shape.\n\t\t\t\tdiagnostics.push(\n\t\t\t\t\t`MCP server \"${name}\" in ${path} carries \"headers\" but headers only apply to remote \"url\" (HTTP) servers; ignoring them.`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst headersValid =\n\t\t\t\t\ttypeof config.headers === \"object\" &&\n\t\t\t\t\tconfig.headers !== null &&\n\t\t\t\t\t!Array.isArray(config.headers) &&\n\t\t\t\t\tObject.values(config.headers as Record<string, unknown>).every(\n\t\t\t\t\t\t(headerValue) => typeof headerValue === \"string\" && headerValue.length > 0,\n\t\t\t\t\t);\n\t\t\t\tif (!headersValid) {\n\t\t\t\t\tdiagnostics.push(\n\t\t\t\t\t\t`MCP server \"${name}\" in ${path} requires \"headers\" to be an object with non-empty string values; ignoring it.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tservers.set(name, {\n\t\t\targs: (config.args as readonly string[] | undefined) ?? [],\n\t\t\tdeferredTools: config.deferredTools === true ? true : undefined,\n\t\t\t...(hasCommand\n\t\t\t\t? { command: config.command as string }\n\t\t\t\t: {\n\t\t\t\t\t\turl: config.url as string,\n\t\t\t\t\t\t// Kept verbatim (no case normalization): managed remote MCP\n\t\t\t\t\t\t// endpoints compare header names and values exactly.\n\t\t\t\t\t\t...(config.headers === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { headers: config.headers as Readonly<Record<string, string>> }),\n\t\t\t\t\t}),\n\t\t});\n\t}\n\treturn { servers, diagnostics };\n}\n\n/**\n * Generated stdio bridge shared by every injected server: JSON-RPC 2.0 over a\n * spawned child process (argv, never a shell — except on win32, where a\n * resolved `.cmd`/`.bat` shim is launched through `cmd.exe /d /s /c`, so its\n * arguments cross cmd's command-line interpreter exactly as with\n * `shell: true`), MCP initialize/tools/list\n * handshake, and one registerTool per remote tool through the public\n * capability API. Tool call policy stays host-owned; the bridge only forwards\n * requests and maps results. On win32 the transport additionally resolves\n * `.cmd`/`.bat` shims (bare names via PATH, explicit suffixes verbatim) and\n * launches them through `cmd.exe /d /s /c` with MSVCRT argv quoting, because\n * Node >= 18.20 refuses to spawn extension shims directly (EINVAL) and\n * extension-less shim names ENOENT.\n */\nconst MCP_POOL_BRIDGE_SOURCE = `// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst REQUEST_TIMEOUT_MS = 30000;\n\n// Windows .cmd/.bat shims cannot be spawned directly: Node >= 18.20 raises\n// EINVAL for commands carrying a shim extension and ENOENT for bare names\n// (npx, pnpm, ...), so bare command names (no path separator) are probed\n// along PATH for a .cmd/.bat shim, and explicit .cmd/.bat commands pass\n// through for cmd.exe wrapping. Everything else - .exe/.com, path-bearing\n// executables, non-win32 platforms, and PATH misses - resolves to undefined\n// and keeps the direct spawn behavior (a miss keeps the original ENOENT).\nfunction resolveWin32ShimCommand(command) {\n\tif (process.platform !== 'win32') return undefined;\n\tconst lowered = command.toLowerCase();\n\tif (lowered.endsWith('.cmd') || lowered.endsWith('.bat')) return command;\n\tif (command.includes('/') || command.includes('\\\\\\\\')) return undefined;\n\tfor (const dir of (process.env.PATH || '').split(';')) {\n\t\tif (!dir) continue;\n\t\tconst cmdShim = join(dir, command + '.cmd');\n\t\tif (existsSync(cmdShim)) return cmdShim;\n\t\tconst batShim = join(dir, command + '.bat');\n\t\tif (existsSync(batShim)) return batShim;\n\t}\n\treturn undefined;\n}\n\n// MSVCRT argv quoting for the cmd.exe /c command string: an argument that is\n// empty or contains space/tab/quote is wrapped in double quotes, embedded\n// quotes are escaped as \\\\\", and backslashes directly before a quote (or a\n// quoted argument's trailing backslashes) double up (2n rule) so they cannot\n// escape the closing quote. Plain arguments pass through untouched.\nfunction quoteCommandString(parts) {\n\tconst quoted = [];\n\tfor (const part of parts) {\n\t\tif (part !== '' && !/[ \\\\t\"]/.test(part)) {\n\t\t\tquoted.push(part);\n\t\t\tcontinue;\n\t\t}\n\t\tlet inner = '';\n\t\tlet backslashes = 0;\n\t\tfor (const ch of part) {\n\t\t\tif (ch === '\\\\\\\\') {\n\t\t\t\tbackslashes += 1;\n\t\t\t} else if (ch === '\"') {\n\t\t\t\tinner += '\\\\\\\\'.repeat(backslashes * 2 + 1) + '\"';\n\t\t\t\tbackslashes = 0;\n\t\t\t} else {\n\t\t\t\tif (backslashes > 0) {\n\t\t\t\t\tinner += '\\\\\\\\'.repeat(backslashes);\n\t\t\t\t\tbackslashes = 0;\n\t\t\t\t}\n\t\t\t\tinner += ch;\n\t\t\t}\n\t\t}\n\t\tif (backslashes > 0) {\n\t\t\tinner += '\\\\\\\\'.repeat(backslashes * 2);\n\t\t}\n\t\tquoted.push('\"' + inner + '\"');\n\t}\n\treturn quoted.join(' ');\n}\n\nfunction startTransport(command, args) {\n\t// win32 only: wrap .cmd/.bat shims through cmd.exe (resolveWin32ShimCommand).\n\t// The MSVCRT-quoted command string gets ONE more plain outer pair of\n\t// quotes (cmd.exe dialect, not MSVCRT): /S strips that outer pair and\n\t// re-parses the inner string. windowsVerbatimArguments is required so the\n\t// pre-built string reaches cmd.exe untouched; Node's default quoting would\n\t// wrap it again and cmd.exe would see literal \\\\\" sequences instead.\n\tconst shim = resolveWin32ShimCommand(command);\n\tconst child =\n\t\tshim === undefined\n\t\t\t? spawn(command, args, { shell: false, stdio: ['pipe', 'pipe', 'pipe'] })\n\t\t\t: spawn('cmd.exe', ['/d', '/s', '/c', '\"' + quoteCommandString([shim].concat(args)) + '\"'], {\n\t\t\t\t\twindowsVerbatimArguments: true,\n\t\t\t\t\tstdio: ['pipe', 'pipe', 'pipe'],\n\t\t\t\t});\n\tlet nextId = 1;\n\tlet closed = false;\n\tlet failure = null;\n\tlet buffered = '';\n\tconst pending = new Map();\n\tconst rejectAll = (error) => {\n\t\tif (failure) return;\n\t\tfailure = error;\n\t\tclosed = true;\n\t\tfor (const request of pending.values()) request.reject(error);\n\t\tpending.clear();\n\t};\n\tchild.stdout.setEncoding('utf8');\n\tchild.stdout.on('data', (chunk) => {\n\t\tbuffered += chunk;\n\t\tconst lines = buffered.split(/\\\\r?\\\\n/);\n\t\tbuffered = lines.pop() || '';\n\t\tfor (const line of lines) {\n\t\t\tif (!line.trim()) continue;\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tresponse = JSON.parse(line);\n\t\t\t} catch {\n\t\t\t\trejectAll(new Error('MCP server produced a malformed JSON-RPC response'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (response.id === undefined || response.id === null) continue;\n\t\t\tconst request = pending.get(response.id);\n\t\t\tif (!request) continue;\n\t\t\tpending.delete(response.id);\n\t\t\tif (response.error) {\n\t\t\t\trequest.reject(new Error('MCP request failed: ' + String(response.error.message || 'unknown error')));\n\t\t\t} else {\n\t\t\t\trequest.resolve(response.result);\n\t\t\t}\n\t\t}\n\t});\n\tchild.stderr.setEncoding('utf8');\n\tchild.stderr.on('data', () => undefined);\n\tchild.once('error', (error) => rejectAll(new Error('Failed to spawn MCP server: ' + error.message)));\n\tchild.once('close', (exitCode) => rejectAll(new Error('MCP server exited with code ' + String(exitCode))));\n\tconst send = (message) => {\n\t\tchild.stdin.write(JSON.stringify(message) + '\\\\n');\n\t};\n\tconst request = (method, params, signal) => {\n\t\tif (failure || closed) return Promise.reject(failure || new Error('MCP transport is closed'));\n\t\tif (signal && signal.aborted) return Promise.reject(new Error('MCP request aborted'));\n\t\tconst id = nextId++;\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tpending.delete(id);\n\t\t\t\treject(new Error('MCP request timed out: ' + method));\n\t\t\t}, REQUEST_TIMEOUT_MS);\n\t\t\tpending.set(id, {\n\t\t\t\tresolve: (result) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tresolve(result);\n\t\t\t\t},\n\t\t\t\treject: (error) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\treject(error);\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (signal) {\n\t\t\t\tsignal.addEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (pending.delete(id)) reject(new Error('MCP request aborted'));\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true },\n\t\t\t\t);\n\t\t\t}\n\t\t\tsend(Object.assign({ jsonrpc: '2.0', id, method }, params === undefined ? {} : { params }));\n\t\t});\n\t};\n\treturn {\n\t\trequest,\n\t\tnotify(method, params) {\n\t\t\tif (closed) return;\n\t\t\tsend(Object.assign({ jsonrpc: '2.0', method }, params === undefined ? {} : { params }));\n\t\t},\n\t\tclose() {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tchild.stdin.end();\n\t\t\tif (!child.killed) child.kill();\n\t\t},\n\t};\n}\n\nfunction normalizeToolResult(result) {\n\tif (result && typeof result === 'object' && Array.isArray(result.content)) {\n\t\treturn { content: result.content, details: result.details };\n\t}\n\tif (result === undefined) return { content: [{ type: 'text', text: '' }], details: undefined };\n\treturn { content: [{ type: 'text', text: JSON.stringify(result) }], details: undefined };\n}\n\nexport default function createMcpStdioServerPlugin(config) {\n\treturn async (api) => {\n\t\tconst transport = startTransport(config.command, config.args || []);\n\t\ttry {\n\t\t\tawait transport.request('initialize', {\n\t\t\t\tprotocolVersion: '2024-11-05',\n\t\t\t\tcapabilities: {},\n\t\t\t\tclientInfo: { name: 'agent-forge-mcp-pool', version: '0.1.0' },\n\t\t\t});\n\t\t\ttransport.notify('notifications/initialized');\n\t\t\tconst listing = await transport.request('tools/list');\n\t\t\tif (!listing || !Array.isArray(listing.tools)) {\n\t\t\t\tthrow new Error('MCP tools/list result must contain tools[]');\n\t\t\t}\n\t\t\tfor (const tool of listing.tools) {\n\t\t\t\tif (!tool || typeof tool.name !== 'string' || !tool.name) {\n\t\t\t\t\tthrow new Error('MCP tool requires a non-empty name');\n\t\t\t\t}\n\t\t\t\tapi.registerTool({\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tlabel: tool.name,\n\t\t\t\t\tdescription: typeof tool.description === 'string' ? tool.description : 'MCP tool: ' + tool.name,\n\t\t\t\t\tparameters:\n\t\t\t\t\t\ttool.inputSchema && typeof tool.inputSchema === 'object'\n\t\t\t\t\t\t\t? tool.inputSchema\n\t\t\t\t\t\t\t: { type: 'object', properties: {} },\n\t\t\t\t\texecute: async (toolCallId, params, signal) => {\n\t\t\t\t\t\t// Dual call convention: the session passes (toolCallId, params,\n\t\t\t\t\t\t// signal); the runtime's invokeTool passes the input as the\n\t\t\t\t\t\t// single first argument.\n\t\t\t\t\t\tconst singleArgCall = params === undefined && typeof toolCallId !== 'string';\n\t\t\t\t\t\tconst input = singleArgCall ? toolCallId : params;\n\t\t\t\t\t\tconst result = await transport.request(\n\t\t\t\t\t\t\t'tools/call',\n\t\t\t\t\t\t\t{ name: tool.name, arguments: input || {} },\n\t\t\t\t\t\t\tsingleArgCall ? undefined : signal,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn normalizeToolResult(result);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdispose() {\n\t\t\t\t\ttransport.close();\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (error) {\n\t\t\ttransport.close();\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n`;\n\nfunction writeMcpPoolBridge(poolDir: string): void {\n\tconst bridgeDir = join(poolDir, MCP_POOL_BRIDGE_DIR);\n\tmkdirSync(bridgeDir, { recursive: true });\n\twriteFileSync(join(bridgeDir, \"index.mjs\"), MCP_POOL_BRIDGE_SOURCE, \"utf8\");\n}\n\n/**\n * Implementation backing url-configured pool entries (createMcpHttpServerPlugin),\n * owned by the plugins/mcp-http package since D-082 批 2. Sources resolve first\n * so development always runs the current implementation; published installs\n * ship only dist, so the bundled snapshot is the fallback.\n */\nfunction mcpHttpPluginImplPath(): string {\n\t// Package-root probe, identical to bundledCapabilityPluginDirectories\n\t// (core/sdk.ts): src runs sit at src/core (two levels up), unbundled dist\n\t// runs at dist/core (two levels up), and the Node bundle at dist/bundle\n\t// (three levels up). The first ancestor carrying a package.json wins.\n\tconst moduleDir = fileURLToPath(new URL(\".\", import.meta.url));\n\tfor (const depth of [2, 3]) {\n\t\tlet candidate = moduleDir;\n\t\tfor (let index = 0; index < depth; index++) candidate = dirname(candidate);\n\t\tif (!existsSync(join(candidate, \"package.json\"))) continue;\n\t\tconst devSource = join(candidate, \"..\", \"..\", \"plugins\", \"mcp-http\", \"src\", \"mcp-http.ts\");\n\t\tif (existsSync(devSource)) return devSource;\n\t\treturn join(candidate, \"bundled-plugins\", \"mcp-http\", \"dist\", \"mcp-http.js\");\n\t}\n\t// Unreachable in every supported layout (the probe always finds the package\n\t// root within depth 3); fail loudly instead of materializing a pool entry\n\t// that imports a guessed path.\n\tthrow new Error(\"Unable to locate the agent-forge package root for the mcp-http plugin implementation\");\n}\n\n/**\n * Import specifier for the HTTP server plugin implementation, as written into\n * a generated pool entry below `fromDir`. Relative same-drive form matches the\n * stdio entry's style; a cross-drive relative() result stays an absolute POSIX\n * path, which the capability loader (jiti) resolves.\n */\nfunction mcpHttpPluginImportSpec(fromDir: string): string {\n\tconst implPath = mcpHttpPluginImplPath();\n\tconst relNative = relative(fromDir, implPath);\n\tconst relPosix = relNative.split(sep).join(\"/\");\n\treturn isAbsolute(relNative) ? relPosix : `./${relPosix}`;\n}\n\n/** Materializes one server as a capability-plugin manifest; returns the manifest path. */\nfunction writeMcpPoolServer(poolDir: string, name: string, server: McpServerConfigV1): string {\n\tconst serverDir = join(poolDir, name);\n\tmkdirSync(serverDir, { recursive: true });\n\tconst manifest = {\n\t\tid: `agent-forge.mcp.${name}`,\n\t\tversion: \"0.1.0\",\n\t\t// The pool is re-materialized every session, so the declared range always\n\t\t// includes the running host (D-073): an upgraded host never rejects its\n\t\t// own generated pool manifests through the hostVersion gate.\n\t\thostVersion: `>=${VERSION}`,\n\t\tapiVersion: EXPERIMENTAL_PUBLIC_API_VERSION,\n\t\tentry: \"./index.mjs\",\n\t\trequiredCapabilities: [\"tools\"],\n\t};\n\twriteFileSync(join(serverDir, \"plugin.json\"), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n\tconst entry =\n\t\tserver.url === undefined\n\t\t\t? [\n\t\t\t\t\t\"// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\",\n\t\t\t\t\t`import createMcpStdioServerPlugin from \"../${MCP_POOL_BRIDGE_DIR}/index.mjs\";`,\n\t\t\t\t\t`export default createMcpStdioServerPlugin(${JSON.stringify({ command: server.command, args: server.args })});`,\n\t\t\t\t\t\"\",\n\t\t\t\t].join(\"\\n\")\n\t\t\t: [\n\t\t\t\t\t\"// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\",\n\t\t\t\t\t`import { createMcpHttpServerPlugin } from \"${mcpHttpPluginImportSpec(serverDir)}\";`,\n\t\t\t\t\t`export default createMcpHttpServerPlugin(${JSON.stringify({\n\t\t\t\t\t\turl: server.url,\n\t\t\t\t\t\t...(server.headers === undefined ? {} : { headers: server.headers }),\n\t\t\t\t\t})});`,\n\t\t\t\t\t\"\",\n\t\t\t\t].join(\"\\n\");\n\twriteFileSync(join(serverDir, \"index.mjs\"), entry, \"utf8\");\n\treturn join(serverDir, \"plugin.json\");\n}\n\n/**\n * Resolves the suite's MCP registration pool (方案系统 M4: MCP 配置面, 设计\n * §4/§5) and materializes each injected server as a capability-plugin\n * manifest below `<agentDir>/mcp/pool/`, ready for the session's\n * `capabilityPluginPaths` channel — the same way plugins directory discovery\n * injects manifests. Filtering: the project level\n * (`<cwd>/.agent-forge/mcp.json`) is the third layer (设计 §4) and always\n * passes; the user level (`<agentDir>/mcp.json`) injects only servers named\n * in `suite.associations.mcp` — an empty association list means zero\n * user-level injection, the same semantics as skills/extensions.\n */\nexport function resolveSuiteMcpPool(options: {\n\tcwd: string;\n\tagentDir: string;\n\tsuite: SuiteDefinition;\n}): SuiteMcpPoolV1 {\n\tconst { cwd, agentDir, suite } = options;\n\tconst userConfigPath = join(agentDir, MCP_CONFIG_FILENAME);\n\tconst projectConfigPath = join(cwd, CONFIG_DIR_NAME, MCP_CONFIG_FILENAME);\n\tconst user = parseMcpConfig(userConfigPath);\n\tconst project = parseMcpConfig(projectConfigPath);\n\tconst diagnostics = [...project.diagnostics, ...user.diagnostics];\n\n\tconst selected = new Map<string, McpServerConfigV1 & { scope: \"user\" | \"project\" }>();\n\t// Third layer (设计 §4): project-level servers always pass; they win name\n\t// collisions over user definitions.\n\tfor (const [name, server] of project.servers) selected.set(name, { ...server, scope: \"project\" });\n\tfor (const [name, server] of user.servers) {\n\t\tif (selected.has(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" from ${userConfigPath} is overridden by the project-level definition at ${projectConfigPath}; keeping the project one.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!suite.associations.mcp.includes(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`Suite \"${suite.id}\" MCP server \"${name}\" is not associated (associations.mcp); not injected.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tselected.set(name, { ...server, scope: \"user\" });\n\t}\n\tfor (const name of suite.associations.mcp) {\n\t\tif (!selected.has(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`Suite \"${suite.id}\" dangling association \"${name}\" (mcp): not found in the discovered registry; ignored.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst servers: SuiteMcpServerV1[] = [];\n\tconst manifestPaths: string[] = [];\n\tconst deferredPluginIds: string[] = [];\n\tif (selected.size > 0) {\n\t\tconst poolDir = join(agentDir, MCP_POOL_DIR);\n\t\twriteMcpPoolBridge(poolDir);\n\t\tfor (const [name, server] of selected) {\n\t\t\tconst manifestPath = writeMcpPoolServer(poolDir, name, server);\n\t\t\tmanifestPaths.push(manifestPath);\n\t\t\tservers.push({\n\t\t\t\tname,\n\t\t\t\targs: server.args,\n\t\t\t\tscope: server.scope,\n\t\t\t\tmanifestPath,\n\t\t\t\tdeferred: server.deferredTools === true,\n\t\t\t\t...(server.url === undefined\n\t\t\t\t\t? { command: server.command }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\turl: server.url,\n\t\t\t\t\t\t\t...(server.headers === undefined ? {} : { headers: server.headers }),\n\t\t\t\t\t\t}),\n\t\t\t});\n\t\t\tif (server.deferredTools === true) {\n\t\t\t\tdeferredPluginIds.push(`agent-forge.mcp.${name}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn { servers, manifestPaths, deferredPluginIds, diagnostics };\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst modelRuntime =\n\t\toptions.modelRuntime ??\n\t\t(await ModelRuntime.create({\n\t\t\tauthPath: join(agentDir, \"auth.json\"),\n\t\t\tmodelsPath: join(agentDir, \"models.json\"),\n\t\t\tcredentials: options.credentials,\n\t\t\tsignal: options.modelRuntimeSignal,\n\t\t}));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\t// Suite assembly (设计 §3/§4/§8, M2): resolve once and wire the shared\n\t// assembly into this loader. Off by default so evals/testkit services keep\n\t// their fixture resources unfiltered.\n\tlet suiteId: string | undefined;\n\tlet suiteLoaderOverrides:\n\t\t| Pick<\n\t\t\t\tDefaultResourceLoaderOptions,\n\t\t\t\t\"agentsFilesOverride\" | \"skillsOverride\" | \"systemPromptOverride\" | \"appendSystemPromptOverride\"\n\t\t >\n\t\t| undefined;\n\tlet suiteLocalSkillsDir: string | undefined;\n\tlet pluginProfile: BuiltinPluginProfileResolutionV1 | undefined;\n\t/** MCP registration pool for the assembled suite (M4); undefined when assembly is off. */\n\tlet mcpPool: SuiteMcpPoolV1 | undefined;\n\tif (options.suiteAssembly) {\n\t\tsuiteId = resolveSuiteId({\n\t\t\texplicit: options.suite,\n\t\t\tenvSuite: process.env[SUITE_ENV_VAR],\n\t\t\tsettings: settingsManager,\n\t\t\tagentDir,\n\t\t});\n\t\tconst suiteAssembly = createSuiteAssembly({\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tsuiteId,\n\t\t\tpluginProfileId: options.pluginProfileId,\n\t\t\tselectedPluginIds: options.selectedPluginIds,\n\t\t\tdisabledPluginIds: options.disabledPluginIds,\n\t\t\tpluginHost: options.pluginHost,\n\t\t\tverifiedPlugins: options.verifiedPlugins,\n\t\t\tmanifestOverrides: options.manifestOverrides,\n\t\t});\n\t\tpluginProfile = suiteAssembly.pluginProfile;\n\t\tsuiteLoaderOverrides = suiteAssembly.loaderOverrides;\n\t\t// Suite-local skill layer (统一修复轮 B): <suiteDir>/skills rides this\n\t\t// loader's skill paths when the suite is active, mirroring the sdk's\n\t\t// self-built loader path so the two first-party entries cannot drift.\n\t\tsuiteLocalSkillsDir = suiteAssembly.localSkillsDir;\n\t\t// MCP registration pool (M4): read the mcp.json config surface, filter\n\t\t// by associations.mcp, and materialize the injected servers as\n\t\t// capability-plugin manifests for the session's explicit paths channel.\n\t\tmcpPool = resolveSuiteMcpPool({ cwd, agentDir, suite: suiteAssembly.workspace.suite });\n\t}\n\tconst additionalSkillPaths = [\n\t\t...(options.resourceLoaderOptions?.additionalSkillPaths ?? []),\n\t\t...(suiteLocalSkillsDir === undefined ? [] : [suiteLocalSkillsDir]),\n\t];\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\t...suiteLoaderOverrides,\n\t\t...(additionalSkillPaths.length > 0 ? { additionalSkillPaths } : {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload(options.resourceLoaderReloadOptions);\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tawait modelRuntime.refresh({ allowNetwork: false });\n\tfor (const message of mcpPool?.diagnostics ?? []) {\n\t\tdiagnostics.push({ type: \"info\", message });\n\t}\n\tdiagnostics.push(...(options.pluginBindingDiagnostics ?? []));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tmodelRuntime,\n\t\tsettingsManager,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t\t...(suiteId === undefined ? {} : { suiteId }),\n\t\t...(pluginProfile === undefined ? {} : { pluginProfile }),\n\t\t...(options.pluginProfileId === undefined ? {} : { pluginProfileId: options.pluginProfileId }),\n\t\t...(options.installedCapabilityPlugins === undefined\n\t\t\t? {}\n\t\t\t: { installedCapabilityPlugins: Object.freeze([...options.installedCapabilityPlugins]) }),\n\t\t...(mcpPool !== undefined && mcpPool.manifestPaths.length > 0\n\t\t\t? { mcpCapabilityPluginPaths: mcpPool.manifestPaths }\n\t\t\t: {}),\n\t\t...(mcpPool !== undefined && mcpPool.deferredPluginIds.length > 0\n\t\t\t? { mcpDeferredToolPluginIds: mcpPool.deferredPluginIds }\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tmodelRuntime: options.services.modelRuntime,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tresourceLoader: options.resourceLoader ?? options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\t...(options.allowSuiteRebind === undefined ? {} : { allowSuiteRebind: options.allowSuiteRebind }),\n\t\tmodel: options.model,\n\t\tstreamFn: options.streamFn,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\t// Suite binding: an explicit option wins; otherwise the services' single\n\t\t// resolution result is forwarded so the sdk does not resolve again and\n\t\t// the two sides cannot drift (设计 §9).\n\t\t...(options.suite !== undefined || options.services.suiteId !== undefined\n\t\t\t? { suite: options.suite ?? options.services.suiteId }\n\t\t\t: {}),\n\t\t// Capability wiring (方案系统 M3): the sdk's caller-supplied-loader\n\t\t// boundary would leave it off for the services' own loader, so first-party\n\t\t// assembly turns it on here; an explicit option wins.\n\t\t...((options.suiteCapabilityWiring ?? options.services.suiteId !== undefined)\n\t\t\t? { suiteCapabilityWiring: true as const }\n\t\t\t: {}),\n\t\t...(options.services.pluginProfile === undefined ? {} : { pluginProfile: options.services.pluginProfile }),\n\t\t...(options.services.installedCapabilityPlugins === undefined\n\t\t\t? {}\n\t\t\t: { installedCapabilityPlugins: options.services.installedCapabilityPlugins }),\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tcapabilityMode: options.capabilityMode,\n\t\tdiscoverCapabilityPlugins: options.discoverCapabilityPlugins,\n\t\t// Trace/log control face (设计 §4.4/§5/§6): undefined passes through, so\n\t\t// the sdk defaults (trace on, no host logging) stay in effect.\n\t\ttraceEnabled: options.traceEnabled,\n\t\thostLogger: options.hostLogger,\n\t\t// MCP registration pool (M4): the services' generated manifest paths ride\n\t\t// the explicit caller-intent channel, so they bypass associations.plugins\n\t\t// filtering (they are governed by associations.mcp, not associations.plugins);\n\t\t// caller-provided paths keep discovery-order precedence on id conflicts.\n\t\t...(options.services.mcpCapabilityPluginPaths === undefined\n\t\t\t? { capabilityPluginPaths: options.capabilityPluginPaths }\n\t\t\t: {\n\t\t\t\t\tcapabilityPluginPaths: [\n\t\t\t\t\t\t...(options.capabilityPluginPaths ?? []),\n\t\t\t\t\t\t...options.services.mcpCapabilityPluginPaths,\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t...(options.services.mcpDeferredToolPluginIds === undefined\n\t\t\t? {}\n\t\t\t: { deferredToolPluginIds: options.services.mcpDeferredToolPluginIds }),\n\t\tcontextStrategyName: options.contextStrategyName,\n\t\tretryPolicyName: options.retryPolicyName,\n\t\tcompactionPolicyName: options.compactionPolicyName,\n\t\toverflowPolicyName: options.overflowPolicyName,\n\t\tbranchSummaryPolicyName: options.branchSummaryPolicyName,\n\t\t...(options.interactionHost === undefined ? {} : { interactionHost: options.interactionHost }),\n\t\t...(options.enableAgentTasks === undefined ? {} : { enableAgentTasks: options.enableAgentTasks }),\n\t\t...(options.subagentCommunicationWiring === undefined\n\t\t\t? {}\n\t\t\t: { subagentCommunicationWiring: options.subagentCommunicationWiring }),\n\t\t...(options.subagentPoolFromSelfInvocation === undefined\n\t\t\t? {}\n\t\t\t: { subagentPoolFromSelfInvocation: options.subagentPoolFromSelfInvocation }),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-services.js","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, CredentialStore, Model } from \"@agent-forge/ai\";\nimport { CONFIG_DIR_NAME, getAgentDir, VERSION } from \"../config.ts\";\nimport type { HostFactsV1 } from \"../plugins/ecosystem/types.ts\";\nimport type { ObservabilityPlugin } from \"../plugins/observability-types.ts\";\nimport type {\n\tBuiltinPluginManifestOverridesV1,\n\tBuiltinPluginProfileIdV1,\n\tBuiltinPluginProfileResolutionV1,\n} from \"../profile/plugin-profiles.ts\";\nimport type { VerifiedToolPluginV1 } from \"../profile/profile-assembly.ts\";\nimport type { SuiteDefinition } from \"../suites/builtin-suites.ts\";\nimport { createSuiteAssembly, resolveSuiteId, SUITE_ENV_VAR } from \"../suites/suite-loader.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { EXPERIMENTAL_PUBLIC_API_VERSION } from \"./extensions/index.ts\";\nimport { ModelRuntime } from \"./model-runtime.ts\";\nimport {\n\tDefaultResourceLoader,\n\ttype DefaultResourceLoaderOptions,\n\ttype ResourceLoader,\n\ttype ResourceLoaderReloadOptions,\n} from \"./resource-loader.ts\";\nimport {\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\tcreateAgentSession,\n\ttype InstalledCapabilityPluginV1,\n} from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport type { SessionStartMetadata } from \"./session-start.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport type { ToolDefinition } from \"./tools/tool-definition.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tsettingsManager?: SettingsManager;\n\tmodelRuntime?: ModelRuntime;\n\t/**\n\t * Credential storage used by the default model runtime (D-067 phase 1):\n\t * forwarded to `ModelRuntime.create` when `modelRuntime` is omitted.\n\t * Ignored when an explicit `modelRuntime` is supplied. Defaults to the\n\t * file at `<agentDir>/auth.json`.\n\t */\n\tcredentials?: CredentialStore;\n\tmodelRuntimeSignal?: AbortSignal;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n\tresourceLoaderReloadOptions?: ResourceLoaderReloadOptions;\n\t/**\n\t * Explicit suite id (highest resolution priority, 设计 §9). Without it the\n\t * suite resolves via AGENT_FORGE_SUITE, then settings, then \"coding\".\n\t */\n\tsuite?: string;\n\t/**\n\t * Wire the full suite assembly (agents.md three-level chain, system prompt\n\t * gate, skill/extension association filters, MCP registration pool) into\n\t * these services' DefaultResourceLoader. Default false: services built\n\t * without it keep the plain loader behavior (evals and testkit\n\t * determinism). When true, the suite id is resolved exactly once here and\n\t * exposed as AgentSessionServices.suiteId so session creation reuses it\n\t * instead of resolving again. The MCP pool (设计 §4/§5) additionally reads\n\t * the mcp.json config surface, filters it by associations.mcp, and\n\t * materializes the injected servers as capability-plugin manifests\n\t * (AgentSessionServices.mcpCapabilityPluginPaths).\n\t */\n\tsuiteAssembly?: boolean;\n\t/** Optional domain plugin profile selected for this suite. */\n\tpluginProfileId?: BuiltinPluginProfileIdV1;\n\t/** Optional subset of plugins from the selected builtin Profile. */\n\tselectedPluginIds?: readonly string[];\n\t/** Optional plugin IDs disabled within the selected builtin Profile. */\n\tdisabledPluginIds?: readonly string[];\n\tpluginHost?: HostFactsV1;\n\tverifiedPlugins?: readonly VerifiedToolPluginV1[];\n\t/** Explicit host-owned active installed manifests; never discovered implicitly. */\n\tmanifestOverrides?: BuiltinPluginManifestOverridesV1;\n\t/**\n\t * Verified active installations (D-075 S2 installed-code-loading) from the\n\t * host's active-binding resolution; forwarded to session creation so their\n\t * plugin.json paths enter the sdk's candidate pool for profile members.\n\t */\n\tinstalledCapabilityPlugins?: readonly InstalledCapabilityPluginV1[];\n\t/** Host diagnostics from active-install resolution; no package data is retained. */\n\tpluginBindingDiagnostics?: readonly AgentSessionRuntimeDiagnostic[];\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartMetadata;\n\t/** --rebind-suite: adopt a drifted suite binding on resume (forwarded to createAgentSession). */\n\tallowSuiteRebind?: boolean;\n\tmodel?: Model<Api>;\n\tstreamFn?: CreateAgentSessionOptions[\"streamFn\"];\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcapabilityMode?: CreateAgentSessionOptions[\"capabilityMode\"];\n\tdiscoverCapabilityPlugins?: CreateAgentSessionOptions[\"discoverCapabilityPlugins\"];\n\t/**\n\t * Session trace collection (设计 §4.4/§6), forwarded to createAgentSession.\n\t * Omitted keeps the sdk default (tracing on); hosts pass `false` for\n\t * `--no-trace`.\n\t */\n\ttraceEnabled?: CreateAgentSessionOptions[\"traceEnabled\"];\n\t/**\n\t * Host-process logger forwarded to createAgentSession (设计 §5). Omitted\n\t * keeps the sdk's explicit no-logging contract (instrumentation no-ops).\n\t */\n\thostLogger?: CreateAgentSessionOptions[\"hostLogger\"];\n\tcapabilityPluginPaths?: CreateAgentSessionOptions[\"capabilityPluginPaths\"];\n\tcontextStrategyName?: CreateAgentSessionOptions[\"contextStrategyName\"];\n\tretryPolicyName?: CreateAgentSessionOptions[\"retryPolicyName\"];\n\tcompactionPolicyName?: CreateAgentSessionOptions[\"compactionPolicyName\"];\n\toverflowPolicyName?: CreateAgentSessionOptions[\"overflowPolicyName\"];\n\tbranchSummaryPolicyName?: CreateAgentSessionOptions[\"branchSummaryPolicyName\"];\n\t/** Host adapter for cancellable interaction tasks, forwarded to createAgentSession. */\n\tinteractionHost?: CreateAgentSessionOptions[\"interactionHost\"];\n\t/**\n\t * 覆盖 services 自带 loader。pooled runner 的叶子会话用它注入子任务档案的\n\t * `systemPromptAppend`(追加语义,不替换继承内容);缺省沿用 services 的 loader。\n\t */\n\tresourceLoader?: CreateAgentSessionOptions[\"resourceLoader\"];\n\t/**\n\t * Forwarded to createAgentSession. Headless subagent runners pass `false` so a\n\t * runner task session stays a leaf (no nested agent tasks; D-045 increment 2b).\n\t */\n\tenableAgentTasks?: CreateAgentSessionOptions[\"enableAgentTasks\"];\n\tcustomTools?: ToolDefinition[];\n\t/**\n\t * Explicit suite id forwarded to createAgentSession. When omitted, the\n\t * services' resolved suiteId (suiteAssembly: true) is used; without either,\n\t * createAgentSession resolves the suite itself.\n\t */\n\tsuite?: string;\n\t/**\n\t * Wire the suite's capability surface (方案系统 M3) onto the created\n\t * sessions. Default: on when the services ran the suite assembly\n\t * (suiteAssembly: true, so first-party entries get the builtin capability\n\t * whitelist and plugin-pool filtering); otherwise off, matching the sdk's\n\t * caller-supplied-loader assembly boundary.\n\t */\n\tsuiteCapabilityWiring?: boolean;\n\t/**\n\t * 子代理通信面的宿主接线(D-060 S5 pooled parity):pooled runner 的叶子会话\n\t * 用它注入 post/drainInbox 闭包(身份绑定到叶子会话,信箱为文件承载、跨进程)。\n\t */\n\tsubagentCommunicationWiring?: CreateAgentSessionOptions[\"subagentCommunicationWiring\"];\n\t/**\n\t * 承载退役切片 1(生产 CLI 默认 pooled):转发 createAgentSession 的\n\t * self-invocation 自动池化声明。仅真实 CLI 装配传 true。\n\t */\n\tsubagentPoolFromSelfInvocation?: CreateAgentSessionOptions[\"subagentPoolFromSelfInvocation\"];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\t/**\n\t * /metrics 命令的数据源共享 ref(observability 插件工厂创建时写入\n\t * plugin.getMetrics、dispose 时置空;宿主装配完成后读取接进命令 options)。\n\t * 空 = 插件未挂载(/metrics 显示未装配警告)。\n\t */\n\tobservabilityGetMetricsRef?: { current?: ObservabilityPlugin[\"getMetrics\"] };\n\tagentDir: string;\n\tmodelRuntime: ModelRuntime;\n\tsettingsManager: SettingsManager;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n\t/**\n\t * Suite id resolved for these services when `suiteAssembly` was requested;\n\t * undefined when assembly was off (no suite filtering was applied here).\n\t */\n\tsuiteId?: string;\n\tpluginProfile?: BuiltinPluginProfileResolutionV1;\n\tpluginProfileId?: BuiltinPluginProfileIdV1;\n\t/**\n\t * Verified active installations (D-075 S2) forwarded from the services\n\t * options; createAgentSessionFromServices passes them to the sdk's\n\t * installed-code-loading candidate pool.\n\t */\n\tinstalledCapabilityPlugins?: readonly InstalledCapabilityPluginV1[];\n\t/**\n\t * Capability-plugin manifest paths materialized for the suite's MCP\n\t * registration pool (M4, 设计 §4/§5). Defined only when `suiteAssembly`\n\t * injected at least one associated mcp.json server;\n\t * createAgentSessionFromServices appends them to the created session's\n\t * capabilityPluginPaths.\n\t */\n\tmcpCapabilityPluginPaths?: readonly string[];\n\t/**\n\t * Plugin ids of the MCP pool servers configured with `deferredTools: true`.\n\t * Their tools register normally but stay out of the default active set; the\n\t * session's tool_search tool discovers and activates them on demand.\n\t */\n\tmcpDeferredToolPluginIds?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Suite MCP registration pool (方案系统 M4: MCP 配置面, 设计 §4/§5)\n// ---------------------------------------------------------------------------\n\n/** User-level MCP config file directly inside the agent dir. */\nconst MCP_CONFIG_FILENAME = \"mcp.json\";\n/** Generated per-server capability-plugin manifests live below this agentDir dir. */\nconst MCP_POOL_DIR = \"mcp/pool\";\n/** Shared stdio bridge module inside the pool dir (leading \"_\" keeps server names distinct). */\nconst MCP_POOL_BRIDGE_DIR = \"_bridge\";\n/** Server names are associations keys and pool directory names; \"_\" is reserved for the bridge. */\nconst MCP_SERVER_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n/** One MCP server resolved from an mcp.json configuration file. */\nexport interface SuiteMcpServerV1 {\n\t/** Server name: the associations.mcp match key and the pool directory name. */\n\treadonly name: string;\n\t/** stdio launch command; undefined for remote HTTP servers (`url` set). */\n\treadonly command?: string;\n\treadonly args: readonly string[];\n\t/** Remote HTTP endpoint; undefined for stdio servers (`command` set). */\n\treadonly url?: string;\n\t/**\n\t * Custom request headers sent with every request to a remote HTTP server;\n\t * undefined for stdio servers (`headers` there only contributes a\n\t * diagnostic and is never forwarded).\n\t */\n\treadonly headers?: Readonly<Record<string, string>>;\n\t/**\n\t * Config layer the server came from. \"project\" (`<cwd>/.agent-forge/mcp.json`)\n\t * is the third layer (设计 §4) and always passes; \"user\"\n\t * (`<agentDir>/mcp.json`) injects only when associated.\n\t */\n\treadonly scope: \"user\" | \"project\";\n\t/** Generated capability-plugin manifest path for this server. */\n\treadonly manifestPath: string;\n\t/** Whether the server's tools stay out of the default active set until tool_search activates them. */\n\treadonly deferred: boolean;\n}\n\nexport interface SuiteMcpPoolV1 {\n\t/** Injected servers in deterministic order (project first, then user). */\n\treadonly servers: readonly SuiteMcpServerV1[];\n\t/** Manifest paths ready for the session's capabilityPluginPaths channel. */\n\treadonly manifestPaths: readonly string[];\n\t/** Plugin ids whose tools are registered but excluded from the default active set. */\n\treadonly deferredPluginIds: readonly string[];\n\t/**\n\t * Diagnostics: unreadable/invalid config files, filtered non-associated\n\t * servers, project-overridden duplicates, and dangling associations.\n\t * Reported, never thrown (设计 §11.3).\n\t */\n\treadonly diagnostics: readonly string[];\n}\n\ninterface McpServerConfigV1 {\n\treadonly command?: string;\n\treadonly args: readonly string[];\n\treadonly url?: string;\n\t/** Custom request headers for remote HTTP servers; ignored (with a diagnostic) on stdio entries. */\n\treadonly headers?: Readonly<Record<string, string>>;\n\treadonly deferredTools?: boolean;\n}\n\n/**\n * Remote MCP URLs accept only http/https; any other protocol or unparseable\n * value is a configuration error, not a fallback path.\n */\nfunction isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst protocol = new URL(value).protocol;\n\t\treturn protocol === \"http:\" || protocol === \"https:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Reads one mcp.json (`{ \"mcpServers\": { \"<name>\": { \"command\", \"args\" } } }`\n * for stdio servers, or `{ \"url\" }` for remote HTTP servers). Each entry must\n * carry exactly one of \"command\" and \"url\". Corruption tolerance: a missing\n * file is an empty config; an unreadable or malformed file, and invalid\n * per-server entries, contribute a diagnostic and are skipped — never thrown.\n */\nfunction parseMcpConfig(path: string): {\n\tservers: Map<string, McpServerConfigV1>;\n\tdiagnostics: string[];\n} {\n\tconst servers = new Map<string, McpServerConfigV1>();\n\tconst diagnostics: string[] = [];\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(readFileSync(path, \"utf8\"));\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return { servers, diagnostics };\n\t\tdiagnostics.push(\n\t\t\t`MCP config at ${path} is unreadable; ignoring it. Errors: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t\treturn { servers, diagnostics };\n\t}\n\tif (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n\t\tdiagnostics.push(`MCP config at ${path} must be an object with an \"mcpServers\" map; ignoring it.`);\n\t\treturn { servers, diagnostics };\n\t}\n\tconst mcpServers = (value as Record<string, unknown>).mcpServers;\n\tif (mcpServers === undefined) return { servers, diagnostics };\n\tif (typeof mcpServers !== \"object\" || mcpServers === null || Array.isArray(mcpServers)) {\n\t\tdiagnostics.push(`MCP config at ${path} must carry an \"mcpServers\" object; ignoring it.`);\n\t\treturn { servers, diagnostics };\n\t}\n\tfor (const [name, entry] of Object.entries(mcpServers as Record<string, unknown>)) {\n\t\tif (!MCP_SERVER_NAME_PATTERN.test(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server name \"${name}\" in ${path} is invalid (must match ${MCP_SERVER_NAME_PATTERN.source}); ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} must be an object with a \"command\" or \"url\"; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst config = entry as Record<string, unknown>;\n\t\tif (config.url !== undefined && (typeof config.url !== \"string\" || config.url.trim().length === 0)) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"url\" to be a non-empty string; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst hasCommand = typeof config.command === \"string\" && config.command.trim().length > 0;\n\t\tconst hasUrl = typeof config.url === \"string\" && config.url.trim().length > 0;\n\t\tif (hasCommand && hasUrl) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} accepts either \"command\" (stdio server) or \"url\" (remote HTTP server), not both; ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!hasCommand && !hasUrl) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} requires a non-empty string \"command\" (stdio server) or \"url\" (remote HTTP server); ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (hasUrl && !isHttpUrl(config.url as string)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" in ${path} requires \"url\" to be a valid http:// or https:// URL; ignoring it.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tconfig.args !== undefined &&\n\t\t\t(!Array.isArray(config.args) || !config.args.every((arg) => typeof arg === \"string\"))\n\t\t) {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"args\" to be a string array; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (config.deferredTools !== undefined && typeof config.deferredTools !== \"boolean\") {\n\t\t\tdiagnostics.push(`MCP server \"${name}\" in ${path} requires \"deferredTools\" to be a boolean; ignoring it.`);\n\t\t\tcontinue;\n\t\t}\n\t\tif (config.headers !== undefined) {\n\t\t\tif (hasCommand) {\n\t\t\t\t// Same acceptance style as a url entry carrying args: the entry\n\t\t\t\t// loads, but the field belongs to the other transport shape.\n\t\t\t\tdiagnostics.push(\n\t\t\t\t\t`MCP server \"${name}\" in ${path} carries \"headers\" but headers only apply to remote \"url\" (HTTP) servers; ignoring them.`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst headersValid =\n\t\t\t\t\ttypeof config.headers === \"object\" &&\n\t\t\t\t\tconfig.headers !== null &&\n\t\t\t\t\t!Array.isArray(config.headers) &&\n\t\t\t\t\tObject.values(config.headers as Record<string, unknown>).every(\n\t\t\t\t\t\t(headerValue) => typeof headerValue === \"string\" && headerValue.length > 0,\n\t\t\t\t\t);\n\t\t\t\tif (!headersValid) {\n\t\t\t\t\tdiagnostics.push(\n\t\t\t\t\t\t`MCP server \"${name}\" in ${path} requires \"headers\" to be an object with non-empty string values; ignoring it.`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tservers.set(name, {\n\t\t\targs: (config.args as readonly string[] | undefined) ?? [],\n\t\t\tdeferredTools: config.deferredTools === true ? true : undefined,\n\t\t\t...(hasCommand\n\t\t\t\t? { command: config.command as string }\n\t\t\t\t: {\n\t\t\t\t\t\turl: config.url as string,\n\t\t\t\t\t\t// Kept verbatim (no case normalization): managed remote MCP\n\t\t\t\t\t\t// endpoints compare header names and values exactly.\n\t\t\t\t\t\t...(config.headers === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { headers: config.headers as Readonly<Record<string, string>> }),\n\t\t\t\t\t}),\n\t\t});\n\t}\n\treturn { servers, diagnostics };\n}\n\n/**\n * Generated stdio bridge shared by every injected server: JSON-RPC 2.0 over a\n * spawned child process (argv, never a shell — except on win32, where a\n * resolved `.cmd`/`.bat` shim is launched through `cmd.exe /d /s /c`, so its\n * arguments cross cmd's command-line interpreter exactly as with\n * `shell: true`), MCP initialize/tools/list\n * handshake, and one registerTool per remote tool through the public\n * capability API. Tool call policy stays host-owned; the bridge only forwards\n * requests and maps results. On win32 the transport additionally resolves\n * `.cmd`/`.bat` shims (bare names via PATH, explicit suffixes verbatim) and\n * launches them through `cmd.exe /d /s /c` with MSVCRT argv quoting, because\n * Node >= 18.20 refuses to spawn extension shims directly (EINVAL) and\n * extension-less shim names ENOENT.\n */\nconst MCP_POOL_BRIDGE_SOURCE = `// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\n\nconst REQUEST_TIMEOUT_MS = 30000;\n\n// Windows .cmd/.bat shims cannot be spawned directly: Node >= 18.20 raises\n// EINVAL for commands carrying a shim extension and ENOENT for bare names\n// (npx, pnpm, ...), so bare command names (no path separator) are probed\n// along PATH for a .cmd/.bat shim, and explicit .cmd/.bat commands pass\n// through for cmd.exe wrapping. Everything else - .exe/.com, path-bearing\n// executables, non-win32 platforms, and PATH misses - resolves to undefined\n// and keeps the direct spawn behavior (a miss keeps the original ENOENT).\nfunction resolveWin32ShimCommand(command) {\n\tif (process.platform !== 'win32') return undefined;\n\tconst lowered = command.toLowerCase();\n\tif (lowered.endsWith('.cmd') || lowered.endsWith('.bat')) return command;\n\tif (command.includes('/') || command.includes('\\\\\\\\')) return undefined;\n\tfor (const dir of (process.env.PATH || '').split(';')) {\n\t\tif (!dir) continue;\n\t\tconst cmdShim = join(dir, command + '.cmd');\n\t\tif (existsSync(cmdShim)) return cmdShim;\n\t\tconst batShim = join(dir, command + '.bat');\n\t\tif (existsSync(batShim)) return batShim;\n\t}\n\treturn undefined;\n}\n\n// MSVCRT argv quoting for the cmd.exe /c command string: an argument that is\n// empty or contains space/tab/quote is wrapped in double quotes, embedded\n// quotes are escaped as \\\\\", and backslashes directly before a quote (or a\n// quoted argument's trailing backslashes) double up (2n rule) so they cannot\n// escape the closing quote. Plain arguments pass through untouched.\nfunction quoteCommandString(parts) {\n\tconst quoted = [];\n\tfor (const part of parts) {\n\t\tif (part !== '' && !/[ \\\\t\"]/.test(part)) {\n\t\t\tquoted.push(part);\n\t\t\tcontinue;\n\t\t}\n\t\tlet inner = '';\n\t\tlet backslashes = 0;\n\t\tfor (const ch of part) {\n\t\t\tif (ch === '\\\\\\\\') {\n\t\t\t\tbackslashes += 1;\n\t\t\t} else if (ch === '\"') {\n\t\t\t\tinner += '\\\\\\\\'.repeat(backslashes * 2 + 1) + '\"';\n\t\t\t\tbackslashes = 0;\n\t\t\t} else {\n\t\t\t\tif (backslashes > 0) {\n\t\t\t\t\tinner += '\\\\\\\\'.repeat(backslashes);\n\t\t\t\t\tbackslashes = 0;\n\t\t\t\t}\n\t\t\t\tinner += ch;\n\t\t\t}\n\t\t}\n\t\tif (backslashes > 0) {\n\t\t\tinner += '\\\\\\\\'.repeat(backslashes * 2);\n\t\t}\n\t\tquoted.push('\"' + inner + '\"');\n\t}\n\treturn quoted.join(' ');\n}\n\nfunction startTransport(command, args) {\n\t// win32 only: wrap .cmd/.bat shims through cmd.exe (resolveWin32ShimCommand).\n\t// The MSVCRT-quoted command string gets ONE more plain outer pair of\n\t// quotes (cmd.exe dialect, not MSVCRT): /S strips that outer pair and\n\t// re-parses the inner string. windowsVerbatimArguments is required so the\n\t// pre-built string reaches cmd.exe untouched; Node's default quoting would\n\t// wrap it again and cmd.exe would see literal \\\\\" sequences instead.\n\tconst shim = resolveWin32ShimCommand(command);\n\tconst child =\n\t\tshim === undefined\n\t\t\t? spawn(command, args, { shell: false, stdio: ['pipe', 'pipe', 'pipe'] })\n\t\t\t: spawn('cmd.exe', ['/d', '/s', '/c', '\"' + quoteCommandString([shim].concat(args)) + '\"'], {\n\t\t\t\t\twindowsVerbatimArguments: true,\n\t\t\t\t\tstdio: ['pipe', 'pipe', 'pipe'],\n\t\t\t\t});\n\tlet nextId = 1;\n\tlet closed = false;\n\tlet failure = null;\n\tlet buffered = '';\n\tconst pending = new Map();\n\tconst rejectAll = (error) => {\n\t\tif (failure) return;\n\t\tfailure = error;\n\t\tclosed = true;\n\t\tfor (const request of pending.values()) request.reject(error);\n\t\tpending.clear();\n\t};\n\tchild.stdout.setEncoding('utf8');\n\tchild.stdout.on('data', (chunk) => {\n\t\tbuffered += chunk;\n\t\tconst lines = buffered.split(/\\\\r?\\\\n/);\n\t\tbuffered = lines.pop() || '';\n\t\tfor (const line of lines) {\n\t\t\tif (!line.trim()) continue;\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tresponse = JSON.parse(line);\n\t\t\t} catch {\n\t\t\t\trejectAll(new Error('MCP server produced a malformed JSON-RPC response'));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (response.id === undefined || response.id === null) continue;\n\t\t\tconst request = pending.get(response.id);\n\t\t\tif (!request) continue;\n\t\t\tpending.delete(response.id);\n\t\t\tif (response.error) {\n\t\t\t\trequest.reject(new Error('MCP request failed: ' + String(response.error.message || 'unknown error')));\n\t\t\t} else {\n\t\t\t\trequest.resolve(response.result);\n\t\t\t}\n\t\t}\n\t});\n\tchild.stderr.setEncoding('utf8');\n\tchild.stderr.on('data', () => undefined);\n\tchild.once('error', (error) => rejectAll(new Error('Failed to spawn MCP server: ' + error.message)));\n\tchild.once('close', (exitCode) => rejectAll(new Error('MCP server exited with code ' + String(exitCode))));\n\tconst send = (message) => {\n\t\tchild.stdin.write(JSON.stringify(message) + '\\\\n');\n\t};\n\tconst request = (method, params, signal) => {\n\t\tif (failure || closed) return Promise.reject(failure || new Error('MCP transport is closed'));\n\t\tif (signal && signal.aborted) return Promise.reject(new Error('MCP request aborted'));\n\t\tconst id = nextId++;\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tpending.delete(id);\n\t\t\t\treject(new Error('MCP request timed out: ' + method));\n\t\t\t}, REQUEST_TIMEOUT_MS);\n\t\t\tpending.set(id, {\n\t\t\t\tresolve: (result) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tresolve(result);\n\t\t\t\t},\n\t\t\t\treject: (error) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\treject(error);\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (signal) {\n\t\t\t\tsignal.addEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tif (pending.delete(id)) reject(new Error('MCP request aborted'));\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true },\n\t\t\t\t);\n\t\t\t}\n\t\t\tsend(Object.assign({ jsonrpc: '2.0', id, method }, params === undefined ? {} : { params }));\n\t\t});\n\t};\n\treturn {\n\t\trequest,\n\t\tnotify(method, params) {\n\t\t\tif (closed) return;\n\t\t\tsend(Object.assign({ jsonrpc: '2.0', method }, params === undefined ? {} : { params }));\n\t\t},\n\t\tclose() {\n\t\t\tif (closed) return;\n\t\t\tclosed = true;\n\t\t\tchild.stdin.end();\n\t\t\tif (!child.killed) child.kill();\n\t\t},\n\t};\n}\n\nfunction normalizeToolResult(result) {\n\tif (result && typeof result === 'object' && Array.isArray(result.content)) {\n\t\treturn { content: result.content, details: result.details };\n\t}\n\tif (result === undefined) return { content: [{ type: 'text', text: '' }], details: undefined };\n\treturn { content: [{ type: 'text', text: JSON.stringify(result) }], details: undefined };\n}\n\nexport default function createMcpStdioServerPlugin(config) {\n\treturn async (api) => {\n\t\tconst transport = startTransport(config.command, config.args || []);\n\t\ttry {\n\t\t\tawait transport.request('initialize', {\n\t\t\t\tprotocolVersion: '2024-11-05',\n\t\t\t\tcapabilities: {},\n\t\t\t\tclientInfo: { name: 'agent-forge-mcp-pool', version: '0.1.0' },\n\t\t\t});\n\t\t\ttransport.notify('notifications/initialized');\n\t\t\tconst listing = await transport.request('tools/list');\n\t\t\tif (!listing || !Array.isArray(listing.tools)) {\n\t\t\t\tthrow new Error('MCP tools/list result must contain tools[]');\n\t\t\t}\n\t\t\tfor (const tool of listing.tools) {\n\t\t\t\tif (!tool || typeof tool.name !== 'string' || !tool.name) {\n\t\t\t\t\tthrow new Error('MCP tool requires a non-empty name');\n\t\t\t\t}\n\t\t\t\tapi.registerTool({\n\t\t\t\t\tname: tool.name,\n\t\t\t\t\tlabel: tool.name,\n\t\t\t\t\tdescription: typeof tool.description === 'string' ? tool.description : 'MCP tool: ' + tool.name,\n\t\t\t\t\tparameters:\n\t\t\t\t\t\ttool.inputSchema && typeof tool.inputSchema === 'object'\n\t\t\t\t\t\t\t? tool.inputSchema\n\t\t\t\t\t\t\t: { type: 'object', properties: {} },\n\t\t\t\t\texecute: async (toolCallId, params, signal) => {\n\t\t\t\t\t\t// Dual call convention: the session passes (toolCallId, params,\n\t\t\t\t\t\t// signal); the runtime's invokeTool passes the input as the\n\t\t\t\t\t\t// single first argument.\n\t\t\t\t\t\tconst singleArgCall = params === undefined && typeof toolCallId !== 'string';\n\t\t\t\t\t\tconst input = singleArgCall ? toolCallId : params;\n\t\t\t\t\t\tconst result = await transport.request(\n\t\t\t\t\t\t\t'tools/call',\n\t\t\t\t\t\t\t{ name: tool.name, arguments: input || {} },\n\t\t\t\t\t\t\tsingleArgCall ? undefined : signal,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn normalizeToolResult(result);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdispose() {\n\t\t\t\t\ttransport.close();\n\t\t\t\t},\n\t\t\t};\n\t\t} catch (error) {\n\t\t\ttransport.close();\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n`;\n\nfunction writeMcpPoolBridge(poolDir: string): void {\n\tconst bridgeDir = join(poolDir, MCP_POOL_BRIDGE_DIR);\n\tmkdirSync(bridgeDir, { recursive: true });\n\twriteFileSync(join(bridgeDir, \"index.mjs\"), MCP_POOL_BRIDGE_SOURCE, \"utf8\");\n}\n\n/**\n * Implementation backing url-configured pool entries (createMcpHttpServerPlugin),\n * owned by the plugins/mcp-http package since D-082 批 2. Sources resolve first\n * so development always runs the current implementation; published installs\n * ship only dist, so the bundled snapshot is the fallback.\n */\nfunction mcpHttpPluginImplPath(): string {\n\t// Package-root probe, identical to bundledCapabilityPluginDirectories\n\t// (core/sdk.ts): src runs sit at src/core (two levels up), unbundled dist\n\t// runs at dist/core (two levels up), and the Node bundle at dist/bundle\n\t// (three levels up). The first ancestor carrying a package.json wins.\n\tconst moduleDir = fileURLToPath(new URL(\".\", import.meta.url));\n\tfor (const depth of [2, 3]) {\n\t\tlet candidate = moduleDir;\n\t\tfor (let index = 0; index < depth; index++) candidate = dirname(candidate);\n\t\tif (!existsSync(join(candidate, \"package.json\"))) continue;\n\t\tconst devSource = join(candidate, \"..\", \"..\", \"plugins\", \"mcp-http\", \"src\", \"mcp-http.ts\");\n\t\tif (existsSync(devSource)) return devSource;\n\t\treturn join(candidate, \"bundled-plugins\", \"mcp-http\", \"dist\", \"mcp-http.js\");\n\t}\n\t// Unreachable in every supported layout (the probe always finds the package\n\t// root within depth 3); fail loudly instead of materializing a pool entry\n\t// that imports a guessed path.\n\tthrow new Error(\"Unable to locate the agent-forge package root for the mcp-http plugin implementation\");\n}\n\n/**\n * Import specifier for the HTTP server plugin implementation, as written into\n * a generated pool entry below `fromDir`. Relative same-drive form matches the\n * stdio entry's style; a cross-drive relative() result stays an absolute POSIX\n * path, which the capability loader (jiti) resolves.\n */\nfunction mcpHttpPluginImportSpec(fromDir: string): string {\n\tconst implPath = mcpHttpPluginImplPath();\n\tconst relNative = relative(fromDir, implPath);\n\tconst relPosix = relNative.split(sep).join(\"/\");\n\treturn isAbsolute(relNative) ? relPosix : `./${relPosix}`;\n}\n\n/** Materializes one server as a capability-plugin manifest; returns the manifest path. */\nfunction writeMcpPoolServer(poolDir: string, name: string, server: McpServerConfigV1): string {\n\tconst serverDir = join(poolDir, name);\n\tmkdirSync(serverDir, { recursive: true });\n\tconst manifest = {\n\t\tid: `agent-forge.mcp.${name}`,\n\t\tversion: \"0.1.0\",\n\t\t// The pool is re-materialized every session, so the declared range always\n\t\t// includes the running host (D-073): an upgraded host never rejects its\n\t\t// own generated pool manifests through the hostVersion gate.\n\t\thostVersion: `>=${VERSION}`,\n\t\tapiVersion: EXPERIMENTAL_PUBLIC_API_VERSION,\n\t\tentry: \"./index.mjs\",\n\t\trequiredCapabilities: [\"tools\"],\n\t};\n\twriteFileSync(join(serverDir, \"plugin.json\"), `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n\tconst entry =\n\t\tserver.url === undefined\n\t\t\t? [\n\t\t\t\t\t\"// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\",\n\t\t\t\t\t`import createMcpStdioServerPlugin from \"../${MCP_POOL_BRIDGE_DIR}/index.mjs\";`,\n\t\t\t\t\t`export default createMcpStdioServerPlugin(${JSON.stringify({ command: server.command, args: server.args })});`,\n\t\t\t\t\t\"\",\n\t\t\t\t].join(\"\\n\")\n\t\t\t: [\n\t\t\t\t\t\"// Generated by the suite MCP registration pool (agent-session-services). Do not edit.\",\n\t\t\t\t\t`import { createMcpHttpServerPlugin } from \"${mcpHttpPluginImportSpec(serverDir)}\";`,\n\t\t\t\t\t`export default createMcpHttpServerPlugin(${JSON.stringify({\n\t\t\t\t\t\turl: server.url,\n\t\t\t\t\t\t...(server.headers === undefined ? {} : { headers: server.headers }),\n\t\t\t\t\t})});`,\n\t\t\t\t\t\"\",\n\t\t\t\t].join(\"\\n\");\n\twriteFileSync(join(serverDir, \"index.mjs\"), entry, \"utf8\");\n\treturn join(serverDir, \"plugin.json\");\n}\n\n/**\n * Resolves the suite's MCP registration pool (方案系统 M4: MCP 配置面, 设计\n * §4/§5) and materializes each injected server as a capability-plugin\n * manifest below `<agentDir>/mcp/pool/`, ready for the session's\n * `capabilityPluginPaths` channel — the same way plugins directory discovery\n * injects manifests. Filtering: the project level\n * (`<cwd>/.agent-forge/mcp.json`) is the third layer (设计 §4) and always\n * passes; the user level (`<agentDir>/mcp.json`) injects only servers named\n * in `suite.associations.mcp` — an empty association list means zero\n * user-level injection, the same semantics as skills/extensions.\n */\nexport function resolveSuiteMcpPool(options: {\n\tcwd: string;\n\tagentDir: string;\n\tsuite: SuiteDefinition;\n}): SuiteMcpPoolV1 {\n\tconst { cwd, agentDir, suite } = options;\n\tconst userConfigPath = join(agentDir, MCP_CONFIG_FILENAME);\n\tconst projectConfigPath = join(cwd, CONFIG_DIR_NAME, MCP_CONFIG_FILENAME);\n\tconst user = parseMcpConfig(userConfigPath);\n\tconst project = parseMcpConfig(projectConfigPath);\n\tconst diagnostics = [...project.diagnostics, ...user.diagnostics];\n\n\tconst selected = new Map<string, McpServerConfigV1 & { scope: \"user\" | \"project\" }>();\n\t// Third layer (设计 §4): project-level servers always pass; they win name\n\t// collisions over user definitions.\n\tfor (const [name, server] of project.servers) selected.set(name, { ...server, scope: \"project\" });\n\tfor (const [name, server] of user.servers) {\n\t\tif (selected.has(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`MCP server \"${name}\" from ${userConfigPath} is overridden by the project-level definition at ${projectConfigPath}; keeping the project one.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!suite.associations.mcp.includes(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`Suite \"${suite.id}\" MCP server \"${name}\" is not associated (associations.mcp); not injected.`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tselected.set(name, { ...server, scope: \"user\" });\n\t}\n\tfor (const name of suite.associations.mcp) {\n\t\tif (!selected.has(name)) {\n\t\t\tdiagnostics.push(\n\t\t\t\t`Suite \"${suite.id}\" dangling association \"${name}\" (mcp): not found in the discovered registry; ignored.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tconst servers: SuiteMcpServerV1[] = [];\n\tconst manifestPaths: string[] = [];\n\tconst deferredPluginIds: string[] = [];\n\tif (selected.size > 0) {\n\t\tconst poolDir = join(agentDir, MCP_POOL_DIR);\n\t\twriteMcpPoolBridge(poolDir);\n\t\tfor (const [name, server] of selected) {\n\t\t\tconst manifestPath = writeMcpPoolServer(poolDir, name, server);\n\t\t\tmanifestPaths.push(manifestPath);\n\t\t\tservers.push({\n\t\t\t\tname,\n\t\t\t\targs: server.args,\n\t\t\t\tscope: server.scope,\n\t\t\t\tmanifestPath,\n\t\t\t\tdeferred: server.deferredTools === true,\n\t\t\t\t...(server.url === undefined\n\t\t\t\t\t? { command: server.command }\n\t\t\t\t\t: {\n\t\t\t\t\t\t\turl: server.url,\n\t\t\t\t\t\t\t...(server.headers === undefined ? {} : { headers: server.headers }),\n\t\t\t\t\t\t}),\n\t\t\t});\n\t\t\tif (server.deferredTools === true) {\n\t\t\t\tdeferredPluginIds.push(`agent-forge.mcp.${name}`);\n\t\t\t}\n\t\t}\n\t}\n\treturn { servers, manifestPaths, deferredPluginIds, diagnostics };\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst modelRuntime =\n\t\toptions.modelRuntime ??\n\t\t(await ModelRuntime.create({\n\t\t\tauthPath: join(agentDir, \"auth.json\"),\n\t\t\tmodelsPath: join(agentDir, \"models.json\"),\n\t\t\tcredentials: options.credentials,\n\t\t\tsignal: options.modelRuntimeSignal,\n\t\t}));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\t// Suite assembly (设计 §3/§4/§8, M2): resolve once and wire the shared\n\t// assembly into this loader. Off by default so evals/testkit services keep\n\t// their fixture resources unfiltered.\n\tlet suiteId: string | undefined;\n\tlet suiteLoaderOverrides:\n\t\t| Pick<\n\t\t\t\tDefaultResourceLoaderOptions,\n\t\t\t\t\"agentsFilesOverride\" | \"skillsOverride\" | \"systemPromptOverride\" | \"appendSystemPromptOverride\"\n\t\t >\n\t\t| undefined;\n\tlet suiteLocalSkillsDir: string | undefined;\n\tlet pluginProfile: BuiltinPluginProfileResolutionV1 | undefined;\n\t/** MCP registration pool for the assembled suite (M4); undefined when assembly is off. */\n\tlet mcpPool: SuiteMcpPoolV1 | undefined;\n\tif (options.suiteAssembly) {\n\t\tsuiteId = resolveSuiteId({\n\t\t\texplicit: options.suite,\n\t\t\tenvSuite: process.env[SUITE_ENV_VAR],\n\t\t\tsettings: settingsManager,\n\t\t\tagentDir,\n\t\t});\n\t\tconst suiteAssembly = createSuiteAssembly({\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tsuiteId,\n\t\t\tpluginProfileId: options.pluginProfileId,\n\t\t\tselectedPluginIds: options.selectedPluginIds,\n\t\t\tdisabledPluginIds: options.disabledPluginIds,\n\t\t\tpluginHost: options.pluginHost,\n\t\t\tverifiedPlugins: options.verifiedPlugins,\n\t\t\tmanifestOverrides: options.manifestOverrides,\n\t\t});\n\t\tpluginProfile = suiteAssembly.pluginProfile;\n\t\tsuiteLoaderOverrides = suiteAssembly.loaderOverrides;\n\t\t// Suite-local skill layer (统一修复轮 B): <suiteDir>/skills rides this\n\t\t// loader's skill paths when the suite is active, mirroring the sdk's\n\t\t// self-built loader path so the two first-party entries cannot drift.\n\t\tsuiteLocalSkillsDir = suiteAssembly.localSkillsDir;\n\t\t// MCP registration pool (M4): read the mcp.json config surface, filter\n\t\t// by associations.mcp, and materialize the injected servers as\n\t\t// capability-plugin manifests for the session's explicit paths channel.\n\t\tmcpPool = resolveSuiteMcpPool({ cwd, agentDir, suite: suiteAssembly.workspace.suite });\n\t}\n\tconst additionalSkillPaths = [\n\t\t...(options.resourceLoaderOptions?.additionalSkillPaths ?? []),\n\t\t...(suiteLocalSkillsDir === undefined ? [] : [suiteLocalSkillsDir]),\n\t];\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\t...suiteLoaderOverrides,\n\t\t...(additionalSkillPaths.length > 0 ? { additionalSkillPaths } : {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload(options.resourceLoaderReloadOptions);\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tawait modelRuntime.refresh({ allowNetwork: false });\n\tfor (const message of mcpPool?.diagnostics ?? []) {\n\t\tdiagnostics.push({ type: \"info\", message });\n\t}\n\tdiagnostics.push(...(options.pluginBindingDiagnostics ?? []));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tmodelRuntime,\n\t\tsettingsManager,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t\t...(suiteId === undefined ? {} : { suiteId }),\n\t\t...(pluginProfile === undefined ? {} : { pluginProfile }),\n\t\t...(options.pluginProfileId === undefined ? {} : { pluginProfileId: options.pluginProfileId }),\n\t\t...(options.installedCapabilityPlugins === undefined\n\t\t\t? {}\n\t\t\t: { installedCapabilityPlugins: Object.freeze([...options.installedCapabilityPlugins]) }),\n\t\t...(mcpPool !== undefined && mcpPool.manifestPaths.length > 0\n\t\t\t? { mcpCapabilityPluginPaths: mcpPool.manifestPaths }\n\t\t\t: {}),\n\t\t...(mcpPool !== undefined && mcpPool.deferredPluginIds.length > 0\n\t\t\t? { mcpDeferredToolPluginIds: mcpPool.deferredPluginIds }\n\t\t\t: {}),\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tmodelRuntime: options.services.modelRuntime,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tresourceLoader: options.resourceLoader ?? options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\t...(options.allowSuiteRebind === undefined ? {} : { allowSuiteRebind: options.allowSuiteRebind }),\n\t\tmodel: options.model,\n\t\tstreamFn: options.streamFn,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\t// Suite binding: an explicit option wins; otherwise the services' single\n\t\t// resolution result is forwarded so the sdk does not resolve again and\n\t\t// the two sides cannot drift (设计 §9).\n\t\t...(options.suite !== undefined || options.services.suiteId !== undefined\n\t\t\t? { suite: options.suite ?? options.services.suiteId }\n\t\t\t: {}),\n\t\t// Capability wiring (方案系统 M3): the sdk's caller-supplied-loader\n\t\t// boundary would leave it off for the services' own loader, so first-party\n\t\t// assembly turns it on here; an explicit option wins.\n\t\t...((options.suiteCapabilityWiring ?? options.services.suiteId !== undefined)\n\t\t\t? { suiteCapabilityWiring: true as const }\n\t\t\t: {}),\n\t\t...(options.services.pluginProfile === undefined ? {} : { pluginProfile: options.services.pluginProfile }),\n\t\t...(options.services.installedCapabilityPlugins === undefined\n\t\t\t? {}\n\t\t\t: { installedCapabilityPlugins: options.services.installedCapabilityPlugins }),\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tcapabilityMode: options.capabilityMode,\n\t\tdiscoverCapabilityPlugins: options.discoverCapabilityPlugins,\n\t\t// Trace/log control face (设计 §4.4/§5/§6): undefined passes through, so\n\t\t// the sdk defaults (trace on, no host logging) stay in effect.\n\t\ttraceEnabled: options.traceEnabled,\n\t\thostLogger: options.hostLogger,\n\t\t// MCP registration pool (M4): the services' generated manifest paths ride\n\t\t// the explicit caller-intent channel, so they bypass associations.plugins\n\t\t// filtering (they are governed by associations.mcp, not associations.plugins);\n\t\t// caller-provided paths keep discovery-order precedence on id conflicts.\n\t\t...(options.services.mcpCapabilityPluginPaths === undefined\n\t\t\t? { capabilityPluginPaths: options.capabilityPluginPaths }\n\t\t\t: {\n\t\t\t\t\tcapabilityPluginPaths: [\n\t\t\t\t\t\t...(options.capabilityPluginPaths ?? []),\n\t\t\t\t\t\t...options.services.mcpCapabilityPluginPaths,\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t...(options.services.mcpDeferredToolPluginIds === undefined\n\t\t\t? {}\n\t\t\t: { deferredToolPluginIds: options.services.mcpDeferredToolPluginIds }),\n\t\tcontextStrategyName: options.contextStrategyName,\n\t\tretryPolicyName: options.retryPolicyName,\n\t\tcompactionPolicyName: options.compactionPolicyName,\n\t\toverflowPolicyName: options.overflowPolicyName,\n\t\tbranchSummaryPolicyName: options.branchSummaryPolicyName,\n\t\t...(options.interactionHost === undefined ? {} : { interactionHost: options.interactionHost }),\n\t\t...(options.enableAgentTasks === undefined ? {} : { enableAgentTasks: options.enableAgentTasks }),\n\t\t...(options.subagentCommunicationWiring === undefined\n\t\t\t? {}\n\t\t\t: { subagentCommunicationWiring: options.subagentCommunicationWiring }),\n\t\t...(options.subagentPoolFromSelfInvocation === undefined\n\t\t\t? {}\n\t\t\t: { subagentPoolFromSelfInvocation: options.subagentPoolFromSelfInvocation }),\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAsD,MAAM,yBAAyB,CAAC;AAChH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAQjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,uEAAuE;IACvE,UAAU,EAAE,wBAAwB,CAAC;IACrC,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CAoDxG;AAWD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAwE9B","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAsD,MAAM,yBAAyB,CAAC;AAChH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAQjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,uEAAuE;IACvE,UAAU,EAAE,wBAAwB,CAAC;IACrC,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CAoDxG;AAWD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAwE9B","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 256000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
|
|
@@ -160,7 +160,7 @@ Summary of that exploration:
|
|
|
160
160
|
export async function generateBranchSummary(entries, options) {
|
|
161
161
|
const { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;
|
|
162
162
|
// Token budget = context window minus reserved space for prompt + response
|
|
163
|
-
const contextWindow = model.contextWindow ||
|
|
163
|
+
const contextWindow = model.contextWindow || 256000;
|
|
164
164
|
const tokenBudget = contextWindow - reserveTokens;
|
|
165
165
|
const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);
|
|
166
166
|
if (messages.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 256000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,wBAAgB,8BAA8B,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,wBAAgB,8BAA8B,IAAI,OAAO,CAExD","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\treturn process.env.AGENT_FORGE_EXPERIMENTAL === \"1\";\n}\n"]}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
export function areExperimentalFeaturesEnabled() {
|
|
2
|
-
|
|
3
|
-
// Legacy fallback for installations configured before the Agent Forge rename.
|
|
4
|
-
return configuredValue === undefined ? process.env.PI_EXPERIMENTAL === "1" : configuredValue === "1";
|
|
2
|
+
return process.env.AGENT_FORGE_EXPERIMENTAL === "1";
|
|
5
3
|
}
|
|
6
4
|
//# sourceMappingURL=experimental.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,8BAA8B,GAAY;IACzD,
|
|
1
|
+
{"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,8BAA8B,GAAY;IACzD,OAAO,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAC;AAAA,CACpD","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\treturn process.env.AGENT_FORGE_EXPERIMENTAL === \"1\";\n}\n"]}
|