@gajae-code/coding-agent 0.17.1 → 0.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +266 -0
- package/dist/types/async/job-manager.d.ts +7 -6
- 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 +24 -0
- package/dist/types/config/file-lock.d.ts +10 -1
- package/dist/types/config/model-profile-activation.d.ts +63 -4
- package/dist/types/config/model-registry.d.ts +20 -2
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/coordinator-mcp/server.d.ts +3 -0
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.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/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/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 +22 -0
- package/dist/types/modes/acp/acp-agent.d.ts +94 -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/thinking-selector.d.ts +2 -1
- 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/manager.d.ts +56 -0
- 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/acp/adapter.d.ts +27 -0
- package/dist/types/sdk/acp/final-text.d.ts +8 -0
- package/dist/types/sdk/broker/broker.d.ts +13 -2
- package/dist/types/sdk/broker/ensure.d.ts +46 -1
- package/dist/types/sdk/broker/identity.d.ts +3 -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/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 +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 +3 -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 +83 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +38 -1
- package/dist/types/sdk/prompt-failure.d.ts +30 -1
- package/dist/types/sdk/prompt-status.d.ts +8 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/replay-retention-gap-cache.d.ts +13 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- 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 +73 -2
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +168 -21
- 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/thinking.d.ts +3 -1
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf-wasm-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 +60 -9
- 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 +535 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +9 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +232 -100
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +16 -0
- package/src/config/file-lock.ts +199 -68
- package/src/config/model-profile-activation.ts +406 -53
- package/src/config/model-registry.ts +204 -25
- 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 +175 -8
- package/src/coordinator-mcp/server.ts +528 -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/debug/report-bundle.ts +114 -24
- 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/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/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/managed-owner-admission.ts +67 -50
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/internal-urls/docs-index.generated.ts +21 -19
- 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 +123 -55
- package/src/modes/acp/acp-agent.ts +593 -47
- package/src/modes/acp/acp-event-mapper.ts +9 -0
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/model-selector.ts +31 -15
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/status-line/segments.ts +6 -1
- package/src/modes/components/thinking-selector.ts +7 -3
- 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/selector-controller.ts +177 -18
- 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/manager.ts +689 -55
- 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 +90 -9
- package/src/sdk/acp/final-text.ts +19 -2
- package/src/sdk/broker/broker.ts +378 -52
- package/src/sdk/broker/ensure.ts +97 -19
- package/src/sdk/broker/identity.ts +9 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +35 -7
- package/src/sdk/broker/stderr-drainer.ts +59 -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 +721 -84
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +3 -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 +687 -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 +636 -9
- package/src/sdk/host/session-runtime.ts +499 -118
- 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/prompt-deadline-flush.ts +334 -0
- package/src/sdk/prompt-deadline-manager.ts +136 -4
- package/src/sdk/prompt-failure.ts +43 -1
- package/src/sdk/prompt-status.ts +8 -0
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/replay-retention-gap-cache.ts +27 -0
- package/src/sdk/router/session-router.ts +31 -4
- package/src/sdk/session.ts +194 -16
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +494 -49
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2437 -400
- 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 +58 -18
- package/src/session/internal/managed-session-storage.ts +304 -11
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/session-import/codex.ts +12 -3
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/slash-commands/builtin-registry.ts +258 -14
- package/src/task/index.ts +14 -2
- package/src/thinking.ts +21 -2
- package/src/tools/bash.ts +98 -78
- package/src/tools/fetch.ts +119 -20
- 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/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-wasm-embedded.ts +3 -0
- package/src/utils/mupdf-wasm.ts +24 -2
- package/src/utils/mupdf.ts +129 -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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ThinkingLevel } from "@gajae-code/agent-core";
|
|
2
|
-
import type
|
|
2
|
+
import { type Api, isKnownProvider, type Model } from "@gajae-code/ai/core";
|
|
3
3
|
import { logger } from "@gajae-code/utils";
|
|
4
4
|
import type { AgentSession, DefaultFallbackRuntimeState } from "../session/agent-session";
|
|
5
5
|
import { clampExplicitThinkingLevelForModel, formatClampedModelSelector } from "../thinking";
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
formatModelProfileDisplayLabel,
|
|
11
11
|
type ModelProfileDefinition,
|
|
12
12
|
PROXY_ROUTABLE_PROVIDER_IDS,
|
|
13
|
+
type ResolvedProfileBinding,
|
|
13
14
|
resolveProfileBindings,
|
|
14
15
|
} from "./model-profiles";
|
|
15
16
|
|
|
@@ -21,11 +22,13 @@ import {
|
|
|
21
22
|
isAuthenticated,
|
|
22
23
|
kNoAuth,
|
|
23
24
|
type ModelRegistry,
|
|
25
|
+
registrySelectorResolvesToModel,
|
|
24
26
|
} from "./model-registry";
|
|
25
27
|
import {
|
|
26
28
|
formatModelSelectorValue,
|
|
27
29
|
formatModelString,
|
|
28
30
|
parseModelString,
|
|
31
|
+
resolveConfiguredModelPatterns,
|
|
29
32
|
resolveModelChainWithAuth,
|
|
30
33
|
resolveModelRoleValue,
|
|
31
34
|
splitSelectorThinkingSuffix,
|
|
@@ -69,7 +72,8 @@ type ModelProfileActivationSession = Pick<
|
|
|
69
72
|
| "resolveModelByLookupAlias"
|
|
70
73
|
| "authStorage"
|
|
71
74
|
| "isCredentiallessProvider"
|
|
72
|
-
|
|
75
|
+
> &
|
|
76
|
+
Partial<Pick<ModelRegistry, "getAvailableForProfileActivation">>;
|
|
73
77
|
getConfiguredModelChainState?: (role: string) => ConfiguredModelChainState | undefined;
|
|
74
78
|
};
|
|
75
79
|
|
|
@@ -105,6 +109,7 @@ export interface PrepareModelProfileActivationOptions {
|
|
|
105
109
|
| "getSessionCanonicalVariant"
|
|
106
110
|
| "restoreSessionCanonicalVariant"
|
|
107
111
|
| "getConfiguredProviderIds"
|
|
112
|
+
| "isKnownProvider"
|
|
108
113
|
>
|
|
109
114
|
> & {
|
|
110
115
|
getError?: ModelRegistry["getError"];
|
|
@@ -248,7 +253,12 @@ function concretizeMaterializedAssignmentValues(
|
|
|
248
253
|
const sessionId = (options.session as { sessionId?: string }).sessionId;
|
|
249
254
|
const credentialSessionId = options.session.credentialSessionId ?? sessionId;
|
|
250
255
|
if (!modelRegistry || !sessionId) return assignments;
|
|
251
|
-
|
|
256
|
+
// Materialized assignments are persisted into `modelRoles` and
|
|
257
|
+
// `task.agentModelOverrides` and later consumed by profile execution, so they
|
|
258
|
+
// must resolve against the descriptor-backed profile-activation catalog, not
|
|
259
|
+
// the broadened general one: otherwise a bare assignment can persist a
|
|
260
|
+
// bundled model that fresh live profile evidence excludes.
|
|
261
|
+
const availableModels = modelRegistry.getAvailableForProfileActivation?.() ?? modelRegistry.getAvailable();
|
|
252
262
|
const authenticatedModels = availableModels.filter(model => {
|
|
253
263
|
const isCredentiallessProvider = modelRegistry.isCredentiallessProvider?.bind(modelRegistry);
|
|
254
264
|
const hasUsableAuth = modelRegistry.authStorage?.hasUsableAuth?.bind(modelRegistry.authStorage);
|
|
@@ -449,7 +459,7 @@ export function materializeActiveModelProfileAssignments(options: MaterializeMod
|
|
|
449
459
|
}
|
|
450
460
|
|
|
451
461
|
export class ModelProfileCredentialError extends Error {
|
|
452
|
-
readonly code = "authentication_failed";
|
|
462
|
+
readonly code: string = "authentication_failed";
|
|
453
463
|
readonly profileLabel: string;
|
|
454
464
|
readonly providers: readonly string[];
|
|
455
465
|
readonly role: string | undefined;
|
|
@@ -466,6 +476,28 @@ export class ModelProfileCredentialError extends Error {
|
|
|
466
476
|
export function formatModelProfileCredentialError(profileLabel: string, providers: readonly string[]): string {
|
|
467
477
|
return `Model profile "${profileLabel}" requires credentials for: ${providers.join(", ")}. Run /login and configure the missing provider(s), then retry.`;
|
|
468
478
|
}
|
|
479
|
+
export function formatModelProfileUnknownProviderError(profileLabel: string, providers: readonly string[]): string {
|
|
480
|
+
return `Model profile "${profileLabel}" requires provider(s) this build does not know: ${providers.join(", ")}. The profile likely targets a newer or custom build; declare the provider(s) in models.yml or use a build that ships them.`;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* A required profile provider that this build cannot know: it is neither a
|
|
485
|
+
* built-in provider id nor declared in models.yml. That is a build/config
|
|
486
|
+
* mismatch (for example a profile authored on a newer or custom build), not a
|
|
487
|
+
* credential gap, so the diagnosis must not send the user to /login.
|
|
488
|
+
*
|
|
489
|
+
* Extends {@link ModelProfileCredentialError} so existing startup recovery
|
|
490
|
+
* (interactive toast-and-continue) keeps working with the sharper message.
|
|
491
|
+
*/
|
|
492
|
+
export class ModelProfileUnknownProviderError extends ModelProfileCredentialError {
|
|
493
|
+
readonly code = "unknown_provider";
|
|
494
|
+
|
|
495
|
+
constructor(profileLabel: string, providers: readonly string[], role?: string) {
|
|
496
|
+
super(profileLabel, providers, role);
|
|
497
|
+
this.name = "ModelProfileUnknownProviderError";
|
|
498
|
+
this.message = formatModelProfileUnknownProviderError(profileLabel, providers);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
469
501
|
|
|
470
502
|
/**
|
|
471
503
|
* Rewrite a selector only within the selector provider's own alternative group.
|
|
@@ -534,6 +566,14 @@ function rewriteBindingsProviders(
|
|
|
534
566
|
),
|
|
535
567
|
};
|
|
536
568
|
}
|
|
569
|
+
export function isModelProfileProxyConfigured(
|
|
570
|
+
provider: string,
|
|
571
|
+
configuredProviders: readonly string[] | undefined,
|
|
572
|
+
credentialless: boolean,
|
|
573
|
+
): boolean {
|
|
574
|
+
return configuredProviders?.includes(provider) === true || (provider === "opencodex" && credentialless);
|
|
575
|
+
}
|
|
576
|
+
|
|
537
577
|
/**
|
|
538
578
|
* Resolve the explicitly configured OpenAI-compatible proxy provider id for a
|
|
539
579
|
* preset. Returns undefined when unset or empty. Passwords/labels are never
|
|
@@ -608,6 +648,245 @@ export function requiresQualifiedModelProfileRoleResolution(profile: Pick<ModelP
|
|
|
608
648
|
return profile.source === "user" || profile.source === "registry";
|
|
609
649
|
}
|
|
610
650
|
|
|
651
|
+
/** Resolve a removed saved-session default through the durable profile without mutating persistent state. */
|
|
652
|
+
export async function resolveMissingSessionModelRecovery(options: {
|
|
653
|
+
modelRegistry: PrepareModelProfileActivationOptions["modelRegistry"];
|
|
654
|
+
settings: Pick<Settings, "get" | "getModelRole">;
|
|
655
|
+
defaultEntries: readonly string[];
|
|
656
|
+
skips: Array<{ selector: string; reason: string }>;
|
|
657
|
+
savedDefault: string | undefined;
|
|
658
|
+
credentialSessionId: string;
|
|
659
|
+
aliasIntent?: "preset-equivalent";
|
|
660
|
+
}): Promise<
|
|
661
|
+
| {
|
|
662
|
+
profileName: string;
|
|
663
|
+
entries: string[];
|
|
664
|
+
model?: Model<Api>;
|
|
665
|
+
thinkingLevel?: ThinkingLevel;
|
|
666
|
+
explicitThinkingLevel: boolean;
|
|
667
|
+
activeIndex: number;
|
|
668
|
+
skips: Array<{ selector: string; reason: string }>;
|
|
669
|
+
}
|
|
670
|
+
| undefined
|
|
671
|
+
> {
|
|
672
|
+
const allSelectorsUnknown =
|
|
673
|
+
options.skips.length === options.defaultEntries.length &&
|
|
674
|
+
options.skips.every(skip => skip.reason === "unknown_model");
|
|
675
|
+
if (!allSelectorsUnknown) return undefined;
|
|
676
|
+
const fullCatalog = options.modelRegistry.getAll();
|
|
677
|
+
const savedSelectorsMissingFromCatalog = resolveConfiguredModelPatterns(
|
|
678
|
+
options.defaultEntries,
|
|
679
|
+
options.settings,
|
|
680
|
+
).every(selector => {
|
|
681
|
+
if (
|
|
682
|
+
resolveModelRoleValue(selector, fullCatalog, {
|
|
683
|
+
settings: options.settings,
|
|
684
|
+
modelRegistry: options.modelRegistry,
|
|
685
|
+
credentialSessionId: options.credentialSessionId,
|
|
686
|
+
...(options.aliasIntent ? { aliasIntent: options.aliasIntent } : {}),
|
|
687
|
+
}).model
|
|
688
|
+
)
|
|
689
|
+
return false;
|
|
690
|
+
return !registrySelectorResolvesToModel(selector, fullCatalog);
|
|
691
|
+
});
|
|
692
|
+
const savedConcreteDefault = options.savedDefault ? parseModelString(options.savedDefault) : undefined;
|
|
693
|
+
const savedConcreteDefaultMissingFromCatalog =
|
|
694
|
+
savedConcreteDefault === undefined ||
|
|
695
|
+
!fullCatalog.some(
|
|
696
|
+
model =>
|
|
697
|
+
model.provider.toLowerCase() === savedConcreteDefault.provider.toLowerCase() &&
|
|
698
|
+
model.id.toLowerCase() === savedConcreteDefault.id.toLowerCase(),
|
|
699
|
+
);
|
|
700
|
+
const durableProfile = options.settings.get("modelProfile.default");
|
|
701
|
+
if (!savedSelectorsMissingFromCatalog || !savedConcreteDefaultMissingFromCatalog || !durableProfile)
|
|
702
|
+
return undefined;
|
|
703
|
+
return resolveModelProfileDefaultChain({
|
|
704
|
+
modelRegistry: options.modelRegistry,
|
|
705
|
+
settings: options.settings,
|
|
706
|
+
profileName: durableProfile,
|
|
707
|
+
credentialSessionId: options.credentialSessionId,
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/** Resolve a durable profile's effective default chain without mutating session or settings state. */
|
|
712
|
+
export async function resolveModelProfileDefaultChain(options: {
|
|
713
|
+
modelRegistry: PrepareModelProfileActivationOptions["modelRegistry"];
|
|
714
|
+
settings: Pick<Settings, "get">;
|
|
715
|
+
profileName: string;
|
|
716
|
+
credentialSessionId: string;
|
|
717
|
+
}): Promise<{
|
|
718
|
+
profileName: string;
|
|
719
|
+
entries: string[];
|
|
720
|
+
model?: Model<Api>;
|
|
721
|
+
thinkingLevel?: ThinkingLevel;
|
|
722
|
+
explicitThinkingLevel: boolean;
|
|
723
|
+
activeIndex: number;
|
|
724
|
+
skips: Array<{ selector: string; reason: string }>;
|
|
725
|
+
}> {
|
|
726
|
+
const profiles = options.modelRegistry.getModelProfiles();
|
|
727
|
+
const profileName = validateModelProfileName(options.profileName, profiles, options.modelRegistry.getError?.());
|
|
728
|
+
const profile = profiles.get(profileName) ?? options.modelRegistry.getModelProfile(profileName)!;
|
|
729
|
+
const profileLabel = formatModelProfileDisplayLabel(profile);
|
|
730
|
+
const requiredProviders = aggregateModelProfileRequiredProviders(profile.requiredProviders, profile);
|
|
731
|
+
const alternativeGroups = profile.alternativeProviderGroups ?? [];
|
|
732
|
+
const alternativeSet = new Set(alternativeGroups.flat());
|
|
733
|
+
const requiredProviderSet = new Set(requiredProviders);
|
|
734
|
+
const authenticatedProviders = new Set<string>();
|
|
735
|
+
const missingProviders: string[] = [];
|
|
736
|
+
const configuredProviderIds = options.modelRegistry.getConfiguredProviderIds?.();
|
|
737
|
+
if (configuredProviderIds !== undefined || options.modelRegistry.isKnownProvider !== undefined) {
|
|
738
|
+
const isProviderKnown = (provider: string): boolean =>
|
|
739
|
+
(options.modelRegistry.isKnownProvider?.(provider) ?? false) ||
|
|
740
|
+
isKnownProvider(provider) ||
|
|
741
|
+
configuredProviderIds?.includes(provider) === true;
|
|
742
|
+
const unknownProviderIds = new Set<string>();
|
|
743
|
+
for (const provider of requiredProviders) {
|
|
744
|
+
if (!alternativeSet.has(provider) && !isProviderKnown(provider)) unknownProviderIds.add(provider);
|
|
745
|
+
}
|
|
746
|
+
for (const group of alternativeGroups) {
|
|
747
|
+
if (group.some(isProviderKnown)) continue;
|
|
748
|
+
for (const provider of group) {
|
|
749
|
+
if (!isProviderKnown(provider)) unknownProviderIds.add(provider);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
const unknownProviders = [...unknownProviderIds].sort();
|
|
753
|
+
if (unknownProviders.length > 0) throw new ModelProfileUnknownProviderError(profileLabel, unknownProviders);
|
|
754
|
+
}
|
|
755
|
+
for (const provider of new Set([
|
|
756
|
+
...requiredProviders,
|
|
757
|
+
...alternativeSet,
|
|
758
|
+
...deriveModelProfileMappedProviders(profile),
|
|
759
|
+
])) {
|
|
760
|
+
let apiKey: string | undefined;
|
|
761
|
+
try {
|
|
762
|
+
apiKey = await options.modelRegistry.getApiKeyForProvider(provider, options.credentialSessionId);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
if (requiredProviderSet.has(provider) && !alternativeSet.has(provider)) throw error;
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
if (apiKey === kNoAuth || isAuthenticated(apiKey)) authenticatedProviders.add(provider);
|
|
768
|
+
else if (requiredProviderSet.has(provider)) missingProviders.push(provider);
|
|
769
|
+
}
|
|
770
|
+
const proxyProvider = profile.source !== "user" ? resolveProxyProviderId(options.settings) : undefined;
|
|
771
|
+
const proxyMode = profile.source !== "user" ? resolveProxyMode(options.settings) : "fallback";
|
|
772
|
+
const proxyRoutableProviders =
|
|
773
|
+
profile.source === "user"
|
|
774
|
+
? new Set<string>()
|
|
775
|
+
: profile.source === "registry"
|
|
776
|
+
? new Set([
|
|
777
|
+
...PROXY_ROUTABLE_PROVIDER_IDS,
|
|
778
|
+
...profile.requiredProviders,
|
|
779
|
+
...deriveModelProfileMappedProviders(profile),
|
|
780
|
+
])
|
|
781
|
+
: PROXY_ROUTABLE_PROVIDER_IDS;
|
|
782
|
+
if (proxyMode === "always" && proxyProvider === undefined)
|
|
783
|
+
throw new Error('modelProfile.proxyMode "always" requires modelProfile.proxyProvider');
|
|
784
|
+
const proxyApiKey =
|
|
785
|
+
proxyProvider === undefined
|
|
786
|
+
? undefined
|
|
787
|
+
: await options.modelRegistry.getApiKeyForProvider(proxyProvider, options.credentialSessionId);
|
|
788
|
+
if (
|
|
789
|
+
proxyProvider !== undefined &&
|
|
790
|
+
!isModelProfileProxyConfigured(proxyProvider, configuredProviderIds, proxyApiKey === kNoAuth)
|
|
791
|
+
) {
|
|
792
|
+
throw new Error(
|
|
793
|
+
`modelProfile.proxyProvider "${proxyProvider}" is not configured. Configure it with \`gjc setup provider\` before activating a preset.`,
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
const proxyAuthenticated = proxyApiKey !== undefined && (proxyApiKey === kNoAuth || isAuthenticated(proxyApiKey));
|
|
797
|
+
if (proxyMode === "always" && !proxyAuthenticated)
|
|
798
|
+
throw new ModelProfileCredentialError(profileLabel, [proxyProvider!]);
|
|
799
|
+
const strictMissing = missingProviders.filter(
|
|
800
|
+
provider => !proxyRoutableProviders.has(provider) && !alternativeSet.has(provider),
|
|
801
|
+
);
|
|
802
|
+
if (strictMissing.length > 0) throw new ModelProfileCredentialError(profileLabel, strictMissing);
|
|
803
|
+
const strictRoutableMissing = missingProviders.filter(
|
|
804
|
+
provider => proxyRoutableProviders.has(provider) && !alternativeSet.has(provider),
|
|
805
|
+
);
|
|
806
|
+
if (strictRoutableMissing.length > 0 && !proxyAuthenticated) {
|
|
807
|
+
throw new ModelProfileCredentialError(
|
|
808
|
+
profileLabel,
|
|
809
|
+
proxyProvider === undefined ? strictRoutableMissing : [proxyProvider],
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
for (const group of alternativeGroups) {
|
|
813
|
+
if (group.some(provider => authenticatedProviders.has(provider))) continue;
|
|
814
|
+
const allRoutable = group.every(provider => proxyRoutableProviders.has(provider));
|
|
815
|
+
if (allRoutable && proxyAuthenticated) continue;
|
|
816
|
+
throw new ModelProfileCredentialError(
|
|
817
|
+
profileLabel,
|
|
818
|
+
allRoutable && proxyProvider !== undefined ? [proxyProvider] : [...group],
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
const availableModels =
|
|
822
|
+
options.modelRegistry.getAvailableForProfileActivation?.() ??
|
|
823
|
+
options.modelRegistry.getAvailable?.() ??
|
|
824
|
+
options.modelRegistry.getAll();
|
|
825
|
+
let bindings = resolveProfileBindings(profile);
|
|
826
|
+
if (alternativeGroups.length > 0)
|
|
827
|
+
bindings = rewriteBindingsProviders(bindings, authenticatedProviders, alternativeGroups);
|
|
828
|
+
if (proxyProvider !== undefined && proxyAuthenticated && profile.source !== "user") {
|
|
829
|
+
bindings = rewriteBindingsForProxy(
|
|
830
|
+
bindings,
|
|
831
|
+
proxyProvider,
|
|
832
|
+
proxyMode,
|
|
833
|
+
availableModels,
|
|
834
|
+
authenticatedProviders,
|
|
835
|
+
proxyRoutableProviders,
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
await preflightModelProfileRoleBindings({
|
|
839
|
+
profile,
|
|
840
|
+
bindings,
|
|
841
|
+
roleCatalogModels: options.modelRegistry.getAll(),
|
|
842
|
+
settings: options.settings as Settings,
|
|
843
|
+
modelRegistry: options.modelRegistry as ModelRegistry,
|
|
844
|
+
sessionId: "",
|
|
845
|
+
credentialSessionId: options.credentialSessionId,
|
|
846
|
+
profileLabel,
|
|
847
|
+
});
|
|
848
|
+
if (!bindings.defaultSelector)
|
|
849
|
+
return { profileName, entries: [], explicitThinkingLevel: false, activeIndex: 0, skips: [] };
|
|
850
|
+
const defaultChain = normalizeModelSelectorValue(
|
|
851
|
+
await resolveAndClampSelectorValue(
|
|
852
|
+
bindings.defaultSelector,
|
|
853
|
+
availableModels,
|
|
854
|
+
{
|
|
855
|
+
settings: options.settings as Settings,
|
|
856
|
+
modelRegistry: options.modelRegistry as ModelRegistry,
|
|
857
|
+
sessionId: "",
|
|
858
|
+
credentialSessionId: options.credentialSessionId,
|
|
859
|
+
aliasIntent: "preset-equivalent",
|
|
860
|
+
},
|
|
861
|
+
profileLabel,
|
|
862
|
+
"default",
|
|
863
|
+
),
|
|
864
|
+
);
|
|
865
|
+
const resolution = await resolveModelChainWithAuth(
|
|
866
|
+
defaultChain,
|
|
867
|
+
{
|
|
868
|
+
getAvailable: () => availableModels,
|
|
869
|
+
getApiKey: (model, sessionId) =>
|
|
870
|
+
options.modelRegistry.getApiKeyForProvider(model.provider, sessionId, model.baseUrl),
|
|
871
|
+
resolveCanonicalModel: options.modelRegistry.resolveCanonicalModel?.bind(options.modelRegistry),
|
|
872
|
+
getCanonicalVariants: options.modelRegistry.getCanonicalVariants?.bind(options.modelRegistry),
|
|
873
|
+
getCanonicalId: options.modelRegistry.getCanonicalId?.bind(options.modelRegistry),
|
|
874
|
+
resolveModelByLookupAlias: options.modelRegistry.resolveModelByLookupAlias?.bind(options.modelRegistry),
|
|
875
|
+
lookupAliasExists: options.modelRegistry.lookupAliasExists?.bind(options.modelRegistry),
|
|
876
|
+
clearCanonicalVariant: options.modelRegistry.clearCanonicalVariant?.bind(options.modelRegistry),
|
|
877
|
+
} as ModelRegistry,
|
|
878
|
+
options.settings as Settings,
|
|
879
|
+
options.credentialSessionId,
|
|
880
|
+
{
|
|
881
|
+
managedFallback: true,
|
|
882
|
+
aliasIntent: "preset-equivalent",
|
|
883
|
+
canonicalSessionId: null,
|
|
884
|
+
credentialSessionId: options.credentialSessionId,
|
|
885
|
+
},
|
|
886
|
+
);
|
|
887
|
+
return { profileName, entries: defaultChain, ...resolution };
|
|
888
|
+
}
|
|
889
|
+
|
|
611
890
|
export function rewriteSelectorForProxy(
|
|
612
891
|
selector: string,
|
|
613
892
|
proxyProvider: string,
|
|
@@ -620,9 +899,13 @@ export function rewriteSelectorForProxy(
|
|
|
620
899
|
const baseSelector = suffix.selector;
|
|
621
900
|
const slash = baseSelector.indexOf("/");
|
|
622
901
|
const proxyModels = allModels.filter(model => model.provider === proxyProvider);
|
|
902
|
+
const matchingProxyModels = (id: string): Model<Api>[] => {
|
|
903
|
+
const publicMatches = proxyModels.filter(model => model.id === id);
|
|
904
|
+
return publicMatches.length > 0 ? publicMatches : proxyModels.filter(model => model.wireModelId === id);
|
|
905
|
+
};
|
|
623
906
|
if (slash < 0) {
|
|
624
907
|
if (proxyMode === "fallback") return selector;
|
|
625
|
-
const exactMatches =
|
|
908
|
+
const exactMatches = matchingProxyModels(baseSelector);
|
|
626
909
|
const finalSegmentMatches = proxyModels.filter(model => model.id.split("/").at(-1) === baseSelector);
|
|
627
910
|
const matches = exactMatches.length > 0 ? exactMatches : finalSegmentMatches;
|
|
628
911
|
if (matches.length !== 1) {
|
|
@@ -640,8 +923,8 @@ export function rewriteSelectorForProxy(
|
|
|
640
923
|
throw new Error(`Configured proxy "${proxyProvider}" cannot route its own direct selector "${baseSelector}"`);
|
|
641
924
|
}
|
|
642
925
|
const directModelId = baseSelector.substring(slash + 1);
|
|
643
|
-
const exactMatches =
|
|
644
|
-
const flatMatches =
|
|
926
|
+
const exactMatches = matchingProxyModels(`${directProvider}/${directModelId}`);
|
|
927
|
+
const flatMatches = matchingProxyModels(directModelId);
|
|
645
928
|
const matches = exactMatches.length > 0 ? exactMatches : flatMatches;
|
|
646
929
|
if (matches.length === 0) {
|
|
647
930
|
throw new Error(`Configured proxy "${proxyProvider}" does not expose a model for "${baseSelector}"`);
|
|
@@ -851,6 +1134,49 @@ async function resolveAndClampSelectorValue(
|
|
|
851
1134
|
return clamped.length === 1 && typeof selectorValue === "string" ? clamped[0] : clamped;
|
|
852
1135
|
}
|
|
853
1136
|
|
|
1137
|
+
/** Resolve every non-default binding under the profile activation contract without installing it. */
|
|
1138
|
+
async function preflightModelProfileRoleBindings(options: {
|
|
1139
|
+
profile: ModelProfileDefinition;
|
|
1140
|
+
bindings: ResolvedProfileBinding;
|
|
1141
|
+
roleCatalogModels: Model<Api>[];
|
|
1142
|
+
settings: Settings;
|
|
1143
|
+
modelRegistry: ModelRegistry;
|
|
1144
|
+
sessionId: string;
|
|
1145
|
+
credentialSessionId: string;
|
|
1146
|
+
profileLabel: string;
|
|
1147
|
+
}): Promise<{
|
|
1148
|
+
modelRoles: Record<string, ModelSelectorValue>;
|
|
1149
|
+
agentModelOverrides: Record<string, ModelSelectorValue>;
|
|
1150
|
+
}> {
|
|
1151
|
+
const resolveBindings = async (bindings: Record<string, ModelSelectorValue>) => {
|
|
1152
|
+
const resolved: Record<string, ModelSelectorValue> = {};
|
|
1153
|
+
for (const [role, selectorValue] of Object.entries(bindings) as [
|
|
1154
|
+
GjcModelAssignmentTargetId,
|
|
1155
|
+
ModelSelectorValue,
|
|
1156
|
+
][]) {
|
|
1157
|
+
resolved[role] = await resolveAndClampSelectorValue(
|
|
1158
|
+
selectorValue,
|
|
1159
|
+
options.roleCatalogModels,
|
|
1160
|
+
{
|
|
1161
|
+
settings: options.settings,
|
|
1162
|
+
modelRegistry: options.modelRegistry,
|
|
1163
|
+
sessionId: options.sessionId,
|
|
1164
|
+
credentialSessionId: options.credentialSessionId,
|
|
1165
|
+
aliasIntent: "preset-equivalent",
|
|
1166
|
+
requireQualifiedResolution: requiresQualifiedModelProfileRoleResolution(options.profile),
|
|
1167
|
+
},
|
|
1168
|
+
options.profileLabel,
|
|
1169
|
+
role,
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
return resolved;
|
|
1173
|
+
};
|
|
1174
|
+
return {
|
|
1175
|
+
modelRoles: await resolveBindings(options.bindings.modelRoles),
|
|
1176
|
+
agentModelOverrides: await resolveBindings(options.bindings.agentModelOverrides),
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
|
|
854
1180
|
async function concretizeProfileSelectorValue(
|
|
855
1181
|
selectorValue: ModelSelectorValue,
|
|
856
1182
|
prepared: PreparedModelProfileActivation,
|
|
@@ -957,6 +1283,33 @@ export async function prepareModelProfileActivation(
|
|
|
957
1283
|
...alternativeSet,
|
|
958
1284
|
...deriveModelProfileMappedProviders(profile),
|
|
959
1285
|
]);
|
|
1286
|
+
// A required provider this build cannot know is a build/config mismatch,
|
|
1287
|
+
// not a credential gap: diagnose it before any auth probing so the user
|
|
1288
|
+
// is never sent to /login for a provider this binary cannot serve (for
|
|
1289
|
+
// example a models.yml profile authored on a newer or custom build). A
|
|
1290
|
+
// registry without provider visibility keeps the legacy
|
|
1291
|
+
// credential diagnosis.
|
|
1292
|
+
const configuredProviderIds = options.modelRegistry.getConfiguredProviderIds?.();
|
|
1293
|
+
if (configuredProviderIds !== undefined || options.modelRegistry.isKnownProvider !== undefined) {
|
|
1294
|
+
const isProviderKnown = (provider: string): boolean =>
|
|
1295
|
+
(options.modelRegistry.isKnownProvider?.(provider) ?? false) ||
|
|
1296
|
+
isKnownProvider(provider) ||
|
|
1297
|
+
configuredProviderIds?.includes(provider) === true;
|
|
1298
|
+
const unknownRequiredProviders = new Set<string>();
|
|
1299
|
+
for (const provider of requiredProviders) {
|
|
1300
|
+
if (!alternativeSet.has(provider) && !isProviderKnown(provider)) unknownRequiredProviders.add(provider);
|
|
1301
|
+
}
|
|
1302
|
+
for (const group of alternativeGroups) {
|
|
1303
|
+
if (group.some(isProviderKnown)) continue;
|
|
1304
|
+
for (const provider of group) {
|
|
1305
|
+
if (!isProviderKnown(provider)) unknownRequiredProviders.add(provider);
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
const unknownProviderIds = [...unknownRequiredProviders].sort();
|
|
1309
|
+
if (unknownProviderIds.length > 0) {
|
|
1310
|
+
throw new ModelProfileUnknownProviderError(profileLabel, unknownProviderIds);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
960
1313
|
|
|
961
1314
|
const missingProviders: string[] = [];
|
|
962
1315
|
const authenticatedProviders: string[] = [];
|
|
@@ -995,18 +1348,18 @@ export async function prepareModelProfileActivation(
|
|
|
995
1348
|
if (proxyMode === "always" && proxyProvider === undefined) {
|
|
996
1349
|
throw new Error('modelProfile.proxyMode "always" requires modelProfile.proxyProvider');
|
|
997
1350
|
}
|
|
1351
|
+
const proxyApiKey =
|
|
1352
|
+
proxyProvider === undefined
|
|
1353
|
+
? undefined
|
|
1354
|
+
: await options.modelRegistry.getApiKeyForProvider(proxyProvider, credentialSessionId);
|
|
998
1355
|
if (proxyProvider !== undefined) {
|
|
999
1356
|
const configuredProxyProviders = options.modelRegistry.getConfiguredProviderIds?.();
|
|
1000
|
-
if (!
|
|
1357
|
+
if (!isModelProfileProxyConfigured(proxyProvider, configuredProxyProviders, proxyApiKey === kNoAuth)) {
|
|
1001
1358
|
throw new Error(
|
|
1002
1359
|
`modelProfile.proxyProvider "${proxyProvider}" is not configured. Configure it with \`gjc setup provider\` before activating a preset.`,
|
|
1003
1360
|
);
|
|
1004
1361
|
}
|
|
1005
1362
|
}
|
|
1006
|
-
const proxyApiKey =
|
|
1007
|
-
proxyProvider === undefined
|
|
1008
|
-
? undefined
|
|
1009
|
-
: await options.modelRegistry.getApiKeyForProvider(proxyProvider, credentialSessionId);
|
|
1010
1363
|
const proxyAuthenticated =
|
|
1011
1364
|
proxyProvider !== undefined &&
|
|
1012
1365
|
proxyApiKey !== undefined &&
|
|
@@ -1118,47 +1471,16 @@ export async function prepareModelProfileActivation(
|
|
|
1118
1471
|
throw new Error(`Model profile "${profileLabel}" default selectors did not resolve to an authenticated model`);
|
|
1119
1472
|
}
|
|
1120
1473
|
|
|
1121
|
-
const modelRoles
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
modelRegistry: options.modelRegistry as ModelRegistry,
|
|
1132
|
-
sessionId: options.session.sessionId,
|
|
1133
|
-
credentialSessionId,
|
|
1134
|
-
aliasIntent: "preset-equivalent",
|
|
1135
|
-
requireQualifiedResolution: requiresQualifiedModelProfileRoleResolution(profile),
|
|
1136
|
-
},
|
|
1137
|
-
profileLabel,
|
|
1138
|
-
role,
|
|
1139
|
-
);
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
const agentModelOverrides: Record<string, ModelSelectorValue> = {};
|
|
1143
|
-
for (const [role, selectorValue] of Object.entries(bindings.agentModelOverrides) as [
|
|
1144
|
-
GjcModelAssignmentTargetId,
|
|
1145
|
-
ModelSelectorValue,
|
|
1146
|
-
][]) {
|
|
1147
|
-
agentModelOverrides[role] = await resolveAndClampSelectorValue(
|
|
1148
|
-
selectorValue,
|
|
1149
|
-
roleCatalogModels,
|
|
1150
|
-
{
|
|
1151
|
-
settings: options.settings as Settings,
|
|
1152
|
-
modelRegistry: options.modelRegistry as ModelRegistry,
|
|
1153
|
-
sessionId: options.session.sessionId,
|
|
1154
|
-
credentialSessionId,
|
|
1155
|
-
aliasIntent: "preset-equivalent",
|
|
1156
|
-
requireQualifiedResolution: requiresQualifiedModelProfileRoleResolution(profile),
|
|
1157
|
-
},
|
|
1158
|
-
profileLabel,
|
|
1159
|
-
role,
|
|
1160
|
-
);
|
|
1161
|
-
}
|
|
1474
|
+
const { modelRoles, agentModelOverrides } = await preflightModelProfileRoleBindings({
|
|
1475
|
+
profile,
|
|
1476
|
+
bindings,
|
|
1477
|
+
roleCatalogModels,
|
|
1478
|
+
settings: options.settings as Settings,
|
|
1479
|
+
modelRegistry: options.modelRegistry as ModelRegistry,
|
|
1480
|
+
sessionId: options.session.sessionId,
|
|
1481
|
+
credentialSessionId,
|
|
1482
|
+
profileLabel,
|
|
1483
|
+
});
|
|
1162
1484
|
|
|
1163
1485
|
return {
|
|
1164
1486
|
profileName,
|
|
@@ -1660,3 +1982,34 @@ export async function activateModelProfile(
|
|
|
1660
1982
|
const prepared = await prepareModelProfileActivation(options);
|
|
1661
1983
|
await applyPreparedModelProfileActivation(prepared, applyOptions);
|
|
1662
1984
|
}
|
|
1985
|
+
|
|
1986
|
+
/** Install only a profile's runtime role layer, preserving session model and configured-chain intent. */
|
|
1987
|
+
export async function applyModelProfileRuntimeBindings(options: PrepareModelProfileActivationOptions): Promise<void> {
|
|
1988
|
+
const prepared = await prepareModelProfileActivation(options);
|
|
1989
|
+
try {
|
|
1990
|
+
prepared.settings.override("modelRoles", {
|
|
1991
|
+
...prepared.baseModelRoles,
|
|
1992
|
+
...prepared.modelRoles,
|
|
1993
|
+
});
|
|
1994
|
+
prepared.settings.override("task.agentModelOverrides", {
|
|
1995
|
+
...prepared.baseAgentModelOverrides,
|
|
1996
|
+
...prepared.agentModelOverrides,
|
|
1997
|
+
});
|
|
1998
|
+
prepared.session.setActiveModelProfile?.(prepared.profileName);
|
|
1999
|
+
prepared.session.noteProfileInstalledOverrides?.(
|
|
2000
|
+
Object.keys(prepared.modelRoles),
|
|
2001
|
+
Object.keys(prepared.agentModelOverrides),
|
|
2002
|
+
prepared.previousModel,
|
|
2003
|
+
);
|
|
2004
|
+
try {
|
|
2005
|
+
await prepared.session.syncEagerDelegation?.();
|
|
2006
|
+
} catch (error) {
|
|
2007
|
+
logger.warn("Failed to sync eager delegation after recovered profile runtime bindings", {
|
|
2008
|
+
profile: prepared.profileName,
|
|
2009
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
} finally {
|
|
2013
|
+
restoreCanonicalVariant(prepared.modelRegistry, prepared.session.sessionId, prepared.previousCanonicalVariant);
|
|
2014
|
+
}
|
|
2015
|
+
}
|