@iislee/opencodex 2.11.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { createAnthropicAdapter } from "./anthropic";
|
|
2
|
+
import { createAzureAdapter } from "./azure";
|
|
3
|
+
import type { ProviderAdapter } from "./base";
|
|
4
|
+
import { withClinePassDeepSeekV4ToolReplayCompatibility } from "./cline-pass-deepseek-v4-tool-replay";
|
|
5
|
+
import { createCommandCodeAdapter } from "./command-code";
|
|
6
|
+
import { createCursorAdapter } from "./cursor";
|
|
7
|
+
import { createGoogleAdapter } from "./google";
|
|
8
|
+
import { createKiroAdapter } from "./kiro";
|
|
9
|
+
import { createMimoFreeAdapter } from "./mimo-free";
|
|
10
|
+
import { createOpenAIChatAdapter } from "./openai-chat";
|
|
11
|
+
import { createResponsesPassthroughAdapter } from "./openai-responses";
|
|
12
|
+
import type { OcxProviderConfig } from "../types";
|
|
13
|
+
import { createAdapterTierMetadata } from "../providers/fastwire";
|
|
14
|
+
|
|
15
|
+
export type AdapterCacheRetention = "none" | "short" | "long";
|
|
16
|
+
|
|
17
|
+
export interface AdapterFactoryContext {
|
|
18
|
+
cacheRetention?: AdapterCacheRetention;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type AdapterWire =
|
|
22
|
+
| "command-code"
|
|
23
|
+
| "openai-chat"
|
|
24
|
+
| "anthropic"
|
|
25
|
+
| "openai-responses"
|
|
26
|
+
| "google"
|
|
27
|
+
| "kiro"
|
|
28
|
+
| "cursor";
|
|
29
|
+
|
|
30
|
+
export type AdapterMutationContract =
|
|
31
|
+
| "codex-owned"
|
|
32
|
+
| "codex-owned-with-gated-native-fallback";
|
|
33
|
+
|
|
34
|
+
type AdapterFactory = (
|
|
35
|
+
provider: OcxProviderConfig,
|
|
36
|
+
context: AdapterFactoryContext,
|
|
37
|
+
) => ProviderAdapter;
|
|
38
|
+
|
|
39
|
+
type DirectAdapterDefinition = {
|
|
40
|
+
wire: AdapterWire;
|
|
41
|
+
mutation: AdapterMutationContract;
|
|
42
|
+
create: AdapterFactory;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type InheritedAdapterDefinition = {
|
|
46
|
+
/** Semantic contract inheritance only. Runtime construction remains independent. */
|
|
47
|
+
contractParent: string;
|
|
48
|
+
create: AdapterFactory;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type AdapterDefinition = DirectAdapterDefinition | InheritedAdapterDefinition;
|
|
52
|
+
|
|
53
|
+
export const ADAPTER_REGISTRY = {
|
|
54
|
+
"command-code": {
|
|
55
|
+
wire: "command-code",
|
|
56
|
+
mutation: "codex-owned",
|
|
57
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createCommandCodeAdapter(provider),
|
|
58
|
+
},
|
|
59
|
+
"openai-chat": {
|
|
60
|
+
wire: "openai-chat",
|
|
61
|
+
mutation: "codex-owned",
|
|
62
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) =>
|
|
63
|
+
withClinePassDeepSeekV4ToolReplayCompatibility(createOpenAIChatAdapter(provider)),
|
|
64
|
+
},
|
|
65
|
+
anthropic: {
|
|
66
|
+
wire: "anthropic",
|
|
67
|
+
mutation: "codex-owned",
|
|
68
|
+
create: (provider: OcxProviderConfig, context: AdapterFactoryContext) =>
|
|
69
|
+
createAnthropicAdapter(provider, context.cacheRetention),
|
|
70
|
+
},
|
|
71
|
+
"openai-responses": {
|
|
72
|
+
wire: "openai-responses",
|
|
73
|
+
mutation: "codex-owned",
|
|
74
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) =>
|
|
75
|
+
createResponsesPassthroughAdapter(provider),
|
|
76
|
+
},
|
|
77
|
+
google: {
|
|
78
|
+
wire: "google",
|
|
79
|
+
mutation: "codex-owned",
|
|
80
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createGoogleAdapter(provider),
|
|
81
|
+
},
|
|
82
|
+
kiro: {
|
|
83
|
+
wire: "kiro",
|
|
84
|
+
mutation: "codex-owned",
|
|
85
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createKiroAdapter(provider),
|
|
86
|
+
},
|
|
87
|
+
azure: {
|
|
88
|
+
contractParent: "openai-responses",
|
|
89
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createAzureAdapter(provider),
|
|
90
|
+
},
|
|
91
|
+
"azure-openai": {
|
|
92
|
+
contractParent: "openai-responses",
|
|
93
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createAzureAdapter(provider),
|
|
94
|
+
},
|
|
95
|
+
cursor: {
|
|
96
|
+
wire: "cursor",
|
|
97
|
+
mutation: "codex-owned-with-gated-native-fallback",
|
|
98
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createCursorAdapter(provider),
|
|
99
|
+
},
|
|
100
|
+
"mimo-free": {
|
|
101
|
+
contractParent: "openai-chat",
|
|
102
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createMimoFreeAdapter(provider),
|
|
103
|
+
},
|
|
104
|
+
} as const satisfies Record<string, AdapterDefinition>;
|
|
105
|
+
|
|
106
|
+
export type AdapterId = keyof typeof ADAPTER_REGISTRY;
|
|
107
|
+
export type RegisteredAdapterDefinition = typeof ADAPTER_REGISTRY[AdapterId];
|
|
108
|
+
|
|
109
|
+
export function adapterDefinitions(): Array<[AdapterId, RegisteredAdapterDefinition]> {
|
|
110
|
+
return Object.entries(ADAPTER_REGISTRY) as Array<[AdapterId, RegisteredAdapterDefinition]>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function getAdapterDefinition(adapterId: unknown): RegisteredAdapterDefinition | undefined {
|
|
114
|
+
if (typeof adapterId !== "string" || !Object.hasOwn(ADAPTER_REGISTRY, adapterId)) return undefined;
|
|
115
|
+
return ADAPTER_REGISTRY[adapterId as AdapterId];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function effectiveAdapterContract(adapterId: string): Readonly<{
|
|
119
|
+
wire: AdapterWire;
|
|
120
|
+
mutation: AdapterMutationContract;
|
|
121
|
+
}> {
|
|
122
|
+
const visited = new Set<string>();
|
|
123
|
+
let current = adapterId;
|
|
124
|
+
|
|
125
|
+
while (true) {
|
|
126
|
+
if (visited.has(current)) {
|
|
127
|
+
throw new Error(`Adapter contract cycle detected at ${current}`);
|
|
128
|
+
}
|
|
129
|
+
visited.add(current);
|
|
130
|
+
|
|
131
|
+
const definition = getAdapterDefinition(current);
|
|
132
|
+
if (!definition) throw new Error(`Unknown adapter: ${current}`);
|
|
133
|
+
if ("wire" in definition) {
|
|
134
|
+
return { wire: definition.wire, mutation: definition.mutation };
|
|
135
|
+
}
|
|
136
|
+
current = definition.contractParent;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function createRegisteredAdapter(
|
|
141
|
+
provider: OcxProviderConfig,
|
|
142
|
+
context: AdapterFactoryContext = {},
|
|
143
|
+
): ProviderAdapter {
|
|
144
|
+
const definition = getAdapterDefinition(provider.adapter);
|
|
145
|
+
if (!definition) throw new Error(`Unknown adapter: ${provider.adapter}`);
|
|
146
|
+
const adapter = definition.create(provider, context);
|
|
147
|
+
const buildRequest = adapter.buildRequest.bind(adapter);
|
|
148
|
+
adapter.buildRequest = (parsed, incoming) => {
|
|
149
|
+
const attachTierMetadata = (request: Awaited<ReturnType<ProviderAdapter["buildRequest"]>>) => {
|
|
150
|
+
// OpenAI-family adapters report the exact emitted field themselves. Other adapters
|
|
151
|
+
// still report an exact absence at this serialization boundary, which makes a routed
|
|
152
|
+
// Fast downgrade observable without asking core to infer an outbound body shape.
|
|
153
|
+
request.tierLog ??= createAdapterTierMetadata(
|
|
154
|
+
parsed.options.tierObservation,
|
|
155
|
+
parsed.options.tierDecision,
|
|
156
|
+
null,
|
|
157
|
+
null,
|
|
158
|
+
);
|
|
159
|
+
return request;
|
|
160
|
+
};
|
|
161
|
+
const request = buildRequest(parsed, incoming);
|
|
162
|
+
return request instanceof Promise
|
|
163
|
+
? request.then(attachTierMetadata)
|
|
164
|
+
: attachTierMetadata(request);
|
|
165
|
+
};
|
|
166
|
+
if (adapter.runTurn && !adapter.tierLogForRunTurn) {
|
|
167
|
+
adapter.tierLogForRunTurn = parsed => createAdapterTierMetadata(
|
|
168
|
+
parsed.options.tierObservation,
|
|
169
|
+
parsed.options.tierDecision,
|
|
170
|
+
null,
|
|
171
|
+
null,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
return adapter;
|
|
175
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Codex multi-agent v2 stamps a Responses-only `encrypted: true` marker on
|
|
2
|
+
// collaboration tool schemas (openai/codex 5f4d06ef; issue #85). It is an
|
|
3
|
+
// annotation for the ChatGPT backend only, so translated provider schemas must
|
|
4
|
+
// drop it without removing properties or definitions literally named `encrypted`.
|
|
5
|
+
const ENCRYPTED_MARKER_NAME_BAG_KEYS = new Set([
|
|
6
|
+
"properties",
|
|
7
|
+
"patternProperties",
|
|
8
|
+
"$defs",
|
|
9
|
+
"definitions",
|
|
10
|
+
"dependencies",
|
|
11
|
+
"dependentSchemas",
|
|
12
|
+
"dependentRequired",
|
|
13
|
+
]);
|
|
14
|
+
const ENCRYPTED_MARKER_LITERAL_VALUE_KEYS = new Set(["const", "default", "enum", "examples"]);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The schema is caller-supplied, so its nesting depth is attacker-influenced. Native recursion
|
|
18
|
+
* would turn a deep schema into a stack overflow that takes down the request path, so this walks
|
|
19
|
+
* an explicit stack instead: depth costs heap, which is bounded and recoverable.
|
|
20
|
+
*/
|
|
21
|
+
export function stripResponsesOnlyEncryptedMarker(node: unknown, inNameBag = false): unknown {
|
|
22
|
+
type Assign = (value: unknown) => void;
|
|
23
|
+
interface Frame { node: unknown; inNameBag: boolean; assign: Assign }
|
|
24
|
+
|
|
25
|
+
let result: unknown;
|
|
26
|
+
const stack: Frame[] = [{ node, inNameBag, assign: value => { result = value; } }];
|
|
27
|
+
|
|
28
|
+
while (stack.length > 0) {
|
|
29
|
+
const frame = stack.pop()!;
|
|
30
|
+
const current = frame.node;
|
|
31
|
+
|
|
32
|
+
if (Array.isArray(current)) {
|
|
33
|
+
const out: unknown[] = new Array(current.length);
|
|
34
|
+
frame.assign(out);
|
|
35
|
+
// Array items are schemas in their own right, never a name bag.
|
|
36
|
+
for (let i = current.length - 1; i >= 0; i--) {
|
|
37
|
+
stack.push({ node: current[i], inNameBag: false, assign: value => { out[i] = value; } });
|
|
38
|
+
}
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (!current || typeof current !== "object") {
|
|
42
|
+
frame.assign(current);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// A schema name may be `__proto__`; a null-prototype record keeps it as data.
|
|
47
|
+
const out: Record<string, unknown> = Object.create(null) as Record<string, unknown>;
|
|
48
|
+
frame.assign(out);
|
|
49
|
+
|
|
50
|
+
for (const [key, value] of Object.entries(current as Record<string, unknown>)) {
|
|
51
|
+
if (frame.inNameBag) {
|
|
52
|
+
// Inside a name bag every key is a caller-chosen name, so `encrypted` here is data.
|
|
53
|
+
stack.push({ node: value, inNameBag: false, assign: v => { out[key] = v; } });
|
|
54
|
+
} else if (key !== "encrypted") {
|
|
55
|
+
if (ENCRYPTED_MARKER_LITERAL_VALUE_KEYS.has(key)) {
|
|
56
|
+
// Literal payloads are values, not schemas: an `encrypted` key inside them is data.
|
|
57
|
+
out[key] = value;
|
|
58
|
+
} else {
|
|
59
|
+
const childInNameBag = ENCRYPTED_MARKER_NAME_BAG_KEYS.has(key);
|
|
60
|
+
stack.push({ node: value, inNameBag: childInNameBag, assign: v => { out[key] = v; } });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Anthropic rejects a `tool_use.id` longer than this. Collision disambiguation has to fit
|
|
5
|
+
* inside it too, which is why candidates are assembled from parts instead of sliced at the end.
|
|
6
|
+
*/
|
|
7
|
+
export const MAX_TOOL_CALL_ID_LENGTH = 64;
|
|
8
|
+
|
|
9
|
+
/** Hex characters of the deterministic tail. Fixed width: it is a discriminator, not a payload. */
|
|
10
|
+
const TOOL_CALL_ID_HASH_WIDTH = 8;
|
|
11
|
+
|
|
12
|
+
const CONFORMING_TOOL_CALL_ID = /^[a-zA-Z0-9_-]+$/;
|
|
13
|
+
|
|
14
|
+
/** An id Anthropic accepts as-is: right character set AND within the length bound. */
|
|
15
|
+
export function isConformingToolCallId(rawId: string): boolean {
|
|
16
|
+
return rawId.length > 0
|
|
17
|
+
&& rawId.length <= MAX_TOOL_CALL_ID_LENGTH
|
|
18
|
+
&& CONFORMING_TOOL_CALL_ID.test(rawId);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The parts a rewritten id is built from: the sanitized prefix and a deterministic tail
|
|
23
|
+
* derived from the raw id. Kept separate so collision handling can truncate the prefix
|
|
24
|
+
* without destroying the discriminator.
|
|
25
|
+
*/
|
|
26
|
+
function toolCallIdComponents(rawId: string | undefined): { cleaned: string; hash: string } | undefined {
|
|
27
|
+
const raw = rawId ?? "";
|
|
28
|
+
if (raw.length === 0) return undefined;
|
|
29
|
+
const cleaned = raw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
30
|
+
const hash = createHash("sha256").update(raw).digest("hex").slice(0, TOOL_CALL_ID_HASH_WIDTH);
|
|
31
|
+
return { cleaned, hash };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Assemble `prefix_hash`, truncating only the prefix, leaving `reserve` characters spare. */
|
|
35
|
+
function fitToolCallId(cleaned: string, hash: string, reserve = 0): string {
|
|
36
|
+
const tail = `_${hash}`;
|
|
37
|
+
const room = MAX_TOOL_CALL_ID_LENGTH - reserve - tail.length;
|
|
38
|
+
return cleaned.slice(0, Math.max(1, room)) + tail;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Normalize a tool call id into the character set and length Anthropic accepts.
|
|
43
|
+
*
|
|
44
|
+
* This is the stateless view, kept for callers that only need the shape of one id. It is NOT
|
|
45
|
+
* injective on its own: `anthropicToolCallId("call:a")` returns something like `call_a_1f2e3d4c`,
|
|
46
|
+
* and a raw id that already equals that value is returned unchanged — two distinct sources, one
|
|
47
|
+
* wire id. Anything building a whole request must use {@link createToolCallIdAllocator}, which
|
|
48
|
+
* reserves the conforming ids first and resolves collisions.
|
|
49
|
+
*
|
|
50
|
+
* Returns `undefined` for an empty id. Callers must handle that rather than falling back to the
|
|
51
|
+
* raw value: restoring `""` puts an id on the wire that Anthropic rejects (#1767).
|
|
52
|
+
*/
|
|
53
|
+
export function anthropicToolCallId(rawId: string | undefined): string | undefined {
|
|
54
|
+
const raw = rawId ?? "";
|
|
55
|
+
if (raw.length === 0) return undefined;
|
|
56
|
+
if (isConformingToolCallId(raw)) return raw;
|
|
57
|
+
const parts = toolCallIdComponents(raw);
|
|
58
|
+
if (!parts) return undefined;
|
|
59
|
+
return fitToolCallId(parts.cleaned, parts.hash);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type ToolCallIdAllocator = {
|
|
63
|
+
/** Claim an already-conforming source id so no rewrite can be handed the same value. */
|
|
64
|
+
reserve(rawId: string | undefined): void;
|
|
65
|
+
/** Wire id for a raw id, stable within the request. `undefined` means "not representable". */
|
|
66
|
+
allocate(rawId: string | undefined): string | undefined;
|
|
67
|
+
/** Wire id previously allocated for this raw id, without creating one. */
|
|
68
|
+
lookup(rawId: string | undefined): string | undefined;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Request-scoped raw-id to wire-id mapping.
|
|
73
|
+
*
|
|
74
|
+
* Two properties the stateless transform cannot provide:
|
|
75
|
+
*
|
|
76
|
+
* - **Injective.** Reserve every already-conforming id first, then allocate rewrites around them,
|
|
77
|
+
* appending a numeric suffix when a candidate is taken. Two distinct raw ids never share a wire id,
|
|
78
|
+
* including the case where one raw id already looks like another's normalized form, and including
|
|
79
|
+
* an ordinary 32-bit hash collision.
|
|
80
|
+
* - **Stable.** A tool result asks for the same raw id its call used and gets the same wire id, so
|
|
81
|
+
* call/result pairing survives normalization.
|
|
82
|
+
*/
|
|
83
|
+
export function createToolCallIdAllocator(): ToolCallIdAllocator {
|
|
84
|
+
const rawToWire = new Map<string, string>();
|
|
85
|
+
const occupied = new Set<string>();
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
reserve(rawId) {
|
|
89
|
+
if (!rawId || rawToWire.has(rawId)) return;
|
|
90
|
+
if (!isConformingToolCallId(rawId)) return;
|
|
91
|
+
rawToWire.set(rawId, rawId);
|
|
92
|
+
occupied.add(rawId);
|
|
93
|
+
},
|
|
94
|
+
allocate(rawId) {
|
|
95
|
+
if (!rawId) return undefined;
|
|
96
|
+
const existing = rawToWire.get(rawId);
|
|
97
|
+
if (existing) return existing;
|
|
98
|
+
if (isConformingToolCallId(rawId) && !occupied.has(rawId)) {
|
|
99
|
+
rawToWire.set(rawId, rawId);
|
|
100
|
+
occupied.add(rawId);
|
|
101
|
+
return rawId;
|
|
102
|
+
}
|
|
103
|
+
const parts = toolCallIdComponents(rawId);
|
|
104
|
+
if (!parts) return undefined;
|
|
105
|
+
let candidate = fitToolCallId(parts.cleaned, parts.hash);
|
|
106
|
+
for (let n = 2; occupied.has(candidate); n++) {
|
|
107
|
+
const suffix = `_${n}`;
|
|
108
|
+
candidate = fitToolCallId(parts.cleaned, parts.hash, suffix.length) + suffix;
|
|
109
|
+
}
|
|
110
|
+
rawToWire.set(rawId, candidate);
|
|
111
|
+
occupied.add(candidate);
|
|
112
|
+
return candidate;
|
|
113
|
+
},
|
|
114
|
+
lookup(rawId) {
|
|
115
|
+
if (!rawId) return undefined;
|
|
116
|
+
return rawToWire.get(rawId);
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -1,30 +1,62 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isAllowedToolChoice,
|
|
3
2
|
namespacedToolName,
|
|
4
|
-
|
|
5
|
-
toolChoiceAliases,
|
|
3
|
+
toolChoiceToolPredicate,
|
|
6
4
|
type OcxRequestOptions,
|
|
7
5
|
type OcxTool,
|
|
8
6
|
type OcxProviderConfig,
|
|
9
7
|
} from "../types";
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
// Tool names that exist only in OTHER agent harnesses (Claude Code and friends). Naming one
|
|
10
|
+
// here tells a routed model not to call it unless this turn's catalog really lists it.
|
|
11
|
+
//
|
|
12
|
+
// `apply_patch` is deliberately absent: it is Codex's own first-class edit tool, not a
|
|
13
|
+
// neighbor's. Under Codex code mode it is reachable as a nested `tools.apply_patch(...)`
|
|
14
|
+
// helper declared inside the `exec` tool description rather than as a top-level wire tool,
|
|
15
|
+
// so a flat catalog check cannot see it and forbidding it pushed routed models into
|
|
16
|
+
// `python3` heredoc edits. The sibling list in `./cursor/tool-definitions.ts` never
|
|
17
|
+
// included it either.
|
|
18
|
+
const NEIGHBOR_AGENT_TOOL_NAMES = ["Read", "Grep", "Glob", "Bash", "LS"] as const;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The two halves of the code-mode shape, kept provider-neutral here.
|
|
22
|
+
*
|
|
23
|
+
* `./cursor/tool-definitions.ts` owns the Cursor-scoped versions of these
|
|
24
|
+
* (`isCursorCodeModeExecTool` / `isBareCodexShellBridgeTool`), but those additionally require
|
|
25
|
+
* the Cursor Responses namespace. This nudge is shared by Anthropic, Google, Kiro,
|
|
26
|
+
* OpenAI-chat and command-code, so it needs the same semantics without that provider gate.
|
|
27
|
+
*/
|
|
28
|
+
const CODEX_UNIFIED_EXEC_TOOL_NAME = "exec";
|
|
29
|
+
const CODEX_SHELL_BRIDGE_TOOL_NAMES = ["exec_command", "shell_command"] as const;
|
|
30
|
+
|
|
31
|
+
function isCodexCodeModeExecTool(tool: Pick<OcxTool, "namespace" | "name" | "freeform">): boolean {
|
|
32
|
+
return !tool.namespace && tool.name === CODEX_UNIFIED_EXEC_TOOL_NAME && tool.freeform === true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* BARE means un-namespaced, and the word is load-bearing.
|
|
37
|
+
*
|
|
38
|
+
* An MCP server can advertise its own `exec_command` or `shell_command` — a docker, k8s or ssh
|
|
39
|
+
* server plausibly does — and those arrive namespaced (`mcp__docker__exec_command`). They are
|
|
40
|
+
* not Codex's shell bridge, so they must not cancel code mode: a genuine code-mode turn that
|
|
41
|
+
* merely happens to sit beside an MCP shell tool would lose its guidance and fall back to the
|
|
42
|
+
* generic sentence.
|
|
43
|
+
*
|
|
44
|
+
* The Cursor original this was ported from (`isBareCodexShellBridgeTool`) carries the same
|
|
45
|
+
* `!tool.namespace` requirement; dropping it here made the name assert a check the body did not
|
|
46
|
+
* perform.
|
|
47
|
+
*/
|
|
48
|
+
function isBareShellBridgeTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
49
|
+
return !tool.namespace && (CODEX_SHELL_BRIDGE_TOOL_NAMES as readonly string[]).includes(tool.name);
|
|
50
|
+
}
|
|
12
51
|
|
|
13
52
|
function quoteNames(names: readonly string[]): string {
|
|
14
|
-
return names.map(name =>
|
|
53
|
+
return names.map(name => "`" + name + "`").join(", ");
|
|
15
54
|
}
|
|
16
55
|
|
|
17
56
|
function uniqueNames(names: readonly string[]): string[] {
|
|
18
57
|
return [...new Set(names.filter(name => name.trim().length > 0))];
|
|
19
58
|
}
|
|
20
59
|
|
|
21
|
-
function toolChoiceAllows(tool: Pick<OcxTool, "namespace" | "name">, toolChoice: OcxRequestOptions["toolChoice"] | undefined): boolean {
|
|
22
|
-
if (!toolChoice || toolChoice === "auto" || toolChoice === "required") return true;
|
|
23
|
-
if (toolChoice === "none") return false;
|
|
24
|
-
if (isAllowedToolChoice(toolChoice)) return toolAllowedByChoice(tool, new Set(toolChoice.allowedTools));
|
|
25
|
-
return toolChoiceAliases(tool).includes(toolChoice.name);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
60
|
function isOpenAIOrChatGPTHost(hostname: string): boolean {
|
|
29
61
|
return hostname === "openai.com"
|
|
30
62
|
|| hostname.endsWith(".openai.com")
|
|
@@ -40,19 +72,58 @@ export function shouldInjectNonOpenAIToolCatalogNudge(provider: Pick<OcxProvider
|
|
|
40
72
|
}
|
|
41
73
|
}
|
|
42
74
|
|
|
43
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Codex code mode is a SEMANTIC property, not a name.
|
|
77
|
+
*
|
|
78
|
+
* The tool that carries it is a `freeform` `exec` whose body is JavaScript evaluated in a V8
|
|
79
|
+
* isolate, advertised alongside no bare shell bridge. A provider is free to advertise an
|
|
80
|
+
* ordinary structured tool called `exec` that runs a shell string — and a catalog can list
|
|
81
|
+
* `exec` next to `exec_command`/`shell_command`, which is the flat-bridge shape, not code mode.
|
|
82
|
+
*
|
|
83
|
+
* Classifying on the name alone would tell those turns that `exec` takes JavaScript and that
|
|
84
|
+
* shell is only reachable as a nested `tools.*` helper. Both are false there, and a model that
|
|
85
|
+
* believes them sends the wrong arguments or avoids a legitimate execution tool entirely.
|
|
86
|
+
*
|
|
87
|
+
* So callers that HAVE the tool objects decide with the semantic predicate and pass the verified
|
|
88
|
+
* wire name in; the name-only entry point cannot decide it and does not try.
|
|
89
|
+
*/
|
|
90
|
+
function codeModeExecWireName(
|
|
91
|
+
advertised: ReadonlySet<string>,
|
|
92
|
+
verifiedName: string | undefined,
|
|
93
|
+
): string | undefined {
|
|
94
|
+
if (!verifiedName) return undefined;
|
|
95
|
+
return advertised.has(verifiedName) ? verifiedName : undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function buildNonOpenAIToolCatalogNudgeFromNames(
|
|
99
|
+
wireNames: readonly string[] | undefined,
|
|
100
|
+
toWireName: (name: string) => string = name => name,
|
|
101
|
+
codeModeExecName?: string,
|
|
102
|
+
): string | undefined {
|
|
44
103
|
const names = uniqueNames(wireNames ?? []);
|
|
45
104
|
if (names.length === 0) return undefined;
|
|
46
105
|
|
|
47
106
|
const advertised = new Set(names);
|
|
48
|
-
|
|
107
|
+
// Compare in the catalog's own coordinate system. `advertised` holds WIRE names, so a
|
|
108
|
+
// provider that rewrites them (Claude OAuth `custom_`, Anthropic compat `cx_`) would never
|
|
109
|
+
// match a bare neighbor name and would forbid tools the turn actually advertises -- the
|
|
110
|
+
// catalog would list `custom_apply_patch` while the same sentence banned `apply_patch`.
|
|
111
|
+
const unavailableNeighborNames = NEIGHBOR_AGENT_TOOL_NAMES.filter(
|
|
112
|
+
name => !advertised.has(name) && !advertised.has(toWireName(name)),
|
|
113
|
+
);
|
|
114
|
+
const verifiedCodeModeExecName = codeModeExecWireName(advertised, codeModeExecName);
|
|
49
115
|
|
|
50
116
|
return [
|
|
51
117
|
"Tool contract: use the current tool catalog as ground truth.",
|
|
52
|
-
|
|
118
|
+
"Valid tool names for this turn are exactly " + quoteNames(names) + ".",
|
|
119
|
+
"These listed names are the complete top-level tool-call surface for this turn.",
|
|
53
120
|
"Call only listed names with their listed argument keys; do not invent, translate, or rename tools.",
|
|
121
|
+
"Names mentioned only in instructions, tool descriptions, argument descriptions, or nested helper APIs are not additional top-level tools.",
|
|
122
|
+
verifiedCodeModeExecName
|
|
123
|
+
? "`" + verifiedCodeModeExecName + "` is Codex code mode: its body is JavaScript evaluated in a V8 isolate. Nested helpers are called INSIDE that body as `await tools.<name>(...)`, for example `await tools.exec_command({cmd: \"ls\"})` or `await tools.codex_app__list_threads({})`. Absence from the top-level catalog or from `" + verifiedCodeModeExecName + "`'s description is not absence: deferred helpers stay callable on `tools.<name>`. Discover them from the isolate global `ALL_TOOLS`, not `tools.ALL_TOOLS`. Do not skip an available nested helper because it is omitted from the listed top-level names."
|
|
124
|
+
: "If a listed tool exposes nested helpers such as a tools.* API, call the listed parent tool and use those helpers only inside that tool's input.",
|
|
54
125
|
unavailableNeighborNames.length > 0
|
|
55
|
-
?
|
|
126
|
+
? "Do not use neighboring-agent tool names " + quoteNames(unavailableNeighborNames) + " unless this turn's catalog lists those exact names."
|
|
56
127
|
: undefined,
|
|
57
128
|
"If you need shell, file search, file read, edit, or discovery behavior, choose the listed tool that provides that capability.",
|
|
58
129
|
"Count a tool call only after its tool result returns; batch independent read-only calls when the runtime supports it.",
|
|
@@ -60,12 +131,24 @@ export function buildNonOpenAIToolCatalogNudgeFromNames(wireNames: readonly stri
|
|
|
60
131
|
}
|
|
61
132
|
|
|
62
133
|
export function buildNonOpenAIToolCatalogNudgeForTools(
|
|
63
|
-
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
134
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
64
135
|
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
65
136
|
toWireName: (tool: Pick<OcxTool, "namespace" | "name">) => string = tool => namespacedToolName(tool.namespace, tool.name),
|
|
66
137
|
): string | undefined {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
138
|
+
const visible = tools?.filter(toolChoiceToolPredicate(toolChoice, tools));
|
|
139
|
+
const visibleNames = visible?.map(toWireName);
|
|
140
|
+
// Decide code mode from the tool OBJECTS, while the `freeform` flag still exists — reducing
|
|
141
|
+
// to wire names first throws away the only thing that distinguishes Codex's JavaScript
|
|
142
|
+
// `exec` from an ordinary structured tool that happens to share the name.
|
|
143
|
+
const codeModeExecTool = visible?.find(isCodexCodeModeExecTool);
|
|
144
|
+
const codeModeExecName = codeModeExecTool
|
|
145
|
+
&& !visible?.some(isBareShellBridgeTool)
|
|
146
|
+
? toWireName(codeModeExecTool)
|
|
147
|
+
: undefined;
|
|
148
|
+
// Neighbor names are bare and un-namespaced, so probe the same transform with a bare tool.
|
|
149
|
+
return buildNonOpenAIToolCatalogNudgeFromNames(
|
|
150
|
+
visibleNames,
|
|
151
|
+
name => toWireName({ name }),
|
|
152
|
+
codeModeExecName,
|
|
153
|
+
);
|
|
71
154
|
}
|