@astralyn/pi 0.82.7 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -5099
- package/README.md +12 -111
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bedrock.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
- package/dist/bun/restore-sandbox-env.js.map +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +28 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +2 -2
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +23 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +117 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/experimental/auth.d.ts +16 -0
- package/dist/cli/experimental/auth.d.ts.map +1 -0
- package/dist/cli/experimental/auth.js +13 -0
- package/dist/cli/experimental/auth.js.map +1 -0
- package/dist/cli/experimental/cli.d.ts +6 -0
- package/dist/cli/experimental/cli.d.ts.map +1 -0
- package/dist/cli/experimental/cli.js +5 -0
- package/dist/cli/experimental/cli.js.map +1 -0
- package/dist/cli/experimental/command-options.d.ts +17 -0
- package/dist/cli/experimental/command-options.d.ts.map +1 -0
- package/dist/cli/experimental/command-options.js +35 -0
- package/dist/cli/experimental/command-options.js.map +1 -0
- package/dist/cli/experimental/command.d.ts +63 -0
- package/dist/cli/experimental/command.d.ts.map +1 -0
- package/dist/cli/experimental/command.js +127 -0
- package/dist/cli/experimental/command.js.map +1 -0
- package/dist/cli/experimental/commands/client.d.ts +13 -0
- package/dist/cli/experimental/commands/client.d.ts.map +1 -0
- package/dist/cli/experimental/commands/client.js +25 -0
- package/dist/cli/experimental/commands/client.js.map +1 -0
- package/dist/cli/experimental/commands/pi.d.ts +15 -0
- package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
- package/dist/cli/experimental/commands/pi.js +28 -0
- package/dist/cli/experimental/commands/pi.js.map +1 -0
- package/dist/cli/experimental/commands/server.d.ts +13 -0
- package/dist/cli/experimental/commands/server.d.ts.map +1 -0
- package/dist/cli/experimental/commands/server.js +25 -0
- package/dist/cli/experimental/commands/server.js.map +1 -0
- package/dist/cli/experimental/transport-address.d.ts +10 -0
- package/dist/cli/experimental/transport-address.d.ts.map +1 -0
- package/dist/cli/experimental/transport-address.js +38 -0
- package/dist/cli/experimental/transport-address.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/initial-message.d.ts +1 -1
- package/dist/cli/initial-message.d.ts.map +1 -1
- package/dist/cli/initial-message.js.map +1 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/remote-session.d.ts +53 -0
- package/dist/client/remote-session.d.ts.map +1 -0
- package/dist/client/remote-session.js +340 -0
- package/dist/client/remote-session.js.map +1 -0
- package/dist/client/transcript.d.ts +12 -0
- package/dist/client/transcript.d.ts.map +1 -0
- package/dist/client/transcript.js +98 -0
- package/dist/client/transcript.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -8
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +31 -11
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +189 -192
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts +15 -9
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +159 -41
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/cache-stats.d.ts.map +1 -1
- package/dist/core/cache-stats.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/utils.d.ts.map +1 -1
- package/dist/core/compaction/utils.js.map +1 -1
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.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/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +43 -20
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +31 -28
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +28 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/extensions/wrapper.d.ts.map +1 -1
- package/dist/core/extensions/wrapper.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +18 -19
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/keybindings.d.ts +157 -125
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +0 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js.map +1 -1
- package/dist/core/model-config.d.ts +37 -13
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +4 -2
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts +5 -3
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -11
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +4 -3
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +41 -10
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +30 -13
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +239 -91
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +84 -16
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/output-guard.d.ts.map +1 -1
- package/dist/core/output-guard.js.map +1 -1
- package/dist/core/package-manager.d.ts +4 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +76 -48
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts +8 -0
- package/dist/core/pi-manifest.d.ts.map +1 -0
- package/dist/core/pi-manifest.js +25 -0
- package/dist/core/pi-manifest.js.map +1 -0
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/provider-composer.d.ts +4 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +36 -15
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/radius.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +73 -67
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +68 -51
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.d.ts.map +1 -1
- package/dist/core/runtime-credentials.js +12 -10
- package/dist/core/runtime-credentials.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +0 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +10 -12
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +12 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +47 -33
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/source-info.d.ts.map +1 -1
- package/dist/core/source-info.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +12 -10
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +3 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +47 -20
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +12 -18
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/truncate.d.ts.map +1 -1
- package/dist/core/tools/truncate.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +0 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +48 -10
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/biu/index.d.ts +19 -0
- package/dist/extensions/biu/index.d.ts.map +1 -0
- package/dist/extensions/biu/index.js +350 -0
- package/dist/extensions/biu/index.js.map +1 -0
- package/dist/extensions/biu/prompts.d.ts +26 -0
- package/dist/extensions/biu/prompts.d.ts.map +1 -0
- package/dist/extensions/biu/prompts.js +260 -0
- package/dist/extensions/biu/prompts.js.map +1 -0
- package/dist/extensions/biu/workspace.d.ts +122 -0
- package/dist/extensions/biu/workspace.d.ts.map +1 -0
- package/dist/extensions/biu/workspace.js +404 -0
- package/dist/extensions/biu/workspace.js.map +1 -0
- package/dist/extensions/deepwiki/client.d.ts.map +1 -1
- package/dist/extensions/deepwiki/client.js.map +1 -1
- package/dist/extensions/deepwiki/constants.d.ts.map +1 -1
- package/dist/extensions/deepwiki/constants.js.map +1 -1
- package/dist/extensions/deepwiki/contents.d.ts.map +1 -1
- package/dist/extensions/deepwiki/contents.js.map +1 -1
- package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
- package/dist/extensions/deepwiki/execute.js.map +1 -1
- package/dist/extensions/deepwiki/http.d.ts.map +1 -1
- package/dist/extensions/deepwiki/http.js.map +1 -1
- package/dist/extensions/deepwiki/index.d.ts.map +1 -1
- package/dist/extensions/deepwiki/index.js.map +1 -1
- package/dist/extensions/deepwiki/render.d.ts.map +1 -1
- package/dist/extensions/deepwiki/render.js.map +1 -1
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
- package/dist/extensions/deepwiki/schema.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -2
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +0 -2
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/huggingface.d.ts.map +1 -1
- package/dist/extensions/llama/huggingface.js +0 -2
- package/dist/extensions/llama/huggingface.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +11 -2
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +22 -8
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/llama/ui.d.ts.map +1 -1
- package/dist/extensions/llama/ui.js +12 -28
- package/dist/extensions/llama/ui.js.map +1 -1
- package/dist/extensions/question/constants.d.ts.map +1 -1
- package/dist/extensions/question/constants.js.map +1 -1
- package/dist/extensions/question/dialog-primitives.d.ts.map +1 -1
- package/dist/extensions/question/dialog-primitives.js.map +1 -1
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/limits.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.d.ts.map +1 -1
- package/dist/extensions/question/render-cache.js +3 -4
- package/dist/extensions/question/render-cache.js.map +1 -1
- package/dist/extensions/question/render.d.ts.map +1 -1
- package/dist/extensions/question/render.js.map +1 -1
- package/dist/extensions/question/results.d.ts.map +1 -1
- package/dist/extensions/question/results.js.map +1 -1
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/state.d.ts.map +1 -1
- package/dist/extensions/question/state.js.map +1 -1
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/rewind/anchor.d.ts.map +1 -1
- package/dist/extensions/rewind/anchor.js.map +1 -1
- package/dist/extensions/rewind/config.d.ts.map +1 -1
- package/dist/extensions/rewind/config.js.map +1 -1
- package/dist/extensions/rewind/engine.d.ts.map +1 -1
- package/dist/extensions/rewind/engine.js.map +1 -1
- package/dist/extensions/rewind/gc.d.ts.map +1 -1
- package/dist/extensions/rewind/gc.js.map +1 -1
- package/dist/extensions/rewind/index.d.ts.map +1 -1
- package/dist/extensions/rewind/index.js.map +1 -1
- package/dist/extensions/rewind/menu.d.ts.map +1 -1
- package/dist/extensions/rewind/menu.js.map +1 -1
- package/dist/extensions/rewind/paths.d.ts.map +1 -1
- package/dist/extensions/rewind/paths.js.map +1 -1
- package/dist/extensions/rewind/restore.d.ts.map +1 -1
- package/dist/extensions/rewind/restore.js.map +1 -1
- package/dist/extensions/rewind/snapshot.d.ts.map +1 -1
- package/dist/extensions/rewind/snapshot.js.map +1 -1
- package/dist/extensions/rewind/storage.d.ts.map +1 -1
- package/dist/extensions/rewind/storage.js.map +1 -1
- package/dist/extensions/rewind/text.d.ts.map +1 -1
- package/dist/extensions/rewind/text.js.map +1 -1
- package/dist/extensions/rewind/tool-path.d.ts.map +1 -1
- package/dist/extensions/rewind/tool-path.js.map +1 -1
- package/dist/extensions/router/constants.d.ts +3 -0
- package/dist/extensions/router/constants.d.ts.map +1 -1
- package/dist/extensions/router/constants.js +3 -0
- package/dist/extensions/router/constants.js.map +1 -1
- package/dist/extensions/router/dialog.d.ts +14 -7
- package/dist/extensions/router/dialog.d.ts.map +1 -1
- package/dist/extensions/router/dialog.js +70 -132
- package/dist/extensions/router/dialog.js.map +1 -1
- package/dist/extensions/router/index.d.ts.map +1 -1
- package/dist/extensions/router/index.js.map +1 -1
- package/dist/extensions/router/presets.d.ts +8 -3
- package/dist/extensions/router/presets.d.ts.map +1 -1
- package/dist/extensions/router/presets.js +33 -17
- package/dist/extensions/router/presets.js.map +1 -1
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/register.d.ts +3 -3
- package/dist/extensions/router/register.d.ts.map +1 -1
- package/dist/extensions/router/register.js.map +1 -1
- package/dist/extensions/router/store.d.ts.map +1 -1
- package/dist/extensions/router/store.js.map +1 -1
- package/dist/extensions/router/stream.d.ts.map +1 -1
- package/dist/extensions/router/stream.js.map +1 -1
- package/dist/extensions/router/types.d.ts.map +1 -1
- package/dist/extensions/router/ui.d.ts +11 -2
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +316 -171
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/statusline/index.d.ts.map +1 -1
- package/dist/extensions/statusline/index.js +17 -9
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/index.d.ts +3 -0
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +83 -12
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/picker.d.ts.map +1 -1
- package/dist/extensions/subagent/picker.js +2 -9
- package/dist/extensions/subagent/picker.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +33 -9
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/retry.d.ts.map +1 -1
- package/dist/extensions/subagent/retry.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +2 -1
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +10 -12
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/schema.d.ts.map +1 -1
- package/dist/extensions/subagent/schema.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +41 -1
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +46 -36
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +0 -1
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/overlay.d.ts.map +1 -1
- package/dist/extensions/todo/overlay.js +6 -10
- package/dist/extensions/todo/overlay.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +2 -2
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +57 -5
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +6 -10
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +13 -11
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -10
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +0 -3
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +1 -3
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +1 -3
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +5 -22
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +1 -7
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +8 -8
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +1 -4
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -7
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js +6 -8
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +0 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +1 -7
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-input.js +2 -8
- package/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +1 -9
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +2 -4
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -4
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -9
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
- package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
- package/dist/modes/interactive/components/markdown-transform.js +19 -0
- package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
- package/dist/modes/interactive/components/mermaid.d.ts +11 -0
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
- package/dist/modes/interactive/components/mermaid.js +75 -0
- package/dist/modes/interactive/components/mermaid.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +32 -30
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +3 -11
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +34 -13
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +35 -60
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +30 -14
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +0 -1
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +1 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +0 -2
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +0 -2
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +0 -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 +18 -36
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +2 -3
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +19 -39
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/trust-selector.js +0 -6
- package/dist/modes/interactive/components/trust-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +3 -6
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +8 -5
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +40 -3
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +46 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +538 -275
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -0
- package/dist/modes/interactive/theme/light.json +1 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +11 -8
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +5 -1
- package/dist/modes/interactive/theme/theme.d.ts +4 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +13 -9
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +28 -0
- package/dist/modes/json-event.d.ts.map +1 -0
- package/dist/modes/json-event.js +12 -0
- package/dist/modes/json-event.js.map +1 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/jsonl.d.ts.map +1 -1
- package/dist/modes/rpc/jsonl.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +5 -4
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -8
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +17 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +11 -9
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +1 -0
- package/dist/rpc-entry.js.map +1 -1
- package/dist/utils/abort.d.ts +5 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +48 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/clipboard.d.ts +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +22 -2
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/coalescing-terminal.d.ts +1 -0
- package/dist/utils/coalescing-terminal.d.ts.map +1 -1
- package/dist/utils/coalescing-terminal.js +16 -8
- package/dist/utils/coalescing-terminal.js.map +1 -1
- package/dist/utils/deprecation.d.ts.map +1 -1
- package/dist/utils/deprecation.js.map +1 -1
- package/dist/utils/exif-orientation.d.ts.map +1 -1
- package/dist/utils/exif-orientation.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/html.d.ts.map +1 -1
- package/dist/utils/html.js.map +1 -1
- package/dist/utils/image-convert.d.ts.map +1 -1
- package/dist/utils/image-convert.js.map +1 -1
- package/dist/utils/image-process.d.ts.map +1 -1
- package/dist/utils/image-process.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js.map +1 -1
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/management-http.d.ts +23 -0
- package/dist/utils/management-http.d.ts.map +1 -0
- package/dist/utils/management-http.js +50 -0
- package/dist/utils/management-http.js.map +1 -0
- package/dist/utils/mime.d.ts.map +1 -1
- package/dist/utils/mime.js.map +1 -1
- package/dist/utils/open-browser.d.ts.map +1 -1
- package/dist/utils/open-browser.js.map +1 -1
- package/dist/utils/paths.d.ts +5 -3
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +25 -4
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js.map +1 -1
- package/dist/utils/pi-user-agent.d.ts.map +1 -1
- package/dist/utils/pi-user-agent.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/sleep.d.ts.map +1 -1
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/tool-result-images.d.ts +19 -0
- package/dist/utils/tool-result-images.d.ts.map +1 -0
- package/dist/utils/tool-result-images.js +45 -0
- package/dist/utils/tool-result-images.js.map +1 -0
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +4 -6
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +20 -2
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/bundled/README.md +14 -16
- package/docs/bundled/extensions/biu.md +63 -0
- package/docs/bundled/extensions/router.md +20 -14
- package/docs/bundled/extensions/statusline.md +7 -5
- package/docs/bundled/themes.md +1 -1
- package/docs/compaction.md +25 -30
- package/docs/custom-provider.md +303 -467
- package/docs/development.md +83 -0
- package/docs/docs.json +6 -10
- package/docs/extensions.md +139 -119
- package/docs/index.md +18 -74
- package/docs/json.md +40 -15
- package/docs/keybindings.md +38 -10
- package/docs/models.md +210 -150
- package/docs/providers.md +3 -1
- package/docs/quickstart.md +5 -3
- package/docs/rpc.md +177 -134
- package/docs/sdk.md +165 -178
- package/docs/security.md +2 -2
- package/docs/session-format.md +139 -119
- package/docs/settings.md +4 -1
- package/docs/skills.md +0 -1
- package/docs/themes.md +5 -3
- package/docs/tui.md +411 -549
- package/docs/usage.md +11 -11
- package/examples/README.md +6 -1
- package/examples/extensions/README.md +13 -33
- package/examples/extensions/custom-compaction.ts +1 -16
- package/examples/extensions/custom-provider-anthropic/index.ts +11 -4
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
- package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
- package/examples/extensions/handoff.ts +2 -11
- package/examples/extensions/qna.ts +3 -7
- package/examples/extensions/summarize.ts +8 -18
- package/examples/extensions/truncated-tool.ts +2 -2
- package/examples/rpc-extension-ui.ts +11 -2
- package/examples/sdk/02-custom-model.ts +1 -2
- package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
- package/examples/sdk/12-full-control.ts +3 -1
- package/examples/sdk/README.md +1 -0
- package/npm-shrinkwrap.json +199 -270
- package/package.json +16 -9
- package/dist/extensions/plan/constants.d.ts +0 -68
- package/dist/extensions/plan/constants.d.ts.map +0 -1
- package/dist/extensions/plan/constants.js +0 -100
- package/dist/extensions/plan/constants.js.map +0 -1
- package/dist/extensions/plan/index.d.ts +0 -30
- package/dist/extensions/plan/index.d.ts.map +0 -1
- package/dist/extensions/plan/index.js +0 -429
- package/dist/extensions/plan/index.js.map +0 -1
- package/dist/extensions/plan/schema.d.ts +0 -20
- package/dist/extensions/plan/schema.d.ts.map +0 -1
- package/dist/extensions/plan/schema.js +0 -13
- package/dist/extensions/plan/schema.js.map +0 -1
- package/dist/extensions/plan/state.d.ts +0 -38
- package/dist/extensions/plan/state.d.ts.map +0 -1
- package/dist/extensions/plan/state.js +0 -96
- package/dist/extensions/plan/state.js.map +0 -1
- package/dist/extensions/plan/storage.d.ts +0 -26
- package/dist/extensions/plan/storage.d.ts.map +0 -1
- package/dist/extensions/plan/storage.js +0 -83
- package/dist/extensions/plan/storage.js.map +0 -1
- package/dist/extensions/plan/view.d.ts +0 -44
- package/dist/extensions/plan/view.d.ts.map +0 -1
- package/dist/extensions/plan/view.js +0 -149
- package/dist/extensions/plan/view.js.map +0 -1
- package/docs/bundled/extensions/README.md +0 -19
- package/docs/bundled/extensions/plan.md +0 -34
- package/examples/extensions/plan-mode/README.md +0 -66
- package/examples/extensions/plan-mode/index.ts +0 -390
- package/examples/extensions/plan-mode/utils.ts +0 -168
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Display name (`name`) is optional: omit it to show the model id in /model.
|
|
7
7
|
*/
|
|
8
|
-
import { DEFAULTS, THINKING_LEVELS } from "./constants.js";
|
|
9
|
-
/**
|
|
8
|
+
import { DEFAULTS, ROUTER_THINKING_LEVELS, THINKING_LEVELS } from "./constants.js";
|
|
9
|
+
/**
|
|
10
|
+
* GPT Gateway defaults: off/minimal are never exposed; all five supported
|
|
11
|
+
* router levels start enabled and can be disabled individually.
|
|
12
|
+
*/
|
|
10
13
|
export const DEFAULT_THINKING_LEVEL_MAP = {
|
|
11
14
|
off: null,
|
|
12
15
|
minimal: null,
|
|
13
|
-
low:
|
|
14
|
-
medium:
|
|
16
|
+
low: "low",
|
|
17
|
+
medium: "medium",
|
|
15
18
|
high: "high",
|
|
16
19
|
xhigh: "xhigh",
|
|
17
20
|
max: "max",
|
|
@@ -47,7 +50,10 @@ export function resolveModelConfig(entry) {
|
|
|
47
50
|
input: entry.input ?? base.input,
|
|
48
51
|
contextWindow: entry.contextWindow ?? base.contextWindow,
|
|
49
52
|
maxTokens: entry.maxTokens ?? base.maxTokens,
|
|
50
|
-
|
|
53
|
+
// Apply the GPT Gateway policy in memory without rewriting legacy router.json
|
|
54
|
+
// files. Legacy off/minimal values therefore become unavailable at runtime,
|
|
55
|
+
// while explicit choices for the five visible levels remain intact.
|
|
56
|
+
thinkingLevelMap: resolveRouterThinkingMap(entry.thinkingLevelMap ?? base.thinkingLevelMap),
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
export function normalizeThinkingMap(map) {
|
|
@@ -60,11 +66,27 @@ export function normalizeThinkingMap(map) {
|
|
|
60
66
|
}
|
|
61
67
|
return result;
|
|
62
68
|
}
|
|
69
|
+
/** Apply the router-wide GPT policy without mutating the stored object. */
|
|
70
|
+
export function resolveRouterThinkingMap(map) {
|
|
71
|
+
const result = normalizeThinkingMap(DEFAULT_THINKING_LEVEL_MAP);
|
|
72
|
+
if (map) {
|
|
73
|
+
for (const level of THINKING_LEVELS) {
|
|
74
|
+
if (!Object.hasOwn(map, level))
|
|
75
|
+
continue;
|
|
76
|
+
const value = map[level];
|
|
77
|
+
if (value !== undefined)
|
|
78
|
+
result[level] = value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
result.off = null;
|
|
82
|
+
result.minimal = null;
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
63
85
|
export function summarizeThinkingMap(map) {
|
|
64
|
-
const resolved =
|
|
86
|
+
const resolved = resolveRouterThinkingMap(map);
|
|
65
87
|
const enabled = [];
|
|
66
88
|
const hidden = [];
|
|
67
|
-
for (const level of
|
|
89
|
+
for (const level of ROUTER_THINKING_LEVELS) {
|
|
68
90
|
const value = resolved[level];
|
|
69
91
|
if (value === null)
|
|
70
92
|
hidden.push(level);
|
|
@@ -77,16 +99,10 @@ export function summarizeThinkingMap(map) {
|
|
|
77
99
|
return hidden.length > 0 ? `${on} · hide ${hidden.join(",")}` : on;
|
|
78
100
|
}
|
|
79
101
|
export function toggleThinkingLevel(map, level) {
|
|
80
|
-
const next =
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
else
|
|
85
|
-
next[level] = level;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
next[level] = null;
|
|
89
|
-
}
|
|
102
|
+
const next = resolveRouterThinkingMap(map);
|
|
103
|
+
if (!ROUTER_THINKING_LEVELS.includes(level))
|
|
104
|
+
return next;
|
|
105
|
+
next[level] = next[level] === null ? level : null;
|
|
90
106
|
return next;
|
|
91
107
|
}
|
|
92
108
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/extensions/router/presets.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/extensions/router/presets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Default model metadata for Codex-style relays (272k context tier).\n * Matches the common GPT-5.6 Sol/Luna/Terra configuration used with transparent\n * sub2api / CPA / codex2api gateways after the product-side 372k rollback.\n *\n * Display name (`name`) is optional: omit it to show the model id in /model.\n */\n\nimport { DEFAULTS, ROUTER_THINKING_LEVELS, THINKING_LEVELS, type ThinkingLevel } from \"./constants.ts\";\nimport type { RelayModelConfig, ThinkingLevelMap } from \"./types.ts\";\n\n/**\n * GPT Gateway defaults: off/minimal are never exposed; all five supported\n * router levels start enabled and can be disabled individually.\n */\nexport const DEFAULT_THINKING_LEVEL_MAP: ThinkingLevelMap = {\n\toff: null,\n\tminimal: null,\n\tlow: \"low\",\n\tmedium: \"medium\",\n\thigh: \"high\",\n\txhigh: \"xhigh\",\n\tmax: \"max\",\n};\n\n/** Optional custom label only — never invent a default name; empty means show id. */\nexport function createDefaultModelConfig(id: string, name?: string): RelayModelConfig {\n\tconst trimmed = name?.trim();\n\tconst config: RelayModelConfig = {\n\t\tid,\n\t\treasoning: true,\n\t\tinput: [\"text\", \"image\"],\n\t\tcontextWindow: DEFAULTS.contextWindow,\n\t\tmaxTokens: DEFAULTS.maxTokens,\n\t\tthinkingLevelMap: { ...DEFAULT_THINKING_LEVEL_MAP },\n\t};\n\tif (trimmed && trimmed !== id) config.name = trimmed;\n\treturn config;\n}\n\n/** Label for UI lists: custom name if set, otherwise id. */\nexport function displayModelLabel(entry: Pick<RelayModelConfig, \"id\" | \"name\">): string {\n\tconst name = entry.name?.trim();\n\treturn name && name !== entry.id ? name : entry.id;\n}\n\n/** Merge stored model entry with defaults so partial saves stay complete. */\nexport function resolveModelConfig(entry: RelayModelConfig): {\n\tid: string;\n\tname?: string;\n\treasoning: boolean;\n\tinput: Array<\"text\" | \"image\">;\n\tcontextWindow: number;\n\tmaxTokens: number;\n\tthinkingLevelMap: ThinkingLevelMap;\n} {\n\tconst base = createDefaultModelConfig(entry.id);\n\tconst name = entry.name?.trim();\n\treturn {\n\t\tid: entry.id,\n\t\t...(name && name !== entry.id ? { name } : {}),\n\t\treasoning: entry.reasoning ?? base.reasoning!,\n\t\tinput: entry.input ?? base.input!,\n\t\tcontextWindow: entry.contextWindow ?? base.contextWindow!,\n\t\tmaxTokens: entry.maxTokens ?? base.maxTokens!,\n\t\t// Apply the GPT Gateway policy in memory without rewriting legacy router.json\n\t\t// files. Legacy off/minimal values therefore become unavailable at runtime,\n\t\t// while explicit choices for the five visible levels remain intact.\n\t\tthinkingLevelMap: resolveRouterThinkingMap(entry.thinkingLevelMap ?? base.thinkingLevelMap),\n\t};\n}\n\nexport function normalizeThinkingMap(map: ThinkingLevelMap | undefined): ThinkingLevelMap {\n\tconst result: ThinkingLevelMap = {};\n\tfor (const level of THINKING_LEVELS) {\n\t\tif (map && level in map) {\n\t\t\tconst value = map[level];\n\t\t\tresult[level] = value === undefined ? undefined : value;\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Apply the router-wide GPT policy without mutating the stored object. */\nexport function resolveRouterThinkingMap(map: ThinkingLevelMap | undefined): ThinkingLevelMap {\n\tconst result = normalizeThinkingMap(DEFAULT_THINKING_LEVEL_MAP);\n\tif (map) {\n\t\tfor (const level of THINKING_LEVELS) {\n\t\t\tif (!Object.hasOwn(map, level)) continue;\n\t\t\tconst value = map[level];\n\t\t\tif (value !== undefined) result[level] = value;\n\t\t}\n\t}\n\tresult.off = null;\n\tresult.minimal = null;\n\treturn result;\n}\n\nexport function summarizeThinkingMap(map: ThinkingLevelMap | undefined): string {\n\tconst resolved = resolveRouterThinkingMap(map);\n\tconst enabled: string[] = [];\n\tconst hidden: string[] = [];\n\tfor (const level of ROUTER_THINKING_LEVELS) {\n\t\tconst value = resolved[level];\n\t\tif (value === null) hidden.push(level);\n\t\telse if (value === undefined) enabled.push(level);\n\t\telse enabled.push(level === value ? level : `${level}→${value}`);\n\t}\n\tconst on = enabled.length > 0 ? enabled.join(\", \") : \"none\";\n\treturn hidden.length > 0 ? `${on} · hide ${hidden.join(\",\")}` : on;\n}\n\nexport function toggleThinkingLevel(map: ThinkingLevelMap, level: ThinkingLevel): ThinkingLevelMap {\n\tconst next = resolveRouterThinkingMap(map);\n\tif (!ROUTER_THINKING_LEVELS.includes(level as (typeof ROUTER_THINKING_LEVELS)[number])) return next;\n\tnext[level] = next[level] === null ? level : null;\n\treturn next;\n}\n\n/**\n * ProviderConfig model entry required by registerProvider.\n * Pi requires a `name` string; when the user left it empty we pass the id so /model shows the id.\n */\nexport function toRegisterModel(entry: RelayModelConfig) {\n\tconst resolved = resolveModelConfig(entry);\n\treturn {\n\t\tid: resolved.id,\n\t\tname: resolved.name ?? resolved.id,\n\t\treasoning: resolved.reasoning,\n\t\tinput: resolved.input,\n\t\tcontextWindow: resolved.contextWindow,\n\t\tmaxTokens: resolved.maxTokens,\n\t\tthinkingLevelMap: resolved.thinkingLevelMap,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/probe.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAIlE,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAyDvB"
|
|
1
|
+
{"version":3,"file":"probe.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/probe.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAIlE,MAAM,WAAW,UAAU;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,WAAW,CAAC,CAyDvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../src/extensions/router/probe.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AASvD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAKtC
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../../src/extensions/router/probe.ts"],"names":[],"mappings":"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","sourcesContent":["/** Fetch OpenAI-compatible model catalog from a relay baseUrl. */\n\nimport { DEFAULTS, formatError } from \"./constants.ts\";\n\nexport interface ProbeModel {\n\tid: string;\n\tname?: string;\n}\n\nexport type ProbeResult = { ok: true; models: ProbeModel[]; truncated: boolean } | { ok: false; error: string };\n\nexport async function probeRelayModels(opts: {\n\tbaseUrl: string;\n\tapiKey?: string;\n\tsignal?: AbortSignal;\n\ttimeoutMs?: number;\n}): Promise<ProbeResult> {\n\tlet baseUrl: URL;\n\ttry {\n\t\tbaseUrl = new URL(opts.baseUrl);\n\t} catch {\n\t\treturn { ok: false, error: \"Base URL is not a valid URL.\" };\n\t}\n\tif (baseUrl.protocol !== \"http:\" && baseUrl.protocol !== \"https:\") {\n\t\treturn { ok: false, error: `Unsupported protocol: ${baseUrl.protocol}` };\n\t}\n\n\tconst controller = new AbortController();\n\tconst timeoutMs = opts.timeoutMs ?? DEFAULTS.probeTimeoutMs;\n\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\tconst onOuterAbort = () => controller.abort();\n\topts.signal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\n\ttry {\n\t\tconst url = appendPath(baseUrl, \"models\");\n\t\tconst headers: Record<string, string> = { Accept: \"application/json\" };\n\t\tif (opts.apiKey) headers.Authorization = `Bearer ${opts.apiKey}`;\n\n\t\tconst response = await fetch(url, { headers, signal: controller.signal });\n\t\tif (!response.ok) {\n\t\t\tconst body = await readTextBounded(response, 4_096);\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: `HTTP ${response.status}${body ? `: ${body.slice(0, 400)}` : \"\"}`,\n\t\t\t};\n\t\t}\n\t\tconst text = await readTextBounded(response, DEFAULTS.probeBodyBytes);\n\t\tlet json: unknown;\n\t\ttry {\n\t\t\tjson = JSON.parse(text);\n\t\t} catch {\n\t\t\treturn { ok: false, error: \"Model catalog response is not JSON.\" };\n\t\t}\n\t\tconst models = parseOpenAIModels(json);\n\t\tif (models === null) {\n\t\t\treturn { ok: false, error: \"JSON has no OpenAI-style `data` array of model ids.\" };\n\t\t}\n\t\tconst sorted = dedupeSort(models);\n\t\tconst truncated = sorted.length > DEFAULTS.probeMaxModels;\n\t\treturn {\n\t\t\tok: true,\n\t\t\tmodels: sorted.slice(0, DEFAULTS.probeMaxModels),\n\t\t\ttruncated,\n\t\t};\n\t} catch (error) {\n\t\tif (controller.signal.aborted) {\n\t\t\treturn { ok: false, error: opts.signal?.aborted ? \"Cancelled.\" : `Timed out after ${timeoutMs}ms.` };\n\t\t}\n\t\treturn { ok: false, error: formatError(error) };\n\t} finally {\n\t\tclearTimeout(timer);\n\t\topts.signal?.removeEventListener(\"abort\", onOuterAbort);\n\t}\n}\n\nfunction appendPath(base: URL, segment: string): URL {\n\tconst url = new URL(base.href);\n\tconst path = url.pathname.replace(/\\/+$/, \"\");\n\turl.pathname = `${path}/${segment}`;\n\treturn url;\n}\n\nfunction parseOpenAIModels(json: unknown): ProbeModel[] | null {\n\tif (!json || typeof json !== \"object\") return null;\n\tconst data = (json as { data?: unknown }).data;\n\tif (!Array.isArray(data)) return null;\n\tconst models: ProbeModel[] = [];\n\tfor (const item of data) {\n\t\tif (!item || typeof item !== \"object\") continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n\t\tif (!id) continue;\n\t\tconst name =\n\t\t\ttypeof record.name === \"string\" && record.name.trim() && record.name.trim() !== id\n\t\t\t\t? record.name.trim()\n\t\t\t\t: undefined;\n\t\tmodels.push(name ? { id, name } : { id });\n\t}\n\treturn models;\n}\n\nfunction dedupeSort(models: ProbeModel[]): ProbeModel[] {\n\tconst map = new Map<string, ProbeModel>();\n\tfor (const model of models) {\n\t\tif (!map.has(model.id)) map.set(model.id, model);\n\t}\n\treturn [...map.values()].sort((a, b) => a.id.localeCompare(b.id));\n}\n\nasync function readTextBounded(response: Response, maxBytes: number): Promise<string> {\n\tconst reader = response.body?.getReader();\n\tif (!reader) return await response.text();\n\tconst chunks: Uint8Array[] = [];\n\tlet total = 0;\n\twhile (true) {\n\t\tconst { done, value } = await reader.read();\n\t\tif (done) break;\n\t\tif (!value) continue;\n\t\ttotal += value.byteLength;\n\t\tif (total > maxBytes) {\n\t\t\tawait reader.cancel();\n\t\t\tthrow new Error(`Response exceeds ${maxBytes} bytes.`);\n\t\t}\n\t\tchunks.push(value);\n\t}\n\tconst merged = new Uint8Array(total);\n\tlet offset = 0;\n\tfor (const chunk of chunks) {\n\t\tmerged.set(chunk, offset);\n\t\toffset += chunk.byteLength;\n\t}\n\treturn new TextDecoder().decode(merged);\n}\n"]}
|
|
@@ -11,20 +11,20 @@ export declare function toProviderConfig(relay: RelayConfig): {
|
|
|
11
11
|
apiKey: string;
|
|
12
12
|
api: "router-codex";
|
|
13
13
|
models: {
|
|
14
|
+
api: "router-codex";
|
|
14
15
|
id: string;
|
|
15
16
|
name: string;
|
|
16
17
|
reasoning: boolean;
|
|
17
|
-
input: ("
|
|
18
|
+
input: ("text" | "image")[];
|
|
18
19
|
contextWindow: number;
|
|
19
20
|
maxTokens: number;
|
|
20
|
-
thinkingLevelMap: Partial<Record<"
|
|
21
|
+
thinkingLevelMap: Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", string | null>>;
|
|
21
22
|
cost: {
|
|
22
23
|
input: number;
|
|
23
24
|
output: number;
|
|
24
25
|
cacheRead: number;
|
|
25
26
|
cacheWrite: number;
|
|
26
27
|
};
|
|
27
|
-
api: "router-codex";
|
|
28
28
|
}[];
|
|
29
29
|
streamSimple: typeof streamRouterCodex;
|
|
30
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAgB,qBAAqB,IAAI,WAAW,CAAC,MAAM,CAAC,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;EAYlD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CA8BxE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAc3E;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAOrE"
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAgB,qBAAqB,IAAI,WAAW,CAAC,MAAM,CAAC,CAE3D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW;;;;;;;;;;;;;;;;;;;;;;EAYlD;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CA8BxE;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAc3E;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAOrE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/extensions/router/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,0EAA0E;AAC1E,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;AAExC,MAAM,UAAU,qBAAqB
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/extensions/router/register.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Apply router.json relays to Pi via registerProvider (config form + streamSimple).\n */\n\nimport type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { ROUTER_API } from \"./constants.ts\";\nimport { toRegisterModel } from \"./presets.ts\";\nimport { streamRouterCodex } from \"./stream.ts\";\nimport type { RelayConfig, RouterFile } from \"./types.ts\";\n\n/** Provider ids currently registered by this extension in the process. */\nconst registeredIds = new Set<string>();\n\nexport function getRegisteredRelayIds(): ReadonlySet<string> {\n\treturn registeredIds;\n}\n\nexport function toProviderConfig(relay: RelayConfig) {\n\treturn {\n\t\tname: relay.id,\n\t\tbaseUrl: relay.baseUrl.replace(/\\/+$/, \"\"),\n\t\tapiKey: relay.apiKey,\n\t\tapi: ROUTER_API,\n\t\tmodels: relay.models.map((model) => ({\n\t\t\t...toRegisterModel(model),\n\t\t\tapi: ROUTER_API,\n\t\t})),\n\t\tstreamSimple: streamRouterCodex,\n\t};\n}\n\nexport function applyRouterFile(pi: ExtensionAPI, file: RouterFile): void {\n\tconst nextIds = new Set(file.relays.map((relay) => relay.id));\n\n\tfor (const id of [...registeredIds]) {\n\t\tif (!nextIds.has(id)) {\n\t\t\ttry {\n\t\t\t\tpi.unregisterProvider(id);\n\t\t\t} catch {\n\t\t\t\t// Provider may already be gone after /reload.\n\t\t\t}\n\t\t\tregisteredIds.delete(id);\n\t\t}\n\t}\n\n\tfor (const relay of file.relays) {\n\t\t// Only register relays that have at least one model; empty catalog is not selectable.\n\t\tif (relay.models.length === 0) {\n\t\t\tif (registeredIds.has(relay.id)) {\n\t\t\t\ttry {\n\t\t\t\t\tpi.unregisterProvider(relay.id);\n\t\t\t\t} catch {\n\t\t\t\t\t// ignore\n\t\t\t\t}\n\t\t\t\tregisteredIds.delete(relay.id);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tpi.registerProvider(relay.id, toProviderConfig(relay));\n\t\tregisteredIds.add(relay.id);\n\t}\n}\n\nexport function registerOneRelay(pi: ExtensionAPI, relay: RelayConfig): void {\n\tif (relay.models.length === 0) {\n\t\tif (registeredIds.has(relay.id)) {\n\t\t\ttry {\n\t\t\t\tpi.unregisterProvider(relay.id);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tregisteredIds.delete(relay.id);\n\t\t}\n\t\treturn;\n\t}\n\tpi.registerProvider(relay.id, toProviderConfig(relay));\n\tregisteredIds.add(relay.id);\n}\n\nexport function unregisterOneRelay(pi: ExtensionAPI, id: string): void {\n\ttry {\n\t\tpi.unregisterProvider(id);\n\t} catch {\n\t\t// ignore\n\t}\n\tregisteredIds.delete(id);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAoB,UAAU,EAAoB,MAAM,YAAY,CAAC;AAE9F,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAU1D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAqBvD;AA+CD,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BpE;AAeD,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAOzE;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAKjE"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAoB,UAAU,EAAoB,MAAM,YAAY,CAAC;AAE9F,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,CAU1D;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAqBvD;AA+CD,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BpE;AAeD,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAOzE;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAKjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/extensions/router/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Persistence for ~/.pi/agent/router.json\n */\n\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { withFileMutationQueue } from \"../../core/tools/file-mutation-queue.ts\";\nimport { CONFIG_VERSION, isValidRelayId } from \"./constants.ts\";\nimport type { RelayConfig, RelayModelConfig, RouterFile, ThinkingLevelMap } from \"./types.ts\";\n\nexport function getRouterConfigPath(): string {\n\treturn join(getAgentDir(), \"router.json\");\n}\n\nexport function emptyRouterFile(): RouterFile {\n\treturn { version: CONFIG_VERSION, relays: [] };\n}\n\nexport async function loadRouterFile(): Promise<RouterFile> {\n\tconst filePath = getRouterConfigPath();\n\tlet raw: string;\n\ttry {\n\t\traw = await readFile(filePath, \"utf8\");\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return emptyRouterFile();\n\t\tthrow error;\n\t}\n\treturn parseRouterFile(raw);\n}\n\nexport function parseRouterFile(raw: string): RouterFile {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch {\n\t\tthrow new Error(\"router.json is not valid JSON.\");\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(\"router.json must be a JSON object.\");\n\t}\n\tconst root = parsed as Record<string, unknown>;\n\tconst relaysRaw = root.relays;\n\tif (relaysRaw !== undefined && !Array.isArray(relaysRaw)) {\n\t\tthrow new Error(\"router.json relays must be an array.\");\n\t}\n\tconst relays: RelayConfig[] = [];\n\tfor (const item of relaysRaw ?? []) {\n\t\tconst relay = normalizeRelay(item);\n\t\tif (relay) relays.push(relay);\n\t}\n\treturn { version: CONFIG_VERSION, relays };\n}\n\nfunction normalizeRelay(value: unknown): RelayConfig | undefined {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tconst id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n\tconst baseUrl = typeof record.baseUrl === \"string\" ? record.baseUrl.trim() : \"\";\n\tconst apiKey = typeof record.apiKey === \"string\" ? record.apiKey : \"\";\n\tif (!id || !isValidRelayId(id) || !baseUrl) return undefined;\n\tconst models: RelayModelConfig[] = [];\n\tif (Array.isArray(record.models)) {\n\t\tfor (const model of record.models) {\n\t\t\tconst normalized = normalizeModel(model);\n\t\t\tif (normalized) models.push(normalized);\n\t\t}\n\t}\n\treturn { id, baseUrl, apiKey, models };\n}\n\nfunction normalizeModel(value: unknown): RelayModelConfig | undefined {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tconst id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n\tif (!id) return undefined;\n\tconst model: RelayModelConfig = { id };\n\tif (typeof record.name === \"string\" && record.name.trim()) model.name = record.name.trim();\n\tif (typeof record.reasoning === \"boolean\") model.reasoning = record.reasoning;\n\tif (Array.isArray(record.input)) {\n\t\tconst input = record.input.filter((item): item is \"text\" | \"image\" => item === \"text\" || item === \"image\");\n\t\tif (input.includes(\"text\")) model.input = input.includes(\"image\") ? [\"text\", \"image\"] : [\"text\"];\n\t}\n\tif (typeof record.contextWindow === \"number\" && Number.isFinite(record.contextWindow) && record.contextWindow > 0) {\n\t\tmodel.contextWindow = Math.floor(record.contextWindow);\n\t}\n\tif (typeof record.maxTokens === \"number\" && Number.isFinite(record.maxTokens) && record.maxTokens > 0) {\n\t\tmodel.maxTokens = Math.floor(record.maxTokens);\n\t}\n\tif (\n\t\trecord.thinkingLevelMap &&\n\t\ttypeof record.thinkingLevelMap === \"object\" &&\n\t\t!Array.isArray(record.thinkingLevelMap)\n\t) {\n\t\tmodel.thinkingLevelMap = record.thinkingLevelMap as ThinkingLevelMap;\n\t}\n\treturn model;\n}\n\nexport async function saveRouterFile(file: RouterFile): Promise<void> {\n\tconst filePath = getRouterConfigPath();\n\tconst payload: RouterFile = {\n\t\tversion: CONFIG_VERSION,\n\t\trelays: file.relays.map((relay) => ({\n\t\t\tid: relay.id,\n\t\t\tbaseUrl: relay.baseUrl,\n\t\t\tapiKey: relay.apiKey,\n\t\t\tmodels: relay.models.map((model) => serializeModel(model)),\n\t\t})),\n\t};\n\tconst serialized = `${JSON.stringify(payload, null, 2)}\\n`;\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tawait withFileMutationQueue(filePath, async () => {\n\t\tconst tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n\t\ttry {\n\t\t\tawait writeFile(tempPath, serialized, { encoding: \"utf8\", mode: 0o600 });\n\t\t\tawait rename(tempPath, filePath);\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait unlink(tempPath);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t});\n}\n\nfunction serializeModel(model: RelayModelConfig): RelayModelConfig {\n\tconst out: RelayModelConfig = { id: model.id };\n\tif (model.name) out.name = model.name;\n\tif (model.reasoning !== undefined) out.reasoning = model.reasoning;\n\tif (model.input) out.input = model.input;\n\tif (model.contextWindow !== undefined) out.contextWindow = model.contextWindow;\n\tif (model.maxTokens !== undefined) out.maxTokens = model.maxTokens;\n\tif (model.thinkingLevelMap && Object.keys(model.thinkingLevelMap).length > 0) {\n\t\tout.thinkingLevelMap = model.thinkingLevelMap;\n\t}\n\treturn out;\n}\n\nexport async function upsertRelay(relay: RelayConfig): Promise<RouterFile> {\n\tconst file = await loadRouterFile();\n\tconst index = file.relays.findIndex((entry) => entry.id === relay.id);\n\tif (index >= 0) file.relays[index] = relay;\n\telse file.relays.push(relay);\n\tawait saveRouterFile(file);\n\treturn file;\n}\n\nexport async function removeRelay(id: string): Promise<RouterFile> {\n\tconst file = await loadRouterFile();\n\tfile.relays = file.relays.filter((entry) => entry.id !== id);\n\tawait saveRouterFile(file);\n\treturn file;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/extensions/router/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhE,MAAM,UAAU,mBAAmB;IAClC,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,eAAe;IAC9B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IACnC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACJ,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,eAAe,EAAE,CAAC;QACjF,MAAM,KAAK,CAAC;IACb,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,IAAI,GAAG,MAAiC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC;IAC9B,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,SAAS,IAAI,EAAE,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,EAAE,GAAG,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,MAAM,OAAO,GAAG,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAChF,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,IAAI,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC7D,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,UAAU;gBAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;IACF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,EAAE,GAAG,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,IAAI,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC1B,MAAM,KAAK,GAAqB,EAAE,EAAE,EAAE,CAAC;IACvC,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3F,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IAC9E,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAA4B,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC;QAC3G,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;QACnH,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QACvG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IACD,IACC,MAAM,CAAC,gBAAgB;QACvB,OAAO,MAAM,CAAC,gBAAgB,KAAK,QAAQ;QAC3C,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,EACtC,CAAC;QACF,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAoC,CAAC;IACtE,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAgB;IACpD,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,OAAO,GAAe;QAC3B,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACnC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;SAC1D,CAAC,CAAC;KACH,CAAC;IACF,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,qBAAqB,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;QAChE,IAAI,CAAC;YACJ,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzE,MAAM,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC;gBACJ,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACR,SAAS;YACV,CAAC;YACD,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAuB;IAC9C,MAAM,GAAG,GAAqB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;IAC/C,IAAI,KAAK,CAAC,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACtC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnE,IAAI,KAAK,CAAC,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACzC,IAAI,KAAK,CAAC,aAAa,KAAK,SAAS;QAAE,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;IAC/E,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnE,IAAI,KAAK,CAAC,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9E,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAkB;IACnD,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,IAAI,KAAK,IAAI,CAAC;QAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAU;IAC3C,MAAM,IAAI,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["/**\n * Persistence for ~/.pi/agent/router.json\n */\n\nimport { mkdir, readFile, rename, unlink, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { getAgentDir } from \"../../config.ts\";\nimport { withFileMutationQueue } from \"../../core/tools/file-mutation-queue.ts\";\nimport { CONFIG_VERSION, isValidRelayId } from \"./constants.ts\";\nimport type { RelayConfig, RelayModelConfig, RouterFile, ThinkingLevelMap } from \"./types.ts\";\n\nexport function getRouterConfigPath(): string {\n\treturn join(getAgentDir(), \"router.json\");\n}\n\nexport function emptyRouterFile(): RouterFile {\n\treturn { version: CONFIG_VERSION, relays: [] };\n}\n\nexport async function loadRouterFile(): Promise<RouterFile> {\n\tconst filePath = getRouterConfigPath();\n\tlet raw: string;\n\ttry {\n\t\traw = await readFile(filePath, \"utf8\");\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return emptyRouterFile();\n\t\tthrow error;\n\t}\n\treturn parseRouterFile(raw);\n}\n\nexport function parseRouterFile(raw: string): RouterFile {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch {\n\t\tthrow new Error(\"router.json is not valid JSON.\");\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(\"router.json must be a JSON object.\");\n\t}\n\tconst root = parsed as Record<string, unknown>;\n\tconst relaysRaw = root.relays;\n\tif (relaysRaw !== undefined && !Array.isArray(relaysRaw)) {\n\t\tthrow new Error(\"router.json relays must be an array.\");\n\t}\n\tconst relays: RelayConfig[] = [];\n\tfor (const item of relaysRaw ?? []) {\n\t\tconst relay = normalizeRelay(item);\n\t\tif (relay) relays.push(relay);\n\t}\n\treturn { version: CONFIG_VERSION, relays };\n}\n\nfunction normalizeRelay(value: unknown): RelayConfig | undefined {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tconst id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n\tconst baseUrl = typeof record.baseUrl === \"string\" ? record.baseUrl.trim() : \"\";\n\tconst apiKey = typeof record.apiKey === \"string\" ? record.apiKey : \"\";\n\tif (!id || !isValidRelayId(id) || !baseUrl) return undefined;\n\tconst models: RelayModelConfig[] = [];\n\tif (Array.isArray(record.models)) {\n\t\tfor (const model of record.models) {\n\t\t\tconst normalized = normalizeModel(model);\n\t\t\tif (normalized) models.push(normalized);\n\t\t}\n\t}\n\treturn { id, baseUrl, apiKey, models };\n}\n\nfunction normalizeModel(value: unknown): RelayModelConfig | undefined {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\tconst record = value as Record<string, unknown>;\n\tconst id = typeof record.id === \"string\" ? record.id.trim() : \"\";\n\tif (!id) return undefined;\n\tconst model: RelayModelConfig = { id };\n\tif (typeof record.name === \"string\" && record.name.trim()) model.name = record.name.trim();\n\tif (typeof record.reasoning === \"boolean\") model.reasoning = record.reasoning;\n\tif (Array.isArray(record.input)) {\n\t\tconst input = record.input.filter((item): item is \"text\" | \"image\" => item === \"text\" || item === \"image\");\n\t\tif (input.includes(\"text\")) model.input = input.includes(\"image\") ? [\"text\", \"image\"] : [\"text\"];\n\t}\n\tif (typeof record.contextWindow === \"number\" && Number.isFinite(record.contextWindow) && record.contextWindow > 0) {\n\t\tmodel.contextWindow = Math.floor(record.contextWindow);\n\t}\n\tif (typeof record.maxTokens === \"number\" && Number.isFinite(record.maxTokens) && record.maxTokens > 0) {\n\t\tmodel.maxTokens = Math.floor(record.maxTokens);\n\t}\n\tif (\n\t\trecord.thinkingLevelMap &&\n\t\ttypeof record.thinkingLevelMap === \"object\" &&\n\t\t!Array.isArray(record.thinkingLevelMap)\n\t) {\n\t\tmodel.thinkingLevelMap = record.thinkingLevelMap as ThinkingLevelMap;\n\t}\n\treturn model;\n}\n\nexport async function saveRouterFile(file: RouterFile): Promise<void> {\n\tconst filePath = getRouterConfigPath();\n\tconst payload: RouterFile = {\n\t\tversion: CONFIG_VERSION,\n\t\trelays: file.relays.map((relay) => ({\n\t\t\tid: relay.id,\n\t\t\tbaseUrl: relay.baseUrl,\n\t\t\tapiKey: relay.apiKey,\n\t\t\tmodels: relay.models.map((model) => serializeModel(model)),\n\t\t})),\n\t};\n\tconst serialized = `${JSON.stringify(payload, null, 2)}\\n`;\n\tawait mkdir(dirname(filePath), { recursive: true });\n\tawait withFileMutationQueue(filePath, async () => {\n\t\tconst tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;\n\t\ttry {\n\t\t\tawait writeFile(tempPath, serialized, { encoding: \"utf8\", mode: 0o600 });\n\t\t\tawait rename(tempPath, filePath);\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait unlink(tempPath);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t});\n}\n\nfunction serializeModel(model: RelayModelConfig): RelayModelConfig {\n\tconst out: RelayModelConfig = { id: model.id };\n\tif (model.name) out.name = model.name;\n\tif (model.reasoning !== undefined) out.reasoning = model.reasoning;\n\tif (model.input) out.input = model.input;\n\tif (model.contextWindow !== undefined) out.contextWindow = model.contextWindow;\n\tif (model.maxTokens !== undefined) out.maxTokens = model.maxTokens;\n\tif (model.thinkingLevelMap && Object.keys(model.thinkingLevelMap).length > 0) {\n\t\tout.thinkingLevelMap = model.thinkingLevelMap;\n\t}\n\treturn out;\n}\n\nexport async function upsertRelay(relay: RelayConfig): Promise<RouterFile> {\n\tconst file = await loadRouterFile();\n\tconst index = file.relays.findIndex((entry) => entry.id === relay.id);\n\tif (index >= 0) file.relays[index] = relay;\n\telse file.relays.push(relay);\n\tawait saveRouterFile(file);\n\treturn file;\n}\n\nexport async function removeRelay(id: string): Promise<RouterFile> {\n\tconst file = await loadRouterFile();\n\tfile.relays = file.relays.filter((entry) => entry.id !== id);\n\tawait saveRouterFile(file);\n\treturn file;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACN,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,iCAAiC,EACjC,KAAK,KAAK,EAEV,KAAK,mBAAmB,EACxB,MAAM,8BAA8B,CAAC;AAMtC,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,UAAU,CAAC,OAAO,iCAAiC,CAAC,CA0EtD;AAiHD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyB/D;AAiED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD","sourcesContent":["/**\n * Codex-oriented Responses client for API relays.\n *\n * Follows Pi's documented custom-provider pattern (see coding-agent docs\n * providers.md / custom-provider.md and examples/custom-provider-gitlab-duo):\n * wrap a built-in pi-ai stream API from `@earendil-works/pi-ai/compat` instead of\n * reimplementing SSE or deep-importing internal modules.\n *\n * We use openAIResponsesApi (works with relay sk- keys) and reshape the request\n * payload toward Codex CLI style so transparent gateways receive a friendlier body.\n */\n\nimport {\n\ttype Api,\n\ttype Context,\n\tcreateAssistantMessageEventStream,\n\ttype Model,\n\topenAIResponsesApi,\n\ttype SimpleStreamOptions,\n} from \"@earendil-works/pi-ai/compat\";\n\nimport { DEFAULTS, formatError, ROUTER_API } from \"./constants.ts\";\n\nconst responsesApi = openAIResponsesApi();\n\nexport function streamRouterCodex(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): ReturnType<typeof createAssistantMessageEventStream> {\n\tconst stream = createAssistantMessageEventStream();\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);\n\n\t\t\t// Built-in Responses stream expects api \"openai-responses\" on the model object.\n\t\t\tconst requestModel = {\n\t\t\t\t...model,\n\t\t\t\tapi: \"openai-responses\" as const,\n\t\t\t\tcompat: {\n\t\t\t\t\tsupportsDeveloperRole: true,\n\t\t\t\t\t// Avoid underscore session_id header that strict proxies reject.\n\t\t\t\t\tsessionAffinityFormat: \"openai-nosession\" as const,\n\t\t\t\t\t// Codex-style upstreams reject prompt_cache_retention: \"24h\".\n\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t\t...(model.compat ?? {}),\n\t\t\t\t},\n\t\t\t} as Model<\"openai-responses\">;\n\n\t\t\tconst headers: Record<string, string> = {\n\t\t\t\toriginator: DEFAULTS.originator,\n\t\t\t\t...(options?.headers as Record<string, string> | undefined),\n\t\t\t};\n\n\t\t\t// Prefer hyphenated Codex-style session affinity when we have a session id.\n\t\t\tconst sessionId = clampCacheKey(options?.sessionId);\n\t\t\tif (sessionId) {\n\t\t\t\tif (!headers[\"session-id\"]) headers[\"session-id\"] = sessionId;\n\t\t\t\tif (!headers[\"x-client-request-id\"]) headers[\"x-client-request-id\"] = sessionId;\n\t\t\t}\n\n\t\t\tconst inner = responsesApi.streamSimple(requestModel, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey,\n\t\t\t\theaders,\n\t\t\t\tonPayload: (payload) => reshapePayloadForRelay(payload, context, options?.onPayload, requestModel),\n\t\t\t});\n\n\t\t\tfor await (const event of inner) {\n\t\t\t\tstream.push(event);\n\t\t\t}\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\t// Match examples/custom-provider-gitlab-duo error event shape.\n\t\t\tstream.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\treason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\terror: {\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: [],\n\t\t\t\t\tapi: model.api,\n\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\tmodel: model.id,\n\t\t\t\t\tusage: {\n\t\t\t\t\t\tinput: 0,\n\t\t\t\t\t\toutput: 0,\n\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\ttotalTokens: 0,\n\t\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t\t},\n\t\t\t\t\tstopReason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\t\terrorMessage: formatError(error),\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Nudge the OpenAI Responses payload toward Codex CLI request shape for\n * transparent relays: instructions + input, store:false, no max_output_tokens /\n * prompt_cache_retention, verbosity + parallel_tool_calls.\n */\nasync function reshapePayloadForRelay(\n\tpayload: unknown,\n\tcontext: Context,\n\tuserOnPayload: SimpleStreamOptions[\"onPayload\"],\n\tmodel: Model<\"openai-responses\">,\n): Promise<unknown> {\n\tconst base =\n\t\tpayload && typeof payload === \"object\" && !Array.isArray(payload)\n\t\t\t? { ...(payload as Record<string, unknown>) }\n\t\t\t: ({} as Record<string, unknown>);\n\n\t// Always safe for ChatGPT/Codex-style backends.\n\tbase.store = false;\n\tbase.stream = true;\n\n\t// Codex CLI sends system prompt as `instructions`, not as a role message in input.\n\tconst { instructions, input } = extractInstructions(base.input, context.systemPrompt);\n\tif (instructions) base.instructions = instructions;\n\tif (input !== undefined) base.input = input;\n\n\t// Released Codex CLI defaults omit replayed ResponseItem ids from store:false\n\t// requests. It also never emits `status` on the item types below, and its\n\t// output_text content has no `annotations`.\n\tsanitizeInputItemsForCodex(base.input);\n\n\t// Fields common on Codex CLI / rejected by many transparent Codex upstreams.\n\tif (!base.text || typeof base.text !== \"object\") {\n\t\tbase.text = { verbosity: \"low\" };\n\t}\n\tif (base.tool_choice === undefined) base.tool_choice = \"auto\";\n\tif (base.parallel_tool_calls === undefined) base.parallel_tool_calls = true;\n\n\t// Prefer encrypted reasoning content for multi-turn store:false sessions.\n\tconst include = Array.isArray(base.include) ? [...(base.include as unknown[])] : [];\n\tif (!include.includes(\"reasoning.encrypted_content\")) {\n\t\tinclude.push(\"reasoning.encrypted_content\");\n\t}\n\tbase.include = include;\n\n\t// Drop Platform-only fields that Codex OAuth endpoints often 400 on.\n\tdelete base.prompt_cache_retention;\n\tdelete base.prompt_cache_options;\n\tdelete base.max_output_tokens;\n\tdelete base.temperature;\n\tdelete base.top_p;\n\tdelete base.user;\n\tdelete base.metadata;\n\tdelete base.service_tier;\n\tdelete base.truncation;\n\tdelete base.context_management;\n\tdelete base.safety_identifier;\n\tdelete base.stream_options;\n\n\tif (userOnPayload) {\n\t\tconst next = await userOnPayload(base, model);\n\t\tif (next !== undefined) return next;\n\t}\n\treturn base;\n}\n\n/**\n * Match the released Codex CLI's default stateless request preparation:\n * optional ResponseItem identity ids are omitted from store:false requests,\n * while semantic ids, call_id, and encrypted_content remain available for\n * reference, tool, and reasoning continuity.\n *\n * These are the tagged variants handled by ResponseItem::set_id in Codex CLI\n * 0.145. Unknown input variants must retain `id`: for example,\n * item_reference.id and local_shell_call_output.id are required references,\n * not optional ResponseItem identities.\n */\nconst RESPONSE_ITEM_ID_TYPES = new Set([\n\t\"additional_tools\",\n\t\"message\",\n\t\"agent_message\",\n\t\"reasoning\",\n\t\"local_shell_call\",\n\t\"function_call\",\n\t\"tool_search_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call\",\n\t\"custom_tool_call_output\",\n\t\"tool_search_output\",\n\t\"web_search_call\",\n\t\"image_generation_call\",\n\t\"compaction\",\n\t\"compaction_summary\",\n\t\"context_compaction\",\n]);\n\n/**\n * Codex ResponseItem serialization has NO `status` field on Message,\n * Reasoning, FunctionCall, FunctionCallOutput, or CustomToolCallOutput\n * (codex-rs/protocol/src/models.rs). Other item types either require `status`\n * (local_shell_call, tool_search_output, image_generation_call) or accept it\n * optionally (tool_search_call, custom_tool_call, web_search_call), so we must\n * not strip it there.\n */\nconst STATUS_LESS_ITEM_TYPES = new Set([\n\t\"message\",\n\t\"reasoning\",\n\t\"function_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call_output\",\n]);\n\nexport function sanitizeInputItemsForCodex(input: unknown): void {\n\tif (!Array.isArray(input)) return;\n\tfor (const item of input) {\n\t\tif (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst type = typeof record.type === \"string\" ? record.type : undefined;\n\t\tif (type && RESPONSE_ITEM_ID_TYPES.has(type)) {\n\t\t\tdelete record.id;\n\t\t}\n\t\tif (type && STATUS_LESS_ITEM_TYPES.has(type) && \"status\" in record) {\n\t\t\tdelete record.status;\n\t\t}\n\t\tif (Array.isArray(record.content)) {\n\t\t\tfor (const part of record.content) {\n\t\t\t\tif (\n\t\t\t\t\tpart &&\n\t\t\t\t\ttypeof part === \"object\" &&\n\t\t\t\t\t(part as { type?: string }).type === \"output_text\" &&\n\t\t\t\t\t\"annotations\" in part\n\t\t\t\t) {\n\t\t\t\t\tdelete (part as Record<string, unknown>).annotations;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction extractInstructions(\n\tinput: unknown,\n\tsystemPrompt: string | undefined,\n): { instructions?: string; input: unknown } {\n\t// Prefer context.systemPrompt (matches Codex stream path).\n\tif (systemPrompt && systemPrompt.length > 0) {\n\t\tconst stripped = stripLeadingSystemRoles(input);\n\t\treturn { instructions: systemPrompt, input: stripped ?? input };\n\t}\n\n\tif (!Array.isArray(input) || input.length === 0) {\n\t\treturn { input };\n\t}\n\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t\"role\" in first &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\tconst content = (first as { content?: unknown }).content;\n\t\tconst text =\n\t\t\ttypeof content === \"string\"\n\t\t\t\t? content\n\t\t\t\t: Array.isArray(content)\n\t\t\t\t\t? content\n\t\t\t\t\t\t\t.map((part) =>\n\t\t\t\t\t\t\t\tpart && typeof part === \"object\" && \"text\" in part\n\t\t\t\t\t\t\t\t\t? String((part as { text: unknown }).text)\n\t\t\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join(\"\")\n\t\t\t\t\t: \"\";\n\t\treturn {\n\t\t\tinstructions: text || undefined,\n\t\t\tinput: input.slice(1),\n\t\t};\n\t}\n\n\treturn { input };\n}\n\nfunction stripLeadingSystemRoles(input: unknown): unknown {\n\tif (!Array.isArray(input) || input.length === 0) return input;\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\treturn input.slice(1);\n\t}\n\treturn input;\n}\n\nfunction clampCacheKey(sessionId: string | undefined): string | undefined {\n\tif (!sessionId) return undefined;\n\treturn sessionId.length <= 64 ? sessionId : sessionId.slice(0, 64);\n}\n\nexport function resolveResponsesUrl(baseUrl: string): string {\n\tconst normalized = baseUrl.trim().replace(/\\/+$/, \"\");\n\tif (!normalized) throw new Error(\"Model baseUrl is empty.\");\n\tif (normalized.endsWith(\"/responses\")) return normalized;\n\treturn `${normalized}/responses`;\n}\n\nexport function isRouterApi(api: string): boolean {\n\treturn api === ROUTER_API;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACN,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,iCAAiC,EACjC,KAAK,KAAK,EAEV,KAAK,mBAAmB,EACxB,MAAM,8BAA8B,CAAC;AAMtC,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC3B,UAAU,CAAC,OAAO,iCAAiC,CAAC,CA0EtD;AAiHD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAyB/D;AAiED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../src/extensions/router/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAGN,iCAAiC,EAEjC,kBAAkB,GAElB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEnE,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;AAE1C,MAAM,UAAU,iBAAiB,CAChC,KAAiB,EACjB,OAAgB,EAChB,OAA6B,EAC0B;IACvD,MAAM,MAAM,GAAG,iCAAiC,EAAE,CAAC;IAEnD,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;YAC/B,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAE3E,gFAAgF;YAChF,MAAM,YAAY,GAAG;gBACpB,GAAG,KAAK;gBACR,GAAG,EAAE,kBAA2B;gBAChC,MAAM,EAAE;oBACP,qBAAqB,EAAE,IAAI;oBAC3B,iEAAiE;oBACjE,qBAAqB,EAAE,kBAA2B;oBAClD,8DAA8D;oBAC9D,0BAA0B,EAAE,KAAK;oBACjC,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;iBACvB;aAC4B,CAAC;YAE/B,MAAM,OAAO,GAA2B;gBACvC,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,GAAI,OAAO,EAAE,OAA8C;aAC3D,CAAC;YAEF,4EAA4E;YAC5E,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpD,IAAI,SAAS,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;oBAAE,OAAO,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAC9D,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC;oBAAE,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,CAAC;YACjF,CAAC;YAED,MAAM,KAAK,GAAG,YAAY,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,EAAE;gBAC9D,GAAG,OAAO;gBACV,MAAM;gBACN,OAAO;gBACP,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC;aAClG,CAAC,CAAC;YAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;YACD,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,+DAA+D;YAC/D,MAAM,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBACtD,KAAK,EAAE;oBACN,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,EAAE;oBACX,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,KAAK,EAAE,KAAK,CAAC,EAAE;oBACf,KAAK,EAAE;wBACN,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,CAAC;wBACT,SAAS,EAAE,CAAC;wBACZ,UAAU,EAAE,CAAC;wBACb,WAAW,EAAE,CAAC;wBACd,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;qBACpE;oBACD,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;oBAC1D,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC;oBAChC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACrB;aACD,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,EAAE,CAAC;QACd,CAAC;IAAA,CACD,CAAC,EAAE,CAAC;IAEL,OAAO,MAAM,CAAC;AAAA,CACd;AAED;;;;GAIG;AACH,KAAK,UAAU,sBAAsB,CACpC,OAAgB,EAChB,OAAgB,EAChB,aAA+C,EAC/C,KAAgC,EACb;IACnB,MAAM,IAAI,GACT,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAChE,CAAC,CAAC,EAAE,GAAI,OAAmC,EAAE;QAC7C,CAAC,CAAE,EAA8B,CAAC;IAEpC,gDAAgD;IAChD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IAEnB,mFAAmF;IACnF,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACtF,IAAI,YAAY;QAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAE5C,8EAA8E;IAC9E,0EAA0E;IAC1E,4CAA4C;IAC5C,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEvC,6EAA6E;IAC7E,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAClC,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC9D,IAAI,IAAI,CAAC,mBAAmB,KAAK,SAAS;QAAE,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAE5E,0EAA0E;IAC1E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAI,IAAI,CAAC,OAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAEvB,qEAAqE;IACrE,OAAO,IAAI,CAAC,sBAAsB,CAAC;IACnC,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACjC,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAC9B,OAAO,IAAI,CAAC,WAAW,CAAC;IACxB,OAAO,IAAI,CAAC,KAAK,CAAC;IAClB,OAAO,IAAI,CAAC,IAAI,CAAC;IACjB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IACzB,OAAO,IAAI,CAAC,UAAU,CAAC;IACvB,OAAO,IAAI,CAAC,kBAAkB,CAAC;IAC/B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAC9B,OAAO,IAAI,CAAC,cAAc,CAAC;IAE3B,IAAI,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED;;;;;;;;;;GAUG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACtC,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,WAAW;IACX,kBAAkB;IAClB,eAAe;IACf,kBAAkB;IAClB,sBAAsB;IACtB,kBAAkB;IAClB,yBAAyB;IACzB,oBAAoB;IACpB,iBAAiB;IACjB,uBAAuB;IACvB,YAAY;IACZ,oBAAoB;IACpB,oBAAoB;CACpB,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACtC,SAAS;IACT,WAAW;IACX,eAAe;IACf,sBAAsB;IACtB,yBAAyB;CACzB,CAAC,CAAC;AAEH,MAAM,UAAU,0BAA0B,CAAC,KAAc,EAAQ;IAChE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,SAAS;QACvE,MAAM,MAAM,GAAG,IAA+B,CAAC;QAC/C,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACvE,IAAI,IAAI,IAAI,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,OAAO,MAAM,CAAC,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,IAAI,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,MAAM,CAAC;QACtB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,IACC,IAAI;oBACJ,OAAO,IAAI,KAAK,QAAQ;oBACvB,IAA0B,CAAC,IAAI,KAAK,aAAa;oBAClD,aAAa,IAAI,IAAI,EACpB,CAAC;oBACF,OAAQ,IAAgC,CAAC,WAAW,CAAC;gBACtD,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;AAAA,CACD;AAED,SAAS,mBAAmB,CAC3B,KAAc,EACd,YAAgC,EACY;IAC5C,2DAA2D;IAC3D,IAAI,YAAY,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IACC,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,MAAM,IAAI,KAAK;QACf,CAAE,KAA2B,CAAC,IAAI,KAAK,QAAQ,IAAK,KAA2B,CAAC,IAAI,KAAK,WAAW,CAAC,EACpG,CAAC;QACF,MAAM,OAAO,GAAI,KAA+B,CAAC,OAAO,CAAC;QACzD,MAAM,IAAI,GACT,OAAO,OAAO,KAAK,QAAQ;YAC1B,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;gBACvB,CAAC,CAAC,OAAO;qBACN,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI;oBACjD,CAAC,CAAC,MAAM,CAAE,IAA0B,CAAC,IAAI,CAAC;oBAC1C,CAAC,CAAC,EAAE,CACL;qBACA,IAAI,CAAC,EAAE,CAAC;gBACX,CAAC,CAAC,EAAE,CAAC;QACR,OAAO;YACN,YAAY,EAAE,IAAI,IAAI,SAAS;YAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;SACrB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC;AAAA,CACjB;AAED,SAAS,uBAAuB,CAAC,KAAc,EAAW;IACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,IACC,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,CAAE,KAA2B,CAAC,IAAI,KAAK,QAAQ,IAAK,KAA2B,CAAC,IAAI,KAAK,WAAW,CAAC,EACpG,CAAC;QACF,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,SAAS,aAAa,CAAC,SAA6B,EAAsB;IACzE,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAAA,CACnE;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAU;IAC5D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC5D,IAAI,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,UAAU,CAAC;IACzD,OAAO,GAAG,UAAU,YAAY,CAAC;AAAA,CACjC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW,EAAW;IACjD,OAAO,GAAG,KAAK,UAAU,CAAC;AAAA,CAC1B","sourcesContent":["/**\n * Codex-oriented Responses client for API relays.\n *\n * Follows Pi's documented custom-provider pattern (see coding-agent docs\n * providers.md / custom-provider.md and examples/custom-provider-gitlab-duo):\n * wrap a built-in pi-ai stream API from `@earendil-works/pi-ai/compat` instead of\n * reimplementing SSE or deep-importing internal modules.\n *\n * We use openAIResponsesApi (works with relay sk- keys) and reshape the request\n * payload toward Codex CLI style so transparent gateways receive a friendlier body.\n */\n\nimport {\n\ttype Api,\n\ttype Context,\n\tcreateAssistantMessageEventStream,\n\ttype Model,\n\topenAIResponsesApi,\n\ttype SimpleStreamOptions,\n} from \"@earendil-works/pi-ai/compat\";\n\nimport { DEFAULTS, formatError, ROUTER_API } from \"./constants.ts\";\n\nconst responsesApi = openAIResponsesApi();\n\nexport function streamRouterCodex(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): ReturnType<typeof createAssistantMessageEventStream> {\n\tconst stream = createAssistantMessageEventStream();\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);\n\n\t\t\t// Built-in Responses stream expects api \"openai-responses\" on the model object.\n\t\t\tconst requestModel = {\n\t\t\t\t...model,\n\t\t\t\tapi: \"openai-responses\" as const,\n\t\t\t\tcompat: {\n\t\t\t\t\tsupportsDeveloperRole: true,\n\t\t\t\t\t// Avoid underscore session_id header that strict proxies reject.\n\t\t\t\t\tsessionAffinityFormat: \"openai-nosession\" as const,\n\t\t\t\t\t// Codex-style upstreams reject prompt_cache_retention: \"24h\".\n\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t\t...(model.compat ?? {}),\n\t\t\t\t},\n\t\t\t} as Model<\"openai-responses\">;\n\n\t\t\tconst headers: Record<string, string> = {\n\t\t\t\toriginator: DEFAULTS.originator,\n\t\t\t\t...(options?.headers as Record<string, string> | undefined),\n\t\t\t};\n\n\t\t\t// Prefer hyphenated Codex-style session affinity when we have a session id.\n\t\t\tconst sessionId = clampCacheKey(options?.sessionId);\n\t\t\tif (sessionId) {\n\t\t\t\tif (!headers[\"session-id\"]) headers[\"session-id\"] = sessionId;\n\t\t\t\tif (!headers[\"x-client-request-id\"]) headers[\"x-client-request-id\"] = sessionId;\n\t\t\t}\n\n\t\t\tconst inner = responsesApi.streamSimple(requestModel, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey,\n\t\t\t\theaders,\n\t\t\t\tonPayload: (payload) => reshapePayloadForRelay(payload, context, options?.onPayload, requestModel),\n\t\t\t});\n\n\t\t\tfor await (const event of inner) {\n\t\t\t\tstream.push(event);\n\t\t\t}\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\t// Match examples/custom-provider-gitlab-duo error event shape.\n\t\t\tstream.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\treason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\terror: {\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: [],\n\t\t\t\t\tapi: model.api,\n\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\tmodel: model.id,\n\t\t\t\t\tusage: {\n\t\t\t\t\t\tinput: 0,\n\t\t\t\t\t\toutput: 0,\n\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\ttotalTokens: 0,\n\t\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t\t},\n\t\t\t\t\tstopReason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\t\terrorMessage: formatError(error),\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Nudge the OpenAI Responses payload toward Codex CLI request shape for\n * transparent relays: instructions + input, store:false, no max_output_tokens /\n * prompt_cache_retention, verbosity + parallel_tool_calls.\n */\nasync function reshapePayloadForRelay(\n\tpayload: unknown,\n\tcontext: Context,\n\tuserOnPayload: SimpleStreamOptions[\"onPayload\"],\n\tmodel: Model<\"openai-responses\">,\n): Promise<unknown> {\n\tconst base =\n\t\tpayload && typeof payload === \"object\" && !Array.isArray(payload)\n\t\t\t? { ...(payload as Record<string, unknown>) }\n\t\t\t: ({} as Record<string, unknown>);\n\n\t// Always safe for ChatGPT/Codex-style backends.\n\tbase.store = false;\n\tbase.stream = true;\n\n\t// Codex CLI sends system prompt as `instructions`, not as a role message in input.\n\tconst { instructions, input } = extractInstructions(base.input, context.systemPrompt);\n\tif (instructions) base.instructions = instructions;\n\tif (input !== undefined) base.input = input;\n\n\t// Released Codex CLI defaults omit replayed ResponseItem ids from store:false\n\t// requests. It also never emits `status` on the item types below, and its\n\t// output_text content has no `annotations`.\n\tsanitizeInputItemsForCodex(base.input);\n\n\t// Fields common on Codex CLI / rejected by many transparent Codex upstreams.\n\tif (!base.text || typeof base.text !== \"object\") {\n\t\tbase.text = { verbosity: \"low\" };\n\t}\n\tif (base.tool_choice === undefined) base.tool_choice = \"auto\";\n\tif (base.parallel_tool_calls === undefined) base.parallel_tool_calls = true;\n\n\t// Prefer encrypted reasoning content for multi-turn store:false sessions.\n\tconst include = Array.isArray(base.include) ? [...(base.include as unknown[])] : [];\n\tif (!include.includes(\"reasoning.encrypted_content\")) {\n\t\tinclude.push(\"reasoning.encrypted_content\");\n\t}\n\tbase.include = include;\n\n\t// Drop Platform-only fields that Codex OAuth endpoints often 400 on.\n\tdelete base.prompt_cache_retention;\n\tdelete base.prompt_cache_options;\n\tdelete base.max_output_tokens;\n\tdelete base.temperature;\n\tdelete base.top_p;\n\tdelete base.user;\n\tdelete base.metadata;\n\tdelete base.service_tier;\n\tdelete base.truncation;\n\tdelete base.context_management;\n\tdelete base.safety_identifier;\n\tdelete base.stream_options;\n\n\tif (userOnPayload) {\n\t\tconst next = await userOnPayload(base, model);\n\t\tif (next !== undefined) return next;\n\t}\n\treturn base;\n}\n\n/**\n * Match the released Codex CLI's default stateless request preparation:\n * optional ResponseItem identity ids are omitted from store:false requests,\n * while semantic ids, call_id, and encrypted_content remain available for\n * reference, tool, and reasoning continuity.\n *\n * These are the tagged variants handled by ResponseItem::set_id in Codex CLI\n * 0.145. Unknown input variants must retain `id`: for example,\n * item_reference.id and local_shell_call_output.id are required references,\n * not optional ResponseItem identities.\n */\nconst RESPONSE_ITEM_ID_TYPES = new Set([\n\t\"additional_tools\",\n\t\"message\",\n\t\"agent_message\",\n\t\"reasoning\",\n\t\"local_shell_call\",\n\t\"function_call\",\n\t\"tool_search_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call\",\n\t\"custom_tool_call_output\",\n\t\"tool_search_output\",\n\t\"web_search_call\",\n\t\"image_generation_call\",\n\t\"compaction\",\n\t\"compaction_summary\",\n\t\"context_compaction\",\n]);\n\n/**\n * Codex ResponseItem serialization has NO `status` field on Message,\n * Reasoning, FunctionCall, FunctionCallOutput, or CustomToolCallOutput\n * (codex-rs/protocol/src/models.rs). Other item types either require `status`\n * (local_shell_call, tool_search_output, image_generation_call) or accept it\n * optionally (tool_search_call, custom_tool_call, web_search_call), so we must\n * not strip it there.\n */\nconst STATUS_LESS_ITEM_TYPES = new Set([\n\t\"message\",\n\t\"reasoning\",\n\t\"function_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call_output\",\n]);\n\nexport function sanitizeInputItemsForCodex(input: unknown): void {\n\tif (!Array.isArray(input)) return;\n\tfor (const item of input) {\n\t\tif (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst type = typeof record.type === \"string\" ? record.type : undefined;\n\t\tif (type && RESPONSE_ITEM_ID_TYPES.has(type)) {\n\t\t\tdelete record.id;\n\t\t}\n\t\tif (type && STATUS_LESS_ITEM_TYPES.has(type) && \"status\" in record) {\n\t\t\tdelete record.status;\n\t\t}\n\t\tif (Array.isArray(record.content)) {\n\t\t\tfor (const part of record.content) {\n\t\t\t\tif (\n\t\t\t\t\tpart &&\n\t\t\t\t\ttypeof part === \"object\" &&\n\t\t\t\t\t(part as { type?: string }).type === \"output_text\" &&\n\t\t\t\t\t\"annotations\" in part\n\t\t\t\t) {\n\t\t\t\t\tdelete (part as Record<string, unknown>).annotations;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction extractInstructions(\n\tinput: unknown,\n\tsystemPrompt: string | undefined,\n): { instructions?: string; input: unknown } {\n\t// Prefer context.systemPrompt (matches Codex stream path).\n\tif (systemPrompt && systemPrompt.length > 0) {\n\t\tconst stripped = stripLeadingSystemRoles(input);\n\t\treturn { instructions: systemPrompt, input: stripped ?? input };\n\t}\n\n\tif (!Array.isArray(input) || input.length === 0) {\n\t\treturn { input };\n\t}\n\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t\"role\" in first &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\tconst content = (first as { content?: unknown }).content;\n\t\tconst text =\n\t\t\ttypeof content === \"string\"\n\t\t\t\t? content\n\t\t\t\t: Array.isArray(content)\n\t\t\t\t\t? content\n\t\t\t\t\t\t\t.map((part) =>\n\t\t\t\t\t\t\t\tpart && typeof part === \"object\" && \"text\" in part\n\t\t\t\t\t\t\t\t\t? String((part as { text: unknown }).text)\n\t\t\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join(\"\")\n\t\t\t\t\t: \"\";\n\t\treturn {\n\t\t\tinstructions: text || undefined,\n\t\t\tinput: input.slice(1),\n\t\t};\n\t}\n\n\treturn { input };\n}\n\nfunction stripLeadingSystemRoles(input: unknown): unknown {\n\tif (!Array.isArray(input) || input.length === 0) return input;\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\treturn input.slice(1);\n\t}\n\treturn input;\n}\n\nfunction clampCacheKey(sessionId: string | undefined): string | undefined {\n\tif (!sessionId) return undefined;\n\treturn sessionId.length <= 64 ? sessionId : sessionId.slice(0, 64);\n}\n\nexport function resolveResponsesUrl(baseUrl: string): string {\n\tconst normalized = baseUrl.trim().replace(/\\/+$/, \"\");\n\tif (!normalized) throw new Error(\"Model baseUrl is empty.\");\n\tif (normalized.endsWith(\"/responses\")) return normalized;\n\treturn `${normalized}/responses`;\n}\n\nexport function isRouterApi(api: string): boolean {\n\treturn api === ROUTER_API;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../../src/extensions/router/stream.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Codex-oriented Responses client for API relays.\n *\n * Follows Pi's documented custom-provider pattern (see coding-agent docs\n * providers.md / custom-provider.md and examples/custom-provider-gitlab-duo):\n * wrap a built-in pi-ai stream API from `@earendil-works/pi-ai/compat` instead of\n * reimplementing SSE or deep-importing internal modules.\n *\n * We use openAIResponsesApi (works with relay sk- keys) and reshape the request\n * payload toward Codex CLI style so transparent gateways receive a friendlier body.\n */\n\nimport {\n\ttype Api,\n\ttype Context,\n\tcreateAssistantMessageEventStream,\n\ttype Model,\n\topenAIResponsesApi,\n\ttype SimpleStreamOptions,\n} from \"@earendil-works/pi-ai/compat\";\n\nimport { DEFAULTS, formatError, ROUTER_API } from \"./constants.ts\";\n\nconst responsesApi = openAIResponsesApi();\n\nexport function streamRouterCodex(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): ReturnType<typeof createAssistantMessageEventStream> {\n\tconst stream = createAssistantMessageEventStream();\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) throw new Error(`No API key for provider: ${model.provider}`);\n\n\t\t\t// Built-in Responses stream expects api \"openai-responses\" on the model object.\n\t\t\tconst requestModel = {\n\t\t\t\t...model,\n\t\t\t\tapi: \"openai-responses\" as const,\n\t\t\t\tcompat: {\n\t\t\t\t\tsupportsDeveloperRole: true,\n\t\t\t\t\t// Avoid underscore session_id header that strict proxies reject.\n\t\t\t\t\tsessionAffinityFormat: \"openai-nosession\" as const,\n\t\t\t\t\t// Codex-style upstreams reject prompt_cache_retention: \"24h\".\n\t\t\t\t\tsupportsLongCacheRetention: false,\n\t\t\t\t\t...(model.compat ?? {}),\n\t\t\t\t},\n\t\t\t} as Model<\"openai-responses\">;\n\n\t\t\tconst headers: Record<string, string> = {\n\t\t\t\toriginator: DEFAULTS.originator,\n\t\t\t\t...(options?.headers as Record<string, string> | undefined),\n\t\t\t};\n\n\t\t\t// Prefer hyphenated Codex-style session affinity when we have a session id.\n\t\t\tconst sessionId = clampCacheKey(options?.sessionId);\n\t\t\tif (sessionId) {\n\t\t\t\tif (!headers[\"session-id\"]) headers[\"session-id\"] = sessionId;\n\t\t\t\tif (!headers[\"x-client-request-id\"]) headers[\"x-client-request-id\"] = sessionId;\n\t\t\t}\n\n\t\t\tconst inner = responsesApi.streamSimple(requestModel, context, {\n\t\t\t\t...options,\n\t\t\t\tapiKey,\n\t\t\t\theaders,\n\t\t\t\tonPayload: (payload) => reshapePayloadForRelay(payload, context, options?.onPayload, requestModel),\n\t\t\t});\n\n\t\t\tfor await (const event of inner) {\n\t\t\t\tstream.push(event);\n\t\t\t}\n\t\t\tstream.end();\n\t\t} catch (error) {\n\t\t\t// Match examples/custom-provider-gitlab-duo error event shape.\n\t\t\tstream.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\treason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\terror: {\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\tcontent: [],\n\t\t\t\t\tapi: model.api,\n\t\t\t\t\tprovider: model.provider,\n\t\t\t\t\tmodel: model.id,\n\t\t\t\t\tusage: {\n\t\t\t\t\t\tinput: 0,\n\t\t\t\t\t\toutput: 0,\n\t\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\t\ttotalTokens: 0,\n\t\t\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t\t\t},\n\t\t\t\t\tstopReason: options?.signal?.aborted ? \"aborted\" : \"error\",\n\t\t\t\t\terrorMessage: formatError(error),\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tstream.end();\n\t\t}\n\t})();\n\n\treturn stream;\n}\n\n/**\n * Nudge the OpenAI Responses payload toward Codex CLI request shape for\n * transparent relays: instructions + input, store:false, no max_output_tokens /\n * prompt_cache_retention, verbosity + parallel_tool_calls.\n */\nasync function reshapePayloadForRelay(\n\tpayload: unknown,\n\tcontext: Context,\n\tuserOnPayload: SimpleStreamOptions[\"onPayload\"],\n\tmodel: Model<\"openai-responses\">,\n): Promise<unknown> {\n\tconst base =\n\t\tpayload && typeof payload === \"object\" && !Array.isArray(payload)\n\t\t\t? { ...(payload as Record<string, unknown>) }\n\t\t\t: ({} as Record<string, unknown>);\n\n\t// Always safe for ChatGPT/Codex-style backends.\n\tbase.store = false;\n\tbase.stream = true;\n\n\t// Codex CLI sends system prompt as `instructions`, not as a role message in input.\n\tconst { instructions, input } = extractInstructions(base.input, context.systemPrompt);\n\tif (instructions) base.instructions = instructions;\n\tif (input !== undefined) base.input = input;\n\n\t// Released Codex CLI defaults omit replayed ResponseItem ids from store:false\n\t// requests. It also never emits `status` on the item types below, and its\n\t// output_text content has no `annotations`.\n\tsanitizeInputItemsForCodex(base.input);\n\n\t// Fields common on Codex CLI / rejected by many transparent Codex upstreams.\n\tif (!base.text || typeof base.text !== \"object\") {\n\t\tbase.text = { verbosity: \"low\" };\n\t}\n\tif (base.tool_choice === undefined) base.tool_choice = \"auto\";\n\tif (base.parallel_tool_calls === undefined) base.parallel_tool_calls = true;\n\n\t// Prefer encrypted reasoning content for multi-turn store:false sessions.\n\tconst include = Array.isArray(base.include) ? [...(base.include as unknown[])] : [];\n\tif (!include.includes(\"reasoning.encrypted_content\")) {\n\t\tinclude.push(\"reasoning.encrypted_content\");\n\t}\n\tbase.include = include;\n\n\t// Drop Platform-only fields that Codex OAuth endpoints often 400 on.\n\tdelete base.prompt_cache_retention;\n\tdelete base.prompt_cache_options;\n\tdelete base.max_output_tokens;\n\tdelete base.temperature;\n\tdelete base.top_p;\n\tdelete base.user;\n\tdelete base.metadata;\n\tdelete base.service_tier;\n\tdelete base.truncation;\n\tdelete base.context_management;\n\tdelete base.safety_identifier;\n\tdelete base.stream_options;\n\n\tif (userOnPayload) {\n\t\tconst next = await userOnPayload(base, model);\n\t\tif (next !== undefined) return next;\n\t}\n\treturn base;\n}\n\n/**\n * Match the released Codex CLI's default stateless request preparation:\n * optional ResponseItem identity ids are omitted from store:false requests,\n * while semantic ids, call_id, and encrypted_content remain available for\n * reference, tool, and reasoning continuity.\n *\n * These are the tagged variants handled by ResponseItem::set_id in Codex CLI\n * 0.145. Unknown input variants must retain `id`: for example,\n * item_reference.id and local_shell_call_output.id are required references,\n * not optional ResponseItem identities.\n */\nconst RESPONSE_ITEM_ID_TYPES = new Set([\n\t\"additional_tools\",\n\t\"message\",\n\t\"agent_message\",\n\t\"reasoning\",\n\t\"local_shell_call\",\n\t\"function_call\",\n\t\"tool_search_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call\",\n\t\"custom_tool_call_output\",\n\t\"tool_search_output\",\n\t\"web_search_call\",\n\t\"image_generation_call\",\n\t\"compaction\",\n\t\"compaction_summary\",\n\t\"context_compaction\",\n]);\n\n/**\n * Codex ResponseItem serialization has NO `status` field on Message,\n * Reasoning, FunctionCall, FunctionCallOutput, or CustomToolCallOutput\n * (codex-rs/protocol/src/models.rs). Other item types either require `status`\n * (local_shell_call, tool_search_output, image_generation_call) or accept it\n * optionally (tool_search_call, custom_tool_call, web_search_call), so we must\n * not strip it there.\n */\nconst STATUS_LESS_ITEM_TYPES = new Set([\n\t\"message\",\n\t\"reasoning\",\n\t\"function_call\",\n\t\"function_call_output\",\n\t\"custom_tool_call_output\",\n]);\n\nexport function sanitizeInputItemsForCodex(input: unknown): void {\n\tif (!Array.isArray(input)) return;\n\tfor (const item of input) {\n\t\tif (!item || typeof item !== \"object\" || Array.isArray(item)) continue;\n\t\tconst record = item as Record<string, unknown>;\n\t\tconst type = typeof record.type === \"string\" ? record.type : undefined;\n\t\tif (type && RESPONSE_ITEM_ID_TYPES.has(type)) {\n\t\t\tdelete record.id;\n\t\t}\n\t\tif (type && STATUS_LESS_ITEM_TYPES.has(type) && \"status\" in record) {\n\t\t\tdelete record.status;\n\t\t}\n\t\tif (Array.isArray(record.content)) {\n\t\t\tfor (const part of record.content) {\n\t\t\t\tif (\n\t\t\t\t\tpart &&\n\t\t\t\t\ttypeof part === \"object\" &&\n\t\t\t\t\t(part as { type?: string }).type === \"output_text\" &&\n\t\t\t\t\t\"annotations\" in part\n\t\t\t\t) {\n\t\t\t\t\tdelete (part as Record<string, unknown>).annotations;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction extractInstructions(\n\tinput: unknown,\n\tsystemPrompt: string | undefined,\n): { instructions?: string; input: unknown } {\n\t// Prefer context.systemPrompt (matches Codex stream path).\n\tif (systemPrompt && systemPrompt.length > 0) {\n\t\tconst stripped = stripLeadingSystemRoles(input);\n\t\treturn { instructions: systemPrompt, input: stripped ?? input };\n\t}\n\n\tif (!Array.isArray(input) || input.length === 0) {\n\t\treturn { input };\n\t}\n\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t\"role\" in first &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\tconst content = (first as { content?: unknown }).content;\n\t\tconst text =\n\t\t\ttypeof content === \"string\"\n\t\t\t\t? content\n\t\t\t\t: Array.isArray(content)\n\t\t\t\t\t? content\n\t\t\t\t\t\t\t.map((part) =>\n\t\t\t\t\t\t\t\tpart && typeof part === \"object\" && \"text\" in part\n\t\t\t\t\t\t\t\t\t? String((part as { text: unknown }).text)\n\t\t\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join(\"\")\n\t\t\t\t\t: \"\";\n\t\treturn {\n\t\t\tinstructions: text || undefined,\n\t\t\tinput: input.slice(1),\n\t\t};\n\t}\n\n\treturn { input };\n}\n\nfunction stripLeadingSystemRoles(input: unknown): unknown {\n\tif (!Array.isArray(input) || input.length === 0) return input;\n\tconst first = input[0];\n\tif (\n\t\tfirst &&\n\t\ttypeof first === \"object\" &&\n\t\t!Array.isArray(first) &&\n\t\t((first as { role?: string }).role === \"system\" || (first as { role?: string }).role === \"developer\")\n\t) {\n\t\treturn input.slice(1);\n\t}\n\treturn input;\n}\n\nfunction clampCacheKey(sessionId: string | undefined): string | undefined {\n\tif (!sessionId) return undefined;\n\treturn sessionId.length <= 64 ? sessionId : sessionId.slice(0, 64);\n}\n\nexport function resolveResponsesUrl(baseUrl: string): string {\n\tconst normalized = baseUrl.trim().replace(/\\/+$/, \"\");\n\tif (!normalized) throw new Error(\"Model baseUrl is empty.\");\n\tif (normalized.endsWith(\"/responses\")) return normalized;\n\treturn `${normalized}/responses`;\n}\n\nexport function isRouterApi(api: string): boolean {\n\treturn api === ROUTER_API;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC3B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC3B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB"}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* /router interactive flows: list, add, edit, fetch, thinking map.
|
|
3
3
|
*
|
|
4
|
-
* Relay edits
|
|
5
|
-
*
|
|
4
|
+
* Relay edits are live: confirmed inputs and every toggle persist immediately.
|
|
5
|
+
* Searchable pickers follow Pi's native /model interaction pattern.
|
|
6
6
|
*/
|
|
7
7
|
import type { ExtensionAPI, ExtensionCommandContext } from "../../core/extensions/types.ts";
|
|
8
|
+
export declare function isCurrentRouterModel(current: {
|
|
9
|
+
provider: string;
|
|
10
|
+
id: string;
|
|
11
|
+
} | undefined, relayId: string, modelId: string): boolean;
|
|
8
12
|
export declare function runRouterCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void>;
|
|
13
|
+
/** Resolve only keys that can be safely used by the catalog probe. */
|
|
14
|
+
export declare function resolveProbeApiKey(apiKey: string): {
|
|
15
|
+
value?: string;
|
|
16
|
+
error?: string;
|
|
17
|
+
};
|
|
9
18
|
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAU5F,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,uBAAuB,EAAE,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BlH","sourcesContent":["/**\n * /router interactive flows: list, add, edit, fetch, thinking map.\n *\n * Relay edits auto-save to router.json (no separate Save step). Nested multi-select\n * and thinking editors require Ctrl+S to apply, and warn on Esc when dirty.\n */\n\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.ts\";\nimport { BorderedLoader } from \"../../modes/interactive/components/bordered-loader.ts\";\nimport { formatError, isValidRelayId, NO_UI_WARNING, truncate } from \"./constants.ts\";\nimport { createModelChecklist, createSearchableSelector, createThinkingMapEditor } from \"./dialog.ts\";\nimport { createDefaultModelConfig, displayModelLabel, resolveModelConfig, summarizeThinkingMap } from \"./presets.ts\";\nimport { probeRelayModels } from \"./probe.ts\";\nimport { applyRouterFile, registerOneRelay, unregisterOneRelay } from \"./register.ts\";\nimport { loadRouterFile, removeRelay, upsertRelay } from \"./store.ts\";\nimport type { RelayConfig, RelayModelConfig } from \"./types.ts\";\n\nexport async function runRouterCommand(args: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {\n\tif (!ctx.hasUI) {\n\t\tctx.ui.notify(NO_UI_WARNING, \"warning\");\n\t\treturn;\n\t}\n\tconst trimmed = args.trim().toLowerCase();\n\tif (!trimmed || trimmed === \"list\") {\n\t\tawait openMainMenu(ctx, pi);\n\t\treturn;\n\t}\n\tif (trimmed === \"add\") {\n\t\tawait addRelayFlow(ctx, pi);\n\t\treturn;\n\t}\n\tif (trimmed === \"reload\") {\n\t\tconst file = await loadRouterFile();\n\t\tapplyRouterFile(pi, file);\n\t\tawait ctx.modelRegistry.refresh();\n\t\tctx.ui.notify(`Reloaded ${file.relays.length} relay(s).`, \"info\");\n\t\treturn;\n\t}\n\t// Treat as relay id open\n\tconst file = await loadRouterFile();\n\tconst exact = file.relays.find((relay) => relay.id.toLowerCase() === trimmed);\n\tif (exact) {\n\t\tawait editRelayFlow(ctx, pi, exact);\n\t\treturn;\n\t}\n\tawait openMainMenu(ctx, pi, args.trim());\n}\n\nasync function openMainMenu(ctx: ExtensionCommandContext, pi: ExtensionAPI, initialQuery?: string): Promise<void> {\n\tlet cursor: string | undefined;\n\tlet query = initialQuery;\n\twhile (true) {\n\t\tconst file = await loadRouterFile();\n\t\t// Relays first (primary content), actions at the bottom.\n\t\tconst items = [\n\t\t\t...file.relays.map((relay) => ({\n\t\t\t\tvalue: `relay:${relay.id}`,\n\t\t\t\tlabel: relay.id,\n\t\t\t\tdescription: `${relay.models.length} model${relay.models.length === 1 ? \"\" : \"s\"} · ${truncate(relay.baseUrl, 40)}`,\n\t\t\t\tsearchText: `${relay.id} ${relay.baseUrl}`,\n\t\t\t})),\n\t\t\t{\n\t\t\t\tvalue: \"action:add\",\n\t\t\t\tlabel: \"+ Add relay\",\n\t\t\t\tdescription: \"Name · base URL · API key · fetch models\",\n\t\t\t\tsearchText: \"add create new relay gateway\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tvalue: \"action:reload\",\n\t\t\t\tlabel: \"Reload from disk\",\n\t\t\t\tdescription: \"Re-register providers from router.json\",\n\t\t\t\tsearchText: \"reload refresh\",\n\t\t\t},\n\t\t];\n\n\t\tconst selected =\n\t\t\tctx.mode === \"tui\"\n\t\t\t\t? await ctx.ui.custom(\n\t\t\t\t\t\tcreateSearchableSelector({\n\t\t\t\t\t\t\ttitle: \"API relays\",\n\t\t\t\t\t\t\tsubtitle:\n\t\t\t\t\t\t\t\tfile.relays.length === 0\n\t\t\t\t\t\t\t\t\t? \"No relays yet — add a base URL + API key.\"\n\t\t\t\t\t\t\t\t\t: `${file.relays.length} relay${file.relays.length === 1 ? \"\" : \"s\"} · Enter opens · Esc closes`,\n\t\t\t\t\t\t\titems,\n\t\t\t\t\t\t\tinitialValue: cursor,\n\t\t\t\t\t\t\tinitialQuery: query,\n\t\t\t\t\t\t\tmaxVisible: 12,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t: await selectNative(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"API relays\",\n\t\t\t\t\t\titems.map((item) => ({ value: item.value, label: item.label, description: item.description })),\n\t\t\t\t\t);\n\n\t\tquery = undefined;\n\t\tif (selected === undefined) return;\n\t\tcursor = selected;\n\n\t\tif (selected === \"action:add\") {\n\t\t\tconst id = await addRelayFlow(ctx, pi);\n\t\t\tif (id) cursor = `relay:${id}`;\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected === \"action:reload\") {\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tapplyRouterFile(pi, latest);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Reloaded ${latest.relays.length} relay(s).`, \"info\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (selected.startsWith(\"relay:\")) {\n\t\t\tconst id = selected.slice(\"relay:\".length);\n\t\t\tconst latest = await loadRouterFile();\n\t\t\tconst relay = latest.relays.find((entry) => entry.id === id);\n\t\t\tif (!relay) {\n\t\t\t\tctx.ui.notify(`Relay \"${id}\" not found.`, \"warning\");\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tawait editRelayFlow(ctx, pi, relay);\n\t\t}\n\t}\n}\n\nasync function addRelayFlow(ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<string | undefined> {\n\tconst file = await loadRouterFile();\n\tconst existing = new Set(file.relays.map((relay) => relay.id));\n\n\tconst id = await promptText(ctx, \"New relay · name (provider id)\", \"my-relay\", (value) => {\n\t\tconst trimmed = value.trim();\n\t\tif (!trimmed) return \"Name is required.\";\n\t\tif (!isValidRelayId(trimmed)) return \"Name cannot be empty or contain '/'.\";\n\t\tif (existing.has(trimmed)) return `Relay \"${trimmed}\" already exists.`;\n\t\treturn undefined;\n\t});\n\tif (id === undefined) return undefined;\n\n\tconst baseUrl = await promptText(ctx, `New relay · ${id.trim()} · base URL`, \"https://relay.example/v1\", (value) => {\n\t\tconst trimmed = value.trim();\n\t\tif (!trimmed) return \"Base URL is required.\";\n\t\ttry {\n\t\t\tconst url = new URL(trimmed);\n\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t} catch {\n\t\t\treturn \"Invalid URL.\";\n\t\t}\n\t\treturn undefined;\n\t});\n\tif (baseUrl === undefined) return undefined;\n\n\tconst apiKey = await promptText(ctx, `New relay · ${id.trim()} · API key`, \"sk-… or $RELAY_KEY\", (value) => {\n\t\tif (!value.trim()) return \"API key is required.\";\n\t\treturn undefined;\n\t});\n\tif (apiKey === undefined) return undefined;\n\n\tconst relay: RelayConfig = {\n\t\tid: id.trim(),\n\t\tbaseUrl: baseUrl.trim().replace(/\\/+$/, \"\"),\n\t\tapiKey: apiKey.trim(),\n\t\tmodels: [],\n\t};\n\n\tconst models = await fetchAndSelectModels(ctx, relay, new Set());\n\tif (models === undefined) {\n\t\tconst keep = await ctx.ui.confirm(\n\t\t\t\"Save relay without models?\",\n\t\t\t\"You can fetch models later from the relay editor. Changes auto-save after that.\",\n\t\t);\n\t\tif (!keep) return undefined;\n\t} else {\n\t\trelay.models = models;\n\t}\n\n\tawait persistRelay(ctx, pi, relay, {\n\t\tnotify:\n\t\t\trelay.models.length > 0\n\t\t\t\t? `Saved \"${relay.id}\" with ${relay.models.length} model(s).`\n\t\t\t\t: `Saved \"${relay.id}\" (no models yet).`,\n\t});\n\treturn relay.id;\n}\n\n/**\n * Relay editor — flat menu. Every mutation writes router.json immediately.\n * Hierarchy: list → relay → (models list | connection field | fetch | remove).\n */\nasync function editRelayFlow(ctx: ExtensionCommandContext, pi: ExtensionAPI, initial: RelayConfig): Promise<void> {\n\tconst relay = structuredClone(initial);\n\twhile (true) {\n\t\tconst modelSummary =\n\t\t\trelay.models.length === 0\n\t\t\t\t? \"none yet — fetch catalog\"\n\t\t\t\t: relay.models.length <= 3\n\t\t\t\t\t? relay.models.map((m) => displayModelLabel(m)).join(\", \")\n\t\t\t\t\t: `${relay.models.length} models · ${relay.models\n\t\t\t\t\t\t\t.slice(0, 2)\n\t\t\t\t\t\t\t.map((m) => displayModelLabel(m))\n\t\t\t\t\t\t\t.join(\", \")}…`;\n\n\t\tconst choice = await selectNative(ctx, `Relay · ${relay.id}`, [\n\t\t\t{\n\t\t\t\tvalue: \"models\",\n\t\t\t\tlabel: \"Models\",\n\t\t\t\tdescription: modelSummary,\n\t\t\t},\n\t\t\t{ value: \"baseUrl\", label: \"Base URL\", description: relay.baseUrl },\n\t\t\t{ value: \"apiKey\", label: \"API key\", description: maskKey(relay.apiKey) },\n\t\t\t{ value: \"remove\", label: \"Remove relay\", description: \"Delete from router.json\" },\n\t\t\t{ value: \"back\", label: \"Back\", description: \"All edits already saved\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"back\") return;\n\n\t\tif (choice === \"baseUrl\") {\n\t\t\tconst next = await promptText(ctx, `Relay · ${relay.id} · base URL`, relay.baseUrl, (value) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst url = new URL(value.trim());\n\t\t\t\t\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") return \"Use http or https.\";\n\t\t\t\t} catch {\n\t\t\t\t\treturn \"Invalid URL.\";\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t});\n\t\t\tif (next === undefined) continue;\n\t\t\tconst normalized = next.trim().replace(/\\/+$/, \"\");\n\t\t\tif (normalized === relay.baseUrl) continue;\n\t\t\trelay.baseUrl = normalized;\n\t\t\tawait persistRelay(ctx, pi, relay, { notify: `Saved base URL for \"${relay.id}\".` });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"apiKey\") {\n\t\t\tconst next = await promptText(ctx, `Relay · ${relay.id} · API key`, relay.apiKey, (value) =>\n\t\t\t\tvalue.trim() ? undefined : \"API key is required.\",\n\t\t\t);\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tif (trimmed === relay.apiKey) continue;\n\t\t\trelay.apiKey = trimmed;\n\t\t\tawait persistRelay(ctx, pi, relay, { notify: `Saved API key for \"${relay.id}\".` });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"models\") {\n\t\t\t// Always open the models screen (fetch lives only here). Empty list still\n\t\t\t// shows Fetch so the path is Relay → Models → Fetch, not a top-level shortcut.\n\t\t\tawait manageModelsFlow(ctx, pi, relay);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice === \"remove\") {\n\t\t\tconst ok = await ctx.ui.confirm(`Remove relay \"${relay.id}\"?`, \"Models will disappear from /model.\");\n\t\t\tif (!ok) continue;\n\t\t\tawait removeRelay(relay.id);\n\t\t\tunregisterOneRelay(pi, relay.id);\n\t\t\tawait ctx.modelRegistry.refresh();\n\t\t\tctx.ui.notify(`Removed relay \"${relay.id}\".`, \"info\");\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * Models screen: flat list of configured models + fetch. Selecting a model opens\n * its editor (name / thinking). No extra \"customize vs list\" intermediate menu.\n */\nasync function manageModelsFlow(ctx: ExtensionCommandContext, pi: ExtensionAPI, relay: RelayConfig): Promise<void> {\n\twhile (true) {\n\t\tconst empty = relay.models.length === 0;\n\t\tconst items: Array<{ value: string; label: string; description?: string }> = [\n\t\t\t{\n\t\t\t\tvalue: \"action:fetch\",\n\t\t\t\tlabel: \"Fetch catalog\",\n\t\t\t\tdescription: empty\n\t\t\t\t\t? \"GET /models · multi-select · auto-saves\"\n\t\t\t\t\t: \"Refresh from server (keeps name/thinking for kept ids)\",\n\t\t\t},\n\t\t\t...relay.models.map((model) => {\n\t\t\t\tconst resolved = resolveModelConfig(model);\n\t\t\t\tconst label = displayModelLabel(resolved);\n\t\t\t\tconst thinking = summarizeThinkingMap(resolved.thinkingLevelMap);\n\t\t\t\treturn {\n\t\t\t\t\tvalue: `model:${model.id}`,\n\t\t\t\t\tlabel: model.id,\n\t\t\t\t\tdescription: label !== model.id ? `${label} · ${thinking}` : thinking,\n\t\t\t\t};\n\t\t\t}),\n\t\t\t{ value: \"action:back\", label: \"Back\", description: \"Return to relay\" },\n\t\t];\n\n\t\tconst choice = await selectNative(ctx, `Relay · ${relay.id} · models`, items);\n\t\tif (choice === undefined || choice === \"action:back\") return;\n\n\t\tif (choice === \"action:fetch\") {\n\t\t\tconst selected = await fetchAndSelectModels(ctx, relay, new Set(relay.models.map((m) => m.id)));\n\t\t\tif (!selected) continue;\n\t\t\trelay.models = mergeModelSelection(relay.models, selected);\n\t\t\tawait persistRelay(ctx, pi, relay, {\n\t\t\t\tnotify: `Saved \"${relay.id}\" · ${relay.models.length} model(s).`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (choice.startsWith(\"model:\")) {\n\t\t\tconst modelId = choice.slice(\"model:\".length);\n\t\t\tconst model = relay.models.find((entry) => entry.id === modelId);\n\t\t\tif (!model) continue;\n\t\t\tawait editModelFlow(ctx, pi, relay, model);\n\t\t}\n\t}\n}\n\n/** Single-model editor: display name + thinking. Auto-saves each applied change. */\nasync function editModelFlow(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\trelay: RelayConfig,\n\tmodel: RelayModelConfig,\n): Promise<void> {\n\twhile (true) {\n\t\tconst resolved = resolveModelConfig(model);\n\t\tconst nameDesc = resolved.name ? resolved.name : \"(empty · /model shows id)\";\n\t\tconst action = await selectNative(ctx, `Relay · ${relay.id} · ${model.id}`, [\n\t\t\t{ value: \"name\", label: \"Display name\", description: nameDesc },\n\t\t\t{\n\t\t\t\tvalue: \"thinking\",\n\t\t\t\tlabel: \"Thinking levels\",\n\t\t\t\tdescription: summarizeThinkingMap(resolved.thinkingLevelMap),\n\t\t\t},\n\t\t\t{ value: \"back\", label: \"Back\", description: \"Edits auto-save when applied\" },\n\t\t]);\n\t\tif (action === undefined || action === \"back\") return;\n\n\t\tif (action === \"name\") {\n\t\t\tconst next = await promptText(ctx, `Display name · ${model.id} (empty = show id)`, resolved.name ?? \"\");\n\t\t\tif (next === undefined) continue;\n\t\t\tconst trimmed = next.trim();\n\t\t\tconst nextName = !trimmed || trimmed === model.id ? undefined : trimmed;\n\t\t\tconst prevName = model.name?.trim() && model.name.trim() !== model.id ? model.name.trim() : undefined;\n\t\t\tif (nextName === prevName) continue;\n\t\t\tif (nextName) model.name = nextName;\n\t\t\telse delete model.name;\n\t\t\tawait persistRelay(ctx, pi, relay, {\n\t\t\t\tnotify: model.name\n\t\t\t\t\t? `Saved display name \"${model.name}\" for ${model.id}.`\n\t\t\t\t\t: `Cleared display name for ${model.id}; /model shows id.`,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (action === \"thinking\") {\n\t\t\tconst nextMap =\n\t\t\t\tctx.mode === \"tui\"\n\t\t\t\t\t? await ctx.ui.custom(\n\t\t\t\t\t\t\tcreateThinkingMapEditor({\n\t\t\t\t\t\t\t\ttitle: `Thinking · ${relay.id} / ${model.id}`,\n\t\t\t\t\t\t\t\tmap: resolved.thinkingLevelMap,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t)\n\t\t\t\t\t: await editThinkingMapNative(ctx, resolved.thinkingLevelMap);\n\t\t\tif (!nextMap) continue;\n\t\t\tmodel.thinkingLevelMap = nextMap;\n\t\t\tmodel.reasoning = true;\n\t\t\tawait persistRelay(ctx, pi, relay, {\n\t\t\t\tnotify: `Saved thinking levels for ${model.id}.`,\n\t\t\t});\n\t\t}\n\t}\n}\n\nasync function editThinkingMapNative(\n\tctx: ExtensionCommandContext,\n\tmap: RelayModelConfig[\"thinkingLevelMap\"],\n): Promise<RelayModelConfig[\"thinkingLevelMap\"] | undefined> {\n\tconst working = { ...(map ?? {}) };\n\twhile (true) {\n\t\tconst choice = await selectNative(ctx, \"Toggle thinking level\", [\n\t\t\t...([\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const).map((level) => ({\n\t\t\t\tvalue: level,\n\t\t\t\tlabel: level,\n\t\t\t\tdescription:\n\t\t\t\t\tworking[level] === null ? \"hidden\" : working[level] === undefined ? \"default\" : String(working[level]),\n\t\t\t})),\n\t\t\t{ value: \"done\", label: \"Apply\" },\n\t\t\t{ value: \"cancel\", label: \"Cancel\" },\n\t\t]);\n\t\tif (choice === undefined || choice === \"cancel\") return undefined;\n\t\tif (choice === \"done\") return working;\n\t\tif (working[choice] === null) working[choice] = choice === \"off\" ? \"none\" : choice;\n\t\telse working[choice] = null;\n\t}\n}\n\nasync function fetchAndSelectModels(\n\tctx: ExtensionCommandContext,\n\trelay: Pick<RelayConfig, \"id\" | \"baseUrl\" | \"apiKey\">,\n\tinitiallySelected: ReadonlySet<string>,\n): Promise<RelayModelConfig[] | undefined> {\n\tconst probeOptions = {\n\t\tbaseUrl: relay.baseUrl,\n\t\tapiKey: literalKey(relay.apiKey),\n\t};\n\n\tlet result: Awaited<ReturnType<typeof probeRelayModels>> | undefined;\n\tif (ctx.mode === \"tui\") {\n\t\tresult = await ctx.ui.custom<Awaited<ReturnType<typeof probeRelayModels>> | undefined>(\n\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\tconst loader = new BorderedLoader(tui, theme, `Fetching models · ${relay.id}`, {\n\t\t\t\t\tcancellable: true,\n\t\t\t\t});\n\t\t\t\tlet settled = false;\n\t\t\t\tconst finish = (value: Awaited<ReturnType<typeof probeRelayModels>> | undefined) => {\n\t\t\t\t\tif (settled) return;\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tloader.dispose();\n\t\t\t\t\tdone(value);\n\t\t\t\t};\n\t\t\t\tloader.onAbort = () => finish(undefined);\n\t\t\t\tvoid probeRelayModels({ ...probeOptions, signal: loader.signal })\n\t\t\t\t\t.then(finish)\n\t\t\t\t\t.catch((error) => finish({ ok: false, error: formatError(error) }));\n\t\t\t\treturn loader;\n\t\t\t},\n\t\t);\n\t} else {\n\t\tctx.ui.notify(`Fetching models from ${relay.baseUrl}…`, \"info\");\n\t\tresult = await probeRelayModels(probeOptions);\n\t}\n\n\tif (result === undefined) return undefined;\n\tif (!result.ok) {\n\t\tctx.ui.notify(`Fetch failed: ${result.error}`, \"error\");\n\t\tconst manual = await ctx.ui.confirm(\"Add model IDs manually?\", \"Comma-separated ids.\");\n\t\tif (!manual) return undefined;\n\t\treturn manualModelEntry(ctx);\n\t}\n\tif (result.models.length === 0) {\n\t\tctx.ui.notify(\"Server returned an empty model list.\", \"warning\");\n\t\treturn manualModelEntry(ctx);\n\t}\n\tif (result.truncated) {\n\t\tctx.ui.notify(\"Catalog truncated to 2,000 models.\", \"warning\");\n\t}\n\n\tlet selectedIds: string[];\n\tif (ctx.mode === \"tui\") {\n\t\tconst choice = await ctx.ui.custom(\n\t\t\tcreateModelChecklist({\n\t\t\t\ttitle: `Select models · ${relay.id}`,\n\t\t\t\tsubtitle: \"Space toggle · Ctrl+S apply · Esc warns if unsaved\",\n\t\t\t\tmodels: result.models,\n\t\t\t\tinitiallySelected,\n\t\t\t}),\n\t\t);\n\t\tif (choice.kind === \"cancel\") return undefined;\n\t\tselectedIds = choice.selectedIds;\n\t} else {\n\t\tconst ok = await ctx.ui.confirm(\n\t\t\t`Import ${result.models.length} models?`,\n\t\t\t\"Non-TUI mode imports the full catalog. Prefer the terminal UI to multi-select.\",\n\t\t);\n\t\tif (!ok) return undefined;\n\t\tselectedIds = result.models.map((model) => model.id);\n\t}\n\n\tif (selectedIds.length === 0) {\n\t\tctx.ui.notify(\"No models selected.\", \"warning\");\n\t\treturn undefined;\n\t}\n\n\t// Do not import remote catalog names — leave name empty so /model shows the id\n\t// unless the user sets a custom display name later.\n\treturn selectedIds.map((id) => createDefaultModelConfig(id));\n}\n\nasync function manualModelEntry(ctx: ExtensionCommandContext): Promise<RelayModelConfig[] | undefined> {\n\tconst value = await ctx.ui.input(\"Model IDs (comma-separated)\", \"gpt-5.6-sol, gpt-5.6-luna\");\n\tif (value === undefined) return undefined;\n\tconst ids = value\n\t\t.split(/[,\\r\\n]+/)\n\t\t.map((id) => id.trim())\n\t\t.filter(Boolean);\n\tif (ids.length === 0) {\n\t\tctx.ui.notify(\"Enter at least one model id.\", \"warning\");\n\t\treturn undefined;\n\t}\n\treturn ids.map((id) => createDefaultModelConfig(id));\n}\n\n/** Keep prior customizations when re-selecting overlapping ids. */\nfunction mergeModelSelection(previous: RelayModelConfig[], selected: RelayModelConfig[]): RelayModelConfig[] {\n\tconst prior = new Map(previous.map((model) => [model.id, model]));\n\treturn selected.map((model) => {\n\t\tconst old = prior.get(model.id);\n\t\tif (!old) return model;\n\t\tconst merged: RelayModelConfig = {\n\t\t\t...model,\n\t\t\treasoning: old.reasoning ?? model.reasoning,\n\t\t\tinput: old.input ?? model.input,\n\t\t\tcontextWindow: old.contextWindow ?? model.contextWindow,\n\t\t\tmaxTokens: old.maxTokens ?? model.maxTokens,\n\t\t\tthinkingLevelMap: old.thinkingLevelMap ?? model.thinkingLevelMap,\n\t\t};\n\t\t// Preserve a user-set display name; never invent one on re-fetch.\n\t\tif (old.name?.trim() && old.name.trim() !== old.id) merged.name = old.name.trim();\n\t\telse delete merged.name;\n\t\treturn merged;\n\t});\n}\n\nasync function persistRelay(\n\tctx: ExtensionCommandContext,\n\tpi: ExtensionAPI,\n\trelay: RelayConfig,\n\topts?: { notify?: string },\n): Promise<void> {\n\tawait upsertRelay(relay);\n\tregisterOneRelay(pi, relay);\n\tawait ctx.modelRegistry.refresh();\n\tif (opts?.notify) ctx.ui.notify(opts.notify, \"info\");\n}\n\nasync function promptText(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\tplaceholder: string,\n\tvalidate?: (value: string) => string | undefined,\n): Promise<string | undefined> {\n\twhile (true) {\n\t\tconst value = await ctx.ui.input(title, placeholder);\n\t\tif (value === undefined) return undefined;\n\t\tconst error = validate?.(value);\n\t\tif (error) {\n\t\t\tctx.ui.notify(error, \"warning\");\n\t\t\tcontinue;\n\t\t}\n\t\treturn value;\n\t}\n}\n\nasync function selectNative<T extends string>(\n\tctx: ExtensionCommandContext,\n\ttitle: string,\n\titems: ReadonlyArray<{ value: T; label: string; description?: string }>,\n): Promise<T | undefined> {\n\tif (ctx.mode === \"tui\") {\n\t\treturn ctx.ui.custom(\n\t\t\tcreateSearchableSelector({\n\t\t\t\ttitle,\n\t\t\t\titems,\n\t\t\t\tmaxVisible: Math.min(12, Math.max(1, items.length)),\n\t\t\t}),\n\t\t);\n\t}\n\tconst labels = items.map((item) => (item.description ? `${item.label} — ${item.description}` : item.label));\n\tconst selected = await ctx.ui.select(title, labels);\n\tif (selected === undefined) return undefined;\n\treturn items[labels.indexOf(selected)]?.value;\n}\n\nfunction maskKey(key: string): string {\n\tif (key.startsWith(\"$\") || key.startsWith(\"!\")) return key;\n\tif (key.length <= 8) return \"••••\";\n\treturn `${key.slice(0, 4)}…${key.slice(-4)}`;\n}\n\n/** Best-effort key for catalog fetch (full resolution still goes through Pi at request time). */\nfunction literalKey(apiKey: string): string | undefined {\n\tconst trimmed = apiKey.trim();\n\tif (!trimmed || trimmed.startsWith(\"!\")) return undefined;\n\tconst envOnly = trimmed.match(/^\\$([A-Za-z_][A-Za-z0-9_]*)$/);\n\tif (envOnly) return process.env[envOnly[1]!];\n\tconst braced = trimmed.match(/^\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\tif (braced) return process.env[braced[1]!];\n\tif (trimmed.includes(\"$\")) return undefined;\n\treturn trimmed;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/extensions/router/ui.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAsE5F,wBAAgB,oBAAoB,CACnC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EACrD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,OAAO,CAET;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,uBAAuB,EAAE,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BlH;AA+mBD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiBrF"}
|