@ai-agent-forge/agent-forge 0.86.3 → 0.86.5
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 +60 -0
- package/dist/bundle/.build-manifest.json +500 -434
- package/dist/bundle/chunks/anthropic-messages-ALDZBUKI.js +6 -0
- package/dist/bundle/chunks/anthropic.js +2 -2
- package/dist/bundle/chunks/{azure-openai-responses-WQCZWFAH.js → azure-openai-responses-A2WJWZFB.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/chunk-A7GUOX2H.js +141 -0
- package/dist/bundle/chunks/{chunk-WGLBM2BP.js → chunk-CIX3FSBK.js} +1 -1
- package/dist/bundle/chunks/{chunk-RK2X2KU2.js → chunk-EALJ5DDX.js} +111 -101
- package/dist/bundle/chunks/chunk-OO6DJ3CL.js +31 -0
- package/dist/bundle/chunks/{chunk-N6BQJSGH.js → chunk-SQFG22WN.js} +3 -3
- package/dist/bundle/chunks/{chunk-V46XUTK3.js → chunk-Y7HXTASS.js} +1 -1
- package/dist/bundle/chunks/{chunk-3WE3W52L.js → chunk-YJCQVXW5.js} +1 -1
- package/dist/bundle/chunks/github-copilot.js +1 -1
- package/dist/bundle/chunks/google-generative-ai-NIB4WONV.js +2 -0
- package/dist/bundle/chunks/google-vertex-DCPYUEUO.js +2 -0
- package/dist/bundle/chunks/mistral-conversations-OC6LA5XL.js +5 -0
- package/dist/bundle/chunks/{openai-codex-responses-YDJSZOIH.js → openai-codex-responses-IO2X4Y7L.js} +1 -1
- package/dist/bundle/chunks/openai-codex.js +2 -2
- package/dist/bundle/chunks/{openai-completions-UPRWTQPT.js → openai-completions-XYQQHETU.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-O63W6HQ3.js → openai-responses-DLIRN3CI.js} +1 -1
- package/dist/bundle/chunks/{openrouter-images-G3GT5BVT.js → openrouter-images-G4GQRUSG.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +2 -2
- package/dist/bundle/chunks/{pi-messages-SLF355GF.js → pi-messages-E6RRYBO7.js} +1 -1
- package/dist/bundle/chunks/radius.js +2 -2
- package/dist/bundle/chunks/{virtual-modules-O72ICTMQ.js → virtual-modules-3IZ4MYSQ.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/capabilities/builtin.d.ts +4 -2
- package/dist/capabilities/builtin.d.ts.map +1 -1
- package/dist/capabilities/builtin.js +5 -1
- package/dist/capabilities/builtin.js.map +1 -1
- package/dist/cli/plugin-command.d.ts.map +1 -1
- package/dist/cli/plugin-command.js +51 -5
- package/dist/cli/plugin-command.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +2 -2
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +54 -6
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-internal.d.ts +2 -4
- package/dist/core/agent-session-internal.d.ts.map +1 -1
- package/dist/core/agent-session-internal.js.map +1 -1
- package/dist/core/agent-session-paths.d.ts +2 -0
- package/dist/core/agent-session-paths.d.ts.map +1 -1
- package/dist/core/agent-session-paths.js +2 -1
- package/dist/core/agent-session-paths.js.map +1 -1
- package/dist/core/agent-session-projection.d.ts +10 -4
- package/dist/core/agent-session-projection.d.ts.map +1 -1
- package/dist/core/agent-session-projection.js +17 -4
- package/dist/core/agent-session-projection.js.map +1 -1
- package/dist/core/agent-session.d.ts +19 -5
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +30 -4
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.js +1 -2
- package/dist/core/extensions/bootstrap-compaction-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.d.ts +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.js +5 -2
- package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
- package/dist/core/extensions/capability-runtime-store.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-store.js +1 -0
- package/dist/core/extensions/capability-runtime-store.js.map +1 -1
- package/dist/core/extensions/capability-runtime-types.d.ts +16 -1
- package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -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 +38 -2
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.d.ts +46 -0
- package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.js +101 -0
- package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
- package/dist/core/extensions/microcompact.d.ts +16 -8
- package/dist/core/extensions/microcompact.d.ts.map +1 -1
- package/dist/core/extensions/microcompact.js +9 -7
- package/dist/core/extensions/microcompact.js.map +1 -1
- package/dist/core/extensions/provider-failover.d.ts +106 -0
- package/dist/core/extensions/provider-failover.d.ts.map +1 -0
- package/dist/core/extensions/provider-failover.js +692 -0
- package/dist/core/extensions/provider-failover.js.map +1 -0
- package/dist/core/facade/coding-agent-facade.d.ts +13 -6
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +3 -1
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/keybindings.d.ts +6 -6
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +23 -6
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-config.d.ts +102 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +46 -14
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +15 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +30 -18
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +4 -9
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +107 -24
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +10 -5
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +74 -5
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +143 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +17 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +9 -10
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition.d.ts +21 -2
- package/dist/core/tools/tool-definition.d.ts.map +1 -1
- package/dist/core/tools/tool-definition.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/agents-view.d.ts +57 -0
- package/dist/modes/interactive/components/agents-view.d.ts.map +1 -0
- package/dist/modes/interactive/components/agents-view.js +260 -0
- package/dist/modes/interactive/components/agents-view.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +2 -2
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +15 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +90 -9
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +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/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +12 -2
- package/dist/modes/interactive/components/settings-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.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +89 -10
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts +3 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +9 -3
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts +119 -0
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -0
- package/dist/modes/interactive/components/workflow-view.js +638 -0
- package/dist/modes/interactive/components/workflow-view.js.map +1 -0
- package/dist/modes/interactive/interactive-commands.d.ts +22 -0
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +56 -0
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +51 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +218 -37
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.d.ts +2 -4
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +10 -1
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +5 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +3 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +4 -2
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/plugins/ecosystem/bootstrap-factory-manifest.d.ts.map +1 -1
- package/dist/plugins/ecosystem/bootstrap-factory-manifest.js +7 -0
- package/dist/plugins/ecosystem/bootstrap-factory-manifest.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +1 -1
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/install-store-paths.d.ts +15 -0
- package/dist/plugins/ecosystem/install-store-paths.d.ts.map +1 -0
- package/dist/plugins/ecosystem/install-store-paths.js +58 -0
- package/dist/plugins/ecosystem/install-store-paths.js.map +1 -0
- package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.js +3 -8
- package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +9 -1
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.js +3 -8
- package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
- package/dist/profile/plugin-profiles.d.ts +2 -0
- package/dist/profile/plugin-profiles.d.ts.map +1 -1
- package/dist/profile/plugin-profiles.js +4 -0
- package/dist/profile/plugin-profiles.js.map +1 -1
- package/dist/profiles/builtin-suites.d.ts +19 -2
- package/dist/profiles/builtin-suites.d.ts.map +1 -1
- package/dist/profiles/builtin-suites.js +20 -2
- package/dist/profiles/builtin-suites.js.map +1 -1
- package/dist/profiles/suite-loader.d.ts.map +1 -1
- package/dist/profiles/suite-loader.js +4 -1
- package/dist/profiles/suite-loader.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +10 -10
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +3 -30
- package/dist/utils/shell.js.map +1 -1
- package/docs/keybindings.md +8 -8
- package/docs/models.md +1 -1
- package/docs/rpc.md +3 -1
- package/docs/settings.md +2 -1
- package/package.json +4 -4
- package/dist/bundle/chunks/anthropic-messages-EVFQ6MLR.js +0 -6
- package/dist/bundle/chunks/chunk-F6SBZUJG.js +0 -141
- package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
- package/dist/bundle/chunks/google-generative-ai-ISTTUZMW.js +0 -2
- package/dist/bundle/chunks/google-vertex-NS7ZF7DK.js +0 -2
- package/dist/bundle/chunks/mistral-conversations-GINO6Z4I.js +0 -5
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import type { ThinkingLevel } from "@agent-forge/agent-core";
|
|
17
17
|
import type { Api, Model } from "@agent-forge/ai/compat";
|
|
18
18
|
import type { Component, EditorComponent, TUI } from "@agent-forge/tui";
|
|
19
|
+
import type { ForkableUserMessage } from "../../core/agent-session-projection.ts";
|
|
19
20
|
import type { CodingAgentFacadeV1, CodingAgentRuntimeFacadeV1 } from "../../core/facade/index.ts";
|
|
20
21
|
import type { SettingsManager } from "../../core/settings-manager.ts";
|
|
21
22
|
import type { FooterComponent } from "./components/footer.ts";
|
|
@@ -52,10 +53,7 @@ export interface SelectorsHost {
|
|
|
52
53
|
/** Available thinking levels of the current session. */
|
|
53
54
|
getAvailableThinkingLevels(): ThinkingLevel[];
|
|
54
55
|
/** Fork candidates of the current session. */
|
|
55
|
-
getUserMessagesForForking():
|
|
56
|
-
entryId: string;
|
|
57
|
-
text: string;
|
|
58
|
-
}>;
|
|
56
|
+
getUserMessagesForForking(): ForkableUserMessage[];
|
|
59
57
|
/** Selector surface; the implementation stays in the mode's selector area. */
|
|
60
58
|
showSelector(create: (done: () => void) => SelectorMount): void;
|
|
61
59
|
showStatus(message: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-selectors.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Selectors for interactive mode (S5 slice 5): the suite, thinking, model,\n * scoped-models, user-message fork, and clone selectors.\n *\n * InteractiveMode implements SelectorsHost and keeps same-name delegate\n * methods so prototype-level tests and the command dispatch table keep\n * working; the functions below receive the mode through SelectorsHost and\n * mount every overlay through the host's selector surface (host.showSelector),\n * mirroring the AuthUiHost pattern in ./interactive-auth.ts. Model snapshot,\n * catalog-refresh, and facade access go through narrow host accessors (D-048:\n * facade projections) so this module never reads session internals directly.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, Model } from \"@agent-forge/ai/compat\";\nimport type { Component, EditorComponent, TUI } from \"@agent-forge/tui\";\nimport { Container, SelectList, Spacer, Text } from \"@agent-forge/tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"../../core/defaults.ts\";\nimport type { CodingAgentFacadeV1, CodingAgentRuntimeFacadeV1 } from \"../../core/facade/index.ts\";\nimport { findExactModelReferenceMatch, resolveModelScopeFromModels } from \"../../core/model-resolver.ts\";\nimport type { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { listSuiteIds } from \"../../profiles/suite-loader.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport { ModelSelectorComponent } from \"./components/model-selector.ts\";\nimport { ScopedModelsSelectorComponent } from \"./components/scoped-models-selector.ts\";\nimport { ThinkingSelectorComponent } from \"./components/thinking-selector.ts\";\nimport { UserMessageSelectorComponent } from \"./components/user-message-selector.ts\";\nimport { type ModelCatalogRuntime, refreshModelCatalogs } from \"./model-catalog-refresh.ts\";\nimport { getSelectListTheme, theme } from \"./theme/theme.ts\";\n\n/** Mount description accepted by the host's selector surface. */\ninterface SelectorMount {\n\tcomponent: Component;\n\tfocus: Component;\n\tdispose?: () => void;\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the selector entry\n * points (which stay on the mode for dispatch and prototype-level tests) plus\n * narrow accessors for the session runtime, the stable facades, and settings.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface SelectorsHost {\n\tui: TUI;\n\teditor: EditorComponent;\n\tfooter: FooterComponent;\n\tsettingsManager: SettingsManager;\n\t/** Stable facade (阶段 1 slice 1). */\n\tfacade: CodingAgentFacadeV1;\n\t/** Stable runtime facade (阶段 4 slice 3); manager-level session reads stay here (D-041). */\n\truntimeFacade: CodingAgentRuntimeFacadeV1;\n\n\t/** Narrow catalog-refresh projection through the stable facade (D-048). */\n\tgetModelCatalog(): ModelCatalogRuntime;\n\t/** Available model snapshot through the stable facade (D-048). */\n\tgetAvailableModels(): readonly Model<Api>[];\n\t/** Current session's suite id; the read stays on the mode (session entries). */\n\tgetCurrentSessionSuiteId(): string | undefined;\n\t/** Available thinking levels of the current session. */\n\tgetAvailableThinkingLevels(): ThinkingLevel[];\n\t/** Fork candidates of the current session. */\n\tgetUserMessagesForForking(): Array<{ entryId: string; text: string }>;\n\n\t/** Selector surface; the implementation stays in the mode's selector area. */\n\tshowSelector(create: (done: () => void) => SelectorMount): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tupdateEditorBorderColor(): void;\n\tupdateAvailableProviderCount(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<Api>): Promise<void>;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport function handleSuiteCommand(host: SelectorsHost, suiteId?: string): void {\n\tconst availableSuites = listSuiteIds(getAgentDir());\n\tif (!suiteId) {\n\t\tshowSuiteSelector(host, availableSuites);\n\t\treturn;\n\t}\n\n\tif (!availableSuites.includes(suiteId)) {\n\t\thost.showError(`Unknown suite \"${suiteId}\". Available suites: ${availableSuites.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\thost.settingsManager.setProjectSuite(suiteId);\n\t// /new re-resolves the suite from current settings (the runtime factory\n\t// rebuilds services per session), so the pick applies to the very next\n\t// new session — unless the process was started with an explicit suite\n\t// source, which keeps winning for the whole process (设计 §9 precedence).\n\thost.showStatus(\n\t\t`Suite set to ${suiteId} — applies to the next new session (/new); an explicit --suite or AGENT_FORGE_SUITE startup keeps overriding it`,\n\t);\n}\n\nexport function showSuiteSelector(host: SelectorsHost, availableSuites: readonly string[]): void {\n\topenSuiteListSelector(host, {\n\t\tavailableSuites,\n\t\tonSelect: (suiteId) => handleSuiteCommand(host, suiteId),\n\t\tonCancel: () => host.ui.requestRender(),\n\t});\n}\n\n/**\n * Shared suite list overlay (设计 §9). Marks and preselects the current\n * session's suite; the caller decides what a selection means.\n */\nexport function openSuiteListSelector(\n\thost: SelectorsHost,\n\tcallbacks: {\n\t\tavailableSuites: readonly string[];\n\t\t/** explanatory line under the title; defaults to the /suite wording */\n\t\tnote?: string;\n\t\tonSelect: (suiteId: string) => void;\n\t\tonCancel: () => void;\n\t},\n): void {\n\thost.showSelector((done) => {\n\t\tconst currentSuiteId = host.getCurrentSessionSuiteId();\n\t\tconst container = new Container();\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.bold(\"Select Suite\"), 1, 0));\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\tcallbacks.note ??\n\t\t\t\t\t\t\"The next new session (/new) uses the selected suite; this session keeps its current suite\",\n\t\t\t\t),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new DynamicBorder());\n\t\tconst list = new SelectList(\n\t\t\tcallbacks.availableSuites.map((id) => ({\n\t\t\t\tvalue: id,\n\t\t\t\tlabel: id,\n\t\t\t\t...(id === currentSuiteId ? { description: \"current session\" } : {}),\n\t\t\t})),\n\t\t\t10,\n\t\t\tgetSelectListTheme(),\n\t\t);\n\t\tif (currentSuiteId !== undefined) {\n\t\t\tconst currentIndex = callbacks.availableSuites.indexOf(currentSuiteId);\n\t\t\tif (currentIndex >= 0) list.setSelectedIndex(currentIndex);\n\t\t}\n\t\tlist.onSelect = (item) => {\n\t\t\tdone();\n\t\t\tcallbacks.onSelect(item.value);\n\t\t};\n\t\tlist.onCancel = () => {\n\t\t\tdone();\n\t\t\tcallbacks.onCancel();\n\t\t};\n\t\tcontainer.addChild(list);\n\t\tcontainer.addChild(new DynamicBorder());\n\t\treturn { component: container, focus: list };\n\t});\n}\n\nexport function handleThinkingCommand(host: SelectorsHost, searchTerm?: string): void {\n\tconst availableLevels = host.getAvailableThinkingLevels();\n\tif (!searchTerm) {\n\t\tshowThinkingSelector(host);\n\t\treturn;\n\t}\n\n\tconst normalized = searchTerm.trim().toLowerCase();\n\tconst level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);\n\tif (!level) {\n\t\thost.showError(`Unknown thinking level \"${searchTerm}\". Available levels: ${availableLevels.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\tselectThinkingLevel(host, level, false);\n}\n\nexport function selectThinkingLevel(host: SelectorsHost, level: ThinkingLevel, persist: boolean): void {\n\ttry {\n\t\thost.facade.setThinkingLevel(level, { persist });\n\t\thost.footer.invalidate();\n\t\thost.updateEditorBorderColor();\n\t\thost.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);\n\t} catch (error) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n\nexport function showThinkingSelector(host: SelectorsHost): void {\n\thost.showSelector((done) => {\n\t\tconst selectLevel = (level: ThinkingLevel, persist: boolean) => {\n\t\t\tselectThinkingLevel(host, level, persist);\n\t\t\tdone();\n\t\t};\n\t\tconst selector = new ThinkingSelectorComponent(\n\t\t\thost.facade.getState().thinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\thost.getAvailableThinkingLevels(),\n\t\t\t(level) => selectLevel(level, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\t(level) => selectLevel(level, true),\n\t\t\thost.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,\n\t\t);\n\t\treturn { component: selector, focus: selector };\n\t});\n}\n\nexport async function handleModelCommand(host: SelectorsHost, searchTerm?: string): Promise<void> {\n\tif (!searchTerm) {\n\t\tshowModelSelector(host);\n\t\treturn;\n\t}\n\n\tconst model = await findExactModelMatch(host, searchTerm);\n\tif (model) {\n\t\ttry {\n\t\t\tawait host.facade.setModel(model, { persist: false });\n\t\t\thost.footer.invalidate();\n\t\t\thost.updateEditorBorderColor();\n\t\t\thost.showStatus(`Model: ${model.id}`);\n\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t} catch (error) {\n\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\treturn;\n\t}\n\n\tshowModelSelector(host, searchTerm);\n}\n\nexport async function findExactModelMatch(host: SelectorsHost, searchTerm: string): Promise<Model<Api> | undefined> {\n\tconst cachedModels =\n\t\thost.facade.getScopedModels().length > 0\n\t\t\t? host.facade.getScopedModels().map((scoped) => scoped.model)\n\t\t\t: [...host.getAvailableModels()];\n\tconst cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);\n\tif (cachedMatch || host.facade.getScopedModels().length > 0) return cachedMatch;\n\n\thost.showStatus(\"Refreshing model catalogs…\");\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, 15_000);\n\ttry {\n\t\tconst result = await refreshModelCatalogs(host.getModelCatalog(), controller.signal);\n\t\tif (result.aborted && timedOut) {\n\t\t\thost.showWarning(\"Model refresh timed out; searching cached models.\");\n\t\t} else if (result.errors.size > 0) {\n\t\t\thost.showWarning(`Could not refresh ${[...result.errors.keys()].join(\", \")}; searching cached models.`);\n\t\t}\n\t} catch (error) {\n\t\thost.showWarning(\n\t\t\ttimedOut\n\t\t\t\t? \"Model refresh timed out; searching cached models.\"\n\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\treturn findExactModelReferenceMatch(searchTerm, [...host.getAvailableModels()]);\n}\n\nexport function showModelSelector(host: SelectorsHost, initialSearchInput?: string): void {\n\thost.showSelector((done) => {\n\t\tconst selectModel = async (model: Model<Api>, persist: boolean) => {\n\t\t\ttry {\n\t\t\t\tawait host.facade.setModel(model, { persist });\n\t\t\t\thost.updateAvailableProviderCount();\n\t\t\t\thost.footer.invalidate();\n\t\t\t\thost.updateEditorBorderColor();\n\t\t\t\tdone();\n\t\t\t\thost.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);\n\t\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t\t} catch (error) {\n\t\t\t\tdone();\n\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t};\n\t\tconst defaultProvider = host.settingsManager.getDefaultProvider();\n\t\tconst defaultModel = host.settingsManager.getDefaultModel();\n\t\tconst selector = new ModelSelectorComponent(\n\t\t\thost.ui,\n\t\t\thost.facade.getModel(),\n\t\t\t{\n\t\t\t\t// D-048: the selector component consumes a narrow read projection;\n\t\t\t\t// the full ModelRuntime never crosses the host boundary.\n\t\t\t\tgetAvailableSnapshot: () => host.getAvailableModels(),\n\t\t\t\tgetError: () => host.facade.getModelsError(),\n\t\t\t\trefresh: (options) => host.getModelCatalog().refresh(options),\n\t\t\t},\n\t\t\thost.facade.getScopedModels(),\n\t\t\t(model) => selectModel(model, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSearchInput,\n\t\t\t(model) => selectModel(model, true),\n\t\t\tdefaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined,\n\t\t);\n\t\treturn { component: selector, focus: selector, dispose: () => selector.dispose() };\n\t});\n}\n\nexport function showModelsSelector(host: SelectorsHost): void {\n\tlet availableModels = [...host.getAvailableModels()];\n\tlet availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\tconst configuredPatterns = host.settingsManager.getEnabledModels();\n\tconst sessionScopedModels = host.facade.getScopedModels();\n\tconst configuredEnabledIds = (models: readonly Model<Api>[]): string[] | null => {\n\t\tif (!configuredPatterns?.length) return null;\n\t\tconst resolved = resolveModelScopeFromModels(configuredPatterns, models);\n\t\tconst ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);\n\t\tfor (const diagnostic of resolved.diagnostics) {\n\t\t\tif (diagnostic.code === \"no-match\" && !ids.includes(diagnostic.pattern)) ids.push(diagnostic.pattern);\n\t\t}\n\t\treturn ids;\n\t};\n\n\tlet currentEnabledIds =\n\t\tsessionScopedModels.length > 0\n\t\t\t? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)\n\t\t\t: configuredEnabledIds(availableModels);\n\tlet selectionChanged = false;\n\n\tconst updateSessionModels = (enabledIds: string[] | null): void => {\n\t\tcurrentEnabledIds = enabledIds === null ? null : [...enabledIds];\n\t\tconst hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;\n\t\tconst allAvailableModelsEnabled =\n\t\t\tenabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));\n\t\tif (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {\n\t\t\tconst newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;\n\t\t\thost.facade.setScopedModels(\n\t\t\t\tnewScopedModels.map((scoped) => ({\n\t\t\t\t\tmodel: scoped.model,\n\t\t\t\t\tthinkingLevel: scoped.thinkingLevel,\n\t\t\t\t})),\n\t\t\t);\n\t\t} else {\n\t\t\thost.facade.setScopedModels([]);\n\t\t}\n\t\thost.updateAvailableProviderCount();\n\t\thost.ui.requestRender();\n\t};\n\n\thost.showSelector((done) => {\n\t\tlet disposed = false;\n\t\tlet timedOut = false;\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, 15_000);\n\t\tconst selector = new ScopedModelsSelectorComponent(\n\t\t\t{\n\t\t\t\tallModels: availableModels,\n\t\t\t\tenabledModelIds: currentEnabledIds,\n\t\t\t\trefreshStatus: \"Refreshing model catalogs…\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tonChange: (enabledIds) => {\n\t\t\t\t\tselectionChanged = true;\n\t\t\t\t\tupdateSessionModels(enabledIds);\n\t\t\t\t},\n\t\t\t\tonPersist: (enabledIds) => {\n\t\t\t\t\tconst allEnabled =\n\t\t\t\t\t\tenabledIds !== null &&\n\t\t\t\t\t\tenabledIds.length === availableModels.length &&\n\t\t\t\t\t\tenabledIds.every((id) => availableModelIds.has(id));\n\t\t\t\t\tconst newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;\n\t\t\t\t\thost.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);\n\t\t\t\t\thost.showStatus(\"Model selection saved to settings\");\n\t\t\t\t},\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tdone();\n\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tvoid refreshModelCatalogs(host.getModelCatalog(), controller.signal)\n\t\t\t.then((result) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tavailableModels = [...host.getAvailableModels()];\n\t\t\t\tavailableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\t\t\t\tif (!selectionChanged && sessionScopedModels.length === 0) {\n\t\t\t\t\tcurrentEnabledIds = configuredEnabledIds(availableModels);\n\t\t\t\t\tselector.updateModels(availableModels, currentEnabledIds);\n\t\t\t\t} else {\n\t\t\t\t\tselector.updateModels(availableModels);\n\t\t\t\t}\n\t\t\t\tif (currentEnabledIds !== null) updateSessionModels(currentEnabledIds);\n\t\t\t\tif (result.aborted && timedOut) {\n\t\t\t\t\tselector.setRefreshStatus(\"Model refresh timed out; showing cached models.\", \"warning\");\n\t\t\t\t} else if (result.errors.size > 0) {\n\t\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\t\t`Could not refresh ${[...result.errors.keys()].join(\", \")}; showing cached models.`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tselector.setRefreshStatus(\"Model catalogs refreshed.\", \"success\");\n\t\t\t\t}\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\ttimedOut\n\t\t\t\t\t\t? \"Model refresh timed out; showing cached models.\"\n\t\t\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.finally(() => clearTimeout(timeout));\n\t\treturn {\n\t\t\tcomponent: selector,\n\t\t\tfocus: selector,\n\t\t\tdispose: () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tcontroller.abort();\n\t\t\t},\n\t\t};\n\t});\n}\n\nexport function showUserMessageSelector(host: SelectorsHost): void {\n\tconst userMessages = host.getUserMessagesForForking();\n\n\tif (userMessages.length === 0) {\n\t\thost.showStatus(\"No messages to fork from\");\n\t\treturn;\n\t}\n\n\tconst initialSelectedId = userMessages[userMessages.length - 1]?.entryId;\n\n\thost.showSelector((done) => {\n\t\tconst selector = new UserMessageSelectorComponent(\n\t\t\tuserMessages.map((m) => ({ id: m.entryId, text: m.text })),\n\t\t\tasync (entryId) => {\n\t\t\t\tdone();\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await host.runtimeFacade.fork(entryId);\n\t\t\t\t\tif (result.cancelled) {\n\t\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\thost.editor.setText(result.selectedText ?? \"\");\n\t\t\t\t\thost.showStatus(\"Forked to new session\");\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSelectedId,\n\t\t);\n\t\treturn { component: selector, focus: selector.getMessageList() };\n\t});\n}\n\nexport async function handleCloneCommand(host: SelectorsHost): Promise<void> {\n\tconst leafId = host.facade.getLeafId();\n\tif (!leafId) {\n\t\thost.showStatus(\"Nothing to clone yet\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst result = await host.runtimeFacade.fork(leafId, { position: \"at\" });\n\t\tif (result.cancelled) {\n\t\t\thost.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\thost.editor.setText(\"\");\n\t\thost.showStatus(\"Cloned to new session\");\n\t} catch (error: unknown) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-selectors.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Selectors for interactive mode (S5 slice 5): the suite, thinking, model,\n * scoped-models, user-message fork, and clone selectors.\n *\n * InteractiveMode implements SelectorsHost and keeps same-name delegate\n * methods so prototype-level tests and the command dispatch table keep\n * working; the functions below receive the mode through SelectorsHost and\n * mount every overlay through the host's selector surface (host.showSelector),\n * mirroring the AuthUiHost pattern in ./interactive-auth.ts. Model snapshot,\n * catalog-refresh, and facade access go through narrow host accessors (D-048:\n * facade projections) so this module never reads session internals directly.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, Model } from \"@agent-forge/ai/compat\";\nimport type { Component, EditorComponent, TUI } from \"@agent-forge/tui\";\nimport { Container, SelectList, Spacer, Text } from \"@agent-forge/tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ForkableUserMessage } from \"../../core/agent-session-projection.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"../../core/defaults.ts\";\nimport type { CodingAgentFacadeV1, CodingAgentRuntimeFacadeV1 } from \"../../core/facade/index.ts\";\nimport { findExactModelReferenceMatch, resolveModelScopeFromModels } from \"../../core/model-resolver.ts\";\nimport type { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { listSuiteIds } from \"../../profiles/suite-loader.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport { ModelSelectorComponent } from \"./components/model-selector.ts\";\nimport { ScopedModelsSelectorComponent } from \"./components/scoped-models-selector.ts\";\nimport { ThinkingSelectorComponent } from \"./components/thinking-selector.ts\";\nimport { UserMessageSelectorComponent } from \"./components/user-message-selector.ts\";\nimport { type ModelCatalogRuntime, refreshModelCatalogs } from \"./model-catalog-refresh.ts\";\nimport { getSelectListTheme, theme } from \"./theme/theme.ts\";\n\n/** Mount description accepted by the host's selector surface. */\ninterface SelectorMount {\n\tcomponent: Component;\n\tfocus: Component;\n\tdispose?: () => void;\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the selector entry\n * points (which stay on the mode for dispatch and prototype-level tests) plus\n * narrow accessors for the session runtime, the stable facades, and settings.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface SelectorsHost {\n\tui: TUI;\n\teditor: EditorComponent;\n\tfooter: FooterComponent;\n\tsettingsManager: SettingsManager;\n\t/** Stable facade (阶段 1 slice 1). */\n\tfacade: CodingAgentFacadeV1;\n\t/** Stable runtime facade (阶段 4 slice 3); manager-level session reads stay here (D-041). */\n\truntimeFacade: CodingAgentRuntimeFacadeV1;\n\n\t/** Narrow catalog-refresh projection through the stable facade (D-048). */\n\tgetModelCatalog(): ModelCatalogRuntime;\n\t/** Available model snapshot through the stable facade (D-048). */\n\tgetAvailableModels(): readonly Model<Api>[];\n\t/** Current session's suite id; the read stays on the mode (session entries). */\n\tgetCurrentSessionSuiteId(): string | undefined;\n\t/** Available thinking levels of the current session. */\n\tgetAvailableThinkingLevels(): ThinkingLevel[];\n\t/** Fork candidates of the current session. */\n\tgetUserMessagesForForking(): ForkableUserMessage[];\n\n\t/** Selector surface; the implementation stays in the mode's selector area. */\n\tshowSelector(create: (done: () => void) => SelectorMount): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tupdateEditorBorderColor(): void;\n\tupdateAvailableProviderCount(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<Api>): Promise<void>;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport function handleSuiteCommand(host: SelectorsHost, suiteId?: string): void {\n\tconst availableSuites = listSuiteIds(getAgentDir());\n\tif (!suiteId) {\n\t\tshowSuiteSelector(host, availableSuites);\n\t\treturn;\n\t}\n\n\tif (!availableSuites.includes(suiteId)) {\n\t\thost.showError(`Unknown suite \"${suiteId}\". Available suites: ${availableSuites.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\thost.settingsManager.setProjectSuite(suiteId);\n\t// /new re-resolves the suite from current settings (the runtime factory\n\t// rebuilds services per session), so the pick applies to the very next\n\t// new session — unless the process was started with an explicit suite\n\t// source, which keeps winning for the whole process (设计 §9 precedence).\n\thost.showStatus(\n\t\t`Suite set to ${suiteId} — applies to the next new session (/new); an explicit --suite or AGENT_FORGE_SUITE startup keeps overriding it`,\n\t);\n}\n\nexport function showSuiteSelector(host: SelectorsHost, availableSuites: readonly string[]): void {\n\topenSuiteListSelector(host, {\n\t\tavailableSuites,\n\t\tonSelect: (suiteId) => handleSuiteCommand(host, suiteId),\n\t\tonCancel: () => host.ui.requestRender(),\n\t});\n}\n\n/**\n * Shared suite list overlay (设计 §9). Marks and preselects the current\n * session's suite; the caller decides what a selection means.\n */\nexport function openSuiteListSelector(\n\thost: SelectorsHost,\n\tcallbacks: {\n\t\tavailableSuites: readonly string[];\n\t\t/** explanatory line under the title; defaults to the /suite wording */\n\t\tnote?: string;\n\t\tonSelect: (suiteId: string) => void;\n\t\tonCancel: () => void;\n\t},\n): void {\n\thost.showSelector((done) => {\n\t\tconst currentSuiteId = host.getCurrentSessionSuiteId();\n\t\tconst container = new Container();\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.bold(\"Select Suite\"), 1, 0));\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\tcallbacks.note ??\n\t\t\t\t\t\t\"The next new session (/new) uses the selected suite; this session keeps its current suite\",\n\t\t\t\t),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new DynamicBorder());\n\t\tconst list = new SelectList(\n\t\t\tcallbacks.availableSuites.map((id) => ({\n\t\t\t\tvalue: id,\n\t\t\t\tlabel: id,\n\t\t\t\t...(id === currentSuiteId ? { description: \"current session\" } : {}),\n\t\t\t})),\n\t\t\t10,\n\t\t\tgetSelectListTheme(),\n\t\t);\n\t\tif (currentSuiteId !== undefined) {\n\t\t\tconst currentIndex = callbacks.availableSuites.indexOf(currentSuiteId);\n\t\t\tif (currentIndex >= 0) list.setSelectedIndex(currentIndex);\n\t\t}\n\t\tlist.onSelect = (item) => {\n\t\t\tdone();\n\t\t\tcallbacks.onSelect(item.value);\n\t\t};\n\t\tlist.onCancel = () => {\n\t\t\tdone();\n\t\t\tcallbacks.onCancel();\n\t\t};\n\t\tcontainer.addChild(list);\n\t\tcontainer.addChild(new DynamicBorder());\n\t\treturn { component: container, focus: list };\n\t});\n}\n\nexport function handleThinkingCommand(host: SelectorsHost, searchTerm?: string): void {\n\tconst availableLevels = host.getAvailableThinkingLevels();\n\tif (!searchTerm) {\n\t\tshowThinkingSelector(host);\n\t\treturn;\n\t}\n\n\tconst normalized = searchTerm.trim().toLowerCase();\n\tconst level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);\n\tif (!level) {\n\t\thost.showError(`Unknown thinking level \"${searchTerm}\". Available levels: ${availableLevels.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\tselectThinkingLevel(host, level, false);\n}\n\nexport function selectThinkingLevel(host: SelectorsHost, level: ThinkingLevel, persist: boolean): void {\n\ttry {\n\t\thost.facade.setThinkingLevel(level, { persist });\n\t\thost.footer.invalidate();\n\t\thost.updateEditorBorderColor();\n\t\thost.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);\n\t} catch (error) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n\nexport function showThinkingSelector(host: SelectorsHost): void {\n\thost.showSelector((done) => {\n\t\tconst selectLevel = (level: ThinkingLevel, persist: boolean) => {\n\t\t\tselectThinkingLevel(host, level, persist);\n\t\t\tdone();\n\t\t};\n\t\tconst selector = new ThinkingSelectorComponent(\n\t\t\thost.facade.getState().thinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\thost.getAvailableThinkingLevels(),\n\t\t\t(level) => selectLevel(level, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\t(level) => selectLevel(level, true),\n\t\t\thost.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,\n\t\t);\n\t\treturn { component: selector, focus: selector };\n\t});\n}\n\nexport async function handleModelCommand(host: SelectorsHost, searchTerm?: string): Promise<void> {\n\tif (!searchTerm) {\n\t\tshowModelSelector(host);\n\t\treturn;\n\t}\n\n\tconst model = await findExactModelMatch(host, searchTerm);\n\tif (model) {\n\t\ttry {\n\t\t\tawait host.facade.setModel(model, { persist: false });\n\t\t\thost.footer.invalidate();\n\t\t\thost.updateEditorBorderColor();\n\t\t\thost.showStatus(`Model: ${model.id}`);\n\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t} catch (error) {\n\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\treturn;\n\t}\n\n\tshowModelSelector(host, searchTerm);\n}\n\nexport async function findExactModelMatch(host: SelectorsHost, searchTerm: string): Promise<Model<Api> | undefined> {\n\tconst cachedModels =\n\t\thost.facade.getScopedModels().length > 0\n\t\t\t? host.facade.getScopedModels().map((scoped) => scoped.model)\n\t\t\t: [...host.getAvailableModels()];\n\tconst cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);\n\tif (cachedMatch || host.facade.getScopedModels().length > 0) return cachedMatch;\n\n\thost.showStatus(\"Refreshing model catalogs…\");\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, 15_000);\n\ttry {\n\t\tconst result = await refreshModelCatalogs(host.getModelCatalog(), controller.signal);\n\t\tif (result.aborted && timedOut) {\n\t\t\thost.showWarning(\"Model refresh timed out; searching cached models.\");\n\t\t} else if (result.errors.size > 0) {\n\t\t\thost.showWarning(`Could not refresh ${[...result.errors.keys()].join(\", \")}; searching cached models.`);\n\t\t}\n\t} catch (error) {\n\t\thost.showWarning(\n\t\t\ttimedOut\n\t\t\t\t? \"Model refresh timed out; searching cached models.\"\n\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\treturn findExactModelReferenceMatch(searchTerm, [...host.getAvailableModels()]);\n}\n\nexport function showModelSelector(host: SelectorsHost, initialSearchInput?: string): void {\n\thost.showSelector((done) => {\n\t\tconst selectModel = async (model: Model<Api>, persist: boolean) => {\n\t\t\ttry {\n\t\t\t\tawait host.facade.setModel(model, { persist });\n\t\t\t\thost.updateAvailableProviderCount();\n\t\t\t\thost.footer.invalidate();\n\t\t\t\thost.updateEditorBorderColor();\n\t\t\t\tdone();\n\t\t\t\thost.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);\n\t\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t\t} catch (error) {\n\t\t\t\tdone();\n\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t};\n\t\tconst defaultProvider = host.settingsManager.getDefaultProvider();\n\t\tconst defaultModel = host.settingsManager.getDefaultModel();\n\t\tconst selector = new ModelSelectorComponent(\n\t\t\thost.ui,\n\t\t\thost.facade.getModel(),\n\t\t\t{\n\t\t\t\t// D-048: the selector component consumes a narrow read projection;\n\t\t\t\t// the full ModelRuntime never crosses the host boundary.\n\t\t\t\tgetAvailableSnapshot: () => host.getAvailableModels(),\n\t\t\t\tgetError: () => host.facade.getModelsError(),\n\t\t\t\trefresh: (options) => host.getModelCatalog().refresh(options),\n\t\t\t},\n\t\t\thost.facade.getScopedModels(),\n\t\t\t(model) => selectModel(model, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSearchInput,\n\t\t\t(model) => selectModel(model, true),\n\t\t\tdefaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined,\n\t\t);\n\t\treturn { component: selector, focus: selector, dispose: () => selector.dispose() };\n\t});\n}\n\nexport function showModelsSelector(host: SelectorsHost): void {\n\tlet availableModels = [...host.getAvailableModels()];\n\tlet availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\tconst configuredPatterns = host.settingsManager.getEnabledModels();\n\tconst sessionScopedModels = host.facade.getScopedModels();\n\tconst configuredEnabledIds = (models: readonly Model<Api>[]): string[] | null => {\n\t\tif (!configuredPatterns?.length) return null;\n\t\tconst resolved = resolveModelScopeFromModels(configuredPatterns, models);\n\t\tconst ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);\n\t\tfor (const diagnostic of resolved.diagnostics) {\n\t\t\tif (diagnostic.code === \"no-match\" && !ids.includes(diagnostic.pattern)) ids.push(diagnostic.pattern);\n\t\t}\n\t\treturn ids;\n\t};\n\n\tlet currentEnabledIds =\n\t\tsessionScopedModels.length > 0\n\t\t\t? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)\n\t\t\t: configuredEnabledIds(availableModels);\n\tlet selectionChanged = false;\n\n\tconst updateSessionModels = (enabledIds: string[] | null): void => {\n\t\tcurrentEnabledIds = enabledIds === null ? null : [...enabledIds];\n\t\tconst hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;\n\t\tconst allAvailableModelsEnabled =\n\t\t\tenabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));\n\t\tif (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {\n\t\t\tconst newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;\n\t\t\thost.facade.setScopedModels(\n\t\t\t\tnewScopedModels.map((scoped) => ({\n\t\t\t\t\tmodel: scoped.model,\n\t\t\t\t\tthinkingLevel: scoped.thinkingLevel,\n\t\t\t\t})),\n\t\t\t);\n\t\t} else {\n\t\t\thost.facade.setScopedModels([]);\n\t\t}\n\t\thost.updateAvailableProviderCount();\n\t\thost.ui.requestRender();\n\t};\n\n\thost.showSelector((done) => {\n\t\tlet disposed = false;\n\t\tlet timedOut = false;\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, 15_000);\n\t\tconst selector = new ScopedModelsSelectorComponent(\n\t\t\t{\n\t\t\t\tallModels: availableModels,\n\t\t\t\tenabledModelIds: currentEnabledIds,\n\t\t\t\trefreshStatus: \"Refreshing model catalogs…\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tonChange: (enabledIds) => {\n\t\t\t\t\tselectionChanged = true;\n\t\t\t\t\tupdateSessionModels(enabledIds);\n\t\t\t\t},\n\t\t\t\tonPersist: (enabledIds) => {\n\t\t\t\t\tconst allEnabled =\n\t\t\t\t\t\tenabledIds !== null &&\n\t\t\t\t\t\tenabledIds.length === availableModels.length &&\n\t\t\t\t\t\tenabledIds.every((id) => availableModelIds.has(id));\n\t\t\t\t\tconst newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;\n\t\t\t\t\thost.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);\n\t\t\t\t\thost.showStatus(\"Model selection saved to settings\");\n\t\t\t\t},\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tdone();\n\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tvoid refreshModelCatalogs(host.getModelCatalog(), controller.signal)\n\t\t\t.then((result) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tavailableModels = [...host.getAvailableModels()];\n\t\t\t\tavailableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\t\t\t\tif (!selectionChanged && sessionScopedModels.length === 0) {\n\t\t\t\t\tcurrentEnabledIds = configuredEnabledIds(availableModels);\n\t\t\t\t\tselector.updateModels(availableModels, currentEnabledIds);\n\t\t\t\t} else {\n\t\t\t\t\tselector.updateModels(availableModels);\n\t\t\t\t}\n\t\t\t\tif (currentEnabledIds !== null) updateSessionModels(currentEnabledIds);\n\t\t\t\tif (result.aborted && timedOut) {\n\t\t\t\t\tselector.setRefreshStatus(\"Model refresh timed out; showing cached models.\", \"warning\");\n\t\t\t\t} else if (result.errors.size > 0) {\n\t\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\t\t`Could not refresh ${[...result.errors.keys()].join(\", \")}; showing cached models.`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tselector.setRefreshStatus(\"Model catalogs refreshed.\", \"success\");\n\t\t\t\t}\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\ttimedOut\n\t\t\t\t\t\t? \"Model refresh timed out; showing cached models.\"\n\t\t\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.finally(() => clearTimeout(timeout));\n\t\treturn {\n\t\t\tcomponent: selector,\n\t\t\tfocus: selector,\n\t\t\tdispose: () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tcontroller.abort();\n\t\t\t},\n\t\t};\n\t});\n}\n\nexport function showUserMessageSelector(host: SelectorsHost): void {\n\tconst userMessages = host.getUserMessagesForForking();\n\n\tif (userMessages.length === 0) {\n\t\thost.showStatus(\"No messages to fork from\");\n\t\treturn;\n\t}\n\n\tconst initialSelectedId = userMessages[userMessages.length - 1]?.entryId;\n\n\thost.showSelector((done) => {\n\t\tconst selector = new UserMessageSelectorComponent(\n\t\t\tuserMessages.map((m) => ({\n\t\t\t\tid: m.entryId,\n\t\t\t\ttext: m.text,\n\t\t\t\t...(m.replySummary === undefined ? {} : { replySummary: m.replySummary }),\n\t\t\t})),\n\t\t\tasync (entryId) => {\n\t\t\t\tdone();\n\t\t\t\t// Restore the selected prompt into the editor even when the fork\n\t\t\t\t// fails, so the user never loses the text they chose (codex\n\t\t\t\t// backtrack precedent: restore_backtrack_prompt_after_revert_error).\n\t\t\t\tconst fallbackText = userMessages.find((m) => m.entryId === entryId)?.text ?? \"\";\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await host.runtimeFacade.fork(entryId);\n\t\t\t\t\tif (result.cancelled) {\n\t\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\thost.editor.setText(result.selectedText ?? \"\");\n\t\t\t\t\thost.showStatus(\"Forked to new session\");\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\thost.editor.setText(fallbackText);\n\t\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSelectedId,\n\t\t);\n\t\treturn { component: selector, focus: selector.getMessageList() };\n\t});\n}\n\nexport async function handleCloneCommand(host: SelectorsHost): Promise<void> {\n\tconst leafId = host.facade.getLeafId();\n\tif (!leafId) {\n\t\thost.showStatus(\"Nothing to clone yet\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst result = await host.runtimeFacade.fork(leafId, { position: \"at\" });\n\t\tif (result.cancelled) {\n\t\t\thost.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\thost.editor.setText(\"\");\n\t\thost.showStatus(\"Cloned to new session\");\n\t} catch (error: unknown) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n"]}
|
|
@@ -318,8 +318,16 @@ export function showUserMessageSelector(host) {
|
|
|
318
318
|
}
|
|
319
319
|
const initialSelectedId = userMessages[userMessages.length - 1]?.entryId;
|
|
320
320
|
host.showSelector((done) => {
|
|
321
|
-
const selector = new UserMessageSelectorComponent(userMessages.map((m) => ({
|
|
321
|
+
const selector = new UserMessageSelectorComponent(userMessages.map((m) => ({
|
|
322
|
+
id: m.entryId,
|
|
323
|
+
text: m.text,
|
|
324
|
+
...(m.replySummary === undefined ? {} : { replySummary: m.replySummary }),
|
|
325
|
+
})), async (entryId) => {
|
|
322
326
|
done();
|
|
327
|
+
// Restore the selected prompt into the editor even when the fork
|
|
328
|
+
// fails, so the user never loses the text they chose (codex
|
|
329
|
+
// backtrack precedent: restore_backtrack_prompt_after_revert_error).
|
|
330
|
+
const fallbackText = userMessages.find((m) => m.entryId === entryId)?.text ?? "";
|
|
323
331
|
try {
|
|
324
332
|
const result = await host.runtimeFacade.fork(entryId);
|
|
325
333
|
if (result.cancelled) {
|
|
@@ -330,6 +338,7 @@ export function showUserMessageSelector(host) {
|
|
|
330
338
|
host.showStatus("Forked to new session");
|
|
331
339
|
}
|
|
332
340
|
catch (error) {
|
|
341
|
+
host.editor.setText(fallbackText);
|
|
333
342
|
host.showError(error instanceof Error ? error.message : String(error));
|
|
334
343
|
}
|
|
335
344
|
}, () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-selectors.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Selectors for interactive mode (S5 slice 5): the suite, thinking, model,\n * scoped-models, user-message fork, and clone selectors.\n *\n * InteractiveMode implements SelectorsHost and keeps same-name delegate\n * methods so prototype-level tests and the command dispatch table keep\n * working; the functions below receive the mode through SelectorsHost and\n * mount every overlay through the host's selector surface (host.showSelector),\n * mirroring the AuthUiHost pattern in ./interactive-auth.ts. Model snapshot,\n * catalog-refresh, and facade access go through narrow host accessors (D-048:\n * facade projections) so this module never reads session internals directly.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, Model } from \"@agent-forge/ai/compat\";\nimport type { Component, EditorComponent, TUI } from \"@agent-forge/tui\";\nimport { Container, SelectList, Spacer, Text } from \"@agent-forge/tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"../../core/defaults.ts\";\nimport type { CodingAgentFacadeV1, CodingAgentRuntimeFacadeV1 } from \"../../core/facade/index.ts\";\nimport { findExactModelReferenceMatch, resolveModelScopeFromModels } from \"../../core/model-resolver.ts\";\nimport type { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { listSuiteIds } from \"../../profiles/suite-loader.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport { ModelSelectorComponent } from \"./components/model-selector.ts\";\nimport { ScopedModelsSelectorComponent } from \"./components/scoped-models-selector.ts\";\nimport { ThinkingSelectorComponent } from \"./components/thinking-selector.ts\";\nimport { UserMessageSelectorComponent } from \"./components/user-message-selector.ts\";\nimport { type ModelCatalogRuntime, refreshModelCatalogs } from \"./model-catalog-refresh.ts\";\nimport { getSelectListTheme, theme } from \"./theme/theme.ts\";\n\n/** Mount description accepted by the host's selector surface. */\ninterface SelectorMount {\n\tcomponent: Component;\n\tfocus: Component;\n\tdispose?: () => void;\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the selector entry\n * points (which stay on the mode for dispatch and prototype-level tests) plus\n * narrow accessors for the session runtime, the stable facades, and settings.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface SelectorsHost {\n\tui: TUI;\n\teditor: EditorComponent;\n\tfooter: FooterComponent;\n\tsettingsManager: SettingsManager;\n\t/** Stable facade (阶段 1 slice 1). */\n\tfacade: CodingAgentFacadeV1;\n\t/** Stable runtime facade (阶段 4 slice 3); manager-level session reads stay here (D-041). */\n\truntimeFacade: CodingAgentRuntimeFacadeV1;\n\n\t/** Narrow catalog-refresh projection through the stable facade (D-048). */\n\tgetModelCatalog(): ModelCatalogRuntime;\n\t/** Available model snapshot through the stable facade (D-048). */\n\tgetAvailableModels(): readonly Model<Api>[];\n\t/** Current session's suite id; the read stays on the mode (session entries). */\n\tgetCurrentSessionSuiteId(): string | undefined;\n\t/** Available thinking levels of the current session. */\n\tgetAvailableThinkingLevels(): ThinkingLevel[];\n\t/** Fork candidates of the current session. */\n\tgetUserMessagesForForking(): Array<{ entryId: string; text: string }>;\n\n\t/** Selector surface; the implementation stays in the mode's selector area. */\n\tshowSelector(create: (done: () => void) => SelectorMount): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tupdateEditorBorderColor(): void;\n\tupdateAvailableProviderCount(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<Api>): Promise<void>;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport function handleSuiteCommand(host: SelectorsHost, suiteId?: string): void {\n\tconst availableSuites = listSuiteIds(getAgentDir());\n\tif (!suiteId) {\n\t\tshowSuiteSelector(host, availableSuites);\n\t\treturn;\n\t}\n\n\tif (!availableSuites.includes(suiteId)) {\n\t\thost.showError(`Unknown suite \"${suiteId}\". Available suites: ${availableSuites.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\thost.settingsManager.setProjectSuite(suiteId);\n\t// /new re-resolves the suite from current settings (the runtime factory\n\t// rebuilds services per session), so the pick applies to the very next\n\t// new session — unless the process was started with an explicit suite\n\t// source, which keeps winning for the whole process (设计 §9 precedence).\n\thost.showStatus(\n\t\t`Suite set to ${suiteId} — applies to the next new session (/new); an explicit --suite or AGENT_FORGE_SUITE startup keeps overriding it`,\n\t);\n}\n\nexport function showSuiteSelector(host: SelectorsHost, availableSuites: readonly string[]): void {\n\topenSuiteListSelector(host, {\n\t\tavailableSuites,\n\t\tonSelect: (suiteId) => handleSuiteCommand(host, suiteId),\n\t\tonCancel: () => host.ui.requestRender(),\n\t});\n}\n\n/**\n * Shared suite list overlay (设计 §9). Marks and preselects the current\n * session's suite; the caller decides what a selection means.\n */\nexport function openSuiteListSelector(\n\thost: SelectorsHost,\n\tcallbacks: {\n\t\tavailableSuites: readonly string[];\n\t\t/** explanatory line under the title; defaults to the /suite wording */\n\t\tnote?: string;\n\t\tonSelect: (suiteId: string) => void;\n\t\tonCancel: () => void;\n\t},\n): void {\n\thost.showSelector((done) => {\n\t\tconst currentSuiteId = host.getCurrentSessionSuiteId();\n\t\tconst container = new Container();\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.bold(\"Select Suite\"), 1, 0));\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\tcallbacks.note ??\n\t\t\t\t\t\t\"The next new session (/new) uses the selected suite; this session keeps its current suite\",\n\t\t\t\t),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new DynamicBorder());\n\t\tconst list = new SelectList(\n\t\t\tcallbacks.availableSuites.map((id) => ({\n\t\t\t\tvalue: id,\n\t\t\t\tlabel: id,\n\t\t\t\t...(id === currentSuiteId ? { description: \"current session\" } : {}),\n\t\t\t})),\n\t\t\t10,\n\t\t\tgetSelectListTheme(),\n\t\t);\n\t\tif (currentSuiteId !== undefined) {\n\t\t\tconst currentIndex = callbacks.availableSuites.indexOf(currentSuiteId);\n\t\t\tif (currentIndex >= 0) list.setSelectedIndex(currentIndex);\n\t\t}\n\t\tlist.onSelect = (item) => {\n\t\t\tdone();\n\t\t\tcallbacks.onSelect(item.value);\n\t\t};\n\t\tlist.onCancel = () => {\n\t\t\tdone();\n\t\t\tcallbacks.onCancel();\n\t\t};\n\t\tcontainer.addChild(list);\n\t\tcontainer.addChild(new DynamicBorder());\n\t\treturn { component: container, focus: list };\n\t});\n}\n\nexport function handleThinkingCommand(host: SelectorsHost, searchTerm?: string): void {\n\tconst availableLevels = host.getAvailableThinkingLevels();\n\tif (!searchTerm) {\n\t\tshowThinkingSelector(host);\n\t\treturn;\n\t}\n\n\tconst normalized = searchTerm.trim().toLowerCase();\n\tconst level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);\n\tif (!level) {\n\t\thost.showError(`Unknown thinking level \"${searchTerm}\". Available levels: ${availableLevels.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\tselectThinkingLevel(host, level, false);\n}\n\nexport function selectThinkingLevel(host: SelectorsHost, level: ThinkingLevel, persist: boolean): void {\n\ttry {\n\t\thost.facade.setThinkingLevel(level, { persist });\n\t\thost.footer.invalidate();\n\t\thost.updateEditorBorderColor();\n\t\thost.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);\n\t} catch (error) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n\nexport function showThinkingSelector(host: SelectorsHost): void {\n\thost.showSelector((done) => {\n\t\tconst selectLevel = (level: ThinkingLevel, persist: boolean) => {\n\t\t\tselectThinkingLevel(host, level, persist);\n\t\t\tdone();\n\t\t};\n\t\tconst selector = new ThinkingSelectorComponent(\n\t\t\thost.facade.getState().thinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\thost.getAvailableThinkingLevels(),\n\t\t\t(level) => selectLevel(level, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\t(level) => selectLevel(level, true),\n\t\t\thost.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,\n\t\t);\n\t\treturn { component: selector, focus: selector };\n\t});\n}\n\nexport async function handleModelCommand(host: SelectorsHost, searchTerm?: string): Promise<void> {\n\tif (!searchTerm) {\n\t\tshowModelSelector(host);\n\t\treturn;\n\t}\n\n\tconst model = await findExactModelMatch(host, searchTerm);\n\tif (model) {\n\t\ttry {\n\t\t\tawait host.facade.setModel(model, { persist: false });\n\t\t\thost.footer.invalidate();\n\t\t\thost.updateEditorBorderColor();\n\t\t\thost.showStatus(`Model: ${model.id}`);\n\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t} catch (error) {\n\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\treturn;\n\t}\n\n\tshowModelSelector(host, searchTerm);\n}\n\nexport async function findExactModelMatch(host: SelectorsHost, searchTerm: string): Promise<Model<Api> | undefined> {\n\tconst cachedModels =\n\t\thost.facade.getScopedModels().length > 0\n\t\t\t? host.facade.getScopedModels().map((scoped) => scoped.model)\n\t\t\t: [...host.getAvailableModels()];\n\tconst cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);\n\tif (cachedMatch || host.facade.getScopedModels().length > 0) return cachedMatch;\n\n\thost.showStatus(\"Refreshing model catalogs…\");\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, 15_000);\n\ttry {\n\t\tconst result = await refreshModelCatalogs(host.getModelCatalog(), controller.signal);\n\t\tif (result.aborted && timedOut) {\n\t\t\thost.showWarning(\"Model refresh timed out; searching cached models.\");\n\t\t} else if (result.errors.size > 0) {\n\t\t\thost.showWarning(`Could not refresh ${[...result.errors.keys()].join(\", \")}; searching cached models.`);\n\t\t}\n\t} catch (error) {\n\t\thost.showWarning(\n\t\t\ttimedOut\n\t\t\t\t? \"Model refresh timed out; searching cached models.\"\n\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\treturn findExactModelReferenceMatch(searchTerm, [...host.getAvailableModels()]);\n}\n\nexport function showModelSelector(host: SelectorsHost, initialSearchInput?: string): void {\n\thost.showSelector((done) => {\n\t\tconst selectModel = async (model: Model<Api>, persist: boolean) => {\n\t\t\ttry {\n\t\t\t\tawait host.facade.setModel(model, { persist });\n\t\t\t\thost.updateAvailableProviderCount();\n\t\t\t\thost.footer.invalidate();\n\t\t\t\thost.updateEditorBorderColor();\n\t\t\t\tdone();\n\t\t\t\thost.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);\n\t\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t\t} catch (error) {\n\t\t\t\tdone();\n\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t};\n\t\tconst defaultProvider = host.settingsManager.getDefaultProvider();\n\t\tconst defaultModel = host.settingsManager.getDefaultModel();\n\t\tconst selector = new ModelSelectorComponent(\n\t\t\thost.ui,\n\t\t\thost.facade.getModel(),\n\t\t\t{\n\t\t\t\t// D-048: the selector component consumes a narrow read projection;\n\t\t\t\t// the full ModelRuntime never crosses the host boundary.\n\t\t\t\tgetAvailableSnapshot: () => host.getAvailableModels(),\n\t\t\t\tgetError: () => host.facade.getModelsError(),\n\t\t\t\trefresh: (options) => host.getModelCatalog().refresh(options),\n\t\t\t},\n\t\t\thost.facade.getScopedModels(),\n\t\t\t(model) => selectModel(model, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSearchInput,\n\t\t\t(model) => selectModel(model, true),\n\t\t\tdefaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined,\n\t\t);\n\t\treturn { component: selector, focus: selector, dispose: () => selector.dispose() };\n\t});\n}\n\nexport function showModelsSelector(host: SelectorsHost): void {\n\tlet availableModels = [...host.getAvailableModels()];\n\tlet availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\tconst configuredPatterns = host.settingsManager.getEnabledModels();\n\tconst sessionScopedModels = host.facade.getScopedModels();\n\tconst configuredEnabledIds = (models: readonly Model<Api>[]): string[] | null => {\n\t\tif (!configuredPatterns?.length) return null;\n\t\tconst resolved = resolveModelScopeFromModels(configuredPatterns, models);\n\t\tconst ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);\n\t\tfor (const diagnostic of resolved.diagnostics) {\n\t\t\tif (diagnostic.code === \"no-match\" && !ids.includes(diagnostic.pattern)) ids.push(diagnostic.pattern);\n\t\t}\n\t\treturn ids;\n\t};\n\n\tlet currentEnabledIds =\n\t\tsessionScopedModels.length > 0\n\t\t\t? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)\n\t\t\t: configuredEnabledIds(availableModels);\n\tlet selectionChanged = false;\n\n\tconst updateSessionModels = (enabledIds: string[] | null): void => {\n\t\tcurrentEnabledIds = enabledIds === null ? null : [...enabledIds];\n\t\tconst hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;\n\t\tconst allAvailableModelsEnabled =\n\t\t\tenabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));\n\t\tif (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {\n\t\t\tconst newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;\n\t\t\thost.facade.setScopedModels(\n\t\t\t\tnewScopedModels.map((scoped) => ({\n\t\t\t\t\tmodel: scoped.model,\n\t\t\t\t\tthinkingLevel: scoped.thinkingLevel,\n\t\t\t\t})),\n\t\t\t);\n\t\t} else {\n\t\t\thost.facade.setScopedModels([]);\n\t\t}\n\t\thost.updateAvailableProviderCount();\n\t\thost.ui.requestRender();\n\t};\n\n\thost.showSelector((done) => {\n\t\tlet disposed = false;\n\t\tlet timedOut = false;\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, 15_000);\n\t\tconst selector = new ScopedModelsSelectorComponent(\n\t\t\t{\n\t\t\t\tallModels: availableModels,\n\t\t\t\tenabledModelIds: currentEnabledIds,\n\t\t\t\trefreshStatus: \"Refreshing model catalogs…\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tonChange: (enabledIds) => {\n\t\t\t\t\tselectionChanged = true;\n\t\t\t\t\tupdateSessionModels(enabledIds);\n\t\t\t\t},\n\t\t\t\tonPersist: (enabledIds) => {\n\t\t\t\t\tconst allEnabled =\n\t\t\t\t\t\tenabledIds !== null &&\n\t\t\t\t\t\tenabledIds.length === availableModels.length &&\n\t\t\t\t\t\tenabledIds.every((id) => availableModelIds.has(id));\n\t\t\t\t\tconst newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;\n\t\t\t\t\thost.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);\n\t\t\t\t\thost.showStatus(\"Model selection saved to settings\");\n\t\t\t\t},\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tdone();\n\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tvoid refreshModelCatalogs(host.getModelCatalog(), controller.signal)\n\t\t\t.then((result) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tavailableModels = [...host.getAvailableModels()];\n\t\t\t\tavailableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\t\t\t\tif (!selectionChanged && sessionScopedModels.length === 0) {\n\t\t\t\t\tcurrentEnabledIds = configuredEnabledIds(availableModels);\n\t\t\t\t\tselector.updateModels(availableModels, currentEnabledIds);\n\t\t\t\t} else {\n\t\t\t\t\tselector.updateModels(availableModels);\n\t\t\t\t}\n\t\t\t\tif (currentEnabledIds !== null) updateSessionModels(currentEnabledIds);\n\t\t\t\tif (result.aborted && timedOut) {\n\t\t\t\t\tselector.setRefreshStatus(\"Model refresh timed out; showing cached models.\", \"warning\");\n\t\t\t\t} else if (result.errors.size > 0) {\n\t\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\t\t`Could not refresh ${[...result.errors.keys()].join(\", \")}; showing cached models.`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tselector.setRefreshStatus(\"Model catalogs refreshed.\", \"success\");\n\t\t\t\t}\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\ttimedOut\n\t\t\t\t\t\t? \"Model refresh timed out; showing cached models.\"\n\t\t\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.finally(() => clearTimeout(timeout));\n\t\treturn {\n\t\t\tcomponent: selector,\n\t\t\tfocus: selector,\n\t\t\tdispose: () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tcontroller.abort();\n\t\t\t},\n\t\t};\n\t});\n}\n\nexport function showUserMessageSelector(host: SelectorsHost): void {\n\tconst userMessages = host.getUserMessagesForForking();\n\n\tif (userMessages.length === 0) {\n\t\thost.showStatus(\"No messages to fork from\");\n\t\treturn;\n\t}\n\n\tconst initialSelectedId = userMessages[userMessages.length - 1]?.entryId;\n\n\thost.showSelector((done) => {\n\t\tconst selector = new UserMessageSelectorComponent(\n\t\t\tuserMessages.map((m) => ({ id: m.entryId, text: m.text })),\n\t\t\tasync (entryId) => {\n\t\t\t\tdone();\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await host.runtimeFacade.fork(entryId);\n\t\t\t\t\tif (result.cancelled) {\n\t\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\thost.editor.setText(result.selectedText ?? \"\");\n\t\t\t\t\thost.showStatus(\"Forked to new session\");\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSelectedId,\n\t\t);\n\t\treturn { component: selector, focus: selector.getMessageList() };\n\t});\n}\n\nexport async function handleCloneCommand(host: SelectorsHost): Promise<void> {\n\tconst leafId = host.facade.getLeafId();\n\tif (!leafId) {\n\t\thost.showStatus(\"Nothing to clone yet\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst result = await host.runtimeFacade.fork(leafId, { position: \"at\" });\n\t\tif (result.cancelled) {\n\t\t\thost.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\thost.editor.setText(\"\");\n\t\thost.showStatus(\"Cloned to new session\");\n\t} catch (error: unknown) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-selectors.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-selectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Selectors for interactive mode (S5 slice 5): the suite, thinking, model,\n * scoped-models, user-message fork, and clone selectors.\n *\n * InteractiveMode implements SelectorsHost and keeps same-name delegate\n * methods so prototype-level tests and the command dispatch table keep\n * working; the functions below receive the mode through SelectorsHost and\n * mount every overlay through the host's selector surface (host.showSelector),\n * mirroring the AuthUiHost pattern in ./interactive-auth.ts. Model snapshot,\n * catalog-refresh, and facade access go through narrow host accessors (D-048:\n * facade projections) so this module never reads session internals directly.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { ThinkingLevel } from \"@agent-forge/agent-core\";\nimport type { Api, Model } from \"@agent-forge/ai/compat\";\nimport type { Component, EditorComponent, TUI } from \"@agent-forge/tui\";\nimport { Container, SelectList, Spacer, Text } from \"@agent-forge/tui\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ForkableUserMessage } from \"../../core/agent-session-projection.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"../../core/defaults.ts\";\nimport type { CodingAgentFacadeV1, CodingAgentRuntimeFacadeV1 } from \"../../core/facade/index.ts\";\nimport { findExactModelReferenceMatch, resolveModelScopeFromModels } from \"../../core/model-resolver.ts\";\nimport type { SettingsManager } from \"../../core/settings-manager.ts\";\nimport { listSuiteIds } from \"../../profiles/suite-loader.ts\";\nimport { DynamicBorder } from \"./components/dynamic-border.ts\";\nimport type { FooterComponent } from \"./components/footer.ts\";\nimport { ModelSelectorComponent } from \"./components/model-selector.ts\";\nimport { ScopedModelsSelectorComponent } from \"./components/scoped-models-selector.ts\";\nimport { ThinkingSelectorComponent } from \"./components/thinking-selector.ts\";\nimport { UserMessageSelectorComponent } from \"./components/user-message-selector.ts\";\nimport { type ModelCatalogRuntime, refreshModelCatalogs } from \"./model-catalog-refresh.ts\";\nimport { getSelectListTheme, theme } from \"./theme/theme.ts\";\n\n/** Mount description accepted by the host's selector surface. */\ninterface SelectorMount {\n\tcomponent: Component;\n\tfocus: Component;\n\tdispose?: () => void;\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the selector entry\n * points (which stay on the mode for dispatch and prototype-level tests) plus\n * narrow accessors for the session runtime, the stable facades, and settings.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface SelectorsHost {\n\tui: TUI;\n\teditor: EditorComponent;\n\tfooter: FooterComponent;\n\tsettingsManager: SettingsManager;\n\t/** Stable facade (阶段 1 slice 1). */\n\tfacade: CodingAgentFacadeV1;\n\t/** Stable runtime facade (阶段 4 slice 3); manager-level session reads stay here (D-041). */\n\truntimeFacade: CodingAgentRuntimeFacadeV1;\n\n\t/** Narrow catalog-refresh projection through the stable facade (D-048). */\n\tgetModelCatalog(): ModelCatalogRuntime;\n\t/** Available model snapshot through the stable facade (D-048). */\n\tgetAvailableModels(): readonly Model<Api>[];\n\t/** Current session's suite id; the read stays on the mode (session entries). */\n\tgetCurrentSessionSuiteId(): string | undefined;\n\t/** Available thinking levels of the current session. */\n\tgetAvailableThinkingLevels(): ThinkingLevel[];\n\t/** Fork candidates of the current session. */\n\tgetUserMessagesForForking(): ForkableUserMessage[];\n\n\t/** Selector surface; the implementation stays in the mode's selector area. */\n\tshowSelector(create: (done: () => void) => SelectorMount): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\tshowWarning(message: string): void;\n\tupdateEditorBorderColor(): void;\n\tupdateAvailableProviderCount(): void;\n\tmaybeWarnAboutAnthropicSubscriptionAuth(model?: Model<Api>): Promise<void>;\n\tcheckDaxnutsEasterEgg(model: { provider: string; id: string }): void;\n}\n\nexport function handleSuiteCommand(host: SelectorsHost, suiteId?: string): void {\n\tconst availableSuites = listSuiteIds(getAgentDir());\n\tif (!suiteId) {\n\t\tshowSuiteSelector(host, availableSuites);\n\t\treturn;\n\t}\n\n\tif (!availableSuites.includes(suiteId)) {\n\t\thost.showError(`Unknown suite \"${suiteId}\". Available suites: ${availableSuites.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\thost.settingsManager.setProjectSuite(suiteId);\n\t// /new re-resolves the suite from current settings (the runtime factory\n\t// rebuilds services per session), so the pick applies to the very next\n\t// new session — unless the process was started with an explicit suite\n\t// source, which keeps winning for the whole process (设计 §9 precedence).\n\thost.showStatus(\n\t\t`Suite set to ${suiteId} — applies to the next new session (/new); an explicit --suite or AGENT_FORGE_SUITE startup keeps overriding it`,\n\t);\n}\n\nexport function showSuiteSelector(host: SelectorsHost, availableSuites: readonly string[]): void {\n\topenSuiteListSelector(host, {\n\t\tavailableSuites,\n\t\tonSelect: (suiteId) => handleSuiteCommand(host, suiteId),\n\t\tonCancel: () => host.ui.requestRender(),\n\t});\n}\n\n/**\n * Shared suite list overlay (设计 §9). Marks and preselects the current\n * session's suite; the caller decides what a selection means.\n */\nexport function openSuiteListSelector(\n\thost: SelectorsHost,\n\tcallbacks: {\n\t\tavailableSuites: readonly string[];\n\t\t/** explanatory line under the title; defaults to the /suite wording */\n\t\tnote?: string;\n\t\tonSelect: (suiteId: string) => void;\n\t\tonCancel: () => void;\n\t},\n): void {\n\thost.showSelector((done) => {\n\t\tconst currentSuiteId = host.getCurrentSessionSuiteId();\n\t\tconst container = new Container();\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.bold(\"Select Suite\"), 1, 0));\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"muted\",\n\t\t\t\t\tcallbacks.note ??\n\t\t\t\t\t\t\"The next new session (/new) uses the selected suite; this session keeps its current suite\",\n\t\t\t\t),\n\t\t\t\t1,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new DynamicBorder());\n\t\tconst list = new SelectList(\n\t\t\tcallbacks.availableSuites.map((id) => ({\n\t\t\t\tvalue: id,\n\t\t\t\tlabel: id,\n\t\t\t\t...(id === currentSuiteId ? { description: \"current session\" } : {}),\n\t\t\t})),\n\t\t\t10,\n\t\t\tgetSelectListTheme(),\n\t\t);\n\t\tif (currentSuiteId !== undefined) {\n\t\t\tconst currentIndex = callbacks.availableSuites.indexOf(currentSuiteId);\n\t\t\tif (currentIndex >= 0) list.setSelectedIndex(currentIndex);\n\t\t}\n\t\tlist.onSelect = (item) => {\n\t\t\tdone();\n\t\t\tcallbacks.onSelect(item.value);\n\t\t};\n\t\tlist.onCancel = () => {\n\t\t\tdone();\n\t\t\tcallbacks.onCancel();\n\t\t};\n\t\tcontainer.addChild(list);\n\t\tcontainer.addChild(new DynamicBorder());\n\t\treturn { component: container, focus: list };\n\t});\n}\n\nexport function handleThinkingCommand(host: SelectorsHost, searchTerm?: string): void {\n\tconst availableLevels = host.getAvailableThinkingLevels();\n\tif (!searchTerm) {\n\t\tshowThinkingSelector(host);\n\t\treturn;\n\t}\n\n\tconst normalized = searchTerm.trim().toLowerCase();\n\tconst level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);\n\tif (!level) {\n\t\thost.showError(`Unknown thinking level \"${searchTerm}\". Available levels: ${availableLevels.join(\", \")}.`);\n\t\treturn;\n\t}\n\n\tselectThinkingLevel(host, level, false);\n}\n\nexport function selectThinkingLevel(host: SelectorsHost, level: ThinkingLevel, persist: boolean): void {\n\ttry {\n\t\thost.facade.setThinkingLevel(level, { persist });\n\t\thost.footer.invalidate();\n\t\thost.updateEditorBorderColor();\n\t\thost.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);\n\t} catch (error) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n\nexport function showThinkingSelector(host: SelectorsHost): void {\n\thost.showSelector((done) => {\n\t\tconst selectLevel = (level: ThinkingLevel, persist: boolean) => {\n\t\t\tselectThinkingLevel(host, level, persist);\n\t\t\tdone();\n\t\t};\n\t\tconst selector = new ThinkingSelectorComponent(\n\t\t\thost.facade.getState().thinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\thost.getAvailableThinkingLevels(),\n\t\t\t(level) => selectLevel(level, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\t(level) => selectLevel(level, true),\n\t\t\thost.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,\n\t\t);\n\t\treturn { component: selector, focus: selector };\n\t});\n}\n\nexport async function handleModelCommand(host: SelectorsHost, searchTerm?: string): Promise<void> {\n\tif (!searchTerm) {\n\t\tshowModelSelector(host);\n\t\treturn;\n\t}\n\n\tconst model = await findExactModelMatch(host, searchTerm);\n\tif (model) {\n\t\ttry {\n\t\t\tawait host.facade.setModel(model, { persist: false });\n\t\t\thost.footer.invalidate();\n\t\t\thost.updateEditorBorderColor();\n\t\t\thost.showStatus(`Model: ${model.id}`);\n\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t} catch (error) {\n\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\treturn;\n\t}\n\n\tshowModelSelector(host, searchTerm);\n}\n\nexport async function findExactModelMatch(host: SelectorsHost, searchTerm: string): Promise<Model<Api> | undefined> {\n\tconst cachedModels =\n\t\thost.facade.getScopedModels().length > 0\n\t\t\t? host.facade.getScopedModels().map((scoped) => scoped.model)\n\t\t\t: [...host.getAvailableModels()];\n\tconst cachedMatch = findExactModelReferenceMatch(searchTerm, cachedModels);\n\tif (cachedMatch || host.facade.getScopedModels().length > 0) return cachedMatch;\n\n\thost.showStatus(\"Refreshing model catalogs…\");\n\tconst controller = new AbortController();\n\tlet timedOut = false;\n\tconst timeout = setTimeout(() => {\n\t\ttimedOut = true;\n\t\tcontroller.abort();\n\t}, 15_000);\n\ttry {\n\t\tconst result = await refreshModelCatalogs(host.getModelCatalog(), controller.signal);\n\t\tif (result.aborted && timedOut) {\n\t\t\thost.showWarning(\"Model refresh timed out; searching cached models.\");\n\t\t} else if (result.errors.size > 0) {\n\t\t\thost.showWarning(`Could not refresh ${[...result.errors.keys()].join(\", \")}; searching cached models.`);\n\t\t}\n\t} catch (error) {\n\t\thost.showWarning(\n\t\t\ttimedOut\n\t\t\t\t? \"Model refresh timed out; searching cached models.\"\n\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t);\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n\treturn findExactModelReferenceMatch(searchTerm, [...host.getAvailableModels()]);\n}\n\nexport function showModelSelector(host: SelectorsHost, initialSearchInput?: string): void {\n\thost.showSelector((done) => {\n\t\tconst selectModel = async (model: Model<Api>, persist: boolean) => {\n\t\t\ttry {\n\t\t\t\tawait host.facade.setModel(model, { persist });\n\t\t\t\thost.updateAvailableProviderCount();\n\t\t\t\thost.footer.invalidate();\n\t\t\t\thost.updateEditorBorderColor();\n\t\t\t\tdone();\n\t\t\t\thost.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);\n\t\t\t\tvoid host.maybeWarnAboutAnthropicSubscriptionAuth(model);\n\t\t\t\thost.checkDaxnutsEasterEgg(model);\n\t\t\t} catch (error) {\n\t\t\t\tdone();\n\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t};\n\t\tconst defaultProvider = host.settingsManager.getDefaultProvider();\n\t\tconst defaultModel = host.settingsManager.getDefaultModel();\n\t\tconst selector = new ModelSelectorComponent(\n\t\t\thost.ui,\n\t\t\thost.facade.getModel(),\n\t\t\t{\n\t\t\t\t// D-048: the selector component consumes a narrow read projection;\n\t\t\t\t// the full ModelRuntime never crosses the host boundary.\n\t\t\t\tgetAvailableSnapshot: () => host.getAvailableModels(),\n\t\t\t\tgetError: () => host.facade.getModelsError(),\n\t\t\t\trefresh: (options) => host.getModelCatalog().refresh(options),\n\t\t\t},\n\t\t\thost.facade.getScopedModels(),\n\t\t\t(model) => selectModel(model, false),\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSearchInput,\n\t\t\t(model) => selectModel(model, true),\n\t\t\tdefaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined,\n\t\t);\n\t\treturn { component: selector, focus: selector, dispose: () => selector.dispose() };\n\t});\n}\n\nexport function showModelsSelector(host: SelectorsHost): void {\n\tlet availableModels = [...host.getAvailableModels()];\n\tlet availableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\tconst configuredPatterns = host.settingsManager.getEnabledModels();\n\tconst sessionScopedModels = host.facade.getScopedModels();\n\tconst configuredEnabledIds = (models: readonly Model<Api>[]): string[] | null => {\n\t\tif (!configuredPatterns?.length) return null;\n\t\tconst resolved = resolveModelScopeFromModels(configuredPatterns, models);\n\t\tconst ids = resolved.scopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`);\n\t\tfor (const diagnostic of resolved.diagnostics) {\n\t\t\tif (diagnostic.code === \"no-match\" && !ids.includes(diagnostic.pattern)) ids.push(diagnostic.pattern);\n\t\t}\n\t\treturn ids;\n\t};\n\n\tlet currentEnabledIds =\n\t\tsessionScopedModels.length > 0\n\t\t\t? sessionScopedModels.map((scoped) => `${scoped.model.provider}/${scoped.model.id}`)\n\t\t\t: configuredEnabledIds(availableModels);\n\tlet selectionChanged = false;\n\n\tconst updateSessionModels = (enabledIds: string[] | null): void => {\n\t\tcurrentEnabledIds = enabledIds === null ? null : [...enabledIds];\n\t\tconst hasEnabledAvailableModel = enabledIds?.some((id) => availableModelIds.has(id)) ?? false;\n\t\tconst allAvailableModelsEnabled =\n\t\t\tenabledIds !== null && [...availableModelIds].every((id) => enabledIds.includes(id));\n\t\tif (enabledIds && hasEnabledAvailableModel && !allAvailableModelsEnabled) {\n\t\t\tconst newScopedModels = resolveModelScopeFromModels(enabledIds, availableModels).scopedModels;\n\t\t\thost.facade.setScopedModels(\n\t\t\t\tnewScopedModels.map((scoped) => ({\n\t\t\t\t\tmodel: scoped.model,\n\t\t\t\t\tthinkingLevel: scoped.thinkingLevel,\n\t\t\t\t})),\n\t\t\t);\n\t\t} else {\n\t\t\thost.facade.setScopedModels([]);\n\t\t}\n\t\thost.updateAvailableProviderCount();\n\t\thost.ui.requestRender();\n\t};\n\n\thost.showSelector((done) => {\n\t\tlet disposed = false;\n\t\tlet timedOut = false;\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tcontroller.abort();\n\t\t}, 15_000);\n\t\tconst selector = new ScopedModelsSelectorComponent(\n\t\t\t{\n\t\t\t\tallModels: availableModels,\n\t\t\t\tenabledModelIds: currentEnabledIds,\n\t\t\t\trefreshStatus: \"Refreshing model catalogs…\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tonChange: (enabledIds) => {\n\t\t\t\t\tselectionChanged = true;\n\t\t\t\t\tupdateSessionModels(enabledIds);\n\t\t\t\t},\n\t\t\t\tonPersist: (enabledIds) => {\n\t\t\t\t\tconst allEnabled =\n\t\t\t\t\t\tenabledIds !== null &&\n\t\t\t\t\t\tenabledIds.length === availableModels.length &&\n\t\t\t\t\t\tenabledIds.every((id) => availableModelIds.has(id));\n\t\t\t\t\tconst newPatterns = enabledIds === null || allEnabled ? undefined : enabledIds;\n\t\t\t\t\thost.settingsManager.setEnabledModels(newPatterns ? [...newPatterns] : undefined);\n\t\t\t\t\thost.showStatus(\"Model selection saved to settings\");\n\t\t\t\t},\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tdone();\n\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tvoid refreshModelCatalogs(host.getModelCatalog(), controller.signal)\n\t\t\t.then((result) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tavailableModels = [...host.getAvailableModels()];\n\t\t\t\tavailableModelIds = new Set(availableModels.map((model) => `${model.provider}/${model.id}`));\n\t\t\t\tif (!selectionChanged && sessionScopedModels.length === 0) {\n\t\t\t\t\tcurrentEnabledIds = configuredEnabledIds(availableModels);\n\t\t\t\t\tselector.updateModels(availableModels, currentEnabledIds);\n\t\t\t\t} else {\n\t\t\t\t\tselector.updateModels(availableModels);\n\t\t\t\t}\n\t\t\t\tif (currentEnabledIds !== null) updateSessionModels(currentEnabledIds);\n\t\t\t\tif (result.aborted && timedOut) {\n\t\t\t\t\tselector.setRefreshStatus(\"Model refresh timed out; showing cached models.\", \"warning\");\n\t\t\t\t} else if (result.errors.size > 0) {\n\t\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\t\t`Could not refresh ${[...result.errors.keys()].join(\", \")}; showing cached models.`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tselector.setRefreshStatus(\"Model catalogs refreshed.\", \"success\");\n\t\t\t\t}\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tselector.setRefreshStatus(\n\t\t\t\t\ttimedOut\n\t\t\t\t\t\t? \"Model refresh timed out; showing cached models.\"\n\t\t\t\t\t\t: `Could not refresh model catalogs: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t\thost.ui.requestRender();\n\t\t\t})\n\t\t\t.finally(() => clearTimeout(timeout));\n\t\treturn {\n\t\t\tcomponent: selector,\n\t\t\tfocus: selector,\n\t\t\tdispose: () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tclearTimeout(timeout);\n\t\t\t\tcontroller.abort();\n\t\t\t},\n\t\t};\n\t});\n}\n\nexport function showUserMessageSelector(host: SelectorsHost): void {\n\tconst userMessages = host.getUserMessagesForForking();\n\n\tif (userMessages.length === 0) {\n\t\thost.showStatus(\"No messages to fork from\");\n\t\treturn;\n\t}\n\n\tconst initialSelectedId = userMessages[userMessages.length - 1]?.entryId;\n\n\thost.showSelector((done) => {\n\t\tconst selector = new UserMessageSelectorComponent(\n\t\t\tuserMessages.map((m) => ({\n\t\t\t\tid: m.entryId,\n\t\t\t\ttext: m.text,\n\t\t\t\t...(m.replySummary === undefined ? {} : { replySummary: m.replySummary }),\n\t\t\t})),\n\t\t\tasync (entryId) => {\n\t\t\t\tdone();\n\t\t\t\t// Restore the selected prompt into the editor even when the fork\n\t\t\t\t// fails, so the user never loses the text they chose (codex\n\t\t\t\t// backtrack precedent: restore_backtrack_prompt_after_revert_error).\n\t\t\t\tconst fallbackText = userMessages.find((m) => m.entryId === entryId)?.text ?? \"\";\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await host.runtimeFacade.fork(entryId);\n\t\t\t\t\tif (result.cancelled) {\n\t\t\t\t\t\thost.ui.requestRender();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\thost.editor.setText(result.selectedText ?? \"\");\n\t\t\t\t\thost.showStatus(\"Forked to new session\");\n\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\thost.editor.setText(fallbackText);\n\t\t\t\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tdone();\n\t\t\t\thost.ui.requestRender();\n\t\t\t},\n\t\t\tinitialSelectedId,\n\t\t);\n\t\treturn { component: selector, focus: selector.getMessageList() };\n\t});\n}\n\nexport async function handleCloneCommand(host: SelectorsHost): Promise<void> {\n\tconst leafId = host.facade.getLeafId();\n\tif (!leafId) {\n\t\thost.showStatus(\"Nothing to clone yet\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tconst result = await host.runtimeFacade.fork(leafId, { position: \"at\" });\n\t\tif (result.cancelled) {\n\t\t\thost.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\thost.editor.setText(\"\");\n\t\thost.showStatus(\"Cloned to new session\");\n\t} catch (error: unknown) {\n\t\thost.showError(error instanceof Error ? error.message : String(error));\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAU5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"print-mode.d.ts","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAU5E;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmM/G","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `agent-forge -p \"prompt\"` - text output\n * - `agent-forge --mode json \"prompt\"` - JSON event stream\n *\n * Text mode stdout carries only the final answer (existing final-output path);\n * tool/diagnostic activity is projected from session events (3.5b) onto stderr\n * as structured lines. JSON mode is untouched.\n */\n\nimport type { AssistantMessage, ImageContent } from \"@agent-forge/ai\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport type { CapabilityCommandResult } from \"../core/extensions/index.ts\";\nimport { createCodingAgentFacade, createCodingAgentRuntimeFacade } from \"../core/facade/index.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { createStdioChannelAdapter } from \"../host/channel-adapter.ts\";\nimport { createHostOutputProjector } from \"../host/output-projection.ts\";\nimport { translateSessionEvent } from \"../host/session-event-translation.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\t// Stable facade (阶段 1): prompt, state, header, and event reads go through\n\t// CodingAgentFacadeV1; runtime lifecycle and session startup below stay on\n\t// AgentSessionRuntime/AgentSession (docs/design/稳定门面统一入口设计.md).\n\tlet facade = createCodingAgentFacade(session);\n\t// Stable runtime facade (阶段 4 slice 3): runtime lifecycle orchestration goes\n\t// through CodingAgentRuntimeFacadeV1, same pattern as interactive mode; rebinds\n\t// are picked up automatically.\n\tconst runtimeFacade = createCodingAgentRuntimeFacade(runtimeHost);\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst commandResults: CapabilityCommandResult[] = [];\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\t// Channel wiring (3.5b): project session events into host output records and\n\t// route them through the print channel. The translation layer emits no\n\t// message records, so stdout is only ever written by the final-output path\n\t// below and stays byte-identical; tool/diagnostic lines go to stderr.\n\tconst projector = createHostOutputProjector();\n\tconst channelAdapter = createStdioChannelAdapter({\n\t\tformat: \"print\",\n\t\twriteStdout: writeRawStdout,\n\t\twriteStderr: (text) => process.stderr.write(text),\n\t});\n\t// One trace per prompt, shared by every host event of that prompt.\n\tlet turnCounter = 0;\n\tlet currentTraceId = \"turn:0\";\n\tconst nextTraceId = (): string => {\n\t\tturnCounter += 1;\n\t\treturn `turn:${turnCounter}`;\n\t};\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeFacade.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tfacade = createCodingAgentFacade(session);\n\t\tawait session.startSession();\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = facade.subscribe((event) => {\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.type === \"capability_command_result\") {\n\t\t\t\tcommandResults.push(event.result);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst hostEvents = translateSessionEvent(event, currentTraceId);\n\t\t\tif (hostEvents.length > 0) {\n\t\t\t\tchannelAdapter.ingest(projector.project(hostEvents));\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? facade.subscribeRawEventGate(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = facade.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\t// -p text mode is a one-shot autonomous path: if a turn ends with an\n\t\t// empty assistant reply — or with no assistant output at all (e.g. a\n\t\t// tool or network failure swallowed the answer) — nudge the model once\n\t\t// instead of exiting silently. Abort is respected and the budget is\n\t\t// capped at one continuation to prevent loops. JSON mode is untouched:\n\t\t// machine consumers own their retry policy.\n\t\tconst autoContinue = mode !== \"json\";\n\t\tconst promptWithAutoContinue = async (text: string, images?: ImageContent[]): Promise<void> => {\n\t\t\tconst seen = facade.getState().messages.length;\n\t\t\tif (images === undefined) {\n\t\t\t\tawait facade.prompt(text);\n\t\t\t} else {\n\t\t\t\tawait facade.prompt(text, { images });\n\t\t\t}\n\t\t\tif (!autoContinue) return;\n\t\t\tconst messagesThisTurn = facade.getState().messages.slice(seen);\n\t\t\t// A capability command intercepted the prompt: session.prompt returns\n\t\t\t// before anything is appended, so an empty turn means \"handled as a\n\t\t\t// command\", not \"the reply was swallowed\" — do not nudge the model.\n\t\t\tif (messagesThisTurn.length === 0) return;\n\t\t\tif (messagesThisTurn.some((m) => m.role === \"assistant\" && m.stopReason === \"aborted\")) return;\n\t\t\tconst lastAssistant = [...messagesThisTurn].reverse().find((m) => m.role === \"assistant\");\n\t\t\tconst replyText =\n\t\t\t\tlastAssistant === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: typeof lastAssistant.content === \"string\"\n\t\t\t\t\t\t? lastAssistant.content\n\t\t\t\t\t\t: lastAssistant.content\n\t\t\t\t\t\t\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n\t\t\t\t\t\t\t\t.map((part) => part.text)\n\t\t\t\t\t\t\t\t.join(\"\");\n\t\t\tif (replyText.trim().length > 0) return;\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait facade.prompt(\n\t\t\t\t\"Your previous reply was empty. Continue the user's task now with tool calls and summarise the result.\",\n\t\t\t);\n\t\t};\n\n\t\tif (initialMessage) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(initialMessage, initialImages);\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(message);\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\tfor (const result of commandResults) {\n\t\t\t\tconst links = result.links?.map((link) => `${link.label}: ${link.url}`) ?? [];\n\t\t\t\tconst message = [result.message, ...links].filter(Boolean).join(\"\\n\");\n\t\t\t\tif (result.status === \"error\") {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\twriteRawStdout(`${message}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst state = facade.getState();\n\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\tconsole.error(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
package/dist/modes/print-mode.js
CHANGED
|
@@ -135,6 +135,11 @@ export async function runPrintMode(runtimeHost, options) {
|
|
|
135
135
|
if (!autoContinue)
|
|
136
136
|
return;
|
|
137
137
|
const messagesThisTurn = facade.getState().messages.slice(seen);
|
|
138
|
+
// A capability command intercepted the prompt: session.prompt returns
|
|
139
|
+
// before anything is appended, so an empty turn means "handled as a
|
|
140
|
+
// command", not "the reply was swallowed" — do not nudge the model.
|
|
141
|
+
if (messagesThisTurn.length === 0)
|
|
142
|
+
return;
|
|
138
143
|
if (messagesThisTurn.some((m) => m.role === "assistant" && m.stopReason === "aborted"))
|
|
139
144
|
return;
|
|
140
145
|
const lastAssistant = [...messagesThisTurn].reverse().find((m) => m.role === "assistant");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"print-mode.js","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `agent-forge -p \"prompt\"` - text output\n * - `agent-forge --mode json \"prompt\"` - JSON event stream\n *\n * Text mode stdout carries only the final answer (existing final-output path);\n * tool/diagnostic activity is projected from session events (3.5b) onto stderr\n * as structured lines. JSON mode is untouched.\n */\n\nimport type { AssistantMessage, ImageContent } from \"@agent-forge/ai\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport type { CapabilityCommandResult } from \"../core/extensions/index.ts\";\nimport { createCodingAgentFacade, createCodingAgentRuntimeFacade } from \"../core/facade/index.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { createStdioChannelAdapter } from \"../host/channel-adapter.ts\";\nimport { createHostOutputProjector } from \"../host/output-projection.ts\";\nimport { translateSessionEvent } from \"../host/session-event-translation.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\t// Stable facade (阶段 1): prompt, state, header, and event reads go through\n\t// CodingAgentFacadeV1; runtime lifecycle and session startup below stay on\n\t// AgentSessionRuntime/AgentSession (docs/design/稳定门面统一入口设计.md).\n\tlet facade = createCodingAgentFacade(session);\n\t// Stable runtime facade (阶段 4 slice 3): runtime lifecycle orchestration goes\n\t// through CodingAgentRuntimeFacadeV1, same pattern as interactive mode; rebinds\n\t// are picked up automatically.\n\tconst runtimeFacade = createCodingAgentRuntimeFacade(runtimeHost);\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst commandResults: CapabilityCommandResult[] = [];\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\t// Channel wiring (3.5b): project session events into host output records and\n\t// route them through the print channel. The translation layer emits no\n\t// message records, so stdout is only ever written by the final-output path\n\t// below and stays byte-identical; tool/diagnostic lines go to stderr.\n\tconst projector = createHostOutputProjector();\n\tconst channelAdapter = createStdioChannelAdapter({\n\t\tformat: \"print\",\n\t\twriteStdout: writeRawStdout,\n\t\twriteStderr: (text) => process.stderr.write(text),\n\t});\n\t// One trace per prompt, shared by every host event of that prompt.\n\tlet turnCounter = 0;\n\tlet currentTraceId = \"turn:0\";\n\tconst nextTraceId = (): string => {\n\t\tturnCounter += 1;\n\t\treturn `turn:${turnCounter}`;\n\t};\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeFacade.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tfacade = createCodingAgentFacade(session);\n\t\tawait session.startSession();\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = facade.subscribe((event) => {\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.type === \"capability_command_result\") {\n\t\t\t\tcommandResults.push(event.result);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst hostEvents = translateSessionEvent(event, currentTraceId);\n\t\t\tif (hostEvents.length > 0) {\n\t\t\t\tchannelAdapter.ingest(projector.project(hostEvents));\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? facade.subscribeRawEventGate(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = facade.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\t// -p text mode is a one-shot autonomous path: if a turn ends with an\n\t\t// empty assistant reply — or with no assistant output at all (e.g. a\n\t\t// tool or network failure swallowed the answer) — nudge the model once\n\t\t// instead of exiting silently. Abort is respected and the budget is\n\t\t// capped at one continuation to prevent loops. JSON mode is untouched:\n\t\t// machine consumers own their retry policy.\n\t\tconst autoContinue = mode !== \"json\";\n\t\tconst promptWithAutoContinue = async (text: string, images?: ImageContent[]): Promise<void> => {\n\t\t\tconst seen = facade.getState().messages.length;\n\t\t\tif (images === undefined) {\n\t\t\t\tawait facade.prompt(text);\n\t\t\t} else {\n\t\t\t\tawait facade.prompt(text, { images });\n\t\t\t}\n\t\t\tif (!autoContinue) return;\n\t\t\tconst messagesThisTurn = facade.getState().messages.slice(seen);\n\t\t\tif (messagesThisTurn.some((m) => m.role === \"assistant\" && m.stopReason === \"aborted\")) return;\n\t\t\tconst lastAssistant = [...messagesThisTurn].reverse().find((m) => m.role === \"assistant\");\n\t\t\tconst replyText =\n\t\t\t\tlastAssistant === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: typeof lastAssistant.content === \"string\"\n\t\t\t\t\t\t? lastAssistant.content\n\t\t\t\t\t\t: lastAssistant.content\n\t\t\t\t\t\t\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n\t\t\t\t\t\t\t\t.map((part) => part.text)\n\t\t\t\t\t\t\t\t.join(\"\");\n\t\t\tif (replyText.trim().length > 0) return;\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait facade.prompt(\n\t\t\t\t\"Your previous reply was empty. Continue the user's task now with tool calls and summarise the result.\",\n\t\t\t);\n\t\t};\n\n\t\tif (initialMessage) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(initialMessage, initialImages);\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(message);\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\tfor (const result of commandResults) {\n\t\t\t\tconst links = result.links?.map((link) => `${link.label}: ${link.url}`) ?? [];\n\t\t\t\tconst message = [result.message, ...links].filter(Boolean).join(\"\\n\");\n\t\t\t\tif (result.status === \"error\") {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\twriteRawStdout(`${message}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst state = facade.getState();\n\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\tconsole.error(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"print-mode.js","sourceRoot":"","sources":["../../src/modes/print-mode.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Print mode (single-shot): Send prompts, output result, exit.\n *\n * Used for:\n * - `agent-forge -p \"prompt\"` - text output\n * - `agent-forge --mode json \"prompt\"` - JSON event stream\n *\n * Text mode stdout carries only the final answer (existing final-output path);\n * tool/diagnostic activity is projected from session events (3.5b) onto stderr\n * as structured lines. JSON mode is untouched.\n */\n\nimport type { AssistantMessage, ImageContent } from \"@agent-forge/ai\";\nimport type { AgentSessionRuntime } from \"../core/agent-session-runtime.ts\";\nimport type { CapabilityCommandResult } from \"../core/extensions/index.ts\";\nimport { createCodingAgentFacade, createCodingAgentRuntimeFacade } from \"../core/facade/index.ts\";\nimport { flushRawStdout, waitForRawStdoutBackpressure, writeRawStdout } from \"../core/output-guard.ts\";\nimport { createStdioChannelAdapter } from \"../host/channel-adapter.ts\";\nimport { createHostOutputProjector } from \"../host/output-projection.ts\";\nimport { translateSessionEvent } from \"../host/session-event-translation.ts\";\nimport { killTrackedDetachedChildren } from \"../utils/shell.ts\";\nimport { toJsonEvent } from \"./json-event.ts\";\n\n/**\n * Options for print mode.\n */\nexport interface PrintModeOptions {\n\t/** Output mode: \"text\" for final response only, \"json\" for all events */\n\tmode: \"text\" | \"json\";\n\t/** Array of additional prompts to send after initialMessage */\n\tmessages?: string[];\n\t/** First message to send (may contain @file content) */\n\tinitialMessage?: string;\n\t/** Images to attach to the initial message */\n\tinitialImages?: ImageContent[];\n}\n\n/**\n * Run in print (single-shot) mode.\n * Sends prompts to the agent and outputs the result.\n */\nexport async function runPrintMode(runtimeHost: AgentSessionRuntime, options: PrintModeOptions): Promise<number> {\n\tconst { mode, messages = [], initialMessage, initialImages } = options;\n\tlet exitCode = 0;\n\tlet session = runtimeHost.session;\n\t// Stable facade (阶段 1): prompt, state, header, and event reads go through\n\t// CodingAgentFacadeV1; runtime lifecycle and session startup below stay on\n\t// AgentSessionRuntime/AgentSession (docs/design/稳定门面统一入口设计.md).\n\tlet facade = createCodingAgentFacade(session);\n\t// Stable runtime facade (阶段 4 slice 3): runtime lifecycle orchestration goes\n\t// through CodingAgentRuntimeFacadeV1, same pattern as interactive mode; rebinds\n\t// are picked up automatically.\n\tconst runtimeFacade = createCodingAgentRuntimeFacade(runtimeHost);\n\tlet unsubscribe: (() => void) | undefined;\n\tlet unsubscribeBackpressure: (() => void) | undefined;\n\tlet disposed = false;\n\tconst commandResults: CapabilityCommandResult[] = [];\n\tconst signalCleanupHandlers: Array<() => void> = [];\n\n\t// Channel wiring (3.5b): project session events into host output records and\n\t// route them through the print channel. The translation layer emits no\n\t// message records, so stdout is only ever written by the final-output path\n\t// below and stays byte-identical; tool/diagnostic lines go to stderr.\n\tconst projector = createHostOutputProjector();\n\tconst channelAdapter = createStdioChannelAdapter({\n\t\tformat: \"print\",\n\t\twriteStdout: writeRawStdout,\n\t\twriteStderr: (text) => process.stderr.write(text),\n\t});\n\t// One trace per prompt, shared by every host event of that prompt.\n\tlet turnCounter = 0;\n\tlet currentTraceId = \"turn:0\";\n\tconst nextTraceId = (): string => {\n\t\tturnCounter += 1;\n\t\treturn `turn:${turnCounter}`;\n\t};\n\n\tconst disposeRuntime = async (): Promise<void> => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tawait runtimeHost.dispose();\n\t};\n\n\tconst registerSignalHandlers = (): void => {\n\t\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\t\tif (process.platform !== \"win32\") {\n\t\t\tsignals.push(\"SIGHUP\");\n\t\t}\n\n\t\tfor (const signal of signals) {\n\t\t\tconst handler = () => {\n\t\t\t\tkillTrackedDetachedChildren();\n\t\t\t\tvoid disposeRuntime().finally(() => {\n\t\t\t\t\tprocess.exit(signal === \"SIGHUP\" ? 129 : 143);\n\t\t\t\t});\n\t\t\t};\n\t\t\tprocess.on(signal, handler);\n\t\t\tsignalCleanupHandlers.push(() => process.off(signal, handler));\n\t\t}\n\t};\n\n\tregisterSignalHandlers();\n\n\truntimeFacade.setRebindSession(async () => {\n\t\tawait rebindSession();\n\t});\n\n\tconst rebindSession = async (): Promise<void> => {\n\t\tsession = runtimeHost.session;\n\t\tfacade = createCodingAgentFacade(session);\n\t\tawait session.startSession();\n\n\t\tunsubscribe?.();\n\t\tunsubscribeBackpressure?.();\n\t\tunsubscribe = facade.subscribe((event) => {\n\t\t\tif (mode === \"json\") {\n\t\t\t\twriteRawStdout(`${JSON.stringify(toJsonEvent(event))}\\n`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (event.type === \"capability_command_result\") {\n\t\t\t\tcommandResults.push(event.result);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst hostEvents = translateSessionEvent(event, currentTraceId);\n\t\t\tif (hostEvents.length > 0) {\n\t\t\t\tchannelAdapter.ingest(projector.project(hostEvents));\n\t\t\t}\n\t\t});\n\t\tunsubscribeBackpressure =\n\t\t\tmode === \"json\"\n\t\t\t\t? facade.subscribeRawEventGate(async () => {\n\t\t\t\t\t\tawait waitForRawStdoutBackpressure();\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\t};\n\n\ttry {\n\t\tif (mode === \"json\") {\n\t\t\tconst header = facade.getHeader();\n\t\t\tif (header) {\n\t\t\t\twriteRawStdout(`${JSON.stringify(header)}\\n`);\n\t\t\t}\n\t\t}\n\n\t\tawait rebindSession();\n\n\t\t// -p text mode is a one-shot autonomous path: if a turn ends with an\n\t\t// empty assistant reply — or with no assistant output at all (e.g. a\n\t\t// tool or network failure swallowed the answer) — nudge the model once\n\t\t// instead of exiting silently. Abort is respected and the budget is\n\t\t// capped at one continuation to prevent loops. JSON mode is untouched:\n\t\t// machine consumers own their retry policy.\n\t\tconst autoContinue = mode !== \"json\";\n\t\tconst promptWithAutoContinue = async (text: string, images?: ImageContent[]): Promise<void> => {\n\t\t\tconst seen = facade.getState().messages.length;\n\t\t\tif (images === undefined) {\n\t\t\t\tawait facade.prompt(text);\n\t\t\t} else {\n\t\t\t\tawait facade.prompt(text, { images });\n\t\t\t}\n\t\t\tif (!autoContinue) return;\n\t\t\tconst messagesThisTurn = facade.getState().messages.slice(seen);\n\t\t\t// A capability command intercepted the prompt: session.prompt returns\n\t\t\t// before anything is appended, so an empty turn means \"handled as a\n\t\t\t// command\", not \"the reply was swallowed\" — do not nudge the model.\n\t\t\tif (messagesThisTurn.length === 0) return;\n\t\t\tif (messagesThisTurn.some((m) => m.role === \"assistant\" && m.stopReason === \"aborted\")) return;\n\t\t\tconst lastAssistant = [...messagesThisTurn].reverse().find((m) => m.role === \"assistant\");\n\t\t\tconst replyText =\n\t\t\t\tlastAssistant === undefined\n\t\t\t\t\t? \"\"\n\t\t\t\t\t: typeof lastAssistant.content === \"string\"\n\t\t\t\t\t\t? lastAssistant.content\n\t\t\t\t\t\t: lastAssistant.content\n\t\t\t\t\t\t\t\t.filter((part): part is { type: \"text\"; text: string } => part.type === \"text\")\n\t\t\t\t\t\t\t\t.map((part) => part.text)\n\t\t\t\t\t\t\t\t.join(\"\");\n\t\t\tif (replyText.trim().length > 0) return;\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait facade.prompt(\n\t\t\t\t\"Your previous reply was empty. Continue the user's task now with tool calls and summarise the result.\",\n\t\t\t);\n\t\t};\n\n\t\tif (initialMessage) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(initialMessage, initialImages);\n\t\t}\n\n\t\tfor (const message of messages) {\n\t\t\tcurrentTraceId = nextTraceId();\n\t\t\tawait promptWithAutoContinue(message);\n\t\t}\n\n\t\tif (mode === \"text\") {\n\t\t\tfor (const result of commandResults) {\n\t\t\t\tconst links = result.links?.map((link) => `${link.label}: ${link.url}`) ?? [];\n\t\t\t\tconst message = [result.message, ...links].filter(Boolean).join(\"\\n\");\n\t\t\t\tif (result.status === \"error\") {\n\t\t\t\t\tconsole.error(message);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\twriteRawStdout(`${message}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst state = facade.getState();\n\t\t\tconst lastMessage = state.messages[state.messages.length - 1];\n\n\t\t\tif (lastMessage?.role === \"assistant\") {\n\t\t\t\tconst assistantMsg = lastMessage as AssistantMessage;\n\t\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\t\tconsole.error(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);\n\t\t\t\t\texitCode = 1;\n\t\t\t\t} else {\n\t\t\t\t\tfor (const content of assistantMsg.content) {\n\t\t\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\t\t\twriteRawStdout(`${content.text}\\n`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn exitCode;\n\t} catch (error: unknown) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\treturn 1;\n\t} finally {\n\t\tfor (const cleanup of signalCleanupHandlers) {\n\t\t\tcleanup();\n\t\t}\n\t\tawait disposeRuntime();\n\t\tawait flushRawStdout();\n\t}\n}\n"]}
|
|
@@ -64,8 +64,10 @@ export declare class RpcClient {
|
|
|
64
64
|
* "handled"); use onEvent() to receive streaming events. If the disposition is
|
|
65
65
|
* "handled", no run started for this prompt, so don't wait for agent_settled.
|
|
66
66
|
* Returns undefined when talking to an older server that does not report a disposition.
|
|
67
|
+
* @param streamingBehavior - How to queue the message when the agent is already
|
|
68
|
+
* streaming ("steer" interrupts mid-run, "followUp" waits for completion).
|
|
67
69
|
*/
|
|
68
|
-
prompt(message: string, images?: ImageContent[]): Promise<PromptDisposition | undefined>;
|
|
70
|
+
prompt(message: string, images?: ImageContent[], streamingBehavior?: "steer" | "followUp"): Promise<PromptDisposition | undefined>;
|
|
69
71
|
/**
|
|
70
72
|
* Queue a steering message to interrupt the agent mid-run.
|
|
71
73
|
* Returns "queued", or "handled" if a handler consumed the message.
|