@gajae-code/coding-agent 0.17.2 → 0.17.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +267 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/github-release.d.ts +17 -0
- package/dist/types/cli/public-command-entry.d.ts +56 -0
- package/dist/types/cli/public-command-errors.d.ts +126 -0
- package/dist/types/cli/public-command-evidence.d.ts +99 -0
- package/dist/types/cli/public-command-help.d.ts +65 -0
- package/dist/types/cli/public-command-registry.d.ts +69 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -0
- package/dist/types/cli/skills-cli.d.ts +5 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +4 -50
- package/dist/types/commands/sdk.d.ts +20 -37
- package/dist/types/commands/setup.d.ts +3 -0
- package/dist/types/commands/skills.d.ts +9 -0
- package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
- package/dist/types/config/file-lock.d.ts +13 -3
- package/dist/types/config/model-profile-activation.d.ts +45 -1
- package/dist/types/config/model-registry.d.ts +14 -3
- package/dist/types/config/model-resolver.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/types.d.ts +12 -0
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
- package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
- package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
- package/dist/types/harness-control-plane/finalize.d.ts +14 -3
- package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/parse.d.ts +9 -1
- package/dist/types/main.d.ts +23 -1
- package/dist/types/modes/acp/acp-agent.d.ts +55 -1
- package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
- package/dist/types/modes/components/session-selector.d.ts +5 -2
- package/dist/types/modes/components/user-message-selector.d.ts +5 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
- package/dist/types/modes/types.d.ts +2 -2
- package/dist/types/runtime/process-lifecycle.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +69 -6
- package/dist/types/runtime-mcp/pool.d.ts +17 -0
- package/dist/types/runtime-mcp/redaction.d.ts +20 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
- package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
- package/dist/types/sdk/broker/broker.d.ts +17 -4
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/identity.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
- package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
- package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
- package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/session-index.d.ts +22 -3
- package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
- package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
- package/dist/types/sdk/bus/index.d.ts +19 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
- package/dist/types/sdk/cli/master-cli.d.ts +6 -10
- package/dist/types/sdk/cli/rows.d.ts +19 -1
- package/dist/types/sdk/cli/session-cli.d.ts +22 -5
- package/dist/types/sdk/client/client.d.ts +2 -0
- package/dist/types/sdk/guides/cli.d.ts +3 -4
- package/dist/types/sdk/guides/verify.d.ts +2 -0
- package/dist/types/sdk/host/host.d.ts +9 -0
- package/dist/types/sdk/host/session-runtime.d.ts +31 -0
- package/dist/types/sdk/host/types.d.ts +10 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +3 -3
- package/dist/types/sdk/startup-capability.d.ts +2 -0
- package/dist/types/sdk/transport/relay.d.ts +1 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +175 -23
- package/dist/types/session/fallback-chain-controller.d.ts +6 -6
- package/dist/types/session/fold-coordinator.d.ts +17 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
- package/dist/types/session/session-manager.d.ts +64 -1
- package/dist/types/session/session-work-lease.d.ts +14 -0
- package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
- package/dist/types/setup/provider-onboarding.d.ts +81 -1
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tools/bash-interactive.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/fetch.d.ts +10 -1
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/tools/subagent.d.ts +8 -1
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf.d.ts +4 -0
- package/dist/types/utils/session-title-generation.d.ts +6 -0
- package/dist/types/utils/title-generator.d.ts +11 -2
- package/dist/types/web/scrapers/types.d.ts +3 -0
- package/package.json +18 -10
- package/scripts/build-binary.ts +9 -3
- package/scripts/compile-args.ts +0 -9
- package/scripts/embed-mupdf.ts +52 -0
- package/scripts/generate-sdk-operation-inventory.ts +31 -1
- package/scripts/vendor-markit.ts +196 -0
- package/src/async/job-manager.ts +22 -1
- package/src/cli/daemon-cli.ts +53 -18
- package/src/cli/github-release.ts +87 -5
- package/src/cli/mcp-cli.ts +38 -4
- package/src/cli/public-command-entry.ts +450 -0
- package/src/cli/public-command-errors.ts +581 -0
- package/src/cli/public-command-evidence.ts +717 -0
- package/src/cli/public-command-help.ts +360 -0
- package/src/cli/public-command-registry.ts +541 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +10 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli/stats-cli.ts +11 -1
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +175 -117
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +543 -3
- package/src/config/file-lock.ts +206 -65
- package/src/config/model-discovery-manager.ts +4 -4
- package/src/config/model-profile-activation.ts +417 -66
- package/src/config/model-registry.ts +254 -36
- package/src/config/model-resolver.ts +6 -1
- package/src/config/settings-schema.ts +26 -2
- package/src/coordinator-mcp/policy.ts +10 -5
- package/src/coordinator-mcp/question-gate-codec.ts +17 -0
- package/src/coordinator-mcp/question-state.ts +179 -9
- package/src/coordinator-mcp/server.ts +521 -87
- package/src/coordinator-mcp/session-reaper.ts +6 -4
- package/src/crash/record-loader.ts +6 -2
- package/src/daemon/operator-contract.ts +26 -12
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
- package/src/eval/js/context-manager.ts +8 -8
- package/src/eval/js/worker-core.ts +9 -4
- package/src/eval/js/worker-protocol.ts +2 -0
- package/src/exec/bash-executor.ts +3 -0
- package/src/extensibility/extensions/runner.ts +52 -4
- package/src/extensibility/extensions/types.ts +10 -0
- package/src/extensibility/gjc-plugins/registry.ts +196 -37
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
- package/src/extensibility/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/state-writer.ts +317 -6
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/harness-control-plane/control-endpoint.ts +24 -6
- package/src/harness-control-plane/finalize.ts +312 -25
- package/src/harness-control-plane/owner.ts +323 -89
- package/src/internal-urls/docs-index.generated.ts +23 -20
- package/src/internal-urls/embedded-protocol.ts +83 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/parse.ts +21 -1
- package/src/internal-urls/router.ts +4 -2
- package/src/main.ts +192 -74
- package/src/modes/acp/acp-agent.ts +973 -56
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/gjc-bundle-settings.ts +21 -1
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/tool-status-header.ts +72 -6
- package/src/modes/components/user-message-selector.ts +57 -15
- package/src/modes/controllers/command-controller.ts +58 -32
- package/src/modes/controllers/extension-ui-controller.ts +33 -7
- package/src/modes/controllers/input-controller.ts +4 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +161 -15
- package/src/modes/interactive-mode.ts +21 -7
- package/src/modes/runtime-init.ts +1 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
- package/src/modes/types.ts +2 -2
- package/src/prompts/agent-fragments/browser-aside.md +1 -0
- package/src/prompts/system/title-system.md +1 -1
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/job.md +1 -1
- package/src/prompts/tools/read.md +2 -0
- package/src/runtime/network-prewarm-service.test.ts +36 -1
- package/src/runtime/network-prewarm-service.ts +28 -3
- package/src/runtime/process-lifecycle.ts +22 -11
- package/src/runtime-mcp/config.ts +16 -1
- package/src/runtime-mcp/loader.ts +6 -3
- package/src/runtime-mcp/manager.ts +845 -109
- package/src/runtime-mcp/pool.test.ts +31 -0
- package/src/runtime-mcp/pool.ts +304 -28
- package/src/runtime-mcp/redaction.ts +42 -0
- package/src/runtime-mcp/startup-policy.ts +7 -0
- package/src/runtime-mcp/tool-bridge.ts +71 -0
- package/src/runtime-mcp/transports/http.ts +108 -25
- package/src/sdk/acp/adapter.ts +27 -8
- package/src/sdk/broker/broker.ts +1431 -198
- package/src/sdk/broker/ensure.ts +21 -3
- package/src/sdk/broker/identity.ts +22 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/managed-task-dag.ts +1927 -0
- package/src/sdk/broker/managed-task-verification.ts +642 -0
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +175 -14
- package/src/sdk/broker/startup-failure.ts +80 -1
- package/src/sdk/broker/stderr-drainer.ts +59 -0
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
- package/src/sdk/bus/index.ts +707 -81
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -3
- package/src/sdk/cli/master-cli.ts +47 -36
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +705 -184
- package/src/sdk/client/client.ts +18 -0
- package/src/sdk/guides/catalog.ts +2 -2
- package/src/sdk/guides/cli.ts +20 -62
- package/src/sdk/guides/verify.ts +14 -0
- package/src/sdk/host/host.ts +49 -5
- package/src/sdk/host/session-runtime.test.ts +184 -2
- package/src/sdk/host/session-runtime.ts +322 -101
- package/src/sdk/host/types.ts +12 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
- package/src/sdk/host/websocket-transport.ts +40 -6
- package/src/sdk/index.ts +11 -0
- package/src/sdk/lifecycle/service.ts +2 -0
- package/src/sdk/prompt-deadline-flush.ts +356 -0
- package/src/sdk/prompt-deadline-manager.ts +133 -1
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/session-router.ts +9 -1
- package/src/sdk/session.ts +763 -116
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +397 -42
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2472 -407
- package/src/session/fallback-chain-controller.ts +6 -7
- package/src/session/fold-coordinator.ts +24 -5
- package/src/session/internal/managed-session-scope.ts +68 -18
- package/src/session/internal/managed-session-storage.ts +334 -12
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +259 -15
- package/src/task/executor.ts +46 -17
- package/src/task/index.ts +14 -2
- package/src/task/types.ts +2 -0
- package/src/tools/bash-interactive.ts +2 -0
- package/src/tools/bash.ts +118 -78
- package/src/tools/fetch.ts +140 -25
- package/src/tools/job.ts +151 -25
- package/src/tools/output-meta.ts +15 -2
- package/src/tools/path-utils.ts +27 -3
- package/src/tools/read.ts +3 -3
- package/src/tools/steer-fold.ts +107 -0
- package/src/tools/subagent-render.ts +24 -1
- package/src/tools/subagent.ts +27 -1
- package/src/tools/tool-catalog.generated.ts +29 -2
- package/src/tools/tool-errors.ts +4 -0
- package/src/utils/git.ts +53 -3
- package/src/utils/markit.ts +55 -41
- package/src/utils/mupdf-assets.d.ts +4 -0
- package/src/utils/mupdf-embedded.ts +4 -0
- package/src/utils/mupdf.ts +136 -0
- package/src/utils/session-title-generation.ts +29 -0
- package/src/utils/title-generator.ts +46 -2
- package/src/web/scrapers/types.ts +24 -3
- package/vendor/markit-ai/LICENSE +21 -0
- package/vendor/markit-ai/MANIFEST.json +412 -0
- package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/config.js +139 -0
- package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
- package/vendor/markit-ai/dist/commands/convert.js +113 -0
- package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/formats.js +92 -0
- package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/init.js +29 -0
- package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/onboard.js +61 -0
- package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/plugin.js +58 -0
- package/vendor/markit-ai/dist/config.d.ts +26 -0
- package/vendor/markit-ai/dist/config.js +42 -0
- package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/audio.js +104 -0
- package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/csv.js +83 -0
- package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/docx.js +57 -0
- package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/epub.js +128 -0
- package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
- package/vendor/markit-ai/dist/converters/github.js +148 -0
- package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/html.js +30 -0
- package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/image.js +124 -0
- package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
- package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
- package/vendor/markit-ai/dist/converters/iwork.js +391 -0
- package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/json.js +21 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
- package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
- package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
- package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
- package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
- package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
- package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
- package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/pptx.js +289 -0
- package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
- package/vendor/markit-ai/dist/converters/rss.js +138 -0
- package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
- package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
- package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/xml.js +18 -0
- package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/yaml.js +17 -0
- package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/zip.js +57 -0
- package/vendor/markit-ai/dist/index.d.ts +30 -0
- package/vendor/markit-ai/dist/index.js +26 -0
- package/vendor/markit-ai/dist/main.d.ts +2 -0
- package/vendor/markit-ai/dist/main.js +191 -0
- package/vendor/markit-ai/dist/markit.d.ts +45 -0
- package/vendor/markit-ai/dist/markit.js +267 -0
- package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
- package/vendor/markit-ai/dist/plugins/api.js +42 -0
- package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
- package/vendor/markit-ai/dist/plugins/index.js +3 -0
- package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/installer.js +176 -0
- package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
- package/vendor/markit-ai/dist/plugins/loader.js +61 -0
- package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/types.js +1 -0
- package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
- package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
- package/vendor/markit-ai/dist/providers/index.js +56 -0
- package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/openai.js +76 -0
- package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
- package/vendor/markit-ai/dist/providers/types.js +1 -0
- package/vendor/markit-ai/dist/types.d.ts +36 -0
- package/vendor/markit-ai/dist/types.js +1 -0
- package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
- package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
- package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
- package/vendor/markit-ai/dist/utils/output.js +31 -0
- package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
- package/vendor/markit-ai/dist/utils/turndown.js +70 -0
- package/vendor/markit-ai/package.json +74 -0
- package/vendor/markit-ai.patch +49 -0
|
@@ -44,6 +44,9 @@ import { fetchModelsDevPayload } from "@gajae-code/ai/provider-models/openai-com
|
|
|
44
44
|
import { isDirectXaiReasoningEffortModel } from "@gajae-code/ai/providers/openai-completions-compat";
|
|
45
45
|
import {
|
|
46
46
|
detectDiscoveredApiFamily,
|
|
47
|
+
isSafeCatalogModelId,
|
|
48
|
+
MODELS_LIST_REQUEST_TIMEOUT_MS,
|
|
49
|
+
readBoundedModelsJson,
|
|
47
50
|
resolveLoopbackOpenAIBaseUrl,
|
|
48
51
|
} from "@gajae-code/ai/utils/discovery/openai-compatible";
|
|
49
52
|
|
|
@@ -80,6 +83,8 @@ import { ModelDiscoveryManager, type ProviderDiscoveryState } from "./model-disc
|
|
|
80
83
|
import {
|
|
81
84
|
loadAcceptedModelPresetProfiles,
|
|
82
85
|
type ModelPresetRegistryDependencies,
|
|
86
|
+
type ModelPresetRegistryRefreshResult,
|
|
87
|
+
refreshModelPresetRegistry,
|
|
83
88
|
refreshModelPresetRegistryInBackground,
|
|
84
89
|
} from "./model-preset-registry";
|
|
85
90
|
|
|
@@ -144,6 +149,36 @@ function redactDiscoveryUrl(value: string | URL): string {
|
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Scrub resolved credential material from a discovery failure before it is
|
|
154
|
+
* published to discovery state, cache provenance, or the logger. Mutates
|
|
155
|
+
* Error messages and stacks in place to preserve class/identity; wraps non-Errors.
|
|
156
|
+
*/
|
|
157
|
+
export function scrubDiscoveryError(error: unknown, secrets: ReadonlyArray<string | undefined>): unknown {
|
|
158
|
+
const redact = (text: string): string => {
|
|
159
|
+
let scrubbed = text;
|
|
160
|
+
for (const secret of secrets) {
|
|
161
|
+
if (secret) scrubbed = scrubbed.split(secret).join("[redacted]");
|
|
162
|
+
}
|
|
163
|
+
return scrubbed;
|
|
164
|
+
};
|
|
165
|
+
if (error instanceof Error) {
|
|
166
|
+
const seen = new Set<Error>();
|
|
167
|
+
const scrubError = (current: Error): void => {
|
|
168
|
+
if (seen.has(current)) return;
|
|
169
|
+
seen.add(current);
|
|
170
|
+
current.message = redact(current.message);
|
|
171
|
+
if (typeof current.stack === "string") current.stack = redact(current.stack);
|
|
172
|
+
if (current.cause instanceof Error) scrubError(current.cause);
|
|
173
|
+
else if (typeof current.cause === "string") current.cause = redact(current.cause);
|
|
174
|
+
};
|
|
175
|
+
scrubError(error);
|
|
176
|
+
return error;
|
|
177
|
+
}
|
|
178
|
+
if (typeof error === "string") return redact(error);
|
|
179
|
+
return error;
|
|
180
|
+
}
|
|
181
|
+
|
|
147
182
|
/** Whether a structured transport code proves that no listener accepted the connection. */
|
|
148
183
|
function isConnectionRefusedDiscoveryCode(value: unknown): boolean {
|
|
149
184
|
if (typeof value === "string") {
|
|
@@ -742,13 +777,26 @@ function registryModelMetadataWithoutApiSpecificFields(model: Model<Api>): Parti
|
|
|
742
777
|
return metadata;
|
|
743
778
|
}
|
|
744
779
|
|
|
745
|
-
function registrySelectorResolvesToModel(selector: string, models: readonly Model<Api>[]): boolean {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
780
|
+
export function registrySelectorResolvesToModel(selector: string, models: readonly Model<Api>[]): boolean {
|
|
781
|
+
const normalizedSelector = selector.trim().toLowerCase();
|
|
782
|
+
if (
|
|
783
|
+
models.some(
|
|
784
|
+
model =>
|
|
785
|
+
model.id.toLowerCase() === normalizedSelector ||
|
|
786
|
+
`${model.provider}/${model.id}`.toLowerCase() === normalizedSelector,
|
|
787
|
+
)
|
|
788
|
+
)
|
|
789
|
+
return true;
|
|
790
|
+
const suffix = splitSelectorThinkingSuffix(normalizedSelector);
|
|
791
|
+
const baseSelector = suffix.thinkingLevel === undefined ? normalizedSelector : suffix.selector;
|
|
749
792
|
const parsed = parseModelString(baseSelector);
|
|
750
|
-
if (parsed)
|
|
751
|
-
|
|
793
|
+
if (parsed)
|
|
794
|
+
return models.some(
|
|
795
|
+
model => model.provider.toLowerCase() === parsed.provider && model.id.toLowerCase() === parsed.id,
|
|
796
|
+
);
|
|
797
|
+
return models.some(
|
|
798
|
+
model => model.id.toLowerCase() === baseSelector || model.id.toLowerCase().endsWith(`/${baseSelector}`),
|
|
799
|
+
);
|
|
752
800
|
}
|
|
753
801
|
|
|
754
802
|
function filterMaterializedRegistryProfiles(
|
|
@@ -1856,6 +1904,17 @@ export class ModelRegistry {
|
|
|
1856
1904
|
});
|
|
1857
1905
|
}
|
|
1858
1906
|
|
|
1907
|
+
/** Refresh the signed profile catalog online, then publish its accepted snapshot. */
|
|
1908
|
+
async refreshModelPresetProfilesFromRegistry(): Promise<ModelPresetRegistryRefreshResult> {
|
|
1909
|
+
const result = await refreshModelPresetRegistry({
|
|
1910
|
+
...this.#modelPresetRegistryDependencies,
|
|
1911
|
+
agentDir: this.#modelPresetRegistryAgentDir,
|
|
1912
|
+
knownManifestSha256: this.#loadedModelPresetRegistryManifestSha256,
|
|
1913
|
+
});
|
|
1914
|
+
await this.refreshStatic();
|
|
1915
|
+
return result;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1859
1918
|
/**
|
|
1860
1919
|
* Reload models from disk and refresh runtime provider discovery state.
|
|
1861
1920
|
*/
|
|
@@ -2501,12 +2560,20 @@ export class ModelRegistry {
|
|
|
2501
2560
|
for (const providerConfig of this.#discoveryManager.providers) {
|
|
2502
2561
|
if (providerId && providerConfig.provider !== providerId) continue;
|
|
2503
2562
|
let expectedProvenance: string | undefined;
|
|
2563
|
+
let effectiveConfig: DiscoveryProviderConfig | undefined;
|
|
2564
|
+
let expectedAuthGeneration: string | undefined;
|
|
2565
|
+
let expectedEndpoint: string | undefined;
|
|
2504
2566
|
try {
|
|
2505
|
-
|
|
2567
|
+
effectiveConfig = this.#effectiveDiscoveryProviderConfig(providerConfig);
|
|
2568
|
+
const effectiveAuthGeneration =
|
|
2569
|
+
authEvidence ?? this.#getProviderEvidenceGeneration(effectiveConfig.provider);
|
|
2570
|
+
const effectiveEndpoint = this.#normalizeDiscoveryEvidenceEndpoint(effectiveConfig.baseUrl ?? "");
|
|
2571
|
+
expectedAuthGeneration = effectiveAuthGeneration;
|
|
2572
|
+
expectedEndpoint = effectiveEndpoint;
|
|
2506
2573
|
expectedProvenance = fingerprintConfiguredDiscoveryRequestShape(
|
|
2507
2574
|
effectiveConfig,
|
|
2508
|
-
|
|
2509
|
-
|
|
2575
|
+
effectiveAuthGeneration,
|
|
2576
|
+
effectiveEndpoint,
|
|
2510
2577
|
);
|
|
2511
2578
|
} catch {
|
|
2512
2579
|
// A context that cannot be fully derived cannot vouch for a cache row.
|
|
@@ -2515,6 +2582,30 @@ export class ModelRegistry {
|
|
|
2515
2582
|
const models = publishDiscoveryState
|
|
2516
2583
|
? this.#discoveryManager.loadCached(providerConfig, this.#cacheDbPath, expectedProvenance)
|
|
2517
2584
|
: this.#readCachedDiscoverableModels(providerConfig, expectedProvenance);
|
|
2585
|
+
if (publishDiscoveryState) {
|
|
2586
|
+
const cache =
|
|
2587
|
+
effectiveConfig !== undefined
|
|
2588
|
+
? readModelCache<Api>(effectiveConfig.provider, 24 * 60 * 60 * 1000, Date.now, this.#cacheDbPath)
|
|
2589
|
+
: null;
|
|
2590
|
+
if (
|
|
2591
|
+
effectiveConfig !== undefined &&
|
|
2592
|
+
expectedAuthGeneration !== undefined &&
|
|
2593
|
+
expectedEndpoint !== undefined &&
|
|
2594
|
+
expectedProvenance !== undefined &&
|
|
2595
|
+
cache?.fresh === true &&
|
|
2596
|
+
cache.authoritative === true &&
|
|
2597
|
+
cache.dynamicModelIds !== undefined &&
|
|
2598
|
+
cache.dynamicModelProvenance === expectedProvenance
|
|
2599
|
+
) {
|
|
2600
|
+
this.#configuredDiscoveryEvidence.set(effectiveConfig.provider, {
|
|
2601
|
+
authGeneration: expectedAuthGeneration,
|
|
2602
|
+
endpoint: expectedEndpoint,
|
|
2603
|
+
modelIds: new Set(cache.dynamicModelIds),
|
|
2604
|
+
});
|
|
2605
|
+
} else {
|
|
2606
|
+
this.#configuredDiscoveryEvidence.delete(providerConfig.provider);
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2518
2609
|
// Cache rows persist sanitized transport metadata (no headers), so a
|
|
2519
2610
|
// rebooted registry re-derives the provider transport override from the
|
|
2520
2611
|
// same source the live publish path uses — mirroring the cached
|
|
@@ -3247,16 +3338,24 @@ export class ModelRegistry {
|
|
|
3247
3338
|
const currentEndpoint = this.#normalizeDiscoveryEvidenceEndpoint(
|
|
3248
3339
|
this.#effectiveDiscoveryProviderConfig(provider).baseUrl ?? "",
|
|
3249
3340
|
);
|
|
3341
|
+
const authoritativeState =
|
|
3342
|
+
state !== undefined &&
|
|
3343
|
+
state.error === undefined &&
|
|
3344
|
+
!state.stale &&
|
|
3345
|
+
((state.status === "ok" && discovery.fetched) ||
|
|
3346
|
+
state.status === "empty" ||
|
|
3347
|
+
(state.status === "ok" && !discovery.fetched));
|
|
3250
3348
|
if (
|
|
3251
3349
|
evidence !== undefined &&
|
|
3252
|
-
|
|
3253
|
-
discovery.fetched &&
|
|
3350
|
+
authoritativeState &&
|
|
3254
3351
|
currentAuthGeneration === evidence.authGeneration &&
|
|
3255
3352
|
currentEndpoint === evidence.endpoint
|
|
3256
3353
|
) {
|
|
3257
3354
|
this.#configuredDiscoveryEvidence.set(provider.provider, evidence);
|
|
3258
3355
|
} else if (
|
|
3259
|
-
(state?.status !== "cached" &&
|
|
3356
|
+
(state?.status !== "cached" &&
|
|
3357
|
+
state?.status !== "empty" &&
|
|
3358
|
+
!(state?.status === "ok" && !discovery.fetched)) ||
|
|
3260
3359
|
state.error !== undefined ||
|
|
3261
3360
|
this.#configuredDiscoveryEvidence.get(provider.provider)?.authGeneration !== currentAuthGeneration ||
|
|
3262
3361
|
this.#configuredDiscoveryEvidence.get(provider.provider)?.endpoint !== currentEndpoint
|
|
@@ -3287,8 +3386,8 @@ export class ModelRegistry {
|
|
|
3287
3386
|
}
|
|
3288
3387
|
|
|
3289
3388
|
#profileAvailabilityEvidenceFingerprint(): string {
|
|
3290
|
-
return JSON.stringify(
|
|
3291
|
-
[...this.#descriptorDiscoveryEvidence.entries()]
|
|
3389
|
+
return JSON.stringify({
|
|
3390
|
+
descriptor: [...this.#descriptorDiscoveryEvidence.entries()]
|
|
3292
3391
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
3293
3392
|
.map(([provider, evidence]) => [
|
|
3294
3393
|
provider,
|
|
@@ -3300,7 +3399,15 @@ export class ModelRegistry {
|
|
|
3300
3399
|
[...evidence.modelIds].sort(),
|
|
3301
3400
|
evidence.profileModelIds === undefined ? undefined : [...evidence.profileModelIds].sort(),
|
|
3302
3401
|
]),
|
|
3303
|
-
|
|
3402
|
+
configured: [...this.#configuredDiscoveryEvidence.entries()]
|
|
3403
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
3404
|
+
.map(([provider, evidence]) => [
|
|
3405
|
+
provider,
|
|
3406
|
+
evidence.authGeneration,
|
|
3407
|
+
evidence.endpoint,
|
|
3408
|
+
[...evidence.modelIds].sort(),
|
|
3409
|
+
]),
|
|
3410
|
+
});
|
|
3304
3411
|
}
|
|
3305
3412
|
|
|
3306
3413
|
#mergeDiscoveredModels(discovered: readonly Model<Api>[]): void {
|
|
@@ -3496,8 +3603,14 @@ export class ModelRegistry {
|
|
|
3496
3603
|
await this.#discoverModelsByProviderType(provider, apiKey),
|
|
3497
3604
|
);
|
|
3498
3605
|
} catch (error) {
|
|
3499
|
-
|
|
3500
|
-
|
|
3606
|
+
// ONE credential-safe discovery error boundary: transport
|
|
3607
|
+
// layers may echo request details (including the bearer)
|
|
3608
|
+
// in failure text. Scrub resolved credential material
|
|
3609
|
+
// before the error reaches discovery state, cache
|
|
3610
|
+
// provenance, or the logger below.
|
|
3611
|
+
const scrubbedError = scrubDiscoveryError(error, [apiKey, preflightApiKey]);
|
|
3612
|
+
discoveryFailureEvidence = scrubbedError;
|
|
3613
|
+
throw scrubbedError;
|
|
3501
3614
|
}
|
|
3502
3615
|
},
|
|
3503
3616
|
getEvidenceGeneration: provider => this.#getProviderEvidenceGeneration(provider.provider, preflightApiKey),
|
|
@@ -3569,24 +3682,35 @@ export class ModelRegistry {
|
|
|
3569
3682
|
};
|
|
3570
3683
|
}
|
|
3571
3684
|
|
|
3572
|
-
#discoverModelsByProviderType(
|
|
3685
|
+
async #discoverModelsByProviderType(
|
|
3573
3686
|
providerConfig: DiscoveryProviderConfig,
|
|
3574
3687
|
apiKey: string | undefined,
|
|
3575
3688
|
): Promise<Model<Api>[]> {
|
|
3689
|
+
let models: Model<Api>[];
|
|
3576
3690
|
switch (providerConfig.discovery.type) {
|
|
3577
3691
|
case "ollama":
|
|
3578
|
-
|
|
3692
|
+
models = await this.#discoverOllamaModels(providerConfig, apiKey);
|
|
3693
|
+
break;
|
|
3579
3694
|
case "llama.cpp":
|
|
3580
|
-
|
|
3695
|
+
models = await this.#discoverLlamaCppModels(providerConfig, apiKey);
|
|
3696
|
+
break;
|
|
3581
3697
|
case "lm-studio":
|
|
3582
3698
|
case "omlx":
|
|
3583
3699
|
case "vllm":
|
|
3584
3700
|
case "sglang":
|
|
3585
3701
|
case "openai-models-list":
|
|
3586
|
-
|
|
3702
|
+
models = await this.#discoverOpenAIModelsList(providerConfig, apiKey);
|
|
3703
|
+
break;
|
|
3587
3704
|
case "models-dev":
|
|
3588
|
-
|
|
3705
|
+
models = await this.#discoverModelsDevProvider(providerConfig);
|
|
3706
|
+
break;
|
|
3589
3707
|
}
|
|
3708
|
+
if (providerConfig.discovery.type === "openai-models-list" && models.length === 0) {
|
|
3709
|
+
throw new Error(
|
|
3710
|
+
`Model discovery for ${redactDiscoveryUrl(providerConfig.baseUrl ?? "")} returned no models; add --model <id> or fix the endpoint catalog.`,
|
|
3711
|
+
);
|
|
3712
|
+
}
|
|
3713
|
+
return models;
|
|
3590
3714
|
}
|
|
3591
3715
|
|
|
3592
3716
|
async #discoverBuiltInProviderModels(
|
|
@@ -4222,7 +4346,7 @@ export class ModelRegistry {
|
|
|
4222
4346
|
...(providerConfig.discovery.type === "vllm" || providerConfig.discovery.type === "sglang"
|
|
4223
4347
|
? { redirect: "error" as const }
|
|
4224
4348
|
: {}),
|
|
4225
|
-
signal: AbortSignal.timeout(hardenedLocalDiscovery ? 500 :
|
|
4349
|
+
signal: AbortSignal.timeout(hardenedLocalDiscovery ? 500 : MODELS_LIST_REQUEST_TIMEOUT_MS),
|
|
4226
4350
|
});
|
|
4227
4351
|
if (!response.ok) {
|
|
4228
4352
|
if (response.status === 401 || response.status === 403) {
|
|
@@ -4234,16 +4358,31 @@ export class ModelRegistry {
|
|
|
4234
4358
|
}
|
|
4235
4359
|
throw new Error(`HTTP ${response.status} from ${redactDiscoveryUrl(modelsUrl)}`);
|
|
4236
4360
|
}
|
|
4237
|
-
|
|
4361
|
+
// Shared 1MB bounded reader (same as the setup probe): a timeout
|
|
4362
|
+
// bounds wall clock, not bytes buffered.
|
|
4363
|
+
let payload: unknown;
|
|
4364
|
+
try {
|
|
4365
|
+
payload = await readBoundedModelsJson(response);
|
|
4366
|
+
} catch {
|
|
4367
|
+
throw new Error(`Malformed OpenAI models-list response from ${redactDiscoveryUrl(modelsUrl)}`);
|
|
4368
|
+
}
|
|
4238
4369
|
if (!isRecord(payload) || !Array.isArray(payload.data)) {
|
|
4239
4370
|
throw new Error(`Malformed OpenAI models-list response from ${redactDiscoveryUrl(modelsUrl)}`);
|
|
4240
4371
|
}
|
|
4241
4372
|
const models = payload.data;
|
|
4242
4373
|
const discovered: Model<Api>[] = [];
|
|
4243
4374
|
for (const item of models) {
|
|
4244
|
-
|
|
4245
|
-
|
|
4375
|
+
// Shared catalog admission: the setup probe applies the same
|
|
4376
|
+
// check, so IDs that appear only between requests cannot enter
|
|
4377
|
+
// the live catalog or cache unsanitized.
|
|
4378
|
+
if (!isRecord(item) || !isSafeCatalogModelId(item.id)) continue;
|
|
4379
|
+
const id = item.id.trim();
|
|
4246
4380
|
const referenceModel = resolveCustomModelReference(id);
|
|
4381
|
+
// Names render directly in the model selector: apply the same
|
|
4382
|
+
// text-safety admission, falling back to the reference name or
|
|
4383
|
+
// the safe ID.
|
|
4384
|
+
const rawName = typeof item.name === "string" ? item.name.trim() : "";
|
|
4385
|
+
const name = rawName && isSafeCatalogModelId(rawName) ? rawName : (referenceModel?.name ?? id);
|
|
4247
4386
|
const discoveredMaxTokens = firstPositiveDiscoveryNumber(
|
|
4248
4387
|
item.max_completion_tokens,
|
|
4249
4388
|
item.max_tokens,
|
|
@@ -4253,7 +4392,7 @@ export class ModelRegistry {
|
|
|
4253
4392
|
discovered.push(
|
|
4254
4393
|
enrichModelThinking({
|
|
4255
4394
|
id,
|
|
4256
|
-
name
|
|
4395
|
+
name,
|
|
4257
4396
|
api,
|
|
4258
4397
|
provider: providerConfig.provider,
|
|
4259
4398
|
baseUrl: requestBaseUrl,
|
|
@@ -5226,8 +5365,10 @@ export class ModelRegistry {
|
|
|
5226
5365
|
}
|
|
5227
5366
|
|
|
5228
5367
|
/**
|
|
5229
|
-
* Get
|
|
5230
|
-
* This is a fast check that doesn't refresh OAuth tokens.
|
|
5368
|
+
* Get selectable models with auth configured.
|
|
5369
|
+
* This is a fast check that doesn't refresh OAuth tokens. A current,
|
|
5370
|
+
* authoritative live catalog also limits each provider to its enrolled ids;
|
|
5371
|
+
* bundled entries remain the fallback until that evidence exists.
|
|
5231
5372
|
*/
|
|
5232
5373
|
getAvailable(): Model<Api>[] {
|
|
5233
5374
|
this.#synchronizeEnvironmentCredentials();
|
|
@@ -5241,12 +5382,82 @@ export class ModelRegistry {
|
|
|
5241
5382
|
) {
|
|
5242
5383
|
return this.#availableModelsCache;
|
|
5243
5384
|
}
|
|
5244
|
-
|
|
5385
|
+
const authoritativeDiscoveryIds = new Map<string, ReadonlySet<string> | undefined>();
|
|
5386
|
+
const bundledIdsByProvider = new Map<string, Set<string>>();
|
|
5387
|
+
this.#availableModelsCache = this.#models.filter(model => {
|
|
5388
|
+
if (!this.#isModelAvailable(model, disabledProviders)) return false;
|
|
5389
|
+
|
|
5390
|
+
let liveIds = authoritativeDiscoveryIds.get(model.provider);
|
|
5391
|
+
if (!authoritativeDiscoveryIds.has(model.provider)) {
|
|
5392
|
+
liveIds = this.#getAuthoritativeDiscoveredModelIds(model.provider);
|
|
5393
|
+
authoritativeDiscoveryIds.set(model.provider, liveIds);
|
|
5394
|
+
}
|
|
5395
|
+
// Undefined means discovery has not run successfully for the current
|
|
5396
|
+
// provider context. Keep the bundled catalog as the explicit fallback.
|
|
5397
|
+
if (liveIds === undefined) return true;
|
|
5398
|
+
if (this.#hasCustomModelOverlay(model.provider, model.id)) return true;
|
|
5399
|
+
|
|
5400
|
+
const activity = this.#providerActivity.get(model.provider);
|
|
5401
|
+
if (!activity?.staticModelIds.has(model.id)) return liveIds.has(model.id);
|
|
5402
|
+
|
|
5403
|
+
let bundledIds = bundledIdsByProvider.get(model.provider);
|
|
5404
|
+
if (!bundledIds) {
|
|
5405
|
+
bundledIds = new Set(
|
|
5406
|
+
(getBundledModels(model.provider as Parameters<typeof getBundledModels>[0]) as Model<Api>[]).map(
|
|
5407
|
+
candidate => candidate.id,
|
|
5408
|
+
),
|
|
5409
|
+
);
|
|
5410
|
+
bundledIdsByProvider.set(model.provider, bundledIds);
|
|
5411
|
+
}
|
|
5412
|
+
return !bundledIds.has(model.id) || liveIds.has(model.id);
|
|
5413
|
+
});
|
|
5245
5414
|
this.#availableModelsDisabledProviders = disabledProviderKey;
|
|
5246
5415
|
this.#availableModelsEnvFingerprint = envFingerprint;
|
|
5247
5416
|
return this.#availableModelsCache;
|
|
5248
5417
|
}
|
|
5249
5418
|
|
|
5419
|
+
/**
|
|
5420
|
+
* Return the current live model ids only when discovery produced an
|
|
5421
|
+
* authoritative catalog for the provider and endpoint. An unavailable or
|
|
5422
|
+
* failed discovery returns undefined so callers retain the bundled fallback.
|
|
5423
|
+
*/
|
|
5424
|
+
#getAuthoritativeDiscoveredModelIds(provider: string): ReadonlySet<string> | undefined {
|
|
5425
|
+
const descriptorEvidence = this.#descriptorDiscoveryEvidence.get(provider);
|
|
5426
|
+
if (descriptorEvidence?.profileFresh && descriptorEvidence.profileModelIds !== undefined) {
|
|
5427
|
+
try {
|
|
5428
|
+
if (
|
|
5429
|
+
descriptorEvidence.authGeneration === this.#getProviderEvidenceGeneration(provider) &&
|
|
5430
|
+
descriptorEvidence.profileEndpoint ===
|
|
5431
|
+
this.#normalizeDiscoveryEvidenceEndpoint(this.#getProviderBaseUrlForDiscovery(provider) ?? "")
|
|
5432
|
+
) {
|
|
5433
|
+
return descriptorEvidence.profileModelIds;
|
|
5434
|
+
}
|
|
5435
|
+
} catch {
|
|
5436
|
+
// A provider context that can no longer be verified must use its fallback.
|
|
5437
|
+
}
|
|
5438
|
+
}
|
|
5439
|
+
|
|
5440
|
+
const configuredEvidence = this.#configuredDiscoveryEvidence.get(provider);
|
|
5441
|
+
if (!configuredEvidence) return undefined;
|
|
5442
|
+
const discoveryState = this.#discoveryManager.getState(provider);
|
|
5443
|
+
if (
|
|
5444
|
+
discoveryState?.status !== "ok" &&
|
|
5445
|
+
discoveryState?.status !== "cached" &&
|
|
5446
|
+
discoveryState?.status !== "empty"
|
|
5447
|
+
) {
|
|
5448
|
+
return undefined;
|
|
5449
|
+
}
|
|
5450
|
+
try {
|
|
5451
|
+
return configuredEvidence.authGeneration === this.#getProviderEvidenceGeneration(provider) &&
|
|
5452
|
+
configuredEvidence.endpoint ===
|
|
5453
|
+
this.#normalizeDiscoveryEvidenceEndpoint(this.#getProviderBaseUrlForDiscovery(provider) ?? "")
|
|
5454
|
+
? configuredEvidence.modelIds
|
|
5455
|
+
: undefined;
|
|
5456
|
+
} catch {
|
|
5457
|
+
return undefined;
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5250
5461
|
#synchronizeEnvironmentCredentials(): void {
|
|
5251
5462
|
// Runtime registrations own a provider while their credential is present.
|
|
5252
5463
|
// Refresh them first so a missing runtime env key can hand ownership back to
|
|
@@ -5267,6 +5478,10 @@ export class ModelRegistry {
|
|
|
5267
5478
|
*/
|
|
5268
5479
|
getAvailableForProfileActivation(): Model<Api>[] {
|
|
5269
5480
|
const bundledIdsByProvider = new Map<string, Set<string>>();
|
|
5481
|
+
// Evidence staleness depends only on the provider, and resolving it scans the
|
|
5482
|
+
// catalog for the provider base URL. Decide it once per provider per call so a
|
|
5483
|
+
// multi-thousand-model catalog is not rescanned for every model.
|
|
5484
|
+
const staleEvidenceByProvider = new Map<string, boolean>();
|
|
5270
5485
|
return this.getAvailable().filter(model => {
|
|
5271
5486
|
const evidence = this.#descriptorDiscoveryEvidence.get(model.provider);
|
|
5272
5487
|
if (!evidence?.profileFresh || evidence.profileModelIds === undefined) return true;
|
|
@@ -5281,12 +5496,15 @@ export class ModelRegistry {
|
|
|
5281
5496
|
bundledIdsByProvider.set(model.provider, bundledModelIds);
|
|
5282
5497
|
}
|
|
5283
5498
|
if (!bundledModelIds.has(model.id)) return true;
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
this.#
|
|
5288
|
-
|
|
5289
|
-
|
|
5499
|
+
let staleEvidence = staleEvidenceByProvider.get(model.provider);
|
|
5500
|
+
if (staleEvidence === undefined) {
|
|
5501
|
+
staleEvidence =
|
|
5502
|
+
evidence.authGeneration !== this.#getProviderEvidenceGeneration(model.provider) ||
|
|
5503
|
+
evidence.profileEndpoint !==
|
|
5504
|
+
this.#normalizeDiscoveryEvidenceEndpoint(this.#getProviderBaseUrlForDiscovery(model.provider) ?? "");
|
|
5505
|
+
staleEvidenceByProvider.set(model.provider, staleEvidence);
|
|
5506
|
+
}
|
|
5507
|
+
if (staleEvidence) return true;
|
|
5290
5508
|
return evidence.profileModelIds.has(model.id);
|
|
5291
5509
|
});
|
|
5292
5510
|
}
|
|
@@ -87,6 +87,7 @@ export function resolveStartupModelRefreshSelectors(
|
|
|
87
87
|
export async function refreshMissingQualifiedModelProviders(
|
|
88
88
|
selectors: ModelSelectorValue | undefined,
|
|
89
89
|
modelRegistry: Pick<ModelRegistry, "getAvailable" | "getRefreshableProviders" | "refreshProvider">,
|
|
90
|
+
credentialSessionId?: string,
|
|
90
91
|
): Promise<boolean> {
|
|
91
92
|
const refreshedProviders = new Set<string>();
|
|
92
93
|
for (const selector of normalizeModelSelectorValue(selectors)) {
|
|
@@ -104,7 +105,11 @@ export async function refreshMissingQualifiedModelProviders(
|
|
|
104
105
|
)
|
|
105
106
|
continue;
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
if (credentialSessionId === undefined) {
|
|
109
|
+
await modelRegistry.refreshProvider(provider, "online-if-uncached");
|
|
110
|
+
} else {
|
|
111
|
+
await modelRegistry.refreshProvider(provider, "online-if-uncached", credentialSessionId);
|
|
112
|
+
}
|
|
108
113
|
refreshedProviders.add(provider);
|
|
109
114
|
}
|
|
110
115
|
return refreshedProviders.size > 0;
|
|
@@ -369,6 +369,24 @@ const AUTOROUTING_PROVENANCE_JSON_SCHEMA: JsonSchemaObject = {
|
|
|
369
369
|
required: ["schema", "source", "declarationFingerprint", "tiersFingerprint"],
|
|
370
370
|
};
|
|
371
371
|
|
|
372
|
+
// SDK prompt deadline defaults. The `sdk.promptDeadlineMs` /
|
|
373
|
+
// `sdk.promptMaxRuntimeMs` schema entries below and the SDK bus/host lease
|
|
374
|
+
// fallbacks read these same constants, so a Settings lookup that misses — no
|
|
375
|
+
// settings object, an unwritten key, a non-finite value — cannot arm a deadline
|
|
376
|
+
// that disagrees with the declared default (#5583).
|
|
377
|
+
export const DEFAULT_SDK_PROMPT_DEADLINE_MS = 3_600_000;
|
|
378
|
+
export const DEFAULT_SDK_PROMPT_MAX_RUNTIME_MS = 21_600_000;
|
|
379
|
+
|
|
380
|
+
/** Resolve a `sdk.promptDeadlineMs` lookup, falling back on any non-finite value. */
|
|
381
|
+
export function resolveSdkPromptDeadlineMs(value: unknown): number {
|
|
382
|
+
return typeof value === "number" && Number.isFinite(value) ? value : DEFAULT_SDK_PROMPT_DEADLINE_MS;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** Resolve a `sdk.promptMaxRuntimeMs` lookup, falling back on any non-finite value. */
|
|
386
|
+
export function resolveSdkPromptMaxRuntimeMs(value: unknown): number {
|
|
387
|
+
return typeof value === "number" && Number.isFinite(value) ? value : DEFAULT_SDK_PROMPT_MAX_RUNTIME_MS;
|
|
388
|
+
}
|
|
389
|
+
|
|
372
390
|
export const SETTINGS_SCHEMA = {
|
|
373
391
|
// ────────────────────────────────────────────────────────────────────────
|
|
374
392
|
// General settings (no UI)
|
|
@@ -416,16 +434,22 @@ export const SETTINGS_SCHEMA = {
|
|
|
416
434
|
// SDK-owned prompt deadline. Hidden from the UI; ACP has no separate timeout.
|
|
417
435
|
"sdk.promptDeadlineMs": {
|
|
418
436
|
type: "number",
|
|
419
|
-
default:
|
|
437
|
+
default: DEFAULT_SDK_PROMPT_DEADLINE_MS,
|
|
420
438
|
description: "SDK-owned prompt deadline; ACP has no separate timeout.",
|
|
421
439
|
validate: (value: number) => Number.isSafeInteger(value) && value >= 60_000 && value <= 86_400_000,
|
|
422
440
|
},
|
|
423
441
|
"sdk.promptMaxRuntimeMs": {
|
|
424
442
|
type: "number",
|
|
425
|
-
default:
|
|
443
|
+
default: DEFAULT_SDK_PROMPT_MAX_RUNTIME_MS,
|
|
426
444
|
description: "Hard maximum runtime for an SDK prompt from acceptance, bounding progress-aware renewals.",
|
|
427
445
|
validate: (value: number) => Number.isSafeInteger(value) && value >= 60_000 && value <= 86_400_000,
|
|
428
446
|
},
|
|
447
|
+
"sdk.flushWorktreeOnDeadline": {
|
|
448
|
+
type: "boolean",
|
|
449
|
+
default: true,
|
|
450
|
+
description:
|
|
451
|
+
"Autosave uncommitted changes in the session's linked worktree by default as a WIP commit when a prompt deadline retires a prompt; primary checkouts require an explicit true opt-in.",
|
|
452
|
+
},
|
|
429
453
|
"sdk.masterOrphanGraceMs": {
|
|
430
454
|
type: "number",
|
|
431
455
|
default: 120_000,
|
|
@@ -275,11 +275,16 @@ export async function assertCoordinatorSessionLocations(
|
|
|
275
275
|
]);
|
|
276
276
|
// Reauthorize both persisted locations independently. A managed worktree may
|
|
277
277
|
// differ from the requested cwd, but neither may escape the current roots.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
278
|
+
const escaped: string[] = [];
|
|
279
|
+
if (!roots.some(root => isInsideCanonicalRoot(canonicalCwd, root, platform))) escaped.push(`cwd ${canonicalCwd}`);
|
|
280
|
+
if (!roots.some(root => isInsideCanonicalRoot(canonicalWorkspace, root, platform)))
|
|
281
|
+
escaped.push(`workspace ${canonicalWorkspace}`);
|
|
282
|
+
if (escaped.length > 0)
|
|
283
|
+
// The message stays exact because isSessionAuthorityError() in server.ts matches it
|
|
284
|
+
// verbatim; the escaping location rides in `cause` so a caller that logs can name it.
|
|
285
|
+
throw new Error("coordinator_workdir_outside_allowed_roots", {
|
|
286
|
+
cause: new Error(`outside allowed roots: ${escaped.join(", ")}`),
|
|
287
|
+
});
|
|
283
288
|
}
|
|
284
289
|
|
|
285
290
|
export async function assertCoordinatorArtifactPath(
|
|
@@ -184,6 +184,23 @@ export function buildCoordinatorAskAnswerSchema(
|
|
|
184
184
|
return {
|
|
185
185
|
title: "CoordinatorQuestionAnswerV1",
|
|
186
186
|
type: "object",
|
|
187
|
+
// `additionalProperties: false` is scoped by the SIBLING `properties` map, not by
|
|
188
|
+
// the `oneOf` branches: a standards-compliant validator evaluates the keyword
|
|
189
|
+
// against this node alone. Without this map every answer field was "additional",
|
|
190
|
+
// so selection, custom-answer, and clarification payloads were all rejected
|
|
191
|
+
// client-side before the server saw them (#5801). Each branch stays closed too,
|
|
192
|
+
// so the union still rejects field combinations this map alone would allow.
|
|
193
|
+
properties: {
|
|
194
|
+
selected: selectedBase,
|
|
195
|
+
other: { type: "boolean", description: "set true to provide a free-text answer in `custom`" },
|
|
196
|
+
custom: boundedAnswerText("free-text answer; required when `other` is true"),
|
|
197
|
+
action: {
|
|
198
|
+
type: "string",
|
|
199
|
+
enum: ["answer", "clarify"],
|
|
200
|
+
description: "set to `clarify` to ask about the choices without answering the round",
|
|
201
|
+
},
|
|
202
|
+
question: boundedAnswerText("clarification question; required when action is `clarify`"),
|
|
203
|
+
},
|
|
187
204
|
additionalProperties: false,
|
|
188
205
|
oneOf: [
|
|
189
206
|
{
|