@iislee/opencodex 2.11.0 → 2.35.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 +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -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 +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- 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 +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- 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 +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- 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 +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- 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 +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- 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 +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- 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 +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- 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 +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -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 +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- 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 +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -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/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -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 +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -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 +360 -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 +622 -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 +675 -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 +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -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 +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -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 +157 -33
- package/src/images/plan.ts +24 -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-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -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/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- 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 +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- 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/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- 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/service-secrets.ts +15 -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 +253 -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 +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -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/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- 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/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -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 +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -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 +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -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 +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -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 +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -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 +155 -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 +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- 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 +1021 -190
- package/src/server/lifecycle.ts +336 -14
- 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 +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -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 +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -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 +289 -33
- 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 +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- 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/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -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 +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -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 +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -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 +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- 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 +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- 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 +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- 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 +27 -16
- 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 +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- 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
package/src/adapters/kiro.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { decodeEventStream } from "../lib/eventstream-decoder";
|
|
2
2
|
import { estimateTokens } from "../lib/token-estimate";
|
|
3
3
|
import { debugProviderDiagnostic } from "../lib/debug";
|
|
4
|
-
import { resolveKiroApiRegion,
|
|
4
|
+
import { resolveKiroApiRegion, resolveKiroRequestProfile } from "../oauth/kiro";
|
|
5
5
|
import { KIRO_MODEL_CONTEXT_WINDOWS, normalizeKiroModelId } from "../providers/kiro-models";
|
|
6
6
|
import { modelRecordValue } from "../reasoning-effort";
|
|
7
7
|
import { parseKiroEvent } from "./kiro-events";
|
|
@@ -19,6 +19,8 @@ import { createKiroToolNameRegistry, fallbackToolUseId, fingerprint, invocationI
|
|
|
19
19
|
import { namespacedToolName } from "../types";
|
|
20
20
|
import {
|
|
21
21
|
isTranslatorBudgetExceededError,
|
|
22
|
+
releaseTranslatedEvent,
|
|
23
|
+
retainTranslatedEvent,
|
|
22
24
|
type TranslatorBudget,
|
|
23
25
|
} from "../lib/translator-budget";
|
|
24
26
|
import type {
|
|
@@ -31,17 +33,21 @@ import type {
|
|
|
31
33
|
OcxTextContent,
|
|
32
34
|
OcxToolCall,
|
|
33
35
|
OcxToolResultMessage,
|
|
36
|
+
OcxTool,
|
|
34
37
|
OcxUsage,
|
|
35
38
|
} from "../types";
|
|
39
|
+
import { hasRecordedTrailingDeliveredFinalAnswer } from "../responses/turn-termination";
|
|
36
40
|
import type { ProviderAdapter } from "./base";
|
|
37
41
|
import type { AdapterFetchContext, AdapterRequest } from "./base";
|
|
38
42
|
import { extractKiroImages, normalizeKiroImages, type KiroImage } from "./kiro-images";
|
|
39
43
|
import { sniffImageDimensions } from "./anthropic-image-guard";
|
|
40
44
|
import { fetchKiroWithRetry, noteKiroTransientThrottle } from "./kiro-retry";
|
|
41
45
|
import { convertKiroToolContext } from "./kiro-tools";
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
46
|
+
import { normalizeEmptyExecToolResultText } from "./exec-tool-result-normalize";
|
|
47
|
+
import { identifyRoutedModel } from "./identity";
|
|
48
|
+
import { buildNonOpenAIToolCatalogNudgeFromNames, isBareShellBridgeTool, isCodexCodeModeExecTool } from "./tool-catalog-nudge";
|
|
44
49
|
import {
|
|
50
|
+
KIRO_ANSWER_DELIVERED_MESSAGE,
|
|
45
51
|
KIRO_COMPLETION_INSTRUCTIONS,
|
|
46
52
|
KIRO_COMPLETION_RETRY_MESSAGE,
|
|
47
53
|
KIRO_COMPLETION_TOOL_NAME,
|
|
@@ -99,7 +105,11 @@ interface KiroUserInputMessage {
|
|
|
99
105
|
}
|
|
100
106
|
interface KiroHistoryEntry {
|
|
101
107
|
userInputMessage?: KiroUserInputMessage;
|
|
102
|
-
assistantResponseMessage?: {
|
|
108
|
+
assistantResponseMessage?: {
|
|
109
|
+
content: string;
|
|
110
|
+
toolUses?: KiroToolUse[];
|
|
111
|
+
reasoningContent?: { redactedContent: string };
|
|
112
|
+
};
|
|
103
113
|
}
|
|
104
114
|
|
|
105
115
|
function kiroToolWireNames(tools: readonly unknown[]): string[] {
|
|
@@ -312,21 +322,78 @@ function validateKiroCapabilities(parsed: OcxParsedRequest): void {
|
|
|
312
322
|
if (choice !== undefined && choice !== "auto" && choice !== "none") {
|
|
313
323
|
throw new Error("Kiro supports only automatic tool choice or tool_choice:none");
|
|
314
324
|
}
|
|
315
|
-
if (parsed.options.parallelToolCalls === true) {
|
|
316
|
-
throw new Error("Kiro does not support parallel tool calls");
|
|
317
|
-
}
|
|
318
325
|
if (parsed.options.serviceTier !== undefined) {
|
|
319
326
|
throw new Error("Kiro does not support service tiers");
|
|
320
327
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
328
|
+
// Structured output is a real contract Kiro cannot honour: the wire has no
|
|
329
|
+
// schema-constrained response mode, so a caller expecting parseable JSON would receive
|
|
330
|
+
// prose and fail downstream. Refuse it.
|
|
331
|
+
//
|
|
332
|
+
// The rest of the Responses `text` object is not that. `text.verbosity` is a length
|
|
333
|
+
// preference and `text.format: {type:"text"}` is ordinary prose — the default output
|
|
334
|
+
// mode, which no capability flag governs and every correct client may send. Testing
|
|
335
|
+
// `_rawBody.text !== undefined` refused those turns for the mere PRESENCE of the key,
|
|
336
|
+
// the same mistake db040e70f removed one condition earlier where a permissive
|
|
337
|
+
// `parallel_tool_calls` hint was read as a requirement.
|
|
338
|
+
//
|
|
339
|
+
// Nothing needs stripping the way openai-responses strips a no-op verbosity:
|
|
340
|
+
// buildKiroPayload composes conversationState field by field from `parsed` and never
|
|
341
|
+
// spreads `_rawBody`, so a tolerated control is dropped by construction. The test
|
|
342
|
+
// asserts that absence so it stays true.
|
|
343
|
+
if (parsed._structuredOutput) {
|
|
344
|
+
throw new Error("Kiro does not support Responses structured output");
|
|
324
345
|
}
|
|
325
346
|
}
|
|
326
347
|
|
|
327
348
|
type KiroTurn =
|
|
328
|
-
| {
|
|
329
|
-
|
|
349
|
+
| {
|
|
350
|
+
kind: "user";
|
|
351
|
+
content: string;
|
|
352
|
+
images: KiroImage[];
|
|
353
|
+
toolResults: KiroToolResult[];
|
|
354
|
+
/**
|
|
355
|
+
* True only for the proxy-generated acknowledgement that follows a delivered final answer.
|
|
356
|
+
* A flag rather than a content comparison: a real user message may legitimately quote the
|
|
357
|
+
* same sentence, and treating that as internal state would strip its thinking tags and
|
|
358
|
+
* completion retry.
|
|
359
|
+
*/
|
|
360
|
+
answerDeliveredAck?: boolean;
|
|
361
|
+
}
|
|
362
|
+
| {
|
|
363
|
+
kind: "assistant";
|
|
364
|
+
content: string;
|
|
365
|
+
toolUses: KiroToolUse[];
|
|
366
|
+
redactedReasoning?: string;
|
|
367
|
+
/**
|
|
368
|
+
* True when this assistant turn was the DELIVERED final answer (Responses
|
|
369
|
+
* `phase: "final_answer"`). A trailing assistant turn normally means the model stopped
|
|
370
|
+
* mid-task and needs a continuation prompt, but a delivered final answer already ended its
|
|
371
|
+
* turn — prompting it again restarts finished work as if a goal were still open.
|
|
372
|
+
*/
|
|
373
|
+
finalAnswer?: boolean;
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* True when the LAST content-bearing message is an assistant final answer that closed its turn.
|
|
378
|
+
*
|
|
379
|
+
* Mirrors the turn-merge rule: a tool call in that message, or any later user/tool-result message,
|
|
380
|
+
* means work continued, so the turn is no longer terminal. Empty assistant messages are skipped
|
|
381
|
+
* rather than treated as continuation, since they carry no visible turn.
|
|
382
|
+
*/
|
|
383
|
+
function hasTrailingDeliveredFinalAnswer(messages: readonly OcxMessage[], parsed?: OcxParsedRequest): boolean {
|
|
384
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
385
|
+
const msg = messages[i];
|
|
386
|
+
if (msg.role !== "assistant") return false;
|
|
387
|
+
const aMsg = msg as OcxAssistantMessage;
|
|
388
|
+
const hasToolCall = (aMsg.content ?? []).some(part => part.type === "toolCall");
|
|
389
|
+
if (hasToolCall) return false;
|
|
390
|
+
const hasText = (aMsg.content ?? []).some(part => part.type === "text" && part.text.trim());
|
|
391
|
+
if (!hasText) continue;
|
|
392
|
+
return aMsg.phase === "final_answer"
|
|
393
|
+
|| (parsed !== undefined && hasRecordedTrailingDeliveredFinalAnswer(parsed, messages));
|
|
394
|
+
}
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
330
397
|
|
|
331
398
|
function appendTurnText(target: string, next: string): string {
|
|
332
399
|
if (!next) return target;
|
|
@@ -381,9 +448,21 @@ function validateKiroConversationState(history: KiroHistoryEntry[], currentMessa
|
|
|
381
448
|
function boundedInjectedInstruction(text: string, used: { value: number }): string | undefined {
|
|
382
449
|
const remaining = MAX_KIRO_INJECTED_INSTRUCTION_CHARS - used.value;
|
|
383
450
|
if (remaining <= 0 || !text) return undefined;
|
|
384
|
-
|
|
451
|
+
let result = text.length <= remaining ? text : text.slice(0, remaining);
|
|
452
|
+
// Never end the slice on a lone high surrogate: encoding it substitutes
|
|
453
|
+
// U+FFFD into the injected instruction. One step back keeps a valid pair
|
|
454
|
+
// out instead of a broken half.
|
|
455
|
+
if (result.length > 0) {
|
|
456
|
+
const last = result.charCodeAt(result.length - 1);
|
|
457
|
+
if (last >= 0xd800 && last <= 0xdbff) result = result.slice(0, -1);
|
|
458
|
+
}
|
|
385
459
|
used.value += result.length;
|
|
386
|
-
return result;
|
|
460
|
+
return result.length > 0 ? result : undefined;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/** Test-only: exercise the surrogate-safe instruction bound directly. */
|
|
464
|
+
export function boundedInjectedInstructionForTests(text: string, used: { value: number }): string | undefined {
|
|
465
|
+
return boundedInjectedInstruction(text, used);
|
|
387
466
|
}
|
|
388
467
|
|
|
389
468
|
function kiroCompletionTool(): Record<string, unknown> {
|
|
@@ -423,22 +502,66 @@ export function buildKiroPayload(
|
|
|
423
502
|
const registry = createKiroToolNameRegistry();
|
|
424
503
|
const toolContext = convertKiroToolContext(parsed, registry);
|
|
425
504
|
const ordinaryTools = toolContext.tools;
|
|
505
|
+
// A turn whose history already ENDS with a delivered final answer has nothing to complete.
|
|
506
|
+
// Leaving completion "required" here would keep advertising codex_kiro_final_answer with its
|
|
507
|
+
// instructions, so the model answers again, or replies with ordinary text and trips the
|
|
508
|
+
// `needsFallback` retry, which ends its payload with KIRO_COMPLETION_RETRY_MESSAGE and reopens
|
|
509
|
+
// the finished task. Suppressing the mode is what actually closes that loop; the neutral
|
|
510
|
+
// acknowledgement below only stops the resume wording.
|
|
511
|
+
//
|
|
512
|
+
// Read from parsed messages because `completionMode` is needed to build the tool catalog, which
|
|
513
|
+
// happens before the turn list exists. `forcedCompletionMode` still wins: the fallback retry
|
|
514
|
+
// passes "text_fallback" explicitly and must not be silently downgraded.
|
|
515
|
+
const trailingDeliveredAnswer = hasTrailingDeliveredFinalAnswer(kiroPayloadMessages(parsed), parsed);
|
|
426
516
|
const completionMode: KiroCompletionMode = forcedCompletionMode
|
|
427
|
-
?? (ordinaryTools.length > 0 ? "required" : "disabled");
|
|
517
|
+
?? (ordinaryTools.length > 0 && !trailingDeliveredAnswer ? "required" : "disabled");
|
|
428
518
|
const kiroTools = completionMode === "disabled"
|
|
429
519
|
? ordinaryTools
|
|
430
520
|
: [...ordinaryTools, kiroCompletionTool()];
|
|
431
521
|
const nameMap = toolContext.nameMap;
|
|
432
522
|
const systemParts: string[] = [];
|
|
433
523
|
const injectedChars = { value: 0 };
|
|
434
|
-
//
|
|
435
|
-
|
|
436
|
-
|
|
524
|
+
// Name the Kiro model id actually sent on the wire without leaking the proxy identity upstream.
|
|
525
|
+
if (parsed.context.systemPrompt?.length) {
|
|
526
|
+
systemParts.push(identifyRoutedModel(parsed.context.systemPrompt.join("\n\n"), modelId));
|
|
527
|
+
}
|
|
437
528
|
for (const addition of toolContext.systemAdditions) {
|
|
438
529
|
const boundedAddition = boundedInjectedInstruction(addition, injectedChars);
|
|
439
530
|
if (boundedAddition) systemParts.push(boundedAddition);
|
|
440
531
|
}
|
|
441
|
-
|
|
532
|
+
// Kiro renames tools to satisfy its wire constraints, so resolve neighbor names through the
|
|
533
|
+
// registry's existing aliases; a bare-name comparison would forbid tools this turn actually
|
|
534
|
+
// advertises. Read the recorded mapping instead of calling `alias()`, which would REGISTER a
|
|
535
|
+
// name for a tool that was never advertised and pollute the collision domain.
|
|
536
|
+
const advertisedAlias = new Map<string, string>();
|
|
537
|
+
for (const [alias, wireName] of registry.nameMap) advertisedAlias.set(wireName, alias);
|
|
538
|
+
// Code mode is decided on the EMITTED catalog, not the requested list.
|
|
539
|
+
//
|
|
540
|
+
// `freeform` only exists on the requested tool objects -- `kiroToolWireNames` has already
|
|
541
|
+
// reduced the emitted catalog to strings -- so the predicates must read the objects. But the
|
|
542
|
+
// SHAPE that matters is the one the model receives: the count/byte budget can drop a requested
|
|
543
|
+
// `exec_command` while `exec` survives, and scanning the requested list would then find a shell
|
|
544
|
+
// bridge the model cannot call and suppress code mode for a catalog that is code-mode-shaped.
|
|
545
|
+
// Intersecting the two keeps `tool_choice: "none"` and budget omission correct for free: both
|
|
546
|
+
// empty the emitted set, so nothing can be named.
|
|
547
|
+
const emittedToolNames = new Set(kiroToolWireNames(kiroTools));
|
|
548
|
+
const emittedAlias = (tool: OcxTool): string | undefined => {
|
|
549
|
+
const wireName = namespacedToolName(tool.namespace, tool.name);
|
|
550
|
+
// Read the recorded mapping; `registry.alias()` would REGISTER a name here.
|
|
551
|
+
const alias = advertisedAlias.get(wireName) ?? wireName;
|
|
552
|
+
return emittedToolNames.has(alias) ? alias : undefined;
|
|
553
|
+
};
|
|
554
|
+
const requestedTools = parsed.context.tools ?? [];
|
|
555
|
+
const emittedCodeModeExec = requestedTools.find(tool => isCodexCodeModeExecTool(tool) && emittedAlias(tool));
|
|
556
|
+
const emittedShellBridge = requestedTools.some(tool => isBareShellBridgeTool(tool) && emittedAlias(tool));
|
|
557
|
+
const codeModeExecName = emittedCodeModeExec && !emittedShellBridge
|
|
558
|
+
? emittedAlias(emittedCodeModeExec)
|
|
559
|
+
: undefined;
|
|
560
|
+
const toolCatalogNudge = buildNonOpenAIToolCatalogNudgeFromNames(
|
|
561
|
+
kiroToolWireNames(kiroTools),
|
|
562
|
+
name => advertisedAlias.get(name) ?? name,
|
|
563
|
+
codeModeExecName,
|
|
564
|
+
);
|
|
442
565
|
const boundedNudge = toolCatalogNudge ? boundedInjectedInstruction(toolCatalogNudge, injectedChars) : undefined;
|
|
443
566
|
if (boundedNudge) systemParts.push(boundedNudge);
|
|
444
567
|
if (completionMode !== "disabled") {
|
|
@@ -458,13 +581,24 @@ export function buildKiroPayload(
|
|
|
458
581
|
turns.push({ kind: "user", content, images: [...images], toolResults: [...toolResults] });
|
|
459
582
|
}
|
|
460
583
|
};
|
|
461
|
-
const pushAssistant = (content: string, toolUses: KiroToolUse[]): void => {
|
|
584
|
+
const pushAssistant = (content: string, toolUses: KiroToolUse[], redactedReasoning?: string, finalAnswer?: boolean): void => {
|
|
462
585
|
const last = turns.at(-1);
|
|
463
586
|
if (last?.kind === "assistant") {
|
|
464
587
|
last.content = appendTurnText(last.content, content);
|
|
465
588
|
last.toolUses.push(...toolUses);
|
|
589
|
+
// Merged turns keep the newest blob: it covers the reasoning up to the merged turn's end.
|
|
590
|
+
if (redactedReasoning) last.redactedReasoning = redactedReasoning;
|
|
591
|
+
// A merged turn is final only if its LAST component was: commentary appended after a final
|
|
592
|
+
// answer means the model kept working, so the turn is no longer terminal.
|
|
593
|
+
last.finalAnswer = finalAnswer === true;
|
|
466
594
|
} else {
|
|
467
|
-
turns.push({
|
|
595
|
+
turns.push({
|
|
596
|
+
kind: "assistant",
|
|
597
|
+
content,
|
|
598
|
+
toolUses: [...toolUses],
|
|
599
|
+
...(redactedReasoning ? { redactedReasoning } : {}),
|
|
600
|
+
...(finalAnswer ? { finalAnswer: true } : {}),
|
|
601
|
+
});
|
|
468
602
|
}
|
|
469
603
|
};
|
|
470
604
|
|
|
@@ -494,14 +628,24 @@ export function buildKiroPayload(
|
|
|
494
628
|
const hasReasoning = aMsg.content.some(part => part.type === "thinking" && part.thinking.trim());
|
|
495
629
|
if (hasReasoning) continue;
|
|
496
630
|
}
|
|
497
|
-
|
|
631
|
+
// `phase` survives the Responses round trip (parser.ts assistant branch), so a replayed
|
|
632
|
+
// final answer is identifiable here rather than guessed from turn position.
|
|
633
|
+
pushAssistant(text, toolUses, aMsg.kiroRedactedReasoning, aMsg.phase === "final_answer" && toolUses.length === 0);
|
|
498
634
|
} else if (msg.role === "toolResult") {
|
|
499
635
|
const tr = msg as OcxToolResultMessage;
|
|
500
636
|
if (tr.containsEncryptedContent) {
|
|
501
637
|
throw new Error(`Kiro cannot translate encrypted output for tool call ${JSON.stringify(tr.toolCallId)}`);
|
|
502
638
|
}
|
|
503
639
|
const text = userContentText(tr.content);
|
|
504
|
-
|
|
640
|
+
// An empty code-mode exec result needs the SPECIFIC reason, not the generic fallback: the
|
|
641
|
+
// model otherwise reads a blank result, concludes its earlier context was lost, and restarts
|
|
642
|
+
// the task instead of calling text()/notify(). Checked before `text.trim()` because the
|
|
643
|
+
// wrapper form ("Script completed\nWall time ...\nOutput:\n") is non-blank and would
|
|
644
|
+
// otherwise pass through as if it were real output.
|
|
645
|
+
const resultText = normalizeEmptyExecToolResultText(text, {
|
|
646
|
+
toolName: tr.toolName,
|
|
647
|
+
toolNamespace: tr.toolNamespace,
|
|
648
|
+
}) ?? (text.trim() ? text : KIRO_EMPTY_TOOL_RESULT_MESSAGE);
|
|
505
649
|
const images = extractKiroImages(tr.content);
|
|
506
650
|
const toolUseId = normalizeToolId(tr.toolCallId);
|
|
507
651
|
if (!priorCalls.has(toolUseId)) {
|
|
@@ -522,12 +666,23 @@ export function buildKiroPayload(
|
|
|
522
666
|
if (turns.length === 0 || turns[0].kind === "assistant") {
|
|
523
667
|
turns.unshift({ kind: "user", content: KIRO_CONTINUATION_MESSAGE, images: [], toolResults: [] });
|
|
524
668
|
}
|
|
525
|
-
|
|
669
|
+
// Kiro requires the request to end with a user turn, so a trailing assistant turn always gets
|
|
670
|
+
// one appended (the pop below throws otherwise). What that turn SAYS is the load-bearing part.
|
|
671
|
+
//
|
|
672
|
+
// Normally a trailing assistant turn means the model stopped mid-task, and a continuation/retry
|
|
673
|
+
// prompt is correct. A DELIVERED final answer is the exception: the turn already ended, and
|
|
674
|
+
// telling that model to "continue" or to call the completion tool again reopens finished work —
|
|
675
|
+
// the completed-task-behaves-like-an-open-goal loop. It gets a neutral acknowledgement instead:
|
|
676
|
+
// structurally valid, but carrying no instruction to resume.
|
|
677
|
+
const trailing = turns.at(-1);
|
|
678
|
+
if (trailing?.kind === "assistant") {
|
|
679
|
+
const resumeText = completionMode === "text_fallback" ? KIRO_COMPLETION_RETRY_MESSAGE : KIRO_CONTINUATION_MESSAGE;
|
|
526
680
|
turns.push({
|
|
527
681
|
kind: "user",
|
|
528
|
-
content:
|
|
682
|
+
content: trailing.finalAnswer ? KIRO_ANSWER_DELIVERED_MESSAGE : resumeText,
|
|
529
683
|
images: [],
|
|
530
684
|
toolResults: [],
|
|
685
|
+
...(trailing.finalAnswer ? { answerDeliveredAck: true } : {}),
|
|
531
686
|
});
|
|
532
687
|
}
|
|
533
688
|
|
|
@@ -543,11 +698,14 @@ export function buildKiroPayload(
|
|
|
543
698
|
|
|
544
699
|
const currentTurn = turns.pop();
|
|
545
700
|
if (!currentTurn || currentTurn.kind !== "user") throw new Error("Kiro request must end with a user turn");
|
|
701
|
+
// Survives the pop as state, so the checks below never infer intent from user-supplied text.
|
|
702
|
+
const answerDeliveredAck = currentTurn.answerDeliveredAck === true;
|
|
546
703
|
const toEntry = (turn: KiroTurn): KiroHistoryEntry => turn.kind === "assistant"
|
|
547
704
|
? {
|
|
548
705
|
assistantResponseMessage: {
|
|
549
706
|
content: turn.content,
|
|
550
707
|
...(turn.toolUses.length > 0 ? { toolUses: turn.toolUses } : {}),
|
|
708
|
+
...(turn.redactedReasoning ? { reasoningContent: { redactedContent: turn.redactedReasoning } } : {}),
|
|
551
709
|
},
|
|
552
710
|
}
|
|
553
711
|
: {
|
|
@@ -572,10 +730,17 @@ export function buildKiroPayload(
|
|
|
572
730
|
currentUim.userInputMessageContext = { ...(currentUim.userInputMessageContext ?? {}), tools: kiroTools };
|
|
573
731
|
}
|
|
574
732
|
if (completionMode === "text_fallback") {
|
|
575
|
-
|
|
733
|
+
// Never append the retry instruction onto the answer-delivered acknowledgement: it exists
|
|
734
|
+
// precisely to avoid asking a finished turn for another completion call, and appending here
|
|
735
|
+
// would reinstate the loop it prevents.
|
|
736
|
+
if (currentUim.content !== KIRO_COMPLETION_RETRY_MESSAGE && !answerDeliveredAck) {
|
|
576
737
|
currentUim.content = appendTurnText(currentUim.content, KIRO_COMPLETION_RETRY_MESSAGE);
|
|
577
738
|
}
|
|
578
|
-
} else if (
|
|
739
|
+
} else if (
|
|
740
|
+
!currentUim.userInputMessageContext?.toolResults
|
|
741
|
+
&& currentUim.content !== KIRO_CONTINUATION_MESSAGE
|
|
742
|
+
&& !answerDeliveredAck
|
|
743
|
+
) {
|
|
579
744
|
currentUim.content = injectKiroThinkingTags(currentUim.content, parsed);
|
|
580
745
|
}
|
|
581
746
|
|
|
@@ -607,8 +772,8 @@ export function buildKiroPayload(
|
|
|
607
772
|
|
|
608
773
|
// Stream parsing (shared by parseStream + parseResponse)
|
|
609
774
|
// CodeWhisperer GenerateAssistantResponse ALWAYS returns an AWS eventstream body (there is no
|
|
610
|
-
// non-streaming mode), so
|
|
611
|
-
//
|
|
775
|
+
// non-streaming wire mode), so the streaming bridge and non-streaming Responses path decode the
|
|
776
|
+
// same way — parseResponse just collects what parseStream yields.
|
|
612
777
|
interface KiroAttemptParseResult {
|
|
613
778
|
terminal?: AdapterEvent;
|
|
614
779
|
needsFallback?: boolean;
|
|
@@ -830,16 +995,12 @@ async function* parseKiroAttempt(
|
|
|
830
995
|
);
|
|
831
996
|
let handedOff = false;
|
|
832
997
|
try {
|
|
833
|
-
|
|
834
|
-
while (!next.done) {
|
|
835
|
-
yield next.value;
|
|
836
|
-
next = await attempt.next();
|
|
837
|
-
}
|
|
998
|
+
const result = yield* attempt;
|
|
838
999
|
for (const event of deferred.splice(0)) {
|
|
839
1000
|
try { yield event; } finally { retention.releaseEvent(event); }
|
|
840
1001
|
}
|
|
841
1002
|
handedOff = true;
|
|
842
|
-
return { ...
|
|
1003
|
+
return { ...result, releaseRetained: () => retention.releaseAll() };
|
|
843
1004
|
} finally {
|
|
844
1005
|
if (!handedOff) retention.releaseAll();
|
|
845
1006
|
}
|
|
@@ -868,6 +1029,12 @@ async function* parseKiroAttemptEvents(
|
|
|
868
1029
|
}
|
|
869
1030
|
|
|
870
1031
|
let open: { id: string; name: string; chunks: string[]; completion: boolean } | null = null;
|
|
1032
|
+
let openCallId: string | undefined;
|
|
1033
|
+
const closeOpenCall = () => {
|
|
1034
|
+
if (!openCallId) return;
|
|
1035
|
+
budget.closeCall(openCallId);
|
|
1036
|
+
openCallId = undefined;
|
|
1037
|
+
};
|
|
871
1038
|
let outputChars = "";
|
|
872
1039
|
let outputCharsBytes = 0;
|
|
873
1040
|
let contextUsagePercentage: number | undefined;
|
|
@@ -1080,7 +1247,7 @@ async function* parseKiroAttemptEvents(
|
|
|
1080
1247
|
if (!open) return { events: [] };
|
|
1081
1248
|
const tool = open;
|
|
1082
1249
|
open = null;
|
|
1083
|
-
|
|
1250
|
+
closeOpenCall();
|
|
1084
1251
|
const input = tool.chunks.join("");
|
|
1085
1252
|
if (!isCompleteKiroToolInput(input)) {
|
|
1086
1253
|
return { events: [], terminal: protocolTerminal(kiroTruncationErrorMessage("incomplete tool input JSON"), tool.completion) };
|
|
@@ -1170,6 +1337,12 @@ async function* parseKiroAttemptEvents(
|
|
|
1170
1337
|
if (ev.data) {
|
|
1171
1338
|
yield* emitRetained(stage({ type: "reasoning_raw_delta", text: ev.data }));
|
|
1172
1339
|
}
|
|
1340
|
+
if (ev.redactedContent) {
|
|
1341
|
+
yield* emitRetained(stage({ type: "kiro_redacted_reasoning", data: ev.redactedContent }));
|
|
1342
|
+
}
|
|
1343
|
+
break;
|
|
1344
|
+
case "context_usage":
|
|
1345
|
+
if (ev.contextUsagePercentage > 0) contextUsagePercentage = ev.contextUsagePercentage;
|
|
1173
1346
|
break;
|
|
1174
1347
|
case "tool": {
|
|
1175
1348
|
for (const contentEvent of thinking.flush()) {
|
|
@@ -1186,11 +1359,12 @@ async function* parseKiroAttemptEvents(
|
|
|
1186
1359
|
if (started.terminal) return { assistantText, sawReasoning, terminal: started.terminal };
|
|
1187
1360
|
open = started.tool!;
|
|
1188
1361
|
budget.openCall(open.id);
|
|
1362
|
+
openCallId = open.id;
|
|
1189
1363
|
} else if (
|
|
1190
1364
|
(ev.toolUseId && ev.toolUseId !== open.id)
|
|
1191
1365
|
|| (ev.name && open.name !== "unknown" && ev.name !== open.name)
|
|
1192
1366
|
) {
|
|
1193
|
-
|
|
1367
|
+
closeOpenCall();
|
|
1194
1368
|
open = null;
|
|
1195
1369
|
return { assistantText, sawReasoning, terminal: protocolTerminal(kiroTruncationErrorMessage("tool input changed identity before stop")) };
|
|
1196
1370
|
}
|
|
@@ -1454,7 +1628,7 @@ async function* parseKiroAttemptEvents(
|
|
|
1454
1628
|
};
|
|
1455
1629
|
} catch (err) {
|
|
1456
1630
|
if (isTranslatorBudgetExceededError(err)) {
|
|
1457
|
-
|
|
1631
|
+
closeOpenCall();
|
|
1458
1632
|
return {
|
|
1459
1633
|
assistantText,
|
|
1460
1634
|
sawReasoning,
|
|
@@ -1496,6 +1670,9 @@ async function* parseKiroAttemptEvents(
|
|
|
1496
1670
|
usage: usage(),
|
|
1497
1671
|
},
|
|
1498
1672
|
};
|
|
1673
|
+
} finally {
|
|
1674
|
+
thinking.dispose();
|
|
1675
|
+
closeOpenCall();
|
|
1499
1676
|
}
|
|
1500
1677
|
}
|
|
1501
1678
|
|
|
@@ -1512,7 +1689,7 @@ export async function* parseKiroStream(
|
|
|
1512
1689
|
contextInputEstimate?: number,
|
|
1513
1690
|
): AsyncGenerator<AdapterEvent> {
|
|
1514
1691
|
const contextWindowState: KiroContextWindowState = { value: contextWindow };
|
|
1515
|
-
const
|
|
1692
|
+
const firstResult = yield* parseKiroAttempt(
|
|
1516
1693
|
response,
|
|
1517
1694
|
budget,
|
|
1518
1695
|
completionMode,
|
|
@@ -1524,12 +1701,6 @@ export async function* parseKiroStream(
|
|
|
1524
1701
|
contextInputEstimate,
|
|
1525
1702
|
false,
|
|
1526
1703
|
);
|
|
1527
|
-
let firstNext = await first.next();
|
|
1528
|
-
while (!firstNext.done) {
|
|
1529
|
-
yield firstNext.value;
|
|
1530
|
-
firstNext = await first.next();
|
|
1531
|
-
}
|
|
1532
|
-
const firstResult = firstNext.value;
|
|
1533
1704
|
try {
|
|
1534
1705
|
if (!firstResult.needsFallback) {
|
|
1535
1706
|
if (firstResult.terminal) yield firstResult.terminal;
|
|
@@ -1607,7 +1778,7 @@ export async function* parseKiroStream(
|
|
|
1607
1778
|
return;
|
|
1608
1779
|
}
|
|
1609
1780
|
|
|
1610
|
-
const
|
|
1781
|
+
const secondResult = yield* parseKiroAttempt(
|
|
1611
1782
|
fallback.response,
|
|
1612
1783
|
budget,
|
|
1613
1784
|
"text_fallback",
|
|
@@ -1621,12 +1792,6 @@ export async function* parseKiroStream(
|
|
|
1621
1792
|
// A zero-output transport failure here must stay non-retryable to avoid duplicating that text.
|
|
1622
1793
|
priorEmittedOutput,
|
|
1623
1794
|
);
|
|
1624
|
-
let secondNext = await second.next();
|
|
1625
|
-
while (!secondNext.done) {
|
|
1626
|
-
yield secondNext.value;
|
|
1627
|
-
secondNext = await second.next();
|
|
1628
|
-
}
|
|
1629
|
-
const secondResult = secondNext.value;
|
|
1630
1795
|
try {
|
|
1631
1796
|
if (!secondResult.terminal) {
|
|
1632
1797
|
yield retryableKiroIncomplete(
|
|
@@ -1695,12 +1860,19 @@ export function createKiroAdapter(provider: OcxProviderConfig): ProviderAdapter
|
|
|
1695
1860
|
throw new Error("kiro token missing — run ocx login kiro");
|
|
1696
1861
|
}
|
|
1697
1862
|
const region = resolveKiroApiRegion(parsed._kiroAuthContext);
|
|
1698
|
-
|
|
1863
|
+
// Request-scoped: an AWS Builder ID account has no profile of its own and resolves to Kiro's
|
|
1864
|
+
// fixed service profile here, without that value ever becoming the account's stored identity.
|
|
1865
|
+
const requestProfile = resolveKiroRequestProfile(parsed._kiroAuthContext);
|
|
1866
|
+
const resolvedProfileArn = requestProfile.profileArn;
|
|
1699
1867
|
const isApiKey = provider.apiKey.trim().startsWith("ksk_");
|
|
1700
1868
|
const profileArn = isApiKey ? undefined : resolvedProfileArn;
|
|
1701
|
-
// Builder ID and Kiro API keys
|
|
1702
|
-
//
|
|
1703
|
-
|
|
1869
|
+
// Builder ID and Kiro API keys are accepted only on Kiro's CLI request path; enterprise
|
|
1870
|
+
// profiles retain the IDE-shaped request. Builder ID now carries a profile ARN, so a truthy
|
|
1871
|
+
// `profileArn` no longer implies "enterprise". The wire path reads the resolver's own verdict
|
|
1872
|
+
// rather than re-deriving it, so the accountless path — where the auth type comes from the
|
|
1873
|
+
// local import, not the request context — cannot send the fallback inside an IDE-shaped call.
|
|
1874
|
+
const isBuilderId = requestProfile.builderIdFallback;
|
|
1875
|
+
const wireClient: KiroWireClient = isApiKey || isBuilderId || !profileArn ? "cli" : "ide";
|
|
1704
1876
|
const fp = fingerprint().slice(0, 64);
|
|
1705
1877
|
const headers: Record<string, string> = wireClient === "cli" ? {
|
|
1706
1878
|
authorization: `Bearer ${provider.apiKey}`,
|
|
@@ -1832,6 +2004,24 @@ export function createKiroAdapter(provider: OcxProviderConfig): ProviderAdapter
|
|
|
1832
2004
|
|
|
1833
2005
|
return {
|
|
1834
2006
|
name: "kiro",
|
|
2007
|
+
// A replayed history that already ENDS with a delivered final answer has nothing to ask Kiro.
|
|
2008
|
+
// Before this hook the adapter still appended a trailing user turn — a neutral acknowledgement,
|
|
2009
|
+
// but structurally still a prompt — and performed a real inference, so the model answered the
|
|
2010
|
+
// closed task again and the finished turn behaved like a still-open goal.
|
|
2011
|
+
//
|
|
2012
|
+
// Suppressing the completion contract (above) removed the instruction to complete; it could not
|
|
2013
|
+
// remove the inference. This is the boundary: no request is built, nothing is sent, and no token
|
|
2014
|
+
// estimate is recorded.
|
|
2015
|
+
//
|
|
2016
|
+
// The forced-fallback build is deliberately NOT consulted here: this hook runs on the inbound
|
|
2017
|
+
// turn only, and the adapter-owned bounded retry passes "text_fallback" through `build`
|
|
2018
|
+
// directly, never through this path.
|
|
2019
|
+
localTerminal(parsed: OcxParsedRequest) {
|
|
2020
|
+
return hasTrailingDeliveredFinalAnswer(kiroPayloadMessages(parsed), parsed)
|
|
2021
|
+
? { reason: "kiro_final_answer_already_delivered" }
|
|
2022
|
+
: undefined;
|
|
2023
|
+
},
|
|
2024
|
+
|
|
1835
2025
|
async buildRequest(parsed: OcxParsedRequest, incoming) {
|
|
1836
2026
|
const built = await build(parsed);
|
|
1837
2027
|
modelId = parsed.modelId;
|
|
@@ -1874,25 +2064,32 @@ export function createKiroAdapter(provider: OcxProviderConfig): ProviderAdapter
|
|
|
1874
2064
|
return safeKiroHttpErrorMessage(status, headers, payloadText);
|
|
1875
2065
|
},
|
|
1876
2066
|
|
|
1877
|
-
//
|
|
1878
|
-
//
|
|
1879
|
-
//
|
|
1880
|
-
// tool failed with "web-search sidecar requires a non-streaming adapter" (kiro-only).
|
|
2067
|
+
// Kiro always returns an event stream, including for non-streaming Responses requests. Drain
|
|
2068
|
+
// the decoder into a budget-owned batch so an upstream stream cannot grow this array without
|
|
2069
|
+
// bound while the caller waits for the complete JSON response.
|
|
1881
2070
|
async parseResponse(response: Response, budget: TranslatorBudget): Promise<AdapterEvent[]> {
|
|
1882
2071
|
const events: AdapterEvent[] = [];
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
2072
|
+
try {
|
|
2073
|
+
for await (const e of parseKiroStream(
|
|
2074
|
+
response,
|
|
2075
|
+
budget,
|
|
2076
|
+
modelId,
|
|
2077
|
+
inputTokens,
|
|
2078
|
+
contextWindow,
|
|
2079
|
+
toolNameMap,
|
|
2080
|
+
conversationId,
|
|
2081
|
+
completionMode,
|
|
2082
|
+
completionMode === "required" ? fallbackFactory : undefined,
|
|
2083
|
+
contextInputEstimate,
|
|
2084
|
+
)) {
|
|
2085
|
+
retainTranslatedEvent(e, budget, events.at(-1));
|
|
2086
|
+
events.push(e);
|
|
2087
|
+
}
|
|
2088
|
+
return events;
|
|
2089
|
+
} catch (error) {
|
|
2090
|
+
for (const event of events) releaseTranslatedEvent(event, budget);
|
|
2091
|
+
throw error;
|
|
2092
|
+
}
|
|
1896
2093
|
},
|
|
1897
2094
|
};
|
|
1898
2095
|
}
|
|
@@ -40,6 +40,18 @@ function randomUserAgent(): string {
|
|
|
40
40
|
return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)]!;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function isCanonicalMimoFreeEndpoint(baseUrl: string): boolean {
|
|
44
|
+
try {
|
|
45
|
+
const actual = new URL(baseUrl.trim());
|
|
46
|
+
const expected = new URL(MIMO_CHAT_URL);
|
|
47
|
+
actual.pathname = actual.pathname.replace(/\/+$/, "") || "/";
|
|
48
|
+
expected.pathname = expected.pathname.replace(/\/+$/, "") || "/";
|
|
49
|
+
return actual.toString().replace(/\/$/, "") === expected.toString().replace(/\/$/, "");
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
43
55
|
/**
|
|
44
56
|
* Anonymous per-install client id for the bootstrap `client` field. A random UUID
|
|
45
57
|
* persisted under the config dir (OPENCODEX_HOME-aware) — deliberately NOT derived
|
|
@@ -194,6 +206,11 @@ export function injectMimoSystemMarker(body: unknown): unknown {
|
|
|
194
206
|
* On 401/403, flushes the JWT cache and retries once via fetchResponse.
|
|
195
207
|
*/
|
|
196
208
|
export function createMimoFreeAdapter(provider: OcxProviderConfig): ProviderAdapter {
|
|
209
|
+
if (!isCanonicalMimoFreeEndpoint(provider.baseUrl)) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
"The mimo-free adapter only supports the canonical Xiaomi MiMo Free endpoint. Use openai-chat for a custom endpoint.",
|
|
212
|
+
);
|
|
213
|
+
}
|
|
197
214
|
const base = createOpenAIChatAdapter(provider);
|
|
198
215
|
// Per-adapter session-affinity id (random, per process instance).
|
|
199
216
|
const sessionId = `ses_${Math.random().toString(36).slice(2, 26)}`;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const TRAILING_SLASHES = /\/+$/;
|
|
2
|
+
const TRAILING_CHAT_COMPLETIONS = /\/chat\/completions\/?$/;
|
|
3
|
+
|
|
4
|
+
/** Build the openai-chat send URL from a configured baseUrl.
|
|
5
|
+
* Accepts /v1, /v1/, /v1/chat/completions, and /v1/chat/completions/.
|
|
6
|
+
*/
|
|
7
|
+
export function openaiChatCompletionsUrl(baseUrl: string): string {
|
|
8
|
+
const trimmed = baseUrl.trim().replace(TRAILING_SLASHES, "");
|
|
9
|
+
const withoutEndpoint = trimmed.replace(TRAILING_CHAT_COMPLETIONS, "");
|
|
10
|
+
return `${withoutEndpoint}/chat/completions`;
|
|
11
|
+
}
|