apex-code 0.0.1-alpha.1 → 0.0.1-alpha.11
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 +482 -0
- package/README.md +75 -680
- package/dist/cli/args.d.ts +21 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +119 -15
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +3 -3
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/concurrent-session.d.ts +3 -0
- package/dist/cli/concurrent-session.d.ts.map +1 -0
- package/dist/cli/concurrent-session.js +13 -0
- package/dist/cli/concurrent-session.js.map +1 -0
- package/dist/cli/cost-command.d.ts +19 -0
- package/dist/cli/cost-command.d.ts.map +1 -0
- package/dist/cli/cost-command.js +107 -0
- package/dist/cli/cost-command.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.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 +1 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +99 -16
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +58 -24
- 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 +2 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +28 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +140 -4
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +147 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +440 -123
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -14
- 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 +18 -10
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/checkpoints/git-checkpoints.d.ts +33 -0
- package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/git-checkpoints.js +230 -0
- package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.js +29 -0
- package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context/deferred-schemas.d.ts +92 -0
- package/dist/core/context/deferred-schemas.d.ts.map +1 -0
- package/dist/core/context/deferred-schemas.js +74 -0
- package/dist/core/context/deferred-schemas.js.map +1 -0
- package/dist/core/context/eviction.d.ts +47 -0
- package/dist/core/context/eviction.d.ts.map +1 -0
- package/dist/core/context/eviction.js +83 -0
- package/dist/core/context/eviction.js.map +1 -0
- package/dist/core/context/pipeline.d.ts +90 -0
- package/dist/core/context/pipeline.d.ts.map +1 -0
- package/dist/core/context/pipeline.js +109 -0
- package/dist/core/context/pipeline.js.map +1 -0
- package/dist/core/credential-failover.d.ts +30 -0
- package/dist/core/credential-failover.d.ts.map +1 -0
- package/dist/core/credential-failover.js +46 -0
- package/dist/core/credential-failover.js.map +1 -0
- package/dist/core/credential-pool.d.ts +60 -0
- package/dist/core/credential-pool.d.ts.map +1 -0
- package/dist/core/credential-pool.js +84 -0
- package/dist/core/credential-pool.js.map +1 -0
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/delegation/agents.d.ts +15 -0
- package/dist/core/delegation/agents.d.ts.map +1 -0
- package/dist/core/delegation/agents.js +55 -0
- package/dist/core/delegation/agents.js.map +1 -0
- package/dist/core/delegation/ceiling.d.ts +29 -0
- package/dist/core/delegation/ceiling.d.ts.map +1 -0
- package/dist/core/delegation/ceiling.js +34 -0
- package/dist/core/delegation/ceiling.js.map +1 -0
- package/dist/core/delegation/runtime.d.ts +94 -0
- package/dist/core/delegation/runtime.d.ts.map +1 -0
- package/dist/core/delegation/runtime.js +117 -0
- package/dist/core/delegation/runtime.js.map +1 -0
- package/dist/core/durable-state/daemon.d.ts +37 -0
- package/dist/core/durable-state/daemon.d.ts.map +1 -0
- package/dist/core/durable-state/daemon.js +62 -0
- package/dist/core/durable-state/daemon.js.map +1 -0
- package/dist/core/durable-state/provenance.d.ts +7 -0
- package/dist/core/durable-state/provenance.d.ts.map +1 -0
- package/dist/core/durable-state/provenance.js +24 -0
- package/dist/core/durable-state/provenance.js.map +1 -0
- package/dist/core/durable-state/sqlite.d.ts +84 -0
- package/dist/core/durable-state/sqlite.d.ts.map +1 -0
- package/dist/core/durable-state/sqlite.js +355 -0
- package/dist/core/durable-state/sqlite.js.map +1 -0
- package/dist/core/environment.d.ts +12 -0
- package/dist/core/environment.d.ts.map +1 -0
- package/dist/core/environment.js +69 -0
- package/dist/core/environment.js.map +1 -0
- package/dist/core/evidence-policy.d.ts +17 -0
- package/dist/core/evidence-policy.d.ts.map +1 -0
- package/dist/core/evidence-policy.js +25 -0
- package/dist/core/evidence-policy.js.map +1 -0
- package/dist/core/evidence.d.ts +16 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +51 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +5 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +6 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +122 -49
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +44 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +1 -2
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -17
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/http-idle-timeout.d.ts +12 -0
- package/dist/core/http-idle-timeout.d.ts.map +1 -0
- package/dist/core/http-idle-timeout.js +27 -0
- package/dist/core/http-idle-timeout.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +38 -13
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lsp/client.d.ts +78 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +494 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/diagnostics.d.ts +47 -0
- package/dist/core/lsp/diagnostics.d.ts.map +1 -0
- package/dist/core/lsp/diagnostics.js +224 -0
- package/dist/core/lsp/diagnostics.js.map +1 -0
- package/dist/core/lsp/pool.d.ts +48 -0
- package/dist/core/lsp/pool.d.ts.map +1 -0
- package/dist/core/lsp/pool.js +150 -0
- package/dist/core/lsp/pool.js.map +1 -0
- package/dist/core/lsp/registry.d.ts +49 -0
- package/dist/core/lsp/registry.d.ts.map +1 -0
- package/dist/core/lsp/registry.js +215 -0
- package/dist/core/lsp/registry.js.map +1 -0
- package/dist/core/lsp/status.d.ts +23 -0
- package/dist/core/lsp/status.d.ts.map +1 -0
- package/dist/core/lsp/status.js +35 -0
- package/dist/core/lsp/status.js.map +1 -0
- package/dist/core/lsp/sync.d.ts +13 -0
- package/dist/core/lsp/sync.d.ts.map +1 -0
- package/dist/core/lsp/sync.js +71 -0
- package/dist/core/lsp/sync.js.map +1 -0
- package/dist/core/mcp/config.d.ts +16 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +152 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/connector.d.ts +10 -0
- package/dist/core/mcp/connector.d.ts.map +1 -0
- package/dist/core/mcp/connector.js +70 -0
- package/dist/core/mcp/connector.js.map +1 -0
- package/dist/core/mcp/contract.d.ts +19 -0
- package/dist/core/mcp/contract.d.ts.map +1 -0
- package/dist/core/mcp/contract.js +89 -0
- package/dist/core/mcp/contract.js.map +1 -0
- package/dist/core/mcp/mcp-tool.d.ts +32 -0
- package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
- package/dist/core/mcp/mcp-tool.js +165 -0
- package/dist/core/mcp/mcp-tool.js.map +1 -0
- package/dist/core/mcp/metadata-cache.d.ts +29 -0
- package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/core/mcp/metadata-cache.js +99 -0
- package/dist/core/mcp/metadata-cache.js.map +1 -0
- package/dist/core/mcp/runtime.d.ts +18 -0
- package/dist/core/mcp/runtime.d.ts.map +1 -0
- package/dist/core/mcp/runtime.js +35 -0
- package/dist/core/mcp/runtime.js.map +1 -0
- package/dist/core/mcp/schema.d.ts +22 -0
- package/dist/core/mcp/schema.d.ts.map +1 -0
- package/dist/core/mcp/schema.js +20 -0
- package/dist/core/mcp/schema.js.map +1 -0
- package/dist/core/mcp/server-manager.d.ts +43 -0
- package/dist/core/mcp/server-manager.d.ts.map +1 -0
- package/dist/core/mcp/server-manager.js +142 -0
- package/dist/core/mcp/server-manager.js.map +1 -0
- package/dist/core/mcp/types.d.ts +98 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +8 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/model-config.d.ts +18 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +25 -6
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +21 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +73 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +73 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +225 -8
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/observability/aggregate.d.ts +21 -0
- package/dist/core/observability/aggregate.d.ts.map +1 -0
- package/dist/core/observability/aggregate.js +36 -0
- package/dist/core/observability/aggregate.js.map +1 -0
- package/dist/core/observability/otlp.d.ts +66 -0
- package/dist/core/observability/otlp.d.ts.map +1 -0
- package/dist/core/observability/otlp.js +95 -0
- package/dist/core/observability/otlp.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +40 -16
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions/gate.d.ts +42 -0
- package/dist/core/permissions/gate.d.ts.map +1 -0
- package/dist/core/permissions/gate.js +72 -0
- package/dist/core/permissions/gate.js.map +1 -0
- package/dist/core/permissions/modes.d.ts +18 -0
- package/dist/core/permissions/modes.d.ts.map +1 -0
- package/dist/core/permissions/modes.js +57 -0
- package/dist/core/permissions/modes.js.map +1 -0
- package/dist/core/permissions/responder.d.ts +30 -0
- package/dist/core/permissions/responder.d.ts.map +1 -0
- package/dist/core/permissions/responder.js +32 -0
- package/dist/core/permissions/responder.js.map +1 -0
- package/dist/core/permissions/rules.d.ts +34 -0
- package/dist/core/permissions/rules.d.ts.map +1 -0
- package/dist/core/permissions/rules.js +74 -0
- package/dist/core/permissions/rules.js.map +1 -0
- package/dist/core/permissions/startup.d.ts +45 -0
- package/dist/core/permissions/startup.d.ts.map +1 -0
- package/dist/core/permissions/startup.js +63 -0
- package/dist/core/permissions/startup.js.map +1 -0
- package/dist/core/permissions/store.d.ts +114 -0
- package/dist/core/permissions/store.d.ts.map +1 -0
- package/dist/core/permissions/store.js +229 -0
- package/dist/core/permissions/store.js.map +1 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +6 -7
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +2 -2
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +22 -17
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/bwrap-arguments.d.ts +52 -0
- package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
- package/dist/core/sandbox/bwrap-arguments.js +86 -0
- package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
- package/dist/core/sandbox/child-entry.d.ts +2 -0
- package/dist/core/sandbox/child-entry.d.ts.map +1 -0
- package/dist/core/sandbox/child-entry.js +22 -0
- package/dist/core/sandbox/child-entry.js.map +1 -0
- package/dist/core/sandbox/cli-launch.d.ts +88 -0
- package/dist/core/sandbox/cli-launch.d.ts.map +1 -0
- package/dist/core/sandbox/cli-launch.js +272 -0
- package/dist/core/sandbox/cli-launch.js.map +1 -0
- package/dist/core/sandbox/cli-supervisor.d.ts +30 -0
- package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/cli-supervisor.js +123 -0
- package/dist/core/sandbox/cli-supervisor.js.map +1 -0
- package/dist/core/sandbox/default-hosts.d.ts +28 -0
- package/dist/core/sandbox/default-hosts.d.ts.map +1 -0
- package/dist/core/sandbox/default-hosts.js +69 -0
- package/dist/core/sandbox/default-hosts.js.map +1 -0
- package/dist/core/sandbox/full-access.d.ts +28 -0
- package/dist/core/sandbox/full-access.d.ts.map +1 -0
- package/dist/core/sandbox/full-access.js +63 -0
- package/dist/core/sandbox/full-access.js.map +1 -0
- package/dist/core/sandbox/git-identity.d.ts +57 -0
- package/dist/core/sandbox/git-identity.d.ts.map +1 -0
- package/dist/core/sandbox/git-identity.js +78 -0
- package/dist/core/sandbox/git-identity.js.map +1 -0
- package/dist/core/sandbox/host-approval.d.ts +42 -0
- package/dist/core/sandbox/host-approval.d.ts.map +1 -0
- package/dist/core/sandbox/host-approval.js +99 -0
- package/dist/core/sandbox/host-approval.js.map +1 -0
- package/dist/core/sandbox/linux-backend.d.ts +46 -0
- package/dist/core/sandbox/linux-backend.d.ts.map +1 -0
- package/dist/core/sandbox/linux-backend.js +304 -0
- package/dist/core/sandbox/linux-backend.js.map +1 -0
- package/dist/core/sandbox/macos-backend.d.ts +28 -0
- package/dist/core/sandbox/macos-backend.d.ts.map +1 -0
- package/dist/core/sandbox/macos-backend.js +313 -0
- package/dist/core/sandbox/macos-backend.js.map +1 -0
- package/dist/core/sandbox/network-proxy.d.ts +38 -0
- package/dist/core/sandbox/network-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/network-proxy.js +153 -0
- package/dist/core/sandbox/network-proxy.js.map +1 -0
- package/dist/core/sandbox/network-refusal.d.ts +24 -0
- package/dist/core/sandbox/network-refusal.d.ts.map +1 -0
- package/dist/core/sandbox/network-refusal.js +72 -0
- package/dist/core/sandbox/network-refusal.js.map +1 -0
- package/dist/core/sandbox/policy.d.ts +40 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -0
- package/dist/core/sandbox/policy.js +55 -0
- package/dist/core/sandbox/policy.js.map +1 -0
- package/dist/core/sandbox/profiles.d.ts +25 -0
- package/dist/core/sandbox/profiles.d.ts.map +1 -0
- package/dist/core/sandbox/profiles.js +23 -0
- package/dist/core/sandbox/profiles.js.map +1 -0
- package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
- package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-client.js +86 -0
- package/dist/core/sandbox/rpc/command-client.js.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.js +120 -0
- package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts +20 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.js +170 -0
- package/dist/core/sandbox/rpc/credential-client.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts +44 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.js +287 -0
- package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/framing.d.ts +35 -0
- package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/framing.js +114 -0
- package/dist/core/sandbox/rpc/framing.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts +40 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js +152 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js +142 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
- package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
- package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor-temp.js +21 -0
- package/dist/core/sandbox/supervisor-temp.js.map +1 -0
- package/dist/core/sandbox/supervisor.d.ts +51 -0
- package/dist/core/sandbox/supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor.js +18 -0
- package/dist/core/sandbox/supervisor.js.map +1 -0
- package/dist/core/sandbox/terminal-handoff.d.ts +45 -0
- package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-handoff.js +176 -0
- package/dist/core/sandbox/terminal-handoff.js.map +1 -0
- package/dist/core/sandbox/terminal-size.d.ts +40 -0
- package/dist/core/sandbox/terminal-size.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-size.js +105 -0
- package/dist/core/sandbox/terminal-size.js.map +1 -0
- package/dist/core/sandbox/violations.d.ts +23 -0
- package/dist/core/sandbox/violations.d.ts.map +1 -0
- package/dist/core/sandbox/violations.js +30 -0
- package/dist/core/sandbox/violations.js.map +1 -0
- package/dist/core/sdk.d.ts +32 -41
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +174 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-lease.d.ts +31 -0
- package/dist/core/session-lease.d.ts.map +1 -0
- package/dist/core/session-lease.js +138 -0
- package/dist/core/session-lease.js.map +1 -0
- package/dist/core/session-manager.d.ts +58 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +92 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-share.d.ts +31 -0
- package/dist/core/session-share.d.ts.map +1 -0
- package/dist/core/session-share.js +45 -0
- package/dist/core/session-share.js.map +1 -0
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +99 -9
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +141 -36
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +19 -7
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +128 -52
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -2
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +59 -68
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +3 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/ask-user.d.ts +25 -0
- package/dist/core/tools/ask-user.d.ts.map +1 -0
- package/dist/core/tools/ask-user.js +49 -0
- package/dist/core/tools/ask-user.js.map +1 -0
- package/dist/core/tools/bash-command-segments.d.ts +22 -0
- package/dist/core/tools/bash-command-segments.d.ts.map +1 -0
- package/dist/core/tools/bash-command-segments.js +128 -0
- package/dist/core/tools/bash-command-segments.js.map +1 -0
- package/dist/core/tools/bash.d.ts +40 -4
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +183 -32
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/contract-snapshot.d.ts +58 -0
- package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
- package/dist/core/tools/contract-snapshot.js +51 -0
- package/dist/core/tools/contract-snapshot.js.map +1 -0
- package/dist/core/tools/contract.d.ts +185 -0
- package/dist/core/tools/contract.d.ts.map +1 -0
- package/dist/core/tools/contract.js +50 -0
- package/dist/core/tools/contract.js.map +1 -0
- package/dist/core/tools/delegate.d.ts +38 -0
- package/dist/core/tools/delegate.d.ts.map +1 -0
- package/dist/core/tools/delegate.js +90 -0
- package/dist/core/tools/delegate.js.map +1 -0
- package/dist/core/tools/diagnostics.d.ts +39 -0
- package/dist/core/tools/diagnostics.d.ts.map +1 -0
- package/dist/core/tools/diagnostics.js +62 -0
- package/dist/core/tools/diagnostics.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +12 -2
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +61 -10
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +13 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +47 -10
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +60 -6
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +148 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +17 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/lsp.d.ts +62 -0
- package/dist/core/tools/lsp.d.ts.map +1 -0
- package/dist/core/tools/lsp.js +216 -0
- package/dist/core/tools/lsp.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-permission.d.ts +18 -0
- package/dist/core/tools/path-permission.d.ts.map +1 -0
- package/dist/core/tools/path-permission.js +28 -0
- package/dist/core/tools/path-permission.js.map +1 -0
- package/dist/core/tools/plan-present.d.ts +27 -0
- package/dist/core/tools/plan-present.d.ts.map +1 -0
- package/dist/core/tools/plan-present.js +55 -0
- package/dist/core/tools/plan-present.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +14 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/skill-search.d.ts +32 -0
- package/dist/core/tools/skill-search.d.ts.map +1 -0
- package/dist/core/tools/skill-search.js +56 -0
- package/dist/core/tools/skill-search.js.map +1 -0
- package/dist/core/tools/test.d.ts +34 -0
- package/dist/core/tools/test.d.ts.map +1 -0
- package/dist/core/tools/test.js +75 -0
- package/dist/core/tools/test.js.map +1 -0
- package/dist/core/tools/todo-write.d.ts +31 -0
- package/dist/core/tools/todo-write.d.ts.map +1 -0
- package/dist/core/tools/todo-write.js +51 -0
- package/dist/core/tools/todo-write.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -2
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +11 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/tool-schema.d.ts +22 -0
- package/dist/core/tools/tool-schema.d.ts.map +1 -0
- package/dist/core/tools/tool-schema.js +45 -0
- package/dist/core/tools/tool-schema.js.map +1 -0
- package/dist/core/tools/web-fetch.d.ts +26 -0
- package/dist/core/tools/web-fetch.d.ts.map +1 -0
- package/dist/core/tools/web-fetch.js +62 -0
- package/dist/core/tools/web-fetch.js.map +1 -0
- package/dist/core/tools/web-search-exa.d.ts +33 -0
- package/dist/core/tools/web-search-exa.d.ts.map +1 -0
- package/dist/core/tools/web-search-exa.js +128 -0
- package/dist/core/tools/web-search-exa.js.map +1 -0
- package/dist/core/tools/web-search.d.ts +26 -0
- package/dist/core/tools/web-search.d.ts.map +1 -0
- package/dist/core/tools/web-search.js +53 -0
- package/dist/core/tools/web-search.js.map +1 -0
- package/dist/core/tools/write.d.ts +16 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +48 -2
- 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 +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-performance-store.d.ts +56 -0
- package/dist/core/usage-performance-store.d.ts.map +1 -0
- package/dist/core/usage-performance-store.js +85 -0
- package/dist/core/usage-performance-store.js.map +1 -0
- package/dist/core/web-search-provider.d.ts +64 -0
- package/dist/core/web-search-provider.d.ts.map +1 -0
- package/dist/core/web-search-provider.js +149 -0
- package/dist/core/web-search-provider.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- 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 +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +87 -22
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +6 -5
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +182 -23
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +20 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +9 -6
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +72 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +338 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +7 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +11 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +4 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +24 -6
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +17 -41
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/first-use-hints.d.ts +8 -0
- package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-use-hints.js +22 -0
- package/dist/modes/interactive/components/first-use-hints.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +31 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +205 -24
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +31 -9
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +236 -96
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +25 -5
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +226 -58
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/splash-header.d.ts +66 -0
- package/dist/modes/interactive/components/splash-header.d.ts.map +1 -0
- package/dist/modes/interactive/components/splash-header.js +180 -0
- package/dist/modes/interactive/components/splash-header.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +28 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +144 -35
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-panel.d.ts +30 -0
- package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-panel.js +130 -0
- package/dist/modes/interactive/components/tool-panel.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +60 -10
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +90 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +729 -206
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +34 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/apex.json +93 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +3 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +11 -3
- package/dist/modes/interactive/theme/theme.d.ts +14 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +65 -10
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +18 -12
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +22 -5
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +210 -19
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +2 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/testing/replay/metrics.d.ts +24 -0
- package/dist/testing/replay/metrics.d.ts.map +1 -0
- package/dist/testing/replay/metrics.js +35 -0
- package/dist/testing/replay/metrics.js.map +1 -0
- package/dist/testing/replay/recorded-provider.d.ts +10 -0
- package/dist/testing/replay/recorded-provider.d.ts.map +1 -0
- package/dist/testing/replay/recorded-provider.js +108 -0
- package/dist/testing/replay/recorded-provider.js.map +1 -0
- package/dist/testing/replay/runner.d.ts +56 -0
- package/dist/testing/replay/runner.d.ts.map +1 -0
- package/dist/testing/replay/runner.js +406 -0
- package/dist/testing/replay/runner.js.map +1 -0
- package/dist/themes/apex-logo.d.ts +41 -0
- package/dist/themes/apex-logo.d.ts.map +1 -0
- package/dist/themes/apex-logo.js +35 -0
- package/dist/themes/apex-logo.js.map +1 -0
- package/dist/utils/apex-code-user-agent.d.ts +2 -0
- package/dist/utils/apex-code-user-agent.d.ts.map +1 -0
- package/dist/utils/apex-code-user-agent.js +5 -0
- package/dist/utils/apex-code-user-agent.js.map +1 -0
- package/dist/utils/changelog.d.ts +7 -2
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +82 -13
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +70 -2
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +280 -124
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +7 -5
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +27 -14
- 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 +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/compaction.md +41 -24
- package/docs/containerization.md +24 -21
- package/docs/custom-provider.md +15 -12
- package/docs/development.md +11 -11
- package/docs/environment-variables.md +37 -77
- package/docs/extensions.md +68 -54
- package/docs/index.md +12 -24
- package/docs/json.md +18 -11
- package/docs/keybindings.md +18 -12
- package/docs/llama-cpp.md +9 -7
- package/docs/models.md +17 -11
- package/docs/packages.md +47 -43
- package/docs/prompt-templates.md +3 -3
- package/docs/providers.md +10 -10
- package/docs/quickstart.md +49 -32
- package/docs/rpc.md +35 -18
- package/docs/sdk.md +20 -6
- package/docs/security.md +18 -18
- package/docs/session-format.md +9 -9
- package/docs/sessions.md +13 -13
- package/docs/settings.md +83 -16
- package/docs/shell-aliases.md +1 -1
- package/docs/skills.md +66 -15
- package/docs/terminal-setup.md +44 -19
- package/docs/termux.md +4 -4
- package/docs/themes.md +32 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +5 -5
- package/docs/usage.md +61 -53
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +24 -36
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +3 -1
- package/examples/extensions/subagent/agents.ts +40 -9
- package/examples/extensions/subagent/index.ts +27 -4
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +435 -452
- package/package.json +17 -18
- package/dist/core/telemetry.d.ts +0 -3
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js +0 -9
- package/dist/core/telemetry.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -104
- package/dist/server/create-harness.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -5
- package/dist/utils/pi-user-agent.js.map +0 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owns when a server is running and nothing about how it is reached.
|
|
3
|
+
*
|
|
4
|
+
* The `McpConnection` seam is why this module has no MCP SDK import and no child
|
|
5
|
+
* process: lifecycle is the part with the interesting failure modes (a connect that
|
|
6
|
+
* never returns, a broken server retried on every call, two callers racing the same
|
|
7
|
+
* spawn) and all of it is testable against a fake.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = 30_000;
|
|
10
|
+
const FAILURE_BACKOFF_MS = 60_000;
|
|
11
|
+
function isKeptAlive(server) {
|
|
12
|
+
return server.lifecycle === "keep-alive" || server.lifecycle === "lazy-keep-alive";
|
|
13
|
+
}
|
|
14
|
+
export class McpServerManager {
|
|
15
|
+
servers;
|
|
16
|
+
connector;
|
|
17
|
+
now;
|
|
18
|
+
connectTimeoutMs;
|
|
19
|
+
entries = new Map();
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.servers = options.servers;
|
|
22
|
+
this.connector = options.connector;
|
|
23
|
+
this.now = options.now ?? Date.now;
|
|
24
|
+
this.connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
25
|
+
}
|
|
26
|
+
state(name) {
|
|
27
|
+
return this.entries.get(name)?.state ?? { kind: "disconnected" };
|
|
28
|
+
}
|
|
29
|
+
entry(name) {
|
|
30
|
+
let entry = this.entries.get(name);
|
|
31
|
+
if (!entry) {
|
|
32
|
+
entry = { state: { kind: "disconnected" }, connection: undefined, pending: undefined };
|
|
33
|
+
this.entries.set(name, entry);
|
|
34
|
+
}
|
|
35
|
+
return entry;
|
|
36
|
+
}
|
|
37
|
+
async connect(server, entry) {
|
|
38
|
+
entry.state = { kind: "connecting", since: this.now() };
|
|
39
|
+
let timer;
|
|
40
|
+
const timeout = new Promise((_, reject) => {
|
|
41
|
+
timer = setTimeout(() => reject(new Error(`Connecting to MCP server "${server.name}" timed out`)), this.connectTimeoutMs);
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
const connection = await Promise.race([this.connector(server), timeout]);
|
|
45
|
+
const at = this.now();
|
|
46
|
+
entry.connection = connection;
|
|
47
|
+
entry.state = { kind: "ready", since: at, lastUsed: at };
|
|
48
|
+
return connection;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
entry.connection = undefined;
|
|
53
|
+
entry.state = {
|
|
54
|
+
kind: "failed",
|
|
55
|
+
error: message,
|
|
56
|
+
failedAt: this.now(),
|
|
57
|
+
retryAfter: this.now() + FAILURE_BACKOFF_MS,
|
|
58
|
+
};
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
if (timer)
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
entry.pending = undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async acquire(name) {
|
|
68
|
+
const server = this.servers.get(name);
|
|
69
|
+
if (!server)
|
|
70
|
+
throw new Error(`MCP server "${name}" is not configured`);
|
|
71
|
+
const entry = this.entry(name);
|
|
72
|
+
if (entry.state.kind === "ready" && entry.connection)
|
|
73
|
+
return entry.connection;
|
|
74
|
+
if (entry.pending)
|
|
75
|
+
return entry.pending;
|
|
76
|
+
// A server that just failed is not retried until its window passes, so one
|
|
77
|
+
// broken server cannot cost every call a spawn attempt.
|
|
78
|
+
if (entry.state.kind === "failed" && this.now() < entry.state.retryAfter) {
|
|
79
|
+
throw new Error(entry.state.error);
|
|
80
|
+
}
|
|
81
|
+
entry.pending = this.connect(server, entry);
|
|
82
|
+
return entry.pending;
|
|
83
|
+
}
|
|
84
|
+
async withConnection(name, use) {
|
|
85
|
+
const connection = await this.acquire(name);
|
|
86
|
+
const result = await use(connection);
|
|
87
|
+
const entry = this.entry(name);
|
|
88
|
+
if (entry.state.kind === "ready")
|
|
89
|
+
entry.state = { ...entry.state, lastUsed: this.now() };
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Connect every `eager` server and cache what it publishes.
|
|
94
|
+
*
|
|
95
|
+
* This is the answer to the cold-cache problem. A lazily configured server has no
|
|
96
|
+
* cached tools until something calls one, so it cannot be discovered by search; a
|
|
97
|
+
* user who wants a server discoverable from the first turn declares it `eager`.
|
|
98
|
+
* Failures are swallowed on purpose, because a broken server must not stop a
|
|
99
|
+
* session from starting.
|
|
100
|
+
*/
|
|
101
|
+
async warmEagerServers(onTools) {
|
|
102
|
+
for (const server of this.servers.values()) {
|
|
103
|
+
if (server.lifecycle !== "eager")
|
|
104
|
+
continue;
|
|
105
|
+
try {
|
|
106
|
+
await this.withConnection(server.name, async (connection) => {
|
|
107
|
+
onTools(server, await connection.listTools());
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Recorded as `failed` by `connect`; the next call reports it.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** Close every `ready` server whose idle window has passed, unless it is kept alive. */
|
|
116
|
+
async sweepIdle() {
|
|
117
|
+
const at = this.now();
|
|
118
|
+
for (const [name, entry] of this.entries) {
|
|
119
|
+
const server = this.servers.get(name);
|
|
120
|
+
if (!server || entry.state.kind !== "ready" || isKeptAlive(server))
|
|
121
|
+
continue;
|
|
122
|
+
if (at - entry.state.lastUsed < server.idleTimeoutMinutes * 60_000)
|
|
123
|
+
continue;
|
|
124
|
+
await this.disconnect(name, entry);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async disconnect(name, entry) {
|
|
128
|
+
const connection = entry.connection;
|
|
129
|
+
entry.connection = undefined;
|
|
130
|
+
entry.state = { kind: "disconnected" };
|
|
131
|
+
if (connection) {
|
|
132
|
+
await connection.close().catch(() => undefined);
|
|
133
|
+
}
|
|
134
|
+
this.entries.set(name, entry);
|
|
135
|
+
}
|
|
136
|
+
async closeAll() {
|
|
137
|
+
for (const [name, entry] of this.entries) {
|
|
138
|
+
await this.disconnect(name, entry);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=server-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-manager.js","sourceRoot":"","sources":["../../../src/core/mcp/server-manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Owns when a server is running and nothing about how it is reached.\n *\n * The `McpConnection` seam is why this module has no MCP SDK import and no child\n * process: lifecycle is the part with the interesting failure modes (a connect that\n * never returns, a broken server retried on every call, two callers racing the same\n * spawn) and all of it is testable against a fake.\n */\n\nimport type { CachedTool, McpConnection, McpConnector, McpServerConfig, ServerState } from \"./types.ts\";\n\nconst DEFAULT_CONNECT_TIMEOUT_MS = 30_000;\nconst FAILURE_BACKOFF_MS = 60_000;\n\ninterface Entry {\n\tstate: ServerState;\n\tconnection: McpConnection | undefined;\n\t/** Held so concurrent callers await one spawn instead of racing a second. */\n\tpending: Promise<McpConnection> | undefined;\n}\n\nexport interface McpServerManagerOptions {\n\tservers: ReadonlyMap<string, McpServerConfig>;\n\tconnector: McpConnector;\n\tnow?: () => number;\n\tconnectTimeoutMs?: number;\n}\n\nfunction isKeptAlive(server: McpServerConfig): boolean {\n\treturn server.lifecycle === \"keep-alive\" || server.lifecycle === \"lazy-keep-alive\";\n}\n\nexport class McpServerManager {\n\tprivate readonly servers: ReadonlyMap<string, McpServerConfig>;\n\tprivate readonly connector: McpConnector;\n\tprivate readonly now: () => number;\n\tprivate readonly connectTimeoutMs: number;\n\tprivate readonly entries = new Map<string, Entry>();\n\n\tconstructor(options: McpServerManagerOptions) {\n\t\tthis.servers = options.servers;\n\t\tthis.connector = options.connector;\n\t\tthis.now = options.now ?? Date.now;\n\t\tthis.connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;\n\t}\n\n\tstate(name: string): ServerState {\n\t\treturn this.entries.get(name)?.state ?? { kind: \"disconnected\" };\n\t}\n\n\tprivate entry(name: string): Entry {\n\t\tlet entry = this.entries.get(name);\n\t\tif (!entry) {\n\t\t\tentry = { state: { kind: \"disconnected\" }, connection: undefined, pending: undefined };\n\t\t\tthis.entries.set(name, entry);\n\t\t}\n\t\treturn entry;\n\t}\n\n\tprivate async connect(server: McpServerConfig, entry: Entry): Promise<McpConnection> {\n\t\tentry.state = { kind: \"connecting\", since: this.now() };\n\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst timeout = new Promise<never>((_, reject) => {\n\t\t\ttimer = setTimeout(\n\t\t\t\t() => reject(new Error(`Connecting to MCP server \"${server.name}\" timed out`)),\n\t\t\t\tthis.connectTimeoutMs,\n\t\t\t);\n\t\t});\n\n\t\ttry {\n\t\t\tconst connection = await Promise.race([this.connector(server), timeout]);\n\t\t\tconst at = this.now();\n\t\t\tentry.connection = connection;\n\t\t\tentry.state = { kind: \"ready\", since: at, lastUsed: at };\n\t\t\treturn connection;\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tentry.connection = undefined;\n\t\t\tentry.state = {\n\t\t\t\tkind: \"failed\",\n\t\t\t\terror: message,\n\t\t\t\tfailedAt: this.now(),\n\t\t\t\tretryAfter: this.now() + FAILURE_BACKOFF_MS,\n\t\t\t};\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tif (timer) clearTimeout(timer);\n\t\t\tentry.pending = undefined;\n\t\t}\n\t}\n\n\tprivate async acquire(name: string): Promise<McpConnection> {\n\t\tconst server = this.servers.get(name);\n\t\tif (!server) throw new Error(`MCP server \"${name}\" is not configured`);\n\n\t\tconst entry = this.entry(name);\n\t\tif (entry.state.kind === \"ready\" && entry.connection) return entry.connection;\n\t\tif (entry.pending) return entry.pending;\n\n\t\t// A server that just failed is not retried until its window passes, so one\n\t\t// broken server cannot cost every call a spawn attempt.\n\t\tif (entry.state.kind === \"failed\" && this.now() < entry.state.retryAfter) {\n\t\t\tthrow new Error(entry.state.error);\n\t\t}\n\n\t\tentry.pending = this.connect(server, entry);\n\t\treturn entry.pending;\n\t}\n\n\tasync withConnection<T>(name: string, use: (connection: McpConnection) => Promise<T>): Promise<T> {\n\t\tconst connection = await this.acquire(name);\n\t\tconst result = await use(connection);\n\n\t\tconst entry = this.entry(name);\n\t\tif (entry.state.kind === \"ready\") entry.state = { ...entry.state, lastUsed: this.now() };\n\t\treturn result;\n\t}\n\n\t/**\n\t * Connect every `eager` server and cache what it publishes.\n\t *\n\t * This is the answer to the cold-cache problem. A lazily configured server has no\n\t * cached tools until something calls one, so it cannot be discovered by search; a\n\t * user who wants a server discoverable from the first turn declares it `eager`.\n\t * Failures are swallowed on purpose, because a broken server must not stop a\n\t * session from starting.\n\t */\n\tasync warmEagerServers(onTools: (server: McpServerConfig, tools: CachedTool[]) => void): Promise<void> {\n\t\tfor (const server of this.servers.values()) {\n\t\t\tif (server.lifecycle !== \"eager\") continue;\n\t\t\ttry {\n\t\t\t\tawait this.withConnection(server.name, async (connection) => {\n\t\t\t\t\tonTools(server, await connection.listTools());\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Recorded as `failed` by `connect`; the next call reports it.\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Close every `ready` server whose idle window has passed, unless it is kept alive. */\n\tasync sweepIdle(): Promise<void> {\n\t\tconst at = this.now();\n\t\tfor (const [name, entry] of this.entries) {\n\t\t\tconst server = this.servers.get(name);\n\t\t\tif (!server || entry.state.kind !== \"ready\" || isKeptAlive(server)) continue;\n\t\t\tif (at - entry.state.lastUsed < server.idleTimeoutMinutes * 60_000) continue;\n\t\t\tawait this.disconnect(name, entry);\n\t\t}\n\t}\n\n\tprivate async disconnect(name: string, entry: Entry): Promise<void> {\n\t\tconst connection = entry.connection;\n\t\tentry.connection = undefined;\n\t\tentry.state = { kind: \"disconnected\" };\n\t\tif (connection) {\n\t\t\tawait connection.close().catch(() => undefined);\n\t\t}\n\t\tthis.entries.set(name, entry);\n\t}\n\n\tasync closeAll(): Promise<void> {\n\t\tfor (const [name, entry] of this.entries) {\n\t\t\tawait this.disconnect(name, entry);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core MCP data shapes. Settled before any logic consumes them, per the plan's U1:
|
|
3
|
+
* a late change to `ServerState` or `CachedTool` is a rewrite of the server manager
|
|
4
|
+
* and the proxy tool, where an early one is a one-line diff.
|
|
5
|
+
*/
|
|
6
|
+
import type { Capability } from "../tools/contract.ts";
|
|
7
|
+
/**
|
|
8
|
+
* How to reach a server. Inferred from which fields the config entry carries, never
|
|
9
|
+
* declared: every MCP host writes `command` for stdio and `url` for HTTP, and none
|
|
10
|
+
* writes a `transport` field, so requiring one would reject the config files users
|
|
11
|
+
* already have.
|
|
12
|
+
*/
|
|
13
|
+
export type McpTransport = {
|
|
14
|
+
kind: "stdio";
|
|
15
|
+
command: string;
|
|
16
|
+
args: string[];
|
|
17
|
+
env: Record<string, string>;
|
|
18
|
+
cwd: string | undefined;
|
|
19
|
+
} | {
|
|
20
|
+
kind: "http";
|
|
21
|
+
url: string;
|
|
22
|
+
headers: Record<string, string>;
|
|
23
|
+
/** Environment variable holding a bearer token. OAuth is a spec non-goal (ADR 0015). */
|
|
24
|
+
bearerTokenEnv: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
export type McpLifecycle = "lazy" | "eager" | "keep-alive" | "lazy-keep-alive";
|
|
27
|
+
export declare const DEFAULT_LIFECYCLE: McpLifecycle;
|
|
28
|
+
export declare const DEFAULT_IDLE_TIMEOUT_MINUTES = 10;
|
|
29
|
+
/**
|
|
30
|
+
* A server's declared authority, and the only place it is stated. The capability set
|
|
31
|
+
* feeds the tool contract every tool on this server projects (ADR 0010), which is why
|
|
32
|
+
* an absent set resolves to the full one rather than the empty one.
|
|
33
|
+
*/
|
|
34
|
+
export interface McpServerConfig {
|
|
35
|
+
name: string;
|
|
36
|
+
transport: McpTransport;
|
|
37
|
+
capabilities: ReadonlySet<Capability>;
|
|
38
|
+
lifecycle: McpLifecycle;
|
|
39
|
+
idleTimeoutMinutes: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Connection state. A union rather than a `connected` boolean beside a `lastError`
|
|
43
|
+
* string, so a state cannot carry data that is invalid for it.
|
|
44
|
+
*/
|
|
45
|
+
export type ServerState = {
|
|
46
|
+
kind: "disconnected";
|
|
47
|
+
} | {
|
|
48
|
+
kind: "connecting";
|
|
49
|
+
since: number;
|
|
50
|
+
} | {
|
|
51
|
+
kind: "ready";
|
|
52
|
+
since: number;
|
|
53
|
+
lastUsed: number;
|
|
54
|
+
} | {
|
|
55
|
+
kind: "failed";
|
|
56
|
+
error: string;
|
|
57
|
+
failedAt: number;
|
|
58
|
+
retryAfter: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* What the disk cache holds. Everything here is producible without a live connection,
|
|
62
|
+
* which is the property that lets search and describe answer with no server running.
|
|
63
|
+
*/
|
|
64
|
+
export interface CachedTool {
|
|
65
|
+
server: string;
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
inputSchema: unknown;
|
|
69
|
+
}
|
|
70
|
+
/** A config problem that dropped an entry or fell back to a default. Never thrown. */
|
|
71
|
+
export interface McpConfigDiagnostic {
|
|
72
|
+
path: string;
|
|
73
|
+
server: string | undefined;
|
|
74
|
+
message: string;
|
|
75
|
+
}
|
|
76
|
+
export interface McpConfig {
|
|
77
|
+
servers: ReadonlyMap<string, McpServerConfig>;
|
|
78
|
+
diagnostics: readonly McpConfigDiagnostic[];
|
|
79
|
+
}
|
|
80
|
+
/** One tool call's result, in the shape the proxy tool converts to `AgentToolResult`. */
|
|
81
|
+
export interface McpCallResult {
|
|
82
|
+
content: Array<{
|
|
83
|
+
type: "text";
|
|
84
|
+
text: string;
|
|
85
|
+
}>;
|
|
86
|
+
isError?: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A live session with one server. The seam that keeps the MCP SDK out of the
|
|
90
|
+
* lifecycle logic, and lets the server manager be tested without a child process.
|
|
91
|
+
*/
|
|
92
|
+
export interface McpConnection {
|
|
93
|
+
listTools(): Promise<CachedTool[]>;
|
|
94
|
+
callTool(name: string, args: unknown): Promise<McpCallResult>;
|
|
95
|
+
close(): Promise<void>;
|
|
96
|
+
}
|
|
97
|
+
export type McpConnector = (server: McpServerConfig) => Promise<McpConnection>;
|
|
98
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACrB;IACA,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACvB,GACD;IACA,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,wFAAwF;IACxF,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAEL,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAE/E,eAAO,MAAM,iBAAiB,EAAE,YAAqB,CAAC;AACtD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,YAAY,CAAC;IACxB,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IACtC,SAAS,EAAE,YAAY,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GACpB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E;;;GAGG;AACH,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACrB;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9C,WAAW,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC5C;AAED,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,SAAS,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC","sourcesContent":["/**\n * Core MCP data shapes. Settled before any logic consumes them, per the plan's U1:\n * a late change to `ServerState` or `CachedTool` is a rewrite of the server manager\n * and the proxy tool, where an early one is a one-line diff.\n */\n\nimport type { Capability } from \"../tools/contract.ts\";\n\n/**\n * How to reach a server. Inferred from which fields the config entry carries, never\n * declared: every MCP host writes `command` for stdio and `url` for HTTP, and none\n * writes a `transport` field, so requiring one would reject the config files users\n * already have.\n */\nexport type McpTransport =\n\t| {\n\t\t\tkind: \"stdio\";\n\t\t\tcommand: string;\n\t\t\targs: string[];\n\t\t\tenv: Record<string, string>;\n\t\t\tcwd: string | undefined;\n\t }\n\t| {\n\t\t\tkind: \"http\";\n\t\t\turl: string;\n\t\t\theaders: Record<string, string>;\n\t\t\t/** Environment variable holding a bearer token. OAuth is a spec non-goal (ADR 0015). */\n\t\t\tbearerTokenEnv: string | undefined;\n\t };\n\nexport type McpLifecycle = \"lazy\" | \"eager\" | \"keep-alive\" | \"lazy-keep-alive\";\n\nexport const DEFAULT_LIFECYCLE: McpLifecycle = \"lazy\";\nexport const DEFAULT_IDLE_TIMEOUT_MINUTES = 10;\n\n/**\n * A server's declared authority, and the only place it is stated. The capability set\n * feeds the tool contract every tool on this server projects (ADR 0010), which is why\n * an absent set resolves to the full one rather than the empty one.\n */\nexport interface McpServerConfig {\n\tname: string;\n\ttransport: McpTransport;\n\tcapabilities: ReadonlySet<Capability>;\n\tlifecycle: McpLifecycle;\n\tidleTimeoutMinutes: number;\n}\n\n/**\n * Connection state. A union rather than a `connected` boolean beside a `lastError`\n * string, so a state cannot carry data that is invalid for it.\n */\nexport type ServerState =\n\t| { kind: \"disconnected\" }\n\t| { kind: \"connecting\"; since: number }\n\t| { kind: \"ready\"; since: number; lastUsed: number }\n\t| { kind: \"failed\"; error: string; failedAt: number; retryAfter: number };\n\n/**\n * What the disk cache holds. Everything here is producible without a live connection,\n * which is the property that lets search and describe answer with no server running.\n */\nexport interface CachedTool {\n\tserver: string;\n\tname: string;\n\tdescription: string;\n\tinputSchema: unknown;\n}\n\n/** A config problem that dropped an entry or fell back to a default. Never thrown. */\nexport interface McpConfigDiagnostic {\n\tpath: string;\n\tserver: string | undefined;\n\tmessage: string;\n}\n\nexport interface McpConfig {\n\tservers: ReadonlyMap<string, McpServerConfig>;\n\tdiagnostics: readonly McpConfigDiagnostic[];\n}\n\n/** One tool call's result, in the shape the proxy tool converts to `AgentToolResult`. */\nexport interface McpCallResult {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tisError?: boolean;\n}\n\n/**\n * A live session with one server. The seam that keeps the MCP SDK out of the\n * lifecycle logic, and lets the server manager be tested without a child process.\n */\nexport interface McpConnection {\n\tlistTools(): Promise<CachedTool[]>;\n\tcallTool(name: string, args: unknown): Promise<McpCallResult>;\n\tclose(): Promise<void>;\n}\n\nexport type McpConnector = (server: McpServerConfig) => Promise<McpConnection>;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core MCP data shapes. Settled before any logic consumes them, per the plan's U1:
|
|
3
|
+
* a late change to `ServerState` or `CachedTool` is a rewrite of the server manager
|
|
4
|
+
* and the proxy tool, where an early one is a one-line diff.
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_LIFECYCLE = "lazy";
|
|
7
|
+
export const DEFAULT_IDLE_TIMEOUT_MINUTES = 10;
|
|
8
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/mcp/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4BH,MAAM,CAAC,MAAM,iBAAiB,GAAiB,MAAM,CAAC;AACtD,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC","sourcesContent":["/**\n * Core MCP data shapes. Settled before any logic consumes them, per the plan's U1:\n * a late change to `ServerState` or `CachedTool` is a rewrite of the server manager\n * and the proxy tool, where an early one is a one-line diff.\n */\n\nimport type { Capability } from \"../tools/contract.ts\";\n\n/**\n * How to reach a server. Inferred from which fields the config entry carries, never\n * declared: every MCP host writes `command` for stdio and `url` for HTTP, and none\n * writes a `transport` field, so requiring one would reject the config files users\n * already have.\n */\nexport type McpTransport =\n\t| {\n\t\t\tkind: \"stdio\";\n\t\t\tcommand: string;\n\t\t\targs: string[];\n\t\t\tenv: Record<string, string>;\n\t\t\tcwd: string | undefined;\n\t }\n\t| {\n\t\t\tkind: \"http\";\n\t\t\turl: string;\n\t\t\theaders: Record<string, string>;\n\t\t\t/** Environment variable holding a bearer token. OAuth is a spec non-goal (ADR 0015). */\n\t\t\tbearerTokenEnv: string | undefined;\n\t };\n\nexport type McpLifecycle = \"lazy\" | \"eager\" | \"keep-alive\" | \"lazy-keep-alive\";\n\nexport const DEFAULT_LIFECYCLE: McpLifecycle = \"lazy\";\nexport const DEFAULT_IDLE_TIMEOUT_MINUTES = 10;\n\n/**\n * A server's declared authority, and the only place it is stated. The capability set\n * feeds the tool contract every tool on this server projects (ADR 0010), which is why\n * an absent set resolves to the full one rather than the empty one.\n */\nexport interface McpServerConfig {\n\tname: string;\n\ttransport: McpTransport;\n\tcapabilities: ReadonlySet<Capability>;\n\tlifecycle: McpLifecycle;\n\tidleTimeoutMinutes: number;\n}\n\n/**\n * Connection state. A union rather than a `connected` boolean beside a `lastError`\n * string, so a state cannot carry data that is invalid for it.\n */\nexport type ServerState =\n\t| { kind: \"disconnected\" }\n\t| { kind: \"connecting\"; since: number }\n\t| { kind: \"ready\"; since: number; lastUsed: number }\n\t| { kind: \"failed\"; error: string; failedAt: number; retryAfter: number };\n\n/**\n * What the disk cache holds. Everything here is producible without a live connection,\n * which is the property that lets search and describe answer with no server running.\n */\nexport interface CachedTool {\n\tserver: string;\n\tname: string;\n\tdescription: string;\n\tinputSchema: unknown;\n}\n\n/** A config problem that dropped an entry or fell back to a default. Never thrown. */\nexport interface McpConfigDiagnostic {\n\tpath: string;\n\tserver: string | undefined;\n\tmessage: string;\n}\n\nexport interface McpConfig {\n\tservers: ReadonlyMap<string, McpServerConfig>;\n\tdiagnostics: readonly McpConfigDiagnostic[];\n}\n\n/** One tool call's result, in the shape the proxy tool converts to `AgentToolResult`. */\nexport interface McpCallResult {\n\tcontent: Array<{ type: \"text\"; text: string }>;\n\tisError?: boolean;\n}\n\n/**\n * A live session with one server. The seam that keeps the MCP SDK out of the\n * lifecycle logic, and lets the server manager be tested without a child process.\n */\nexport interface McpConnection {\n\tlistTools(): Promise<CachedTool[]>;\n\tcallTool(name: string, args: unknown): Promise<McpCallResult>;\n\tclose(): Promise<void>;\n}\n\nexport type McpConnector = (server: McpServerConfig) => Promise<McpConnection>;\n"]}
|
|
@@ -38,6 +38,7 @@ declare const ModelDefinitionSchema: Type.TObject<{
|
|
|
38
38
|
supportsDeveloperRole: Type.TOptional<Type.TBoolean>;
|
|
39
39
|
supportsReasoningEffort: Type.TOptional<Type.TBoolean>;
|
|
40
40
|
supportsUsageInStreaming: Type.TOptional<Type.TBoolean>;
|
|
41
|
+
supportsFinishReason: Type.TOptional<Type.TBoolean>;
|
|
41
42
|
maxTokensField: Type.TOptional<Type.TUnion<[Type.TLiteral<"max_completion_tokens">, Type.TLiteral<"max_tokens">]>>;
|
|
42
43
|
requiresToolResultName: Type.TOptional<Type.TBoolean>;
|
|
43
44
|
requiresAssistantAfterToolResult: Type.TOptional<Type.TBoolean>;
|
|
@@ -103,6 +104,7 @@ declare const ModelDefinitionSchema: Type.TObject<{
|
|
|
103
104
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
104
105
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
105
106
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
107
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
106
108
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
107
109
|
}>, Type.TObject<{
|
|
108
110
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -151,6 +153,7 @@ declare const ModelOverrideSchema: Type.TObject<{
|
|
|
151
153
|
supportsDeveloperRole: Type.TOptional<Type.TBoolean>;
|
|
152
154
|
supportsReasoningEffort: Type.TOptional<Type.TBoolean>;
|
|
153
155
|
supportsUsageInStreaming: Type.TOptional<Type.TBoolean>;
|
|
156
|
+
supportsFinishReason: Type.TOptional<Type.TBoolean>;
|
|
154
157
|
maxTokensField: Type.TOptional<Type.TUnion<[Type.TLiteral<"max_completion_tokens">, Type.TLiteral<"max_tokens">]>>;
|
|
155
158
|
requiresToolResultName: Type.TOptional<Type.TBoolean>;
|
|
156
159
|
requiresAssistantAfterToolResult: Type.TOptional<Type.TBoolean>;
|
|
@@ -216,6 +219,7 @@ declare const ModelOverrideSchema: Type.TObject<{
|
|
|
216
219
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
217
220
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
218
221
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
222
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
219
223
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
220
224
|
}>, Type.TObject<{
|
|
221
225
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -241,6 +245,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
241
245
|
supportsDeveloperRole: Type.TOptional<Type.TBoolean>;
|
|
242
246
|
supportsReasoningEffort: Type.TOptional<Type.TBoolean>;
|
|
243
247
|
supportsUsageInStreaming: Type.TOptional<Type.TBoolean>;
|
|
248
|
+
supportsFinishReason: Type.TOptional<Type.TBoolean>;
|
|
244
249
|
maxTokensField: Type.TOptional<Type.TUnion<[Type.TLiteral<"max_completion_tokens">, Type.TLiteral<"max_tokens">]>>;
|
|
245
250
|
requiresToolResultName: Type.TOptional<Type.TBoolean>;
|
|
246
251
|
requiresAssistantAfterToolResult: Type.TOptional<Type.TBoolean>;
|
|
@@ -306,6 +311,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
306
311
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
307
312
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
308
313
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
314
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
309
315
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
310
316
|
}>, Type.TObject<{
|
|
311
317
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -357,6 +363,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
357
363
|
supportsDeveloperRole: Type.TOptional<Type.TBoolean>;
|
|
358
364
|
supportsReasoningEffort: Type.TOptional<Type.TBoolean>;
|
|
359
365
|
supportsUsageInStreaming: Type.TOptional<Type.TBoolean>;
|
|
366
|
+
supportsFinishReason: Type.TOptional<Type.TBoolean>;
|
|
360
367
|
maxTokensField: Type.TOptional<Type.TUnion<[Type.TLiteral<"max_completion_tokens">, Type.TLiteral<"max_tokens">]>>;
|
|
361
368
|
requiresToolResultName: Type.TOptional<Type.TBoolean>;
|
|
362
369
|
requiresAssistantAfterToolResult: Type.TOptional<Type.TBoolean>;
|
|
@@ -422,6 +429,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
422
429
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
423
430
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
424
431
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
432
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
425
433
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
426
434
|
}>, Type.TObject<{
|
|
427
435
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -470,6 +478,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
470
478
|
supportsDeveloperRole: Type.TOptional<Type.TBoolean>;
|
|
471
479
|
supportsReasoningEffort: Type.TOptional<Type.TBoolean>;
|
|
472
480
|
supportsUsageInStreaming: Type.TOptional<Type.TBoolean>;
|
|
481
|
+
supportsFinishReason: Type.TOptional<Type.TBoolean>;
|
|
473
482
|
maxTokensField: Type.TOptional<Type.TUnion<[Type.TLiteral<"max_completion_tokens">, Type.TLiteral<"max_tokens">]>>;
|
|
474
483
|
requiresToolResultName: Type.TOptional<Type.TBoolean>;
|
|
475
484
|
requiresAssistantAfterToolResult: Type.TOptional<Type.TBoolean>;
|
|
@@ -535,6 +544,7 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
535
544
|
supportsLongCacheRetention: Type.TOptional<Type.TBoolean>;
|
|
536
545
|
supportsStrictMode: Type.TOptional<Type.TBoolean>;
|
|
537
546
|
supportsOpenAIGrammarTools: Type.TOptional<Type.TBoolean>;
|
|
547
|
+
supportsAdditionalTools: Type.TOptional<Type.TBoolean>;
|
|
538
548
|
supportsToolSearch: Type.TOptional<Type.TBoolean>;
|
|
539
549
|
}>, Type.TObject<{
|
|
540
550
|
supportsEagerToolInputStreaming: Type.TOptional<Type.TBoolean>;
|
|
@@ -549,17 +559,25 @@ declare const ProviderConfigSchema: Type.TObject<{
|
|
|
549
559
|
}>]>>;
|
|
550
560
|
}>>>;
|
|
551
561
|
}>;
|
|
562
|
+
declare const RoleDefinitionSchema: Type.TObject<{
|
|
563
|
+
/** Ordered, non-empty list of canonical "provider/modelId" candidates. */
|
|
564
|
+
models: Type.TArray<Type.TString>;
|
|
565
|
+
}>;
|
|
552
566
|
export type ModelsJsonModel = Static<typeof ModelDefinitionSchema>;
|
|
553
567
|
export type ModelsJsonModelOverride = Static<typeof ModelOverrideSchema>;
|
|
554
568
|
export type ModelsJsonProvider = Static<typeof ProviderConfigSchema>;
|
|
569
|
+
export type ModelsJsonRoleDefinition = Static<typeof RoleDefinitionSchema>;
|
|
555
570
|
/** One immutable load of models.json. */
|
|
556
571
|
export declare class ModelConfig {
|
|
557
572
|
private readonly providers;
|
|
573
|
+
private readonly roles;
|
|
558
574
|
private readonly error;
|
|
559
575
|
private constructor();
|
|
560
576
|
static load(modelsJsonPath: string | undefined): Promise<ModelConfig>;
|
|
561
577
|
getProvider(providerId: string): ModelsJsonProvider | undefined;
|
|
562
578
|
getProviderIds(): readonly string[];
|
|
579
|
+
/** Additive role -> ordered "provider/modelId" candidate references, unresolved. */
|
|
580
|
+
getRoles(): ReadonlyMap<string, readonly string[]>;
|
|
563
581
|
getError(): string | undefined;
|
|
564
582
|
}
|
|
565
583
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-config.d.ts","sourceRoot":"","sources":["../../src/core/model-config.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAGxD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAwJ5C,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAczB,CAAC;AAEH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBvB,CAAC;AAEH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWxB,CAAC;AAOH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACnE,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAsBrE,yCAAyC;AACzC,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAE3C,OAAO,eAGN;IAED,OAAa,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAuC1E;IAED,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE9D;IAED,cAAc,IAAI,SAAS,MAAM,EAAE,CAElC;IAED,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7B;CACD","sourcesContent":["/** Immutable, credential-blind models.json snapshot. */\n\nimport { readFile } from \"node:fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { stripJsonComments } from \"../utils/json.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\n\nconst PercentileCutoffsSchema = Type.Object({\n\tp50: Type.Optional(Type.Number()),\n\tp75: Type.Optional(Type.Number()),\n\tp90: Type.Optional(Type.Number()),\n\tp99: Type.Optional(Type.Number()),\n});\n\nconst OpenRouterRoutingSchema = Type.Object({\n\tallow_fallbacks: Type.Optional(Type.Boolean()),\n\trequire_parameters: Type.Optional(Type.Boolean()),\n\tdata_collection: Type.Optional(Type.Union([Type.Literal(\"deny\"), Type.Literal(\"allow\")])),\n\tzdr: Type.Optional(Type.Boolean()),\n\tenforce_distillable_text: Type.Optional(Type.Boolean()),\n\torder: Type.Optional(Type.Array(Type.String())),\n\tonly: Type.Optional(Type.Array(Type.String())),\n\tignore: Type.Optional(Type.Array(Type.String())),\n\tquantizations: Type.Optional(Type.Array(Type.String())),\n\tsort: Type.Optional(\n\t\tType.Union([\n\t\t\tType.String(),\n\t\t\tType.Object({\n\t\t\t\tby: Type.Optional(Type.String()),\n\t\t\t\tpartition: Type.Optional(Type.Union([Type.String(), Type.Null()])),\n\t\t\t}),\n\t\t]),\n\t),\n\tmax_price: Type.Optional(\n\t\tType.Object({\n\t\t\tprompt: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\tcompletion: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\timage: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\taudio: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\trequest: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t}),\n\t),\n\tpreferred_min_throughput: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n\tpreferred_max_latency: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n});\n\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\nconst ThinkingLevelMapValueSchema = Type.Union([Type.String(), Type.Null()]);\nconst ThinkingLevelMapSchema = Type.Object({\n\toff: Type.Optional(ThinkingLevelMapValueSchema),\n\tminimal: Type.Optional(ThinkingLevelMapValueSchema),\n\tlow: Type.Optional(ThinkingLevelMapValueSchema),\n\tmedium: Type.Optional(ThinkingLevelMapValueSchema),\n\thigh: Type.Optional(ThinkingLevelMapValueSchema),\n\txhigh: Type.Optional(ThinkingLevelMapValueSchema),\n\tmax: Type.Optional(ThinkingLevelMapValueSchema),\n});\n\nconst ChatTemplateKwargScalarSchema = Type.Union([Type.String(), Type.Number(), Type.Boolean(), Type.Null()]);\nconst ChatTemplateKwargVariableSchema = Type.Object({\n\t$var: Type.Union([Type.Literal(\"thinking.enabled\"), Type.Literal(\"thinking.effort\")]),\n\tomitWhenOff: Type.Optional(Type.Boolean()),\n});\nconst ChatTemplateKwargSchema = Type.Union([ChatTemplateKwargScalarSchema, ChatTemplateKwargVariableSchema]);\n\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresReasoningContentOnAssistantMessages: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"openai\"),\n\t\t\tType.Literal(\"openrouter\"),\n\t\t\tType.Literal(\"together\"),\n\t\t\tType.Literal(\"baseten\"),\n\t\t\tType.Literal(\"deepseek\"),\n\t\t\tType.Literal(\"zai\"),\n\t\t\tType.Literal(\"qwen\"),\n\t\t\tType.Literal(\"chat-template\"),\n\t\t\tType.Literal(\"qwen-chat-template\"),\n\t\t\tType.Literal(\"string-thinking\"),\n\t\t\tType.Literal(\"ant-ling\"),\n\t\t]),\n\t),\n\tchatTemplateKwargs: Type.Optional(Type.Record(Type.String(), ChatTemplateKwargSchema)),\n\tchatTemplateArgs: Type.Optional(Type.Record(Type.String(), ChatTemplateKwargSchema)),\n\tcacheControlFormat: Type.Optional(Type.Literal(\"anthropic\")),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n\tsupportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsendSessionAffinityHeaders: Type.Optional(Type.Boolean()),\n\tdeferredToolsMode: Type.Optional(Type.Literal(\"kimi\")),\n\tsessionAffinityFormat: Type.Optional(\n\t\tType.Union([Type.Literal(\"openai\"), Type.Literal(\"openai-nosession\"), Type.Literal(\"openrouter\")]),\n\t),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsessionAffinityFormat: Type.Optional(\n\t\tType.Union([Type.Literal(\"openai\"), Type.Literal(\"openai-nosession\"), Type.Literal(\"openrouter\")]),\n\t),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsupportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),\n\tsupportsToolSearch: Type.Optional(Type.Boolean()),\n});\n\nconst AnthropicMessagesCompatSchema = Type.Object({\n\tsupportsEagerToolInputStreaming: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tsendSessionAffinityHeaders: Type.Optional(Type.Boolean()),\n\tsupportsCacheControlOnTools: Type.Optional(Type.Boolean()),\n\tsupportsTemperature: Type.Optional(Type.Boolean()),\n\tforceAdaptiveThinking: Type.Optional(Type.Boolean()),\n\tallowEmptySignature: Type.Optional(Type.Boolean()),\n\tsupportsStrictTools: Type.Optional(Type.Boolean()),\n\tsupportsToolReferences: Type.Optional(Type.Boolean()),\n});\n\nconst ProviderCompatSchema = Type.Union([\n\tOpenAICompletionsCompatSchema,\n\tOpenAIResponsesCompatSchema,\n\tAnthropicMessagesCompatSchema,\n]);\n\nconst ModelCostRatesSchema = {\n\tinput: Type.Number(),\n\toutput: Type.Number(),\n\tcacheRead: Type.Number(),\n\tcacheWrite: Type.Number(),\n};\nconst ModelCostTierSchema = Type.Object({\n\tinputTokensAbove: Type.Number(),\n\t...ModelCostRatesSchema,\n});\nconst ModelCostSchema = Type.Object({\n\t...ModelCostRatesSchema,\n\ttiers: Type.Optional(Type.Array(ModelCostTierSchema)),\n});\n\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(ModelCostSchema),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\tsamplingParams: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t\ttiers: Type.Optional(Type.Array(ModelCostTierSchema)),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\tsamplingParams: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\nconst ProviderConfigSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\toauth: Type.Optional(Type.Literal(\"radius\")),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n});\nconst validateModelsConfig = Compile(ModelsConfigSchema);\n\nexport type ModelsJsonModel = Static<typeof ModelDefinitionSchema>;\nexport type ModelsJsonModelOverride = Static<typeof ModelOverrideSchema>;\nexport type ModelsJsonProvider = Static<typeof ProviderConfigSchema>;\ntype ModelsJson = Static<typeof ModelsConfigSchema>;\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\nfunction deepFreeze<T>(value: T): T {\n\tif (typeof value !== \"object\" || value === null || Object.isFrozen(value)) return value;\n\tfor (const child of Object.values(value)) deepFreeze(child);\n\treturn Object.freeze(value);\n}\n\n/** One immutable load of models.json. */\nexport class ModelConfig {\n\tprivate readonly providers: ReadonlyMap<string, ModelsJsonProvider>;\n\tprivate readonly error: string | undefined;\n\n\tprivate constructor(providers: ReadonlyMap<string, ModelsJsonProvider>, error?: string) {\n\t\tthis.providers = providers;\n\t\tthis.error = error;\n\t}\n\n\tstatic async load(modelsJsonPath: string | undefined): Promise<ModelConfig> {\n\t\tif (!modelsJsonPath) return new ModelConfig(new Map());\n\t\tconst path = normalizePath(modelsJsonPath);\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await readFile(path, \"utf-8\");\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return new ModelConfig(new Map());\n\t\t\treturn new ModelConfig(\n\t\t\t\tnew Map(),\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${path}`,\n\t\t\t);\n\t\t}\n\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(stripJsonComments(content));\n\t\t} catch (error) {\n\t\t\treturn new ModelConfig(\n\t\t\t\tnew Map(),\n\t\t\t\t`Failed to parse models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${path}`,\n\t\t\t);\n\t\t}\n\n\t\tif (!validateModelsConfig.Check(parsed)) {\n\t\t\tconst errors =\n\t\t\t\tvalidateModelsConfig\n\t\t\t\t\t.Errors(parsed)\n\t\t\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t\t\t.join(\"\\n\") || \"Unknown schema error\";\n\t\t\treturn new ModelConfig(new Map(), `Invalid models.json schema:\\n${errors}\\n\\nFile: ${path}`);\n\t\t}\n\n\t\tconst config = parsed as ModelsJson;\n\t\tconst providers = new Map<string, ModelsJsonProvider>();\n\t\tfor (const [providerId, provider] of Object.entries(config.providers)) {\n\t\t\tproviders.set(providerId, deepFreeze(structuredClone(provider)));\n\t\t}\n\t\treturn new ModelConfig(providers);\n\t}\n\n\tgetProvider(providerId: string): ModelsJsonProvider | undefined {\n\t\treturn this.providers.get(providerId);\n\t}\n\n\tgetProviderIds(): readonly string[] {\n\t\treturn [...this.providers.keys()];\n\t}\n\n\tgetError(): string | undefined {\n\t\treturn this.error;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-config.d.ts","sourceRoot":"","sources":["../../src/core/model-config.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAGxD,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AA2J5C,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAczB,CAAC;AAEH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBvB,CAAC;AAEH,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWxB,CAAC;AAEH,QAAA,MAAM,oBAAoB;IACzB,0EAA0E;;EAEzE,CAAC;AASH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACnE,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACrE,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAsB3E,yCAAyC;AACzC,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IACpE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;IAC/D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAE3C,OAAO,eAQN;IAED,OAAa,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CA6C1E;IAED,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE9D;IAED,cAAc,IAAI,SAAS,MAAM,EAAE,CAElC;IAED,oFAAoF;IACpF,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAEjD;IAED,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7B;CACD","sourcesContent":["/** Immutable, credential-blind models.json snapshot. */\n\nimport { readFile } from \"node:fs/promises\";\nimport { type Static, Type } from \"typebox\";\nimport { Compile } from \"typebox/compile\";\nimport type { TLocalizedValidationError } from \"typebox/error\";\nimport { stripJsonComments } from \"../utils/json.ts\";\nimport { normalizePath } from \"../utils/paths.ts\";\nimport { stripBom } from \"../utils/text.ts\";\n\nconst PercentileCutoffsSchema = Type.Object({\n\tp50: Type.Optional(Type.Number()),\n\tp75: Type.Optional(Type.Number()),\n\tp90: Type.Optional(Type.Number()),\n\tp99: Type.Optional(Type.Number()),\n});\n\nconst OpenRouterRoutingSchema = Type.Object({\n\tallow_fallbacks: Type.Optional(Type.Boolean()),\n\trequire_parameters: Type.Optional(Type.Boolean()),\n\tdata_collection: Type.Optional(Type.Union([Type.Literal(\"deny\"), Type.Literal(\"allow\")])),\n\tzdr: Type.Optional(Type.Boolean()),\n\tenforce_distillable_text: Type.Optional(Type.Boolean()),\n\torder: Type.Optional(Type.Array(Type.String())),\n\tonly: Type.Optional(Type.Array(Type.String())),\n\tignore: Type.Optional(Type.Array(Type.String())),\n\tquantizations: Type.Optional(Type.Array(Type.String())),\n\tsort: Type.Optional(\n\t\tType.Union([\n\t\t\tType.String(),\n\t\t\tType.Object({\n\t\t\t\tby: Type.Optional(Type.String()),\n\t\t\t\tpartition: Type.Optional(Type.Union([Type.String(), Type.Null()])),\n\t\t\t}),\n\t\t]),\n\t),\n\tmax_price: Type.Optional(\n\t\tType.Object({\n\t\t\tprompt: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\tcompletion: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\timage: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\taudio: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t\trequest: Type.Optional(Type.Union([Type.Number(), Type.String()])),\n\t\t}),\n\t),\n\tpreferred_min_throughput: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n\tpreferred_max_latency: Type.Optional(Type.Union([Type.Number(), PercentileCutoffsSchema])),\n});\n\nconst VercelGatewayRoutingSchema = Type.Object({\n\tonly: Type.Optional(Type.Array(Type.String())),\n\torder: Type.Optional(Type.Array(Type.String())),\n});\n\nconst ThinkingLevelMapValueSchema = Type.Union([Type.String(), Type.Null()]);\nconst ThinkingLevelMapSchema = Type.Object({\n\toff: Type.Optional(ThinkingLevelMapValueSchema),\n\tminimal: Type.Optional(ThinkingLevelMapValueSchema),\n\tlow: Type.Optional(ThinkingLevelMapValueSchema),\n\tmedium: Type.Optional(ThinkingLevelMapValueSchema),\n\thigh: Type.Optional(ThinkingLevelMapValueSchema),\n\txhigh: Type.Optional(ThinkingLevelMapValueSchema),\n\tmax: Type.Optional(ThinkingLevelMapValueSchema),\n});\n\nconst ChatTemplateKwargScalarSchema = Type.Union([Type.String(), Type.Number(), Type.Boolean(), Type.Null()]);\nconst ChatTemplateKwargVariableSchema = Type.Object({\n\t$var: Type.Union([Type.Literal(\"thinking.enabled\"), Type.Literal(\"thinking.effort\")]),\n\tomitWhenOff: Type.Optional(Type.Boolean()),\n});\nconst ChatTemplateKwargSchema = Type.Union([ChatTemplateKwargScalarSchema, ChatTemplateKwargVariableSchema]);\n\nconst OpenAICompletionsCompatSchema = Type.Object({\n\tsupportsStore: Type.Optional(Type.Boolean()),\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsupportsReasoningEffort: Type.Optional(Type.Boolean()),\n\tsupportsUsageInStreaming: Type.Optional(Type.Boolean()),\n\tsupportsFinishReason: Type.Optional(Type.Boolean()),\n\tmaxTokensField: Type.Optional(Type.Union([Type.Literal(\"max_completion_tokens\"), Type.Literal(\"max_tokens\")])),\n\trequiresToolResultName: Type.Optional(Type.Boolean()),\n\trequiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),\n\trequiresThinkingAsText: Type.Optional(Type.Boolean()),\n\trequiresReasoningContentOnAssistantMessages: Type.Optional(Type.Boolean()),\n\tthinkingFormat: Type.Optional(\n\t\tType.Union([\n\t\t\tType.Literal(\"openai\"),\n\t\t\tType.Literal(\"openrouter\"),\n\t\t\tType.Literal(\"together\"),\n\t\t\tType.Literal(\"baseten\"),\n\t\t\tType.Literal(\"deepseek\"),\n\t\t\tType.Literal(\"zai\"),\n\t\t\tType.Literal(\"qwen\"),\n\t\t\tType.Literal(\"chat-template\"),\n\t\t\tType.Literal(\"qwen-chat-template\"),\n\t\t\tType.Literal(\"string-thinking\"),\n\t\t\tType.Literal(\"ant-ling\"),\n\t\t]),\n\t),\n\tchatTemplateKwargs: Type.Optional(Type.Record(Type.String(), ChatTemplateKwargSchema)),\n\tchatTemplateArgs: Type.Optional(Type.Record(Type.String(), ChatTemplateKwargSchema)),\n\tcacheControlFormat: Type.Optional(Type.Literal(\"anthropic\")),\n\topenRouterRouting: Type.Optional(OpenRouterRoutingSchema),\n\tvercelGatewayRouting: Type.Optional(VercelGatewayRoutingSchema),\n\tsupportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsendSessionAffinityHeaders: Type.Optional(Type.Boolean()),\n\tdeferredToolsMode: Type.Optional(Type.Literal(\"kimi\")),\n\tsessionAffinityFormat: Type.Optional(\n\t\tType.Union([Type.Literal(\"openai\"), Type.Literal(\"openai-nosession\"), Type.Literal(\"openrouter\")]),\n\t),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n});\n\nconst OpenAIResponsesCompatSchema = Type.Object({\n\tsupportsDeveloperRole: Type.Optional(Type.Boolean()),\n\tsessionAffinityFormat: Type.Optional(\n\t\tType.Union([Type.Literal(\"openai\"), Type.Literal(\"openai-nosession\"), Type.Literal(\"openrouter\")]),\n\t),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tsupportsStrictMode: Type.Optional(Type.Boolean()),\n\tsupportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),\n\tsupportsAdditionalTools: Type.Optional(Type.Boolean()),\n\tsupportsToolSearch: Type.Optional(Type.Boolean()),\n});\n\nconst AnthropicMessagesCompatSchema = Type.Object({\n\tsupportsEagerToolInputStreaming: Type.Optional(Type.Boolean()),\n\tsupportsLongCacheRetention: Type.Optional(Type.Boolean()),\n\tsendSessionAffinityHeaders: Type.Optional(Type.Boolean()),\n\tsupportsCacheControlOnTools: Type.Optional(Type.Boolean()),\n\tsupportsTemperature: Type.Optional(Type.Boolean()),\n\tforceAdaptiveThinking: Type.Optional(Type.Boolean()),\n\tallowEmptySignature: Type.Optional(Type.Boolean()),\n\tsupportsStrictTools: Type.Optional(Type.Boolean()),\n\tsupportsToolReferences: Type.Optional(Type.Boolean()),\n});\n\nconst ProviderCompatSchema = Type.Union([\n\tOpenAICompletionsCompatSchema,\n\tOpenAIResponsesCompatSchema,\n\tAnthropicMessagesCompatSchema,\n]);\n\nconst ModelCostRatesSchema = {\n\tinput: Type.Number(),\n\toutput: Type.Number(),\n\tcacheRead: Type.Number(),\n\tcacheWrite: Type.Number(),\n};\nconst ModelCostTierSchema = Type.Object({\n\tinputTokensAbove: Type.Number(),\n\t...ModelCostRatesSchema,\n});\nconst ModelCostSchema = Type.Object({\n\t...ModelCostRatesSchema,\n\ttiers: Type.Optional(Type.Array(ModelCostTierSchema)),\n});\n\nconst ModelDefinitionSchema = Type.Object({\n\tid: Type.String({ minLength: 1 }),\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(ModelCostSchema),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\tsamplingParams: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\nconst ModelOverrideSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\treasoning: Type.Optional(Type.Boolean()),\n\tthinkingLevelMap: Type.Optional(ThinkingLevelMapSchema),\n\tinput: Type.Optional(Type.Array(Type.Union([Type.Literal(\"text\"), Type.Literal(\"image\")]))),\n\tcost: Type.Optional(\n\t\tType.Object({\n\t\t\tinput: Type.Optional(Type.Number()),\n\t\t\toutput: Type.Optional(Type.Number()),\n\t\t\tcacheRead: Type.Optional(Type.Number()),\n\t\t\tcacheWrite: Type.Optional(Type.Number()),\n\t\t\ttiers: Type.Optional(Type.Array(ModelCostTierSchema)),\n\t\t}),\n\t),\n\tcontextWindow: Type.Optional(Type.Number()),\n\tmaxTokens: Type.Optional(Type.Number()),\n\tsamplingParams: Type.Optional(Type.Record(Type.String(), Type.Unknown())),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n});\n\nconst ProviderConfigSchema = Type.Object({\n\tname: Type.Optional(Type.String({ minLength: 1 })),\n\tbaseUrl: Type.Optional(Type.String({ minLength: 1 })),\n\tapiKey: Type.Optional(Type.String({ minLength: 1 })),\n\tapi: Type.Optional(Type.String({ minLength: 1 })),\n\toauth: Type.Optional(Type.Literal(\"radius\")),\n\theaders: Type.Optional(Type.Record(Type.String(), Type.String())),\n\tcompat: Type.Optional(ProviderCompatSchema),\n\tauthHeader: Type.Optional(Type.Boolean()),\n\tmodels: Type.Optional(Type.Array(ModelDefinitionSchema)),\n\tmodelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),\n});\n\nconst RoleDefinitionSchema = Type.Object({\n\t/** Ordered, non-empty list of canonical \"provider/modelId\" candidates. */\n\tmodels: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),\n});\n\nconst ModelsConfigSchema = Type.Object({\n\tproviders: Type.Record(Type.String(), ProviderConfigSchema),\n\t/** Additive, credential-blind role -> ordered model-candidate mapping. */\n\troles: Type.Optional(Type.Record(Type.String(), RoleDefinitionSchema)),\n});\nconst validateModelsConfig = Compile(ModelsConfigSchema);\n\nexport type ModelsJsonModel = Static<typeof ModelDefinitionSchema>;\nexport type ModelsJsonModelOverride = Static<typeof ModelOverrideSchema>;\nexport type ModelsJsonProvider = Static<typeof ProviderConfigSchema>;\nexport type ModelsJsonRoleDefinition = Static<typeof RoleDefinitionSchema>;\ntype ModelsJson = Static<typeof ModelsConfigSchema>;\n\nfunction formatValidationPath(error: TLocalizedValidationError): string {\n\tif (error.keyword === \"required\") {\n\t\tconst requiredProperties = (error.params as { requiredProperties?: string[] }).requiredProperties;\n\t\tconst requiredProperty = requiredProperties?.[0];\n\t\tif (requiredProperty) {\n\t\t\tconst basePath = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\t\t\treturn basePath ? `${basePath}.${requiredProperty}` : requiredProperty;\n\t\t}\n\t}\n\tconst path = error.instancePath.replace(/^\\//, \"\").replace(/\\//g, \".\");\n\treturn path || \"root\";\n}\n\nfunction deepFreeze<T>(value: T): T {\n\tif (typeof value !== \"object\" || value === null || Object.isFrozen(value)) return value;\n\tfor (const child of Object.values(value)) deepFreeze(child);\n\treturn Object.freeze(value);\n}\n\n/** One immutable load of models.json. */\nexport class ModelConfig {\n\tprivate readonly providers: ReadonlyMap<string, ModelsJsonProvider>;\n\tprivate readonly roles: ReadonlyMap<string, readonly string[]>;\n\tprivate readonly error: string | undefined;\n\n\tprivate constructor(\n\t\tproviders: ReadonlyMap<string, ModelsJsonProvider>,\n\t\troles: ReadonlyMap<string, readonly string[]> = new Map(),\n\t\terror?: string,\n\t) {\n\t\tthis.providers = providers;\n\t\tthis.roles = roles;\n\t\tthis.error = error;\n\t}\n\n\tstatic async load(modelsJsonPath: string | undefined): Promise<ModelConfig> {\n\t\tif (!modelsJsonPath) return new ModelConfig(new Map());\n\t\tconst path = normalizePath(modelsJsonPath);\n\t\tlet content: string;\n\t\ttry {\n\t\t\tcontent = await readFile(path, \"utf-8\");\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code === \"ENOENT\") return new ModelConfig(new Map());\n\t\t\treturn new ModelConfig(\n\t\t\t\tnew Map(),\n\t\t\t\tnew Map(),\n\t\t\t\t`Failed to load models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${path}`,\n\t\t\t);\n\t\t}\n\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(stripJsonComments(stripBom(content)));\n\t\t} catch (error) {\n\t\t\treturn new ModelConfig(\n\t\t\t\tnew Map(),\n\t\t\t\tnew Map(),\n\t\t\t\t`Failed to parse models.json: ${error instanceof Error ? error.message : error}\\n\\nFile: ${path}`,\n\t\t\t);\n\t\t}\n\n\t\tif (!validateModelsConfig.Check(parsed)) {\n\t\t\tconst errors =\n\t\t\t\tvalidateModelsConfig\n\t\t\t\t\t.Errors(parsed)\n\t\t\t\t\t.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)\n\t\t\t\t\t.join(\"\\n\") || \"Unknown schema error\";\n\t\t\treturn new ModelConfig(new Map(), new Map(), `Invalid models.json schema:\\n${errors}\\n\\nFile: ${path}`);\n\t\t}\n\n\t\tconst config = parsed as ModelsJson;\n\t\tconst providers = new Map<string, ModelsJsonProvider>();\n\t\tfor (const [providerId, provider] of Object.entries(config.providers)) {\n\t\t\tproviders.set(providerId, deepFreeze(structuredClone(provider)));\n\t\t}\n\t\tconst roles = new Map<string, readonly string[]>();\n\t\tfor (const [roleName, role] of Object.entries(config.roles ?? {})) {\n\t\t\troles.set(roleName, Object.freeze([...role.models]));\n\t\t}\n\t\treturn new ModelConfig(providers, roles);\n\t}\n\n\tgetProvider(providerId: string): ModelsJsonProvider | undefined {\n\t\treturn this.providers.get(providerId);\n\t}\n\n\tgetProviderIds(): readonly string[] {\n\t\treturn [...this.providers.keys()];\n\t}\n\n\t/** Additive role -> ordered \"provider/modelId\" candidate references, unresolved. */\n\tgetRoles(): ReadonlyMap<string, readonly string[]> {\n\t\treturn this.roles;\n\t}\n\n\tgetError(): string | undefined {\n\t\treturn this.error;\n\t}\n}\n"]}
|
|
@@ -4,6 +4,7 @@ import { Type } from "typebox";
|
|
|
4
4
|
import { Compile } from "typebox/compile";
|
|
5
5
|
import { stripJsonComments } from "../utils/json.js";
|
|
6
6
|
import { normalizePath } from "../utils/paths.js";
|
|
7
|
+
import { stripBom } from "../utils/text.js";
|
|
7
8
|
const PercentileCutoffsSchema = Type.Object({
|
|
8
9
|
p50: Type.Optional(Type.Number()),
|
|
9
10
|
p75: Type.Optional(Type.Number()),
|
|
@@ -62,6 +63,7 @@ const OpenAICompletionsCompatSchema = Type.Object({
|
|
|
62
63
|
supportsDeveloperRole: Type.Optional(Type.Boolean()),
|
|
63
64
|
supportsReasoningEffort: Type.Optional(Type.Boolean()),
|
|
64
65
|
supportsUsageInStreaming: Type.Optional(Type.Boolean()),
|
|
66
|
+
supportsFinishReason: Type.Optional(Type.Boolean()),
|
|
65
67
|
maxTokensField: Type.Optional(Type.Union([Type.Literal("max_completion_tokens"), Type.Literal("max_tokens")])),
|
|
66
68
|
requiresToolResultName: Type.Optional(Type.Boolean()),
|
|
67
69
|
requiresAssistantAfterToolResult: Type.Optional(Type.Boolean()),
|
|
@@ -98,6 +100,7 @@ const OpenAIResponsesCompatSchema = Type.Object({
|
|
|
98
100
|
supportsLongCacheRetention: Type.Optional(Type.Boolean()),
|
|
99
101
|
supportsStrictMode: Type.Optional(Type.Boolean()),
|
|
100
102
|
supportsOpenAIGrammarTools: Type.Optional(Type.Boolean()),
|
|
103
|
+
supportsAdditionalTools: Type.Optional(Type.Boolean()),
|
|
101
104
|
supportsToolSearch: Type.Optional(Type.Boolean()),
|
|
102
105
|
});
|
|
103
106
|
const AnthropicMessagesCompatSchema = Type.Object({
|
|
@@ -175,8 +178,14 @@ const ProviderConfigSchema = Type.Object({
|
|
|
175
178
|
models: Type.Optional(Type.Array(ModelDefinitionSchema)),
|
|
176
179
|
modelOverrides: Type.Optional(Type.Record(Type.String(), ModelOverrideSchema)),
|
|
177
180
|
});
|
|
181
|
+
const RoleDefinitionSchema = Type.Object({
|
|
182
|
+
/** Ordered, non-empty list of canonical "provider/modelId" candidates. */
|
|
183
|
+
models: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),
|
|
184
|
+
});
|
|
178
185
|
const ModelsConfigSchema = Type.Object({
|
|
179
186
|
providers: Type.Record(Type.String(), ProviderConfigSchema),
|
|
187
|
+
/** Additive, credential-blind role -> ordered model-candidate mapping. */
|
|
188
|
+
roles: Type.Optional(Type.Record(Type.String(), RoleDefinitionSchema)),
|
|
180
189
|
});
|
|
181
190
|
const validateModelsConfig = Compile(ModelsConfigSchema);
|
|
182
191
|
function formatValidationPath(error) {
|
|
@@ -201,9 +210,11 @@ function deepFreeze(value) {
|
|
|
201
210
|
/** One immutable load of models.json. */
|
|
202
211
|
export class ModelConfig {
|
|
203
212
|
providers;
|
|
213
|
+
roles;
|
|
204
214
|
error;
|
|
205
|
-
constructor(providers, error) {
|
|
215
|
+
constructor(providers, roles = new Map(), error) {
|
|
206
216
|
this.providers = providers;
|
|
217
|
+
this.roles = roles;
|
|
207
218
|
this.error = error;
|
|
208
219
|
}
|
|
209
220
|
static async load(modelsJsonPath) {
|
|
@@ -217,28 +228,32 @@ export class ModelConfig {
|
|
|
217
228
|
catch (error) {
|
|
218
229
|
if (error.code === "ENOENT")
|
|
219
230
|
return new ModelConfig(new Map());
|
|
220
|
-
return new ModelConfig(new Map(), `Failed to load models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${path}`);
|
|
231
|
+
return new ModelConfig(new Map(), new Map(), `Failed to load models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${path}`);
|
|
221
232
|
}
|
|
222
233
|
let parsed;
|
|
223
234
|
try {
|
|
224
|
-
parsed = JSON.parse(stripJsonComments(content));
|
|
235
|
+
parsed = JSON.parse(stripJsonComments(stripBom(content)));
|
|
225
236
|
}
|
|
226
237
|
catch (error) {
|
|
227
|
-
return new ModelConfig(new Map(), `Failed to parse models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${path}`);
|
|
238
|
+
return new ModelConfig(new Map(), new Map(), `Failed to parse models.json: ${error instanceof Error ? error.message : error}\n\nFile: ${path}`);
|
|
228
239
|
}
|
|
229
240
|
if (!validateModelsConfig.Check(parsed)) {
|
|
230
241
|
const errors = validateModelsConfig
|
|
231
242
|
.Errors(parsed)
|
|
232
243
|
.map((error) => ` - ${formatValidationPath(error)}: ${error.message}`)
|
|
233
244
|
.join("\n") || "Unknown schema error";
|
|
234
|
-
return new ModelConfig(new Map(), `Invalid models.json schema:\n${errors}\n\nFile: ${path}`);
|
|
245
|
+
return new ModelConfig(new Map(), new Map(), `Invalid models.json schema:\n${errors}\n\nFile: ${path}`);
|
|
235
246
|
}
|
|
236
247
|
const config = parsed;
|
|
237
248
|
const providers = new Map();
|
|
238
249
|
for (const [providerId, provider] of Object.entries(config.providers)) {
|
|
239
250
|
providers.set(providerId, deepFreeze(structuredClone(provider)));
|
|
240
251
|
}
|
|
241
|
-
|
|
252
|
+
const roles = new Map();
|
|
253
|
+
for (const [roleName, role] of Object.entries(config.roles ?? {})) {
|
|
254
|
+
roles.set(roleName, Object.freeze([...role.models]));
|
|
255
|
+
}
|
|
256
|
+
return new ModelConfig(providers, roles);
|
|
242
257
|
}
|
|
243
258
|
getProvider(providerId) {
|
|
244
259
|
return this.providers.get(providerId);
|
|
@@ -246,6 +261,10 @@ export class ModelConfig {
|
|
|
246
261
|
getProviderIds() {
|
|
247
262
|
return [...this.providers.keys()];
|
|
248
263
|
}
|
|
264
|
+
/** Additive role -> ordered "provider/modelId" candidate references, unresolved. */
|
|
265
|
+
getRoles() {
|
|
266
|
+
return this.roles;
|
|
267
|
+
}
|
|
249
268
|
getError() {
|
|
250
269
|
return this.error;
|
|
251
270
|
}
|