harness-mix 0.1.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/LICENSE +202 -0
- package/NOTICE +14 -0
- package/README.md +184 -0
- package/Start-Codex.cmd +5 -0
- package/config/codex-desktop-compatibility.json +23 -0
- package/docs/chatgpt-web-sidebar.md +27 -0
- package/docs/harness-management.md +41 -0
- package/docs/images/harness-mix-home.png +0 -0
- package/docs/images/harness-mix-session.png +0 -0
- package/docs/multi-agent-collaboration.md +89 -0
- package/docs/native-codex.md +72 -0
- package/licenses/codex-host-MIT.txt +21 -0
- package/output/native-build/desktop-controller.mjs +1460 -0
- package/output/native-build/harness-mix-appx.exe +0 -0
- package/output/native-build/harness-mix-shim.exe +0 -0
- package/output/native-build/renderer-extension.js +28884 -0
- package/package.json +142 -0
- package/scripts/acp-capabilities-probe.cjs +100 -0
- package/scripts/adapters-test.cjs +17 -0
- package/scripts/antigravity-adapter-test.cjs +174 -0
- package/scripts/architecture-test.cjs +62 -0
- package/scripts/build-native.cjs +46 -0
- package/scripts/catalog-test.cjs +25 -0
- package/scripts/cdp-eval.cjs +40 -0
- package/scripts/cdp-watch.cjs +36 -0
- package/scripts/check.cjs +23 -0
- package/scripts/codex-adapter-test.cjs +83 -0
- package/scripts/collaboration-recovery-test.cjs +91 -0
- package/scripts/collaboration-test.cjs +102 -0
- package/scripts/collaboration-ui-smoke.cjs +52 -0
- package/scripts/concurrency-layers-test.cjs +179 -0
- package/scripts/contracts-test.cjs +105 -0
- package/scripts/core-concurrency-test.cjs +103 -0
- package/scripts/core-replay-test.cjs +179 -0
- package/scripts/core-runtime-test.cjs +104 -0
- package/scripts/core-services-test.cjs +50 -0
- package/scripts/determinism-test.cjs +36 -0
- package/scripts/docs-command-test.cjs +49 -0
- package/scripts/dsh-adapter-test.cjs +87 -0
- package/scripts/dsh-native.cjs +9 -0
- package/scripts/dsh-native.cmd +2 -0
- package/scripts/e2e-codex.cjs +82 -0
- package/scripts/e2e-collaboration.cjs +58 -0
- package/scripts/e2e-core-files.cjs +58 -0
- package/scripts/e2e-core-fork.cjs +49 -0
- package/scripts/e2e-core-resume.cjs +49 -0
- package/scripts/e2e-delegate.cjs +38 -0
- package/scripts/e2e-dsh.cjs +23 -0
- package/scripts/e2e-native-commands.cjs +54 -0
- package/scripts/e2e-native-host.cjs +144 -0
- package/scripts/e2e-openclaw-image.cjs +59 -0
- package/scripts/e2e-openclaw.cjs +21 -0
- package/scripts/e2e-pi.cjs +23 -0
- package/scripts/e2e-shadow.cjs +52 -0
- package/scripts/fixture-capture.cjs +103 -0
- package/scripts/git-test.cjs +33 -0
- package/scripts/launch-codex.cjs +5 -0
- package/scripts/native-compatibility-test.cjs +42 -0
- package/scripts/native-config-test.cjs +25 -0
- package/scripts/native-file-change-test.cjs +94 -0
- package/scripts/native-host.cjs +8 -0
- package/scripts/native-images-test.cjs +56 -0
- package/scripts/native-protocol-test.cjs +233 -0
- package/scripts/native-rollback-test.cjs +46 -0
- package/scripts/native-sidebar-test.cjs +88 -0
- package/scripts/native-ui-smoke.cjs +94 -0
- package/scripts/native-updater-test.cjs +100 -0
- package/scripts/native-vendor-adapters-test.cjs +40 -0
- package/scripts/openclaw-acp-probe.cjs +39 -0
- package/scripts/openclaw-adapter-test.cjs +180 -0
- package/scripts/openclaw-models-probe.cjs +13 -0
- package/scripts/projector-test.cjs +144 -0
- package/scripts/sequence-test.cjs +57 -0
- package/scripts/shadow-test.cjs +154 -0
- package/scripts/support/legacy-projection.cjs +95 -0
- package/scripts/support/legacy-transcript.cjs +48 -0
- package/scripts/support/parity-observer.cjs +27 -0
- package/scripts/support/shadow-comparator.cjs +62 -0
- package/scripts/support/shadow.cjs +114 -0
- package/scripts/switch-harness-test.cjs +145 -0
- package/scripts/tool-concurrency-regression-test.cjs +118 -0
- package/scripts/transcript-test.cjs +24 -0
- package/scripts/turn-manager-test.cjs +91 -0
- package/scripts/workspace-test.cjs +98 -0
- package/src/assets/brand-harness-mix.png +0 -0
- package/src/assets/icons/activity-compact.svg +1 -0
- package/src/assets/icons/activity-edit.svg +1 -0
- package/src/assets/icons/activity-terminal.svg +1 -0
- package/src/assets/icons/antigravity-color.svg +1 -0
- package/src/assets/icons/claude-color.svg +1 -0
- package/src/assets/icons/codex-color.svg +1 -0
- package/src/assets/icons/codex-harness.svg +1 -0
- package/src/assets/icons/commands.svg +1 -0
- package/src/assets/icons/deepseek-color.svg +1 -0
- package/src/assets/icons/grok-color.svg +1 -0
- package/src/assets/icons/hermes-color.svg +1 -0
- package/src/assets/icons/home-chat.svg +1 -0
- package/src/assets/icons/home-folder.svg +1 -0
- package/src/assets/icons/model-astra.svg +1 -0
- package/src/assets/icons/model-claude.svg +1 -0
- package/src/assets/icons/model-deepseek.svg +1 -0
- package/src/assets/icons/model-gemini.svg +1 -0
- package/src/assets/icons/model-hunyuan.svg +1 -0
- package/src/assets/icons/model-kimi.svg +1 -0
- package/src/assets/icons/model-minimax.svg +1 -0
- package/src/assets/icons/model-openai.svg +1 -0
- package/src/assets/icons/model-qwen-color.svg +1 -0
- package/src/assets/icons/model-xiaomimimo.svg +1 -0
- package/src/assets/icons/model-zai.svg +1 -0
- package/src/assets/icons/omp-color.svg +1 -0
- package/src/assets/icons/openclaw-color.svg +1 -0
- package/src/assets/icons/opencode-color.svg +1 -0
- package/src/assets/icons/pi.svg +1 -0
- package/src/assets/icons/pinumber1_80899.svg +48 -0
- package/src/assets/icons/qoder-color.svg +1 -0
- package/src/assets/icons/thread-fork.svg +1 -0
- package/src/assets/icons/trae-color.svg +1 -0
- package/src/assets/icons/workbuddy-color.svg +1 -0
- package/src/assets/icons/zcode-color.svg +1 -0
- package/src/main/adapters/acp.js +171 -0
- package/src/main/adapters/antigravity.js +895 -0
- package/src/main/adapters/claude.js +399 -0
- package/src/main/adapters/codex-app-server.js +119 -0
- package/src/main/adapters/codex.js +547 -0
- package/src/main/adapters/dsh-web-host.js +207 -0
- package/src/main/adapters/dsh.js +415 -0
- package/src/main/adapters/grok.js +161 -0
- package/src/main/adapters/hermes.js +24 -0
- package/src/main/adapters/index.js +30 -0
- package/src/main/adapters/omp.js +12 -0
- package/src/main/adapters/openclaw-gateway.js +215 -0
- package/src/main/adapters/openclaw.js +337 -0
- package/src/main/adapters/opencode-server.js +72 -0
- package/src/main/adapters/opencode.js +166 -0
- package/src/main/adapters/pi-family.js +315 -0
- package/src/main/adapters/pi-usage.js +24 -0
- package/src/main/adapters/pi.js +10 -0
- package/src/main/adapters/qoder.js +35 -0
- package/src/main/adapters/trae.js +19 -0
- package/src/main/adapters/workbuddy.js +67 -0
- package/src/main/adapters/zcode.js +38 -0
- package/src/main/harness-adapter/contract-test.js +53 -0
- package/src/main/harness-adapter/contract.js +34 -0
- package/src/main/harness-adapter/event-normalizer.js +233 -0
- package/src/main/harness-adapter/fixture-recorder.js +56 -0
- package/src/main/harness-adapter/index.js +6 -0
- package/src/main/harness-adapter/manifest.js +44 -0
- package/src/main/host/collaboration-mcp.cjs +35 -0
- package/src/main/host/collaboration-pi.mjs +17 -0
- package/src/main/host/collaboration-tools.js +16 -0
- package/src/main/host/collaboration-worktree.js +82 -0
- package/src/main/host/collaboration.js +238 -0
- package/src/main/host/core-session.js +81 -0
- package/src/main/host/handoff.js +46 -0
- package/src/main/host/history-import.js +55 -0
- package/src/main/host/jsonl.js +115 -0
- package/src/main/host/native-history.js +74 -0
- package/src/main/host/runtime.js +927 -0
- package/src/main/host/session-history.js +63 -0
- package/src/main/host/store.js +42 -0
- package/src/main/native/compatibility.js +55 -0
- package/src/main/native/config.js +49 -0
- package/src/main/native/host.js +108 -0
- package/src/main/native/icons.js +101 -0
- package/src/main/native/input.js +43 -0
- package/src/main/native/launcher.js +100 -0
- package/src/main/native/protocol.js +552 -0
- package/src/main/native/rs/Cargo.lock +11 -0
- package/src/main/native/rs/Cargo.toml +9 -0
- package/src/main/native/rs/crates/appx/Cargo.toml +13 -0
- package/src/main/native/rs/crates/appx/src/main.rs +309 -0
- package/src/main/native/rs/crates/shim/Cargo.toml +10 -0
- package/src/main/native/rs/crates/shim/src/main.rs +207 -0
- package/src/main/native/thread-list.js +38 -0
- package/src/main/native/updater.js +102 -0
- package/src/main/native/usage.js +29 -0
- package/src/main/protocol-core/capability-manager.js +16 -0
- package/src/main/protocol-core/event-router.js +32 -0
- package/src/main/protocol-core/file-change-projector.js +45 -0
- package/src/main/protocol-core/index.js +8 -0
- package/src/main/protocol-core/interaction-router.js +30 -0
- package/src/main/protocol-core/projector.js +238 -0
- package/src/main/protocol-core/protocol-core.js +132 -0
- package/src/main/protocol-core/sequence-validator.js +44 -0
- package/src/main/protocol-core/thread-manager.js +50 -0
- package/src/main/protocol-core/turn-manager.js +63 -0
- package/src/main/shared-contracts/capability.js +35 -0
- package/src/main/shared-contracts/event.js +55 -0
- package/src/main/shared-contracts/ids.js +12 -0
- package/src/main/shared-contracts/index.js +11 -0
- package/src/main/shared-contracts/interaction.js +37 -0
- package/src/main/shared-contracts/item.js +50 -0
- package/src/main/shared-contracts/native-ref.js +24 -0
- package/src/main/shared-contracts/thread.js +36 -0
- package/src/main/shared-contracts/turn.js +54 -0
- package/src/main/workspace/core-review.js +53 -0
- package/src/main/workspace/diff.js +27 -0
- package/src/main/workspace/file-changes.js +21 -0
- package/src/main/workspace/files.js +65 -0
- package/src/main/workspace/git.js +73 -0
- package/src/main/workspace/ipc.js +50 -0
- package/src/main/workspace/review-controller.js +102 -0
- package/src/main/workspace/review.js +83 -0
- package/src/main/workspace/terminal.js +36 -0
- package/src/native-ui/LICENSE +21 -0
- package/src/native-ui/README.md +12 -0
- package/src/native-ui/desktop-control/dist/cdp-client.d.ts +53 -0
- package/src/native-ui/desktop-control/dist/cdp-client.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/cdp-client.js +258 -0
- package/src/native-ui/desktop-control/dist/cdp-client.js.map +1 -0
- package/src/native-ui/desktop-control/dist/contract-audit.d.ts +73 -0
- package/src/native-ui/desktop-control/dist/contract-audit.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/contract-audit.js +152 -0
- package/src/native-ui/desktop-control/dist/contract-audit.js.map +1 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts +10 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.js +77 -0
- package/src/native-ui/desktop-control/dist/controller-attachment-server.js.map +1 -0
- package/src/native-ui/desktop-control/dist/index.d.ts +21 -0
- package/src/native-ui/desktop-control/dist/index.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/index.js +14 -0
- package/src/native-ui/desktop-control/dist/index.js.map +1 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts +24 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js +246 -0
- package/src/native-ui/desktop-control/dist/main-process-title-policy.js.map +1 -0
- package/src/native-ui/desktop-control/dist/production-controller.d.ts +32 -0
- package/src/native-ui/desktop-control/dist/production-controller.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/production-controller.js +291 -0
- package/src/native-ui/desktop-control/dist/production-controller.js.map +1 -0
- package/src/native-ui/desktop-control/dist/release-main.d.ts +2 -0
- package/src/native-ui/desktop-control/dist/release-main.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/release-main.js +17 -0
- package/src/native-ui/desktop-control/dist/release-main.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts +49 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js +214 -0
- package/src/native-ui/desktop-control/dist/renderer-cdp-control-session.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts +79 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.js +366 -0
- package/src/native-ui/desktop-control/dist/renderer-control-session.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.d.ts +24 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.js +110 -0
- package/src/native-ui/desktop-control/dist/renderer-dom.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts +19 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js +162 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-policy.js.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts +38 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.d.ts.map +1 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js +633 -0
- package/src/native-ui/desktop-control/dist/renderer-draft-prewarm-runtime.js.map +1 -0
- package/src/native-ui/desktop-control/dist/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/desktop-control/package.json +22 -0
- package/src/native-ui/desktop-control/scripts/build-release.mjs +94 -0
- package/src/native-ui/desktop-control/src/cdp-client.ts +347 -0
- package/src/native-ui/desktop-control/src/contract-audit.ts +291 -0
- package/src/native-ui/desktop-control/src/controller-attachment-server.ts +93 -0
- package/src/native-ui/desktop-control/src/index.ts +91 -0
- package/src/native-ui/desktop-control/src/main-process-title-policy.ts +334 -0
- package/src/native-ui/desktop-control/src/production-controller.ts +344 -0
- package/src/native-ui/desktop-control/src/release-main.ts +18 -0
- package/src/native-ui/desktop-control/src/renderer-cdp-control-session.ts +358 -0
- package/src/native-ui/desktop-control/src/renderer-control-session.ts +595 -0
- package/src/native-ui/desktop-control/src/renderer-dom.ts +144 -0
- package/src/native-ui/desktop-control/src/renderer-draft-prewarm-policy.ts +209 -0
- package/src/native-ui/desktop-control/src/renderer-draft-prewarm-runtime.ts +746 -0
- package/src/native-ui/desktop-control/test/cdp-client.test.ts +157 -0
- package/src/native-ui/desktop-control/test/contract-audit.test.ts +56 -0
- package/src/native-ui/desktop-control/test/controller-attachment-server.test.ts +98 -0
- package/src/native-ui/desktop-control/test/index.test.ts +11 -0
- package/src/native-ui/desktop-control/test/main-process-title-policy.test.ts +166 -0
- package/src/native-ui/desktop-control/test/production-controller.test.ts +389 -0
- package/src/native-ui/desktop-control/test/renderer-cdp-control-session.test.ts +205 -0
- package/src/native-ui/desktop-control/test/renderer-control-session.test.ts +451 -0
- package/src/native-ui/desktop-control/test/renderer-dom.test.ts +62 -0
- package/src/native-ui/desktop-control/test/renderer-draft-prewarm-policy.test.ts +998 -0
- package/src/native-ui/desktop-control/tsconfig.json +12 -0
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts +39 -0
- package/src/native-ui/renderer-extension/dist/types/agent-group-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts +83 -0
- package/src/native-ui/renderer-extension/dist/types/agent-selection-state.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/audit-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/codex-locale-adapter.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/collaboration-icon.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts +37 -0
- package/src/native-ui/renderer-extension/dist/types/contract-audit.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/harness-mix-settings.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/index.d.ts +49 -0
- package/src/native-ui/renderer-extension/dist/types/index.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/install-renderer-binding.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts +2 -0
- package/src/native-ui/renderer-extension/dist/types/probe-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/production-entry.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-icon.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts +62 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-agent-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts +70 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-binding-probe.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts +34 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-options.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts +19 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-codex-account-state.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts +82 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-composer-dom.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts +21 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-credits-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts +7 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-external-steering.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts +34 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-fork-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-claim.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts +15 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-command-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts +25 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-localization.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-harness-mentions.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts +94 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-client.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts +22 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker-positioning.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts +54 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-model-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-new-thread-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts +42 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-picker.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-permission-mode-preference.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts +9 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-request-sender.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts +12 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-session-import-client.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-settings-lifecycle.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts +45 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-sidebar-agent-icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts +23 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-transcript-dom.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts +3 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-trigger-chip-style.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts +72 -0
- package/src/native-ui/renderer-extension/dist/types/renderer-usage-control.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts +24 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-list.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts +18 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts +27 -0
- package/src/native-ui/renderer-extension/dist/types/settings/accounts-usage.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts +42 -0
- package/src/native-ui/renderer-extension/dist/types/settings/connections-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts +38 -0
- package/src/native-ui/renderer-extension/dist/types/settings/core.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts +14 -0
- package/src/native-ui/renderer-extension/dist/types/settings/harness-accounts.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts +6 -0
- package/src/native-ui/renderer-extension/dist/types/settings/icons.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts +231 -0
- package/src/native-ui/renderer-extension/dist/types/settings/localization.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts +22 -0
- package/src/native-ui/renderer-extension/dist/types/settings/pages.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts +4 -0
- package/src/native-ui/renderer-extension/dist/types/settings/release-notes.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts +12 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-list-controls.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts +8 -0
- package/src/native-ui/renderer-extension/dist/types/settings/session-import-page.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts +24 -0
- package/src/native-ui/renderer-extension/dist/types/settings/shell.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts +45 -0
- package/src/native-ui/renderer-extension/dist/types/settings/trigger.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts +6 -0
- package/src/native-ui/renderer-extension/dist/types/settings/update-request.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/dist/types/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts +143 -0
- package/src/native-ui/renderer-extension/dist/types/versioned-renderer-adapter.d.ts.map +1 -0
- package/src/native-ui/renderer-extension/package.json +22 -0
- package/src/native-ui/renderer-extension/src/agent-group-preference.ts +174 -0
- package/src/native-ui/renderer-extension/src/agent-selection-state.ts +610 -0
- package/src/native-ui/renderer-extension/src/assets/README.md +43 -0
- package/src/native-ui/renderer-extension/src/assets/antigravity-agent.svg +1 -0
- package/src/native-ui/renderer-extension/src/assets/claude-agent.svg +3 -0
- package/src/native-ui/renderer-extension/src/assets/codex-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codex-logo-bright.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codex-logo-transparent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codex-logo.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codexhost-icon.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codexhost-logo-transparent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codexhost-logo.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/codexhost-readme.svg +8 -0
- package/src/native-ui/renderer-extension/src/assets/grok-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/kiro-agent.svg +11 -0
- package/src/native-ui/renderer-extension/src/assets/omp-agent.svg +14 -0
- package/src/native-ui/renderer-extension/src/assets/opencode-agent.png +0 -0
- package/src/native-ui/renderer-extension/src/assets/pi-agent.svg +4 -0
- package/src/native-ui/renderer-extension/src/assets.d.ts +26 -0
- package/src/native-ui/renderer-extension/src/audit-entry.ts +5 -0
- package/src/native-ui/renderer-extension/src/codex-locale-adapter.ts +321 -0
- package/src/native-ui/renderer-extension/src/collaboration-icon.ts +13 -0
- package/src/native-ui/renderer-extension/src/contract-audit.ts +102 -0
- package/src/native-ui/renderer-extension/src/harness-mix-icons.ts +24 -0
- package/src/native-ui/renderer-extension/src/harness-mix-settings.ts +80 -0
- package/src/native-ui/renderer-extension/src/index.ts +266 -0
- package/src/native-ui/renderer-extension/src/install-renderer-binding.ts +30 -0
- package/src/native-ui/renderer-extension/src/probe-entry.ts +4 -0
- package/src/native-ui/renderer-extension/src/production-entry.ts +23 -0
- package/src/native-ui/renderer-extension/src/renderer-agent-icon.ts +145 -0
- package/src/native-ui/renderer-extension/src/renderer-agent-picker.ts +813 -0
- package/src/native-ui/renderer-extension/src/renderer-binding-probe.ts +2936 -0
- package/src/native-ui/renderer-extension/src/renderer-codex-account-options.ts +281 -0
- package/src/native-ui/renderer-extension/src/renderer-codex-account-state.ts +53 -0
- package/src/native-ui/renderer-extension/src/renderer-composer-dom.ts +782 -0
- package/src/native-ui/renderer-extension/src/renderer-credits-control.ts +500 -0
- package/src/native-ui/renderer-extension/src/renderer-external-steering.ts +339 -0
- package/src/native-ui/renderer-extension/src/renderer-fork-control.ts +273 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-command-claim.ts +64 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-command-control.ts +417 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-localization.ts +144 -0
- package/src/native-ui/renderer-extension/src/renderer-harness-mentions.ts +213 -0
- package/src/native-ui/renderer-extension/src/renderer-model-client.ts +567 -0
- package/src/native-ui/renderer-extension/src/renderer-model-picker-positioning.ts +65 -0
- package/src/native-ui/renderer-extension/src/renderer-model-picker.ts +640 -0
- package/src/native-ui/renderer-extension/src/renderer-new-thread-preference.ts +175 -0
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-picker.ts +413 -0
- package/src/native-ui/renderer-extension/src/renderer-permission-mode-preference.ts +49 -0
- package/src/native-ui/renderer-extension/src/renderer-request-sender.ts +43 -0
- package/src/native-ui/renderer-extension/src/renderer-session-import-client.ts +68 -0
- package/src/native-ui/renderer-extension/src/renderer-settings-lifecycle.ts +239 -0
- package/src/native-ui/renderer-extension/src/renderer-sidebar-agent-icons.ts +456 -0
- package/src/native-ui/renderer-extension/src/renderer-transcript-dom.ts +47 -0
- package/src/native-ui/renderer-extension/src/renderer-trigger-chip-style.ts +52 -0
- package/src/native-ui/renderer-extension/src/renderer-usage-control.ts +602 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-list.ts +236 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-page.ts +585 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-quota-interactive.prototype.html +1418 -0
- package/src/native-ui/renderer-extension/src/settings/accounts-usage.ts +221 -0
- package/src/native-ui/renderer-extension/src/settings/accounts.css +607 -0
- package/src/native-ui/renderer-extension/src/settings/connections-page.ts +1354 -0
- package/src/native-ui/renderer-extension/src/settings/core.ts +158 -0
- package/src/native-ui/renderer-extension/src/settings/harness-accounts.ts +134 -0
- package/src/native-ui/renderer-extension/src/settings/icons.ts +141 -0
- package/src/native-ui/renderer-extension/src/settings/localization.ts +752 -0
- package/src/native-ui/renderer-extension/src/settings/pages.ts +615 -0
- package/src/native-ui/renderer-extension/src/settings/release-notes.ts +222 -0
- package/src/native-ui/renderer-extension/src/settings/session-import-list-controls.ts +128 -0
- package/src/native-ui/renderer-extension/src/settings/session-import-page.ts +461 -0
- package/src/native-ui/renderer-extension/src/settings/shell.css +2149 -0
- package/src/native-ui/renderer-extension/src/settings/shell.ts +329 -0
- package/src/native-ui/renderer-extension/src/settings/trigger.ts +323 -0
- package/src/native-ui/renderer-extension/src/settings/update-notes.preview.html +491 -0
- package/src/native-ui/renderer-extension/src/settings/update-request.ts +49 -0
- package/src/native-ui/renderer-extension/src/settings/windows-update.preview.html +2135 -0
- package/src/native-ui/renderer-extension/src/versioned-renderer-adapter.ts +1278 -0
- package/src/native-ui/renderer-extension/test/agent-selection-state.test.ts +611 -0
- package/src/native-ui/renderer-extension/test/codex-locale-adapter.test.ts +152 -0
- package/src/native-ui/renderer-extension/test/contract-audit.test.ts +71 -0
- package/src/native-ui/renderer-extension/test/index.test.ts +9 -0
- package/src/native-ui/renderer-extension/test/renderer-agent-icon.test.ts +98 -0
- package/src/native-ui/renderer-extension/test/renderer-agent-picker.test.ts +226 -0
- package/src/native-ui/renderer-extension/test/renderer-binding-probe-host-catalog.test.ts +728 -0
- package/src/native-ui/renderer-extension/test/renderer-binding-probe.test.ts +1290 -0
- package/src/native-ui/renderer-extension/test/renderer-codex-account-state.test.ts +65 -0
- package/src/native-ui/renderer-extension/test/renderer-composer-permissions.test.ts +75 -0
- package/src/native-ui/renderer-extension/test/renderer-credits-control.test.ts +70 -0
- package/src/native-ui/renderer-extension/test/renderer-external-steering-rpc.test.ts +184 -0
- package/src/native-ui/renderer-extension/test/renderer-external-steering.test.ts +279 -0
- package/src/native-ui/renderer-extension/test/renderer-fork-control.test.ts +363 -0
- package/src/native-ui/renderer-extension/test/renderer-harness-command-claim.test.ts +167 -0
- package/src/native-ui/renderer-extension/test/renderer-harness-command-control.test.ts +54 -0
- package/src/native-ui/renderer-extension/test/renderer-model-client.test.ts +708 -0
- package/src/native-ui/renderer-extension/test/renderer-model-picker.test.ts +302 -0
- package/src/native-ui/renderer-extension/test/renderer-native-thread-ownership.test.ts +84 -0
- package/src/native-ui/renderer-extension/test/renderer-new-thread-preference.test.ts +81 -0
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-picker.test.ts +269 -0
- package/src/native-ui/renderer-extension/test/renderer-permission-mode-preference.test.ts +48 -0
- package/src/native-ui/renderer-extension/test/renderer-settings-lifecycle.test.ts +156 -0
- package/src/native-ui/renderer-extension/test/renderer-sidebar-agent-icons.test.ts +575 -0
- package/src/native-ui/renderer-extension/test/renderer-unsupported-methods.test.ts +167 -0
- package/src/native-ui/renderer-extension/test/renderer-usage-control.test.ts +96 -0
- package/src/native-ui/renderer-extension/test/settings/accounts-usage.test.ts +208 -0
- package/src/native-ui/renderer-extension/test/settings/core.test.ts +145 -0
- package/src/native-ui/renderer-extension/test/settings/harness-settings.test.ts +88 -0
- package/src/native-ui/renderer-extension/test/settings/localization.test.ts +80 -0
- package/src/native-ui/renderer-extension/test/settings/pages.test.ts +2000 -0
- package/src/native-ui/renderer-extension/test/settings/release-notes.test.ts +163 -0
- package/src/native-ui/renderer-extension/test/settings/shell.test.ts +74 -0
- package/src/native-ui/renderer-extension/test/settings/trigger.test.ts +270 -0
- package/src/native-ui/renderer-extension/test/settings/update-request.test.ts +48 -0
- package/src/native-ui/renderer-extension/test/versioned-renderer-adapter.test.ts +682 -0
- package/src/native-ui/renderer-extension/tsconfig.json +15 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts +246 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.js +99 -0
- package/src/native-ui/shared-contracts/dist/codex-accounts.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts +37 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js +36 -0
- package/src/native-ui/shared-contracts/dist/deepseek-modern-sessions.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/errors.d.ts +17 -0
- package/src/native-ui/shared-contracts/dist/errors.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/errors.js +14 -0
- package/src/native-ui/shared-contracts/dist/errors.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts +11 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.js +14 -0
- package/src/native-ui/shared-contracts/dist/external-thread-fork.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts +64 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.js +24 -0
- package/src/native-ui/shared-contracts/dist/harness-accounts.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.d.ts +46 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.js +61 -0
- package/src/native-ui/shared-contracts/dist/harness-commands.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts +278 -0
- package/src/native-ui/shared-contracts/dist/harness-models.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-models.js +317 -0
- package/src/native-ui/shared-contracts/dist/harness-models.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts +30 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.js +57 -0
- package/src/native-ui/shared-contracts/dist/harness-permission-modes.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts +56 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.js +75 -0
- package/src/native-ui/shared-contracts/dist/harness-plugins.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts +16 -0
- package/src/native-ui/shared-contracts/dist/harness-route.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-route.js +42 -0
- package/src/native-ui/shared-contracts/dist/harness-route.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts +54 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.js +72 -0
- package/src/native-ui/shared-contracts/dist/harness-session-import.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/ids.d.ts +12 -0
- package/src/native-ui/shared-contracts/dist/ids.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/ids.js +10 -0
- package/src/native-ui/shared-contracts/dist/ids.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/index.d.ts +47 -0
- package/src/native-ui/shared-contracts/dist/index.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/index.js +29 -0
- package/src/native-ui/shared-contracts/dist/index.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.d.ts +84 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.js +65 -0
- package/src/native-ui/shared-contracts/dist/json-rpc.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-value.d.ts +13 -0
- package/src/native-ui/shared-contracts/dist/json-value.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/json-value.js +60 -0
- package/src/native-ui/shared-contracts/dist/json-value.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/native-refs.d.ts +43 -0
- package/src/native-ui/shared-contracts/dist/native-refs.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/native-refs.js +35 -0
- package/src/native-ui/shared-contracts/dist/native-refs.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts +7 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.js +7 -0
- package/src/native-ui/shared-contracts/dist/reasoning-transcript.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts +22 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.js +30 -0
- package/src/native-ui/shared-contracts/dist/thread-delegate.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts +16 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.js +19 -0
- package/src/native-ui/shared-contracts/dist/thread-harness-switch.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.d.ts +106 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.js +103 -0
- package/src/native-ui/shared-contracts/dist/thread-usage.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/tsconfig.tsbuildinfo +1 -0
- package/src/native-ui/shared-contracts/dist/updates.d.ts +128 -0
- package/src/native-ui/shared-contracts/dist/updates.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/updates.js +58 -0
- package/src/native-ui/shared-contracts/dist/updates.js.map +1 -0
- package/src/native-ui/shared-contracts/dist/version.d.ts +2 -0
- package/src/native-ui/shared-contracts/dist/version.d.ts.map +1 -0
- package/src/native-ui/shared-contracts/dist/version.js +2 -0
- package/src/native-ui/shared-contracts/dist/version.js.map +1 -0
- package/src/native-ui/shared-contracts/package.json +25 -0
- package/src/native-ui/shared-contracts/src/codex-accounts.ts +140 -0
- package/src/native-ui/shared-contracts/src/deepseek-modern-sessions.ts +67 -0
- package/src/native-ui/shared-contracts/src/errors.ts +25 -0
- package/src/native-ui/shared-contracts/src/external-thread-fork.ts +20 -0
- package/src/native-ui/shared-contracts/src/harness-accounts.ts +29 -0
- package/src/native-ui/shared-contracts/src/harness-commands.ts +81 -0
- package/src/native-ui/shared-contracts/src/harness-models.ts +401 -0
- package/src/native-ui/shared-contracts/src/harness-permission-modes.ts +73 -0
- package/src/native-ui/shared-contracts/src/harness-plugins.ts +96 -0
- package/src/native-ui/shared-contracts/src/harness-route.ts +47 -0
- package/src/native-ui/shared-contracts/src/harness-session-import.ts +90 -0
- package/src/native-ui/shared-contracts/src/ids.ts +20 -0
- package/src/native-ui/shared-contracts/src/index.ts +320 -0
- package/src/native-ui/shared-contracts/src/json-rpc.ts +80 -0
- package/src/native-ui/shared-contracts/src/json-value.ts +78 -0
- package/src/native-ui/shared-contracts/src/native-refs.ts +58 -0
- package/src/native-ui/shared-contracts/src/reasoning-transcript.ts +6 -0
- package/src/native-ui/shared-contracts/src/thread-delegate.ts +40 -0
- package/src/native-ui/shared-contracts/src/thread-harness-switch.ts +25 -0
- package/src/native-ui/shared-contracts/src/thread-usage.ts +126 -0
- package/src/native-ui/shared-contracts/src/updates.ts +78 -0
- package/src/native-ui/shared-contracts/src/version.ts +1 -0
- package/src/native-ui/shared-contracts/test/browser-bundle.test.ts +36 -0
- package/src/native-ui/shared-contracts/test/deepseek-modern-sessions.test.ts +120 -0
- package/src/native-ui/shared-contracts/test/errors.test.ts +72 -0
- package/src/native-ui/shared-contracts/test/harness-commands.test.ts +64 -0
- package/src/native-ui/shared-contracts/test/harness-models.test.ts +390 -0
- package/src/native-ui/shared-contracts/test/harness-permission-modes.test.ts +134 -0
- package/src/native-ui/shared-contracts/test/harness-plugins.test.ts +113 -0
- package/src/native-ui/shared-contracts/test/harness-session-import.test.ts +117 -0
- package/src/native-ui/shared-contracts/test/ids.test.ts +69 -0
- package/src/native-ui/shared-contracts/test/index.test.ts +80 -0
- package/src/native-ui/shared-contracts/test/json-rpc.test.ts +177 -0
- package/src/native-ui/shared-contracts/test/json-value.test.ts +62 -0
- package/src/native-ui/shared-contracts/test/native-refs.test.ts +95 -0
- package/src/native-ui/shared-contracts/test/thread-usage.test.ts +115 -0
- package/src/native-ui/shared-contracts/test/updates.test.ts +120 -0
- package/src/native-ui/shared-contracts/tsconfig.json +10 -0
- package/src/tsconfig.base.json +19 -0
|
@@ -0,0 +1,1278 @@
|
|
|
1
|
+
import {
|
|
2
|
+
encodeHarnessPluginRoute,
|
|
3
|
+
harnessIdSchema,
|
|
4
|
+
harnessModelRefSchema,
|
|
5
|
+
harnessPermissionModeIdSchema,
|
|
6
|
+
harnessThinkingOptionIdSchema,
|
|
7
|
+
hostThreadIdSchema,
|
|
8
|
+
type ExternalThreadForkParams,
|
|
9
|
+
type HarnessInspectParams,
|
|
10
|
+
type HarnessModelRef,
|
|
11
|
+
type HarnessPermissionModeId,
|
|
12
|
+
type HarnessThinkingOptionId,
|
|
13
|
+
type HostThreadId,
|
|
14
|
+
type ThreadCommandExecuteParams,
|
|
15
|
+
type HarnessCommandsInspectParams,
|
|
16
|
+
type ThreadCommandsInspectParams,
|
|
17
|
+
type ThreadInspectionParams,
|
|
18
|
+
type ThreadModelSelectParams,
|
|
19
|
+
type ThreadPermissionModeSelectParams,
|
|
20
|
+
type ThreadHarnessSwitchParams,
|
|
21
|
+
type ThreadThinkingSelectParams,
|
|
22
|
+
type ThreadOwnershipListParams,
|
|
23
|
+
type ThreadUsageInspection,
|
|
24
|
+
type ThreadUsageInspectionParams,
|
|
25
|
+
} from "@codexhost/shared-contracts";
|
|
26
|
+
|
|
27
|
+
import type { RendererAgent } from "./agent-selection-state.js";
|
|
28
|
+
import { installRendererForkControl } from "./renderer-fork-control.js";
|
|
29
|
+
import { installRendererExternalSteering } from "./renderer-external-steering.js";
|
|
30
|
+
import {
|
|
31
|
+
createRendererModelClient,
|
|
32
|
+
createThreadUsageSubscriptionRelay,
|
|
33
|
+
type RendererModelClient,
|
|
34
|
+
} from "./renderer-model-client.js";
|
|
35
|
+
|
|
36
|
+
export const PI_TRANSPORT_MODEL_ID = "codexhost/pi-native";
|
|
37
|
+
export const PI_TRANSPORT_MODEL_PREFIX = `${PI_TRANSPORT_MODEL_ID}@`;
|
|
38
|
+
export const CLAUDE_CODE_TRANSPORT_MODEL_ID = "codexhost/claude-code-native";
|
|
39
|
+
export const CLAUDE_CODE_TRANSPORT_MODEL_PREFIX = `${CLAUDE_CODE_TRANSPORT_MODEL_ID}@`;
|
|
40
|
+
export const DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID = "codexhost/deepseek-harness-native";
|
|
41
|
+
export const DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX = `${DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID}@`;
|
|
42
|
+
export const OPENCODE_TRANSPORT_MODEL_ID = "codexhost/opencode-native";
|
|
43
|
+
export const OPENCODE_TRANSPORT_MODEL_PREFIX = `${OPENCODE_TRANSPORT_MODEL_ID}@`;
|
|
44
|
+
export const GROK_TRANSPORT_MODEL_ID = "codexhost/grok-native";
|
|
45
|
+
export const GROK_TRANSPORT_MODEL_PREFIX = `${GROK_TRANSPORT_MODEL_ID}@`;
|
|
46
|
+
export const OMP_TRANSPORT_MODEL_ID = "codexhost/omp-native";
|
|
47
|
+
export const OMP_TRANSPORT_MODEL_PREFIX = `${OMP_TRANSPORT_MODEL_ID}@`;
|
|
48
|
+
export const ANTIGRAVITY_TRANSPORT_MODEL_ID = "codexhost/antigravity-native";
|
|
49
|
+
export const ANTIGRAVITY_TRANSPORT_MODEL_PREFIX = `${ANTIGRAVITY_TRANSPORT_MODEL_ID}@`;
|
|
50
|
+
|
|
51
|
+
export type RendererAdapterState = "installing" | "ready" | "unsupported";
|
|
52
|
+
|
|
53
|
+
export interface LockedComposerSelection {
|
|
54
|
+
agent: RendererAgent;
|
|
55
|
+
composerId: string;
|
|
56
|
+
phase: "locked";
|
|
57
|
+
model?: HarnessModelRef;
|
|
58
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
59
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface RendererAdapterStatus {
|
|
63
|
+
state: RendererAdapterState;
|
|
64
|
+
reason:
|
|
65
|
+
| "installing"
|
|
66
|
+
| "ready"
|
|
67
|
+
| "asset-import-failed"
|
|
68
|
+
| "installation-failed"
|
|
69
|
+
| "draft-prewarm-clear-failed"
|
|
70
|
+
| "draft-routing-policy-unavailable";
|
|
71
|
+
modelUpdates: number;
|
|
72
|
+
hook: "request-bridge" | null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type RendererAdapterStatusTransition = Pick<RendererAdapterStatus, "state" | "reason" | "hook">;
|
|
76
|
+
|
|
77
|
+
export function transitionRendererAdapterStatus(
|
|
78
|
+
current: RendererAdapterStatus,
|
|
79
|
+
next: RendererAdapterStatusTransition,
|
|
80
|
+
publish: () => void,
|
|
81
|
+
): boolean {
|
|
82
|
+
if (
|
|
83
|
+
current.state === next.state &&
|
|
84
|
+
current.reason === next.reason &&
|
|
85
|
+
current.hook === next.hook
|
|
86
|
+
) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
current.state = next.state;
|
|
90
|
+
current.reason = next.reason;
|
|
91
|
+
current.hook = next.hook;
|
|
92
|
+
publish();
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
interface PrewarmTarget {
|
|
97
|
+
addNotificationCallback?: (
|
|
98
|
+
method: string | readonly string[],
|
|
99
|
+
callback: (notification: unknown) => void,
|
|
100
|
+
) => () => void;
|
|
101
|
+
enqueueRequest?: (...args: unknown[]) => unknown;
|
|
102
|
+
prewarmThreadStart?: (params: unknown, options?: unknown) => Promise<unknown> | unknown;
|
|
103
|
+
sendRequest?: (method: string, params: unknown, options?: unknown) => Promise<unknown> | unknown;
|
|
104
|
+
requestClient?: PrewarmTarget;
|
|
105
|
+
hostId?: unknown;
|
|
106
|
+
getHostId?: () => unknown;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface ModelPowerSelection {
|
|
110
|
+
model: unknown;
|
|
111
|
+
reasoningEffort: unknown;
|
|
112
|
+
[key: string]: unknown;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface RendererDraftPrewarmPolicy {
|
|
116
|
+
state: "ready";
|
|
117
|
+
hostId: string;
|
|
118
|
+
readonly requestTarget?: () => unknown;
|
|
119
|
+
select(model: string | null): boolean;
|
|
120
|
+
readonly selectAccount?: (accountId: string | null) => boolean;
|
|
121
|
+
clear(): Promise<void>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
interface RendererDraftPrewarmPolicyTarget {
|
|
125
|
+
__codexhostDraftPrewarmPolicyV1?: RendererDraftPrewarmPolicy;
|
|
126
|
+
setTimeout(handler: TimerHandler, timeout?: number): number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS = 10_000;
|
|
130
|
+
const DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS = 25;
|
|
131
|
+
|
|
132
|
+
declare global {
|
|
133
|
+
interface Window {
|
|
134
|
+
__codexhostMainProcessTitlePolicyV1?: { state: "ready" };
|
|
135
|
+
__codexhostDraftPrewarmPolicyV1?: RendererDraftPrewarmPolicy;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const KIRO_CLI_HARNESS_ID = harnessIdSchema.parse("kiro-cli");
|
|
140
|
+
const OPENCLAW_HARNESS_ID = harnessIdSchema.parse("openclaw");
|
|
141
|
+
const HERMES_HARNESS_ID = harnessIdSchema.parse("hermes");
|
|
142
|
+
|
|
143
|
+
function transportModelIdForAgent(agent: RendererAgent): string | null {
|
|
144
|
+
if (agent === "pi") return PI_TRANSPORT_MODEL_ID;
|
|
145
|
+
if (agent === "claude-code") return CLAUDE_CODE_TRANSPORT_MODEL_ID;
|
|
146
|
+
if (agent === "deepseek-harness") return DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID;
|
|
147
|
+
if (agent === "opencode") return OPENCODE_TRANSPORT_MODEL_ID;
|
|
148
|
+
if (agent === "grok") return GROK_TRANSPORT_MODEL_ID;
|
|
149
|
+
if (agent === "omp") return OMP_TRANSPORT_MODEL_ID;
|
|
150
|
+
if (agent === "antigravity") return ANTIGRAVITY_TRANSPORT_MODEL_ID;
|
|
151
|
+
if (agent === "kiro-cli") return encodeHarnessPluginRoute({ harnessId: KIRO_CLI_HARNESS_ID });
|
|
152
|
+
if (agent === "openclaw") return encodeHarnessPluginRoute({ harnessId: OPENCLAW_HARNESS_ID });
|
|
153
|
+
if (agent === "hermes") return encodeHarnessPluginRoute({ harnessId: HERMES_HARNESS_ID });
|
|
154
|
+
if (agent === "qoder") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("qoder") });
|
|
155
|
+
if (agent === "workbuddy") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("workbuddy") });
|
|
156
|
+
if (agent === "zcode") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("zcode") });
|
|
157
|
+
if (agent === "trae") return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse("trae") });
|
|
158
|
+
if (agent === 'codex-harness') return encodeHarnessPluginRoute({ harnessId: harnessIdSchema.parse(agent) });
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
163
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function piTransportModelId(
|
|
167
|
+
model?: HarnessModelRef,
|
|
168
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
169
|
+
): string {
|
|
170
|
+
if (!model) {
|
|
171
|
+
if (thinkingOptionId) throw new Error("Pi transport Thinking requires a Model Ref");
|
|
172
|
+
return PI_TRANSPORT_MODEL_ID;
|
|
173
|
+
}
|
|
174
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
175
|
+
const parsedThinking = thinkingOptionId
|
|
176
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
177
|
+
: undefined;
|
|
178
|
+
return `${PI_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedThinking ? `@${parsedThinking}` : ""}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function ompTransportModelId(
|
|
182
|
+
model?: HarnessModelRef,
|
|
183
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
184
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
185
|
+
): string {
|
|
186
|
+
if (!model) {
|
|
187
|
+
if (permissionModeId || thinkingOptionId) {
|
|
188
|
+
throw new Error("OMP transport configuration requires a Model Ref");
|
|
189
|
+
}
|
|
190
|
+
return OMP_TRANSPORT_MODEL_ID;
|
|
191
|
+
}
|
|
192
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
193
|
+
const parsedPermissionMode = permissionModeId
|
|
194
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
195
|
+
: undefined;
|
|
196
|
+
const parsedThinking = thinkingOptionId
|
|
197
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
198
|
+
: undefined;
|
|
199
|
+
if (parsedPermissionMode) {
|
|
200
|
+
return `${OMP_TRANSPORT_MODEL_PREFIX}${parsedModel.id}@${parsedPermissionMode}@${parsedThinking ?? ""}`;
|
|
201
|
+
}
|
|
202
|
+
return `${OMP_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedThinking ? `@${parsedThinking}` : ""}`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function antigravityTransportModelId(
|
|
206
|
+
model?: HarnessModelRef,
|
|
207
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
208
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
209
|
+
): string {
|
|
210
|
+
if (!model) {
|
|
211
|
+
if (permissionModeId || thinkingOptionId) {
|
|
212
|
+
throw new Error("Antigravity transport configuration requires a Model Ref");
|
|
213
|
+
}
|
|
214
|
+
return ANTIGRAVITY_TRANSPORT_MODEL_ID;
|
|
215
|
+
}
|
|
216
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
217
|
+
const parsedPermission = permissionModeId
|
|
218
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
219
|
+
: undefined;
|
|
220
|
+
const parsedThinking = thinkingOptionId
|
|
221
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
222
|
+
: undefined;
|
|
223
|
+
if (parsedThinking) {
|
|
224
|
+
return `${ANTIGRAVITY_TRANSPORT_MODEL_PREFIX}${parsedModel.id}@${parsedPermission ?? ""}@${parsedThinking}`;
|
|
225
|
+
}
|
|
226
|
+
return `${ANTIGRAVITY_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedPermission ? `@${parsedPermission}` : ""}`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function openCodeTransportModelId(
|
|
230
|
+
model?: HarnessModelRef,
|
|
231
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
232
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
233
|
+
): string {
|
|
234
|
+
if (!model) {
|
|
235
|
+
if (permissionModeId || thinkingOptionId) {
|
|
236
|
+
throw new Error("OpenCode transport configuration requires a Model Ref");
|
|
237
|
+
}
|
|
238
|
+
return OPENCODE_TRANSPORT_MODEL_ID;
|
|
239
|
+
}
|
|
240
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
241
|
+
const parsedPermissionMode = permissionModeId
|
|
242
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
243
|
+
: undefined;
|
|
244
|
+
const parsedThinking = thinkingOptionId
|
|
245
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
246
|
+
: undefined;
|
|
247
|
+
if (parsedThinking) {
|
|
248
|
+
return `${OPENCODE_TRANSPORT_MODEL_PREFIX}${parsedModel.id}@${parsedPermissionMode ?? ""}@${parsedThinking}`;
|
|
249
|
+
}
|
|
250
|
+
return `${OPENCODE_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedPermissionMode ? `@${parsedPermissionMode}` : ""}`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export function decodeOpenCodeTransportModelId(value: unknown): {
|
|
254
|
+
model?: HarnessModelRef;
|
|
255
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
256
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
257
|
+
} | null {
|
|
258
|
+
if (value === OPENCODE_TRANSPORT_MODEL_ID) return {};
|
|
259
|
+
if (typeof value !== "string" || !value.startsWith(OPENCODE_TRANSPORT_MODEL_PREFIX)) return null;
|
|
260
|
+
const components = value.slice(OPENCODE_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
261
|
+
if (components.length < 1 || components.length > 3) return null;
|
|
262
|
+
const [modelId, permissionModeId, thinkingOptionId] = components;
|
|
263
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
264
|
+
if (components.length === 3 && !thinkingOptionId) return null;
|
|
265
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
266
|
+
if (!model.success) return null;
|
|
267
|
+
const permissionMode = permissionModeId
|
|
268
|
+
? harnessPermissionModeIdSchema.safeParse(permissionModeId)
|
|
269
|
+
: null;
|
|
270
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
271
|
+
const thinking = thinkingOptionId
|
|
272
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
273
|
+
: null;
|
|
274
|
+
if (thinking && !thinking.success) return null;
|
|
275
|
+
return {
|
|
276
|
+
model: model.data,
|
|
277
|
+
...(permissionMode?.success ? { permissionModeId: permissionMode.data } : {}),
|
|
278
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function isOpenCodeTransportModelId(value: unknown): value is string {
|
|
283
|
+
return decodeOpenCodeTransportModelId(value) !== null;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export function claudeTransportModelId(
|
|
287
|
+
model?: HarnessModelRef,
|
|
288
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
289
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
290
|
+
): string {
|
|
291
|
+
if (!model) {
|
|
292
|
+
if (permissionModeId || thinkingOptionId) {
|
|
293
|
+
throw new Error("Claude Code transport configuration requires a Model Ref");
|
|
294
|
+
}
|
|
295
|
+
return CLAUDE_CODE_TRANSPORT_MODEL_ID;
|
|
296
|
+
}
|
|
297
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
298
|
+
const parsedPermissionMode = permissionModeId
|
|
299
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
300
|
+
: undefined;
|
|
301
|
+
const parsedThinkingOption = thinkingOptionId
|
|
302
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
303
|
+
: undefined;
|
|
304
|
+
if (parsedThinkingOption) {
|
|
305
|
+
return `${CLAUDE_CODE_TRANSPORT_MODEL_PREFIX}${parsedModel.id}@${parsedPermissionMode ?? ""}@${parsedThinkingOption}`;
|
|
306
|
+
}
|
|
307
|
+
return `${CLAUDE_CODE_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedPermissionMode ? `@${parsedPermissionMode}` : ""}`;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export function grokTransportModelId(
|
|
311
|
+
model?: HarnessModelRef,
|
|
312
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
313
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
314
|
+
): string {
|
|
315
|
+
if (!model) {
|
|
316
|
+
if (permissionModeId || thinkingOptionId) {
|
|
317
|
+
throw new Error("Grok transport configuration requires a Model Ref");
|
|
318
|
+
}
|
|
319
|
+
return GROK_TRANSPORT_MODEL_ID;
|
|
320
|
+
}
|
|
321
|
+
const parsedModel = harnessModelRefSchema.parse(model);
|
|
322
|
+
const parsedPermissionMode = permissionModeId
|
|
323
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
324
|
+
: undefined;
|
|
325
|
+
const parsedThinking = thinkingOptionId
|
|
326
|
+
? harnessThinkingOptionIdSchema.parse(thinkingOptionId)
|
|
327
|
+
: undefined;
|
|
328
|
+
if (parsedThinking) {
|
|
329
|
+
return `${GROK_TRANSPORT_MODEL_PREFIX}${parsedModel.id}@${parsedPermissionMode ?? ""}@${parsedThinking}`;
|
|
330
|
+
}
|
|
331
|
+
return `${GROK_TRANSPORT_MODEL_PREFIX}${parsedModel.id}${parsedPermissionMode ? `@${parsedPermissionMode}` : ""}`;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export function decodeGrokTransportModelId(value: unknown): {
|
|
335
|
+
model?: HarnessModelRef;
|
|
336
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
337
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
338
|
+
} | null {
|
|
339
|
+
if (value === GROK_TRANSPORT_MODEL_ID) return {};
|
|
340
|
+
if (typeof value !== "string" || !value.startsWith(GROK_TRANSPORT_MODEL_PREFIX)) return null;
|
|
341
|
+
const components = value.slice(GROK_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
342
|
+
if (components.length < 1 || components.length > 3) return null;
|
|
343
|
+
const [modelId, permissionModeId, thinkingOptionId] = components;
|
|
344
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
345
|
+
if (components.length === 3 && !thinkingOptionId) return null;
|
|
346
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
347
|
+
if (!model.success) return null;
|
|
348
|
+
const permissionMode = permissionModeId
|
|
349
|
+
? harnessPermissionModeIdSchema.safeParse(permissionModeId)
|
|
350
|
+
: null;
|
|
351
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
352
|
+
const thinking = thinkingOptionId
|
|
353
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
354
|
+
: null;
|
|
355
|
+
if (thinking && !thinking.success) return null;
|
|
356
|
+
return {
|
|
357
|
+
model: model.data,
|
|
358
|
+
...(permissionMode?.success ? { permissionModeId: permissionMode.data } : {}),
|
|
359
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export function decodeClaudeTransportModelId(value: unknown): {
|
|
364
|
+
model?: HarnessModelRef;
|
|
365
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
366
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
367
|
+
} | null {
|
|
368
|
+
if (value === CLAUDE_CODE_TRANSPORT_MODEL_ID) return {};
|
|
369
|
+
if (typeof value !== "string" || !value.startsWith(CLAUDE_CODE_TRANSPORT_MODEL_PREFIX)) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
const components = value.slice(CLAUDE_CODE_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
373
|
+
if (components.length < 1 || components.length > 3) return null;
|
|
374
|
+
const [modelId, permissionModeId, thinkingOptionId] = components;
|
|
375
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
376
|
+
if (components.length === 3 && !thinkingOptionId) return null;
|
|
377
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
378
|
+
if (!model.success) return null;
|
|
379
|
+
const permissionMode = permissionModeId
|
|
380
|
+
? harnessPermissionModeIdSchema.safeParse(permissionModeId)
|
|
381
|
+
: null;
|
|
382
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
383
|
+
const thinking = thinkingOptionId
|
|
384
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
385
|
+
: null;
|
|
386
|
+
if (thinking && !thinking.success) return null;
|
|
387
|
+
return {
|
|
388
|
+
model: model.data,
|
|
389
|
+
...(permissionMode?.success ? { permissionModeId: permissionMode.data } : {}),
|
|
390
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export function isGrokTransportModelId(value: unknown): value is string {
|
|
395
|
+
return decodeGrokTransportModelId(value) !== null;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export function isClaudeTransportModelId(value: unknown): value is string {
|
|
399
|
+
return decodeClaudeTransportModelId(value) !== null;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export function deepSeekHarnessTransportModelId(
|
|
403
|
+
model?: HarnessModelRef,
|
|
404
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
405
|
+
): string {
|
|
406
|
+
if (!model) {
|
|
407
|
+
if (permissionModeId) {
|
|
408
|
+
throw new Error("DeepSeek Harness transport Permission Mode requires a Model Ref");
|
|
409
|
+
}
|
|
410
|
+
return DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID;
|
|
411
|
+
}
|
|
412
|
+
const parsedPermissionModeId = permissionModeId
|
|
413
|
+
? harnessPermissionModeIdSchema.parse(permissionModeId)
|
|
414
|
+
: undefined;
|
|
415
|
+
return `${DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX}${harnessModelRefSchema.parse(model).id}${parsedPermissionModeId ? `@${parsedPermissionModeId}` : ""}`;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function decodeDeepSeekHarnessTransportModelId(value: unknown): {
|
|
419
|
+
model?: HarnessModelRef;
|
|
420
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
421
|
+
} | null {
|
|
422
|
+
if (value === DEEPSEEK_HARNESS_TRANSPORT_MODEL_ID) return {};
|
|
423
|
+
if (typeof value !== "string" || !value.startsWith(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX)) {
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
const components = value.slice(DEEPSEEK_HARNESS_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
427
|
+
if (components.length < 1 || components.length > 2) return null;
|
|
428
|
+
const [modelId, permissionModeId] = components;
|
|
429
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
430
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
431
|
+
if (!model.success) return null;
|
|
432
|
+
const permissionMode = permissionModeId
|
|
433
|
+
? harnessPermissionModeIdSchema.safeParse(permissionModeId)
|
|
434
|
+
: null;
|
|
435
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
436
|
+
return {
|
|
437
|
+
model: model.data,
|
|
438
|
+
...(permissionMode?.success ? { permissionModeId: permissionMode.data } : {}),
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export function isDeepSeekHarnessTransportModelId(value: unknown): value is string {
|
|
443
|
+
return decodeDeepSeekHarnessTransportModelId(value) !== null;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export function decodePiTransportModelId(value: unknown): {
|
|
447
|
+
model?: HarnessModelRef;
|
|
448
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
449
|
+
} | null {
|
|
450
|
+
if (value === PI_TRANSPORT_MODEL_ID) return {};
|
|
451
|
+
if (typeof value !== "string" || !value.startsWith(PI_TRANSPORT_MODEL_PREFIX)) return null;
|
|
452
|
+
const components = value.slice(PI_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
453
|
+
if (components.length < 1 || components.length > 2) return null;
|
|
454
|
+
const [modelId, thinkingOptionId] = components;
|
|
455
|
+
if (components.length === 2 && !thinkingOptionId) return null;
|
|
456
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
457
|
+
if (!model.success) return null;
|
|
458
|
+
const thinking = thinkingOptionId
|
|
459
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
460
|
+
: null;
|
|
461
|
+
if (thinking && !thinking.success) return null;
|
|
462
|
+
return {
|
|
463
|
+
model: model.data,
|
|
464
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export function isPiTransportModelId(value: unknown): value is string {
|
|
469
|
+
return decodePiTransportModelId(value) !== null;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export function decodeOmpTransportModelId(value: unknown): {
|
|
473
|
+
model?: HarnessModelRef;
|
|
474
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
475
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
476
|
+
} | null {
|
|
477
|
+
if (value === OMP_TRANSPORT_MODEL_ID) return {};
|
|
478
|
+
if (typeof value !== "string" || !value.startsWith(OMP_TRANSPORT_MODEL_PREFIX)) return null;
|
|
479
|
+
const components = value.slice(OMP_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
480
|
+
if (components.length < 1 || components.length > 3) return null;
|
|
481
|
+
const [modelId, permissionOrThinkingId, thinkingOptionId] = components;
|
|
482
|
+
if (components.length === 2 && !permissionOrThinkingId) return null;
|
|
483
|
+
if (components.length === 3 && !permissionOrThinkingId) return null;
|
|
484
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
485
|
+
if (!model.success) return null;
|
|
486
|
+
const permissionMode =
|
|
487
|
+
components.length === 3
|
|
488
|
+
? harnessPermissionModeIdSchema.safeParse(permissionOrThinkingId)
|
|
489
|
+
: null;
|
|
490
|
+
if (permissionMode && !permissionMode.success) return null;
|
|
491
|
+
const thinking =
|
|
492
|
+
components.length === 2
|
|
493
|
+
? harnessThinkingOptionIdSchema.safeParse(permissionOrThinkingId)
|
|
494
|
+
: thinkingOptionId
|
|
495
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
496
|
+
: null;
|
|
497
|
+
if (thinking && !thinking.success) return null;
|
|
498
|
+
return {
|
|
499
|
+
model: model.data,
|
|
500
|
+
...(permissionMode?.success ? { permissionModeId: permissionMode.data } : {}),
|
|
501
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
export function isOmpTransportModelId(value: unknown): value is string {
|
|
506
|
+
return decodeOmpTransportModelId(value) !== null;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
export function decodeAntigravityTransportModelId(value: unknown): {
|
|
510
|
+
model?: HarnessModelRef;
|
|
511
|
+
permissionModeId?: HarnessPermissionModeId;
|
|
512
|
+
thinkingOptionId?: HarnessThinkingOptionId;
|
|
513
|
+
} | null {
|
|
514
|
+
if (value === ANTIGRAVITY_TRANSPORT_MODEL_ID) return {};
|
|
515
|
+
if (typeof value !== "string" || !value.startsWith(ANTIGRAVITY_TRANSPORT_MODEL_PREFIX)) {
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
const components = value.slice(ANTIGRAVITY_TRANSPORT_MODEL_PREFIX.length).split("@");
|
|
519
|
+
if (components.length < 1 || components.length > 3) return null;
|
|
520
|
+
const [modelId, permissionModeId, thinkingOptionId] = components;
|
|
521
|
+
if (components.length === 2 && !permissionModeId) return null;
|
|
522
|
+
if (components.length === 3 && !thinkingOptionId) return null;
|
|
523
|
+
const model = harnessModelRefSchema.safeParse({ id: modelId });
|
|
524
|
+
const permission = permissionModeId
|
|
525
|
+
? harnessPermissionModeIdSchema.safeParse(permissionModeId)
|
|
526
|
+
: null;
|
|
527
|
+
if (!model.success || (permission && !permission.success)) return null;
|
|
528
|
+
const thinking = thinkingOptionId
|
|
529
|
+
? harnessThinkingOptionIdSchema.safeParse(thinkingOptionId)
|
|
530
|
+
: null;
|
|
531
|
+
if (thinking && !thinking.success) return null;
|
|
532
|
+
return {
|
|
533
|
+
model: model.data,
|
|
534
|
+
...(permission?.success ? { permissionModeId: permission.data } : {}),
|
|
535
|
+
...(thinking?.success ? { thinkingOptionId: thinking.data } : {}),
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
export function isAntigravityTransportModelId(value: unknown): value is string {
|
|
540
|
+
return decodeAntigravityTransportModelId(value) !== null;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
export function threadIdFromComposerModelTarget(
|
|
544
|
+
target: readonly unknown[] | null,
|
|
545
|
+
): HostThreadId | null {
|
|
546
|
+
if (
|
|
547
|
+
target?.[0] !== "conversation" ||
|
|
548
|
+
typeof target[1] !== "string" ||
|
|
549
|
+
target[1].trim().length === 0
|
|
550
|
+
) {
|
|
551
|
+
return null;
|
|
552
|
+
}
|
|
553
|
+
return hostThreadIdSchema.parse(target[1]);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function isCurrentRequestBridge(value: unknown): value is PrewarmTarget {
|
|
557
|
+
return (
|
|
558
|
+
isRecord(value) &&
|
|
559
|
+
typeof value.hostId === "string" &&
|
|
560
|
+
value.hostId.length > 0 &&
|
|
561
|
+
typeof value.sendRequest === "function" &&
|
|
562
|
+
typeof value.prewarmThreadStart === "function" &&
|
|
563
|
+
typeof value.enqueueRequest === "function"
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export function findActivePrewarmTargets(root: ParentNode): PrewarmTarget[] {
|
|
568
|
+
const editor = root.querySelector<HTMLElement>(
|
|
569
|
+
'[data-codex-composer], [contenteditable="true"][role="textbox"]',
|
|
570
|
+
);
|
|
571
|
+
if (!editor) return [];
|
|
572
|
+
|
|
573
|
+
let fiberElement: Element | undefined = [editor, ...editor.querySelectorAll("*")].find(
|
|
574
|
+
(element) =>
|
|
575
|
+
Object.getOwnPropertyNames(element).some((name) => name.startsWith("__reactFiber$")),
|
|
576
|
+
);
|
|
577
|
+
for (let ancestor = editor.parentElement; !fiberElement && ancestor;) {
|
|
578
|
+
if (Object.getOwnPropertyNames(ancestor).some((name) => name.startsWith("__reactFiber$"))) {
|
|
579
|
+
fiberElement = ancestor;
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
ancestor = ancestor.parentElement;
|
|
583
|
+
}
|
|
584
|
+
const fiberName = fiberElement
|
|
585
|
+
? Object.getOwnPropertyNames(fiberElement).find((name) => name.startsWith("__reactFiber$"))
|
|
586
|
+
: null;
|
|
587
|
+
const firstFiber =
|
|
588
|
+
fiberElement && fiberName
|
|
589
|
+
? Object.getOwnPropertyDescriptor(fiberElement, fiberName)?.value
|
|
590
|
+
: null;
|
|
591
|
+
if ((typeof firstFiber !== "object" && typeof firstFiber !== "function") || !firstFiber) {
|
|
592
|
+
return [];
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const targets = new Set<PrewarmTarget>();
|
|
596
|
+
let fiber = firstFiber as { return?: unknown; memoizedState?: unknown };
|
|
597
|
+
for (let depth = 0; depth < 200; depth += 1) {
|
|
598
|
+
let hook = fiber.memoizedState as { memoizedState?: unknown; next?: unknown } | null;
|
|
599
|
+
for (let hookIndex = 0; hook && hookIndex < 100; hookIndex += 1) {
|
|
600
|
+
const hookState = hook.memoizedState;
|
|
601
|
+
if (isRecord(hookState)) {
|
|
602
|
+
const requestClient = hookState.requestClient;
|
|
603
|
+
const bridge = isCurrentRequestBridge(requestClient)
|
|
604
|
+
? requestClient
|
|
605
|
+
: isCurrentRequestBridge(hookState)
|
|
606
|
+
? hookState
|
|
607
|
+
: null;
|
|
608
|
+
if (bridge) {
|
|
609
|
+
targets.add(typeof hookState.sendRequest === "function" ? hookState : bridge);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
hook =
|
|
613
|
+
typeof hook.next === "object" && hook.next !== null
|
|
614
|
+
? (hook.next as { memoizedState?: unknown; next?: unknown })
|
|
615
|
+
: null;
|
|
616
|
+
}
|
|
617
|
+
const parent = fiber.return;
|
|
618
|
+
if ((typeof parent !== "object" && typeof parent !== "function") || parent === null) break;
|
|
619
|
+
fiber = parent as typeof fiber;
|
|
620
|
+
}
|
|
621
|
+
return [...targets];
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function findComposerFiber(composer?: Element): {
|
|
625
|
+
return?: unknown;
|
|
626
|
+
updateQueue?: unknown;
|
|
627
|
+
memoizedProps?: unknown;
|
|
628
|
+
} | null {
|
|
629
|
+
const selector = '[data-codex-composer], [contenteditable="true"][role="textbox"]';
|
|
630
|
+
const editor =
|
|
631
|
+
composer?.matches(selector) === true
|
|
632
|
+
? composer
|
|
633
|
+
: (composer ?? document).querySelector<HTMLElement>(selector);
|
|
634
|
+
let fiberElement: Element | null = editor;
|
|
635
|
+
let fiberName: string | undefined;
|
|
636
|
+
for (let depth = 0; fiberElement && depth < 12; depth += 1) {
|
|
637
|
+
fiberName = Object.getOwnPropertyNames(fiberElement).find((name) =>
|
|
638
|
+
name.startsWith("__reactFiber$"),
|
|
639
|
+
);
|
|
640
|
+
if (fiberName) break;
|
|
641
|
+
fiberElement = fiberElement.parentElement;
|
|
642
|
+
}
|
|
643
|
+
return fiberElement && fiberName
|
|
644
|
+
? (Object.getOwnPropertyDescriptor(fiberElement, fiberName)?.value as {
|
|
645
|
+
return?: unknown;
|
|
646
|
+
updateQueue?: unknown;
|
|
647
|
+
memoizedProps?: unknown;
|
|
648
|
+
} | null)
|
|
649
|
+
: null;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function findComposerConversationThreadId(composer?: Element): HostThreadId | null | undefined {
|
|
653
|
+
let threadId: HostThreadId | undefined;
|
|
654
|
+
let fiber = findComposerFiber(composer);
|
|
655
|
+
for (let depth = 0; fiber && depth < 120; depth += 1) {
|
|
656
|
+
const props = fiber.memoizedProps;
|
|
657
|
+
if (isRecord(props) && "conversationId" in props && props.conversationId != null) {
|
|
658
|
+
const candidate = hostThreadIdSchema.safeParse(props.conversationId);
|
|
659
|
+
if (!candidate.success || (threadId !== undefined && threadId !== candidate.data)) {
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
threadId = candidate.data;
|
|
663
|
+
}
|
|
664
|
+
const parent = fiber.return;
|
|
665
|
+
fiber =
|
|
666
|
+
(typeof parent === "object" || typeof parent === "function") && parent !== null
|
|
667
|
+
? (parent as typeof fiber)
|
|
668
|
+
: null;
|
|
669
|
+
}
|
|
670
|
+
return threadId;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function isCurrentDraftWrapper(value: unknown): value is readonly unknown[] {
|
|
674
|
+
if (
|
|
675
|
+
!Array.isArray(value) ||
|
|
676
|
+
value.length !== 7 ||
|
|
677
|
+
value[3] !== value[5] ||
|
|
678
|
+
value[3] !== value[6] ||
|
|
679
|
+
!isRecord(value[3]) ||
|
|
680
|
+
typeof value[3].get !== "function" ||
|
|
681
|
+
(typeof value[2] !== "string" && value[2] !== null)
|
|
682
|
+
) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
try {
|
|
686
|
+
const draft = value[3].get();
|
|
687
|
+
return isRecord(draft) && "modelSettings" in draft && "isManuallyChanged" in draft;
|
|
688
|
+
} catch {
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
type ComposerDomIdentity =
|
|
694
|
+
| { kind: "unsupported" }
|
|
695
|
+
| { kind: "draft" }
|
|
696
|
+
| { kind: "conversation"; threadId: HostThreadId }
|
|
697
|
+
| { kind: "ambiguous" };
|
|
698
|
+
|
|
699
|
+
function findComposerDomIdentity(composer: Element): ComposerDomIdentity {
|
|
700
|
+
// Codex 26.818 renders one direct portal marker inside the Composer root. The
|
|
701
|
+
// conversation attribute is omitted for an unsubmitted client-new-thread and
|
|
702
|
+
// populated once that draft is bound to a real Thread. Prefer this scoped DOM
|
|
703
|
+
// contract over arbitrary ancestor props: remote project pages can carry a
|
|
704
|
+
// background/prewarm conversationId above an otherwise-new Composer.
|
|
705
|
+
const children = Array.from(composer.children ?? []);
|
|
706
|
+
const portals = children.filter((child) => child.hasAttribute("data-above-composer-portal"));
|
|
707
|
+
if (portals.length === 0) return { kind: "unsupported" };
|
|
708
|
+
if (portals.length !== 1) return { kind: "ambiguous" };
|
|
709
|
+
|
|
710
|
+
const value = portals[0]?.getAttribute("data-above-composer-conversation-id");
|
|
711
|
+
if (value === null) return { kind: "draft" };
|
|
712
|
+
const candidate = hostThreadIdSchema.safeParse(value);
|
|
713
|
+
return candidate.success
|
|
714
|
+
? { kind: "conversation", threadId: candidate.data }
|
|
715
|
+
: { kind: "ambiguous" };
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
function findComposerDraftIds(composer: Element): Set<string> {
|
|
719
|
+
const draftIds = new Set<string>();
|
|
720
|
+
let fiber = findComposerFiber(composer);
|
|
721
|
+
for (let depth = 0; fiber && depth < 120; depth += 1) {
|
|
722
|
+
const updateQueue = fiber.updateQueue;
|
|
723
|
+
const memoCache = isRecord(updateQueue) ? updateQueue.memoCache : null;
|
|
724
|
+
const data = isRecord(memoCache) && Array.isArray(memoCache.data) ? memoCache.data : [];
|
|
725
|
+
for (const value of data) {
|
|
726
|
+
if (
|
|
727
|
+
isCurrentDraftWrapper(value) &&
|
|
728
|
+
typeof value[2] === "string" &&
|
|
729
|
+
value[2].startsWith("client-new-thread:")
|
|
730
|
+
) {
|
|
731
|
+
draftIds.add(value[2]);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
const parent = fiber.return;
|
|
735
|
+
fiber =
|
|
736
|
+
(typeof parent === "object" || typeof parent === "function") && parent !== null
|
|
737
|
+
? (parent as typeof fiber)
|
|
738
|
+
: null;
|
|
739
|
+
}
|
|
740
|
+
return draftIds;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
export function findComposerModelTarget(composer: Element): readonly unknown[] | null {
|
|
744
|
+
const draftIds = findComposerDraftIds(composer);
|
|
745
|
+
const domIdentity = findComposerDomIdentity(composer);
|
|
746
|
+
if (domIdentity.kind === "ambiguous") return null;
|
|
747
|
+
if (domIdentity.kind === "conversation") {
|
|
748
|
+
return ["conversation", domIdentity.threadId];
|
|
749
|
+
}
|
|
750
|
+
if (domIdentity.kind === "draft") {
|
|
751
|
+
return draftIds.size === 1 ? ["default", draftIds.values().next().value] : null;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Older supported Desktop builds do not expose the scoped portal marker.
|
|
755
|
+
// Retain their reviewed Fiber fallback, including fail-closed ambiguity.
|
|
756
|
+
const conversationThreadId = findComposerConversationThreadId(composer);
|
|
757
|
+
if (conversationThreadId === null) return null;
|
|
758
|
+
if (conversationThreadId !== undefined) return ["conversation", conversationThreadId];
|
|
759
|
+
|
|
760
|
+
if (draftIds.size !== 1) return null;
|
|
761
|
+
return ["default", draftIds.values().next().value];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
export type RendererComposerModelContractState = "draft" | "conversation" | "missing" | "ambiguous";
|
|
765
|
+
|
|
766
|
+
export function inspectComposerModelContract(
|
|
767
|
+
composer: Element,
|
|
768
|
+
): RendererComposerModelContractState {
|
|
769
|
+
const target = findComposerModelTarget(composer);
|
|
770
|
+
if (target?.[0] === "default") return "draft";
|
|
771
|
+
if (target?.[0] === "conversation") return "conversation";
|
|
772
|
+
const domIdentity = findComposerDomIdentity(composer);
|
|
773
|
+
if (domIdentity.kind === "ambiguous") return "ambiguous";
|
|
774
|
+
return "missing";
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export function isMainProcessTitlePolicyReady(value: unknown): boolean {
|
|
778
|
+
return isRecord(value) && value.state === "ready";
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
export function isDraftPrewarmPolicyReady(value: unknown): value is RendererDraftPrewarmPolicy {
|
|
782
|
+
return (
|
|
783
|
+
isRecord(value) &&
|
|
784
|
+
value.state === "ready" &&
|
|
785
|
+
typeof value.hostId === "string" &&
|
|
786
|
+
value.hostId.length > 0 &&
|
|
787
|
+
typeof value.select === "function" &&
|
|
788
|
+
typeof value.clear === "function"
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
export function activeRendererDraftPrewarmPolicy(
|
|
793
|
+
policy: unknown,
|
|
794
|
+
targets: readonly PrewarmTarget[],
|
|
795
|
+
): RendererDraftPrewarmPolicy | null {
|
|
796
|
+
if (!isDraftPrewarmPolicyReady(policy)) return null;
|
|
797
|
+
return activeRendererDraftPrewarmTargets(policy, targets) ? policy : null;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function prewarmTargetHostId(target: PrewarmTarget): string | null {
|
|
801
|
+
const bridge = target.requestClient ?? target;
|
|
802
|
+
const hostId = target.getHostId?.() ?? bridge.hostId;
|
|
803
|
+
return typeof hostId === "string" && hostId.length > 0 ? hostId : null;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
function isRendererRequestTarget(value: unknown): value is PrewarmTarget {
|
|
807
|
+
if (!isRecord(value) || typeof value.sendRequest !== "function") return false;
|
|
808
|
+
return isCurrentRequestBridge(value.requestClient ?? value);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function hasPolicyRequestTarget(policy: RendererDraftPrewarmPolicy): boolean {
|
|
812
|
+
return "requestTarget" in policy;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
function exactRendererRequestTarget(
|
|
816
|
+
policy: RendererDraftPrewarmPolicy,
|
|
817
|
+
): readonly PrewarmTarget[] | null {
|
|
818
|
+
if (typeof policy.requestTarget !== "function") return null;
|
|
819
|
+
try {
|
|
820
|
+
const target = policy.requestTarget();
|
|
821
|
+
if (!isRendererRequestTarget(target) || prewarmTargetHostId(target) !== policy.hostId) {
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
return [target];
|
|
825
|
+
} catch {
|
|
826
|
+
return null;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
export function rendererRequestTargetsForHost(
|
|
831
|
+
targets: readonly PrewarmTarget[],
|
|
832
|
+
hostId: string,
|
|
833
|
+
): readonly PrewarmTarget[] | null {
|
|
834
|
+
const matching = targets.filter((target) => prewarmTargetHostId(target) === hostId);
|
|
835
|
+
return matching.length === 1 ? matching : null;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
function activeRendererDraftPrewarmTargets(
|
|
839
|
+
policy: unknown,
|
|
840
|
+
targets: readonly PrewarmTarget[],
|
|
841
|
+
): readonly PrewarmTarget[] | null {
|
|
842
|
+
if (!isDraftPrewarmPolicyReady(policy)) return null;
|
|
843
|
+
if (hasPolicyRequestTarget(policy)) return exactRendererRequestTarget(policy);
|
|
844
|
+
return rendererRequestTargetsForHost(targets, policy.hostId);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
export interface RendererRequestRoute {
|
|
848
|
+
readonly policy: RendererDraftPrewarmPolicy;
|
|
849
|
+
readonly targets: readonly PrewarmTarget[];
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
export function resolveRendererRequestRoute(
|
|
853
|
+
policy: unknown,
|
|
854
|
+
discoveredTargets: readonly PrewarmTarget[],
|
|
855
|
+
previous: RendererRequestRoute | null,
|
|
856
|
+
): RendererRequestRoute | null {
|
|
857
|
+
const activeTargets = activeRendererDraftPrewarmTargets(policy, discoveredTargets);
|
|
858
|
+
if (isDraftPrewarmPolicyReady(policy) && activeTargets) {
|
|
859
|
+
return { policy, targets: activeTargets };
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) return null;
|
|
863
|
+
|
|
864
|
+
// Composer replacement and settings overlays can briefly remove the only
|
|
865
|
+
// Fiber path that exposes the request manager. Retain the confirmed route
|
|
866
|
+
// only while discovery is empty and the installed policy object is unchanged.
|
|
867
|
+
// Positive discovery for another Host invalidates the cache immediately;
|
|
868
|
+
// policy identity also prevents reuse across reconnects or same-id switches.
|
|
869
|
+
return discoveredTargets.length === 0 &&
|
|
870
|
+
isDraftPrewarmPolicyReady(policy) &&
|
|
871
|
+
previous?.policy === policy
|
|
872
|
+
? previous
|
|
873
|
+
: null;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
export function createRendererRequestRouteResolver(
|
|
877
|
+
readPolicy: () => unknown,
|
|
878
|
+
discoverTargets: () => readonly PrewarmTarget[],
|
|
879
|
+
): {
|
|
880
|
+
resolve(): RendererRequestRoute | null;
|
|
881
|
+
clear(): void;
|
|
882
|
+
} {
|
|
883
|
+
let route: RendererRequestRoute | null = null;
|
|
884
|
+
return {
|
|
885
|
+
resolve() {
|
|
886
|
+
// Persist null invalidations too, otherwise a later empty discovery gap
|
|
887
|
+
// could revive a request manager that belonged to the previous Host.
|
|
888
|
+
const policy = readPolicy();
|
|
889
|
+
const discoveredTargets =
|
|
890
|
+
isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)
|
|
891
|
+
? []
|
|
892
|
+
: discoverTargets();
|
|
893
|
+
route = resolveRendererRequestRoute(policy, discoveredTargets, route);
|
|
894
|
+
return route;
|
|
895
|
+
},
|
|
896
|
+
clear() {
|
|
897
|
+
route = null;
|
|
898
|
+
},
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
export async function waitForRendererDraftPrewarmPolicy(
|
|
903
|
+
target: RendererDraftPrewarmPolicyTarget,
|
|
904
|
+
): Promise<RendererDraftPrewarmPolicy> {
|
|
905
|
+
const deadline = Date.now() + DRAFT_PREWARM_POLICY_WAIT_TIMEOUT_MS;
|
|
906
|
+
while (true) {
|
|
907
|
+
const policy = target.__codexhostDraftPrewarmPolicyV1;
|
|
908
|
+
if (isDraftPrewarmPolicyReady(policy)) return policy;
|
|
909
|
+
const remaining = deadline - Date.now();
|
|
910
|
+
if (remaining <= 0) throw new Error("Renderer draft prewarm policy is unavailable");
|
|
911
|
+
await new Promise<void>((resolve) => {
|
|
912
|
+
target.setTimeout(resolve, Math.min(DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS, remaining));
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
export function modelSelectionForAgent(
|
|
918
|
+
officialSelection: ModelPowerSelection | null,
|
|
919
|
+
reasoningEffort: unknown,
|
|
920
|
+
agent: RendererAgent,
|
|
921
|
+
model?: HarnessModelRef,
|
|
922
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
923
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
924
|
+
): ModelPowerSelection | null {
|
|
925
|
+
const transportModelId =
|
|
926
|
+
agent === "pi"
|
|
927
|
+
? piTransportModelId(model, thinkingOptionId)
|
|
928
|
+
: agent === "claude-code"
|
|
929
|
+
? claudeTransportModelId(model, permissionModeId, thinkingOptionId)
|
|
930
|
+
: agent === "deepseek-harness"
|
|
931
|
+
? deepSeekHarnessTransportModelId(model, permissionModeId)
|
|
932
|
+
: agent === "opencode"
|
|
933
|
+
? openCodeTransportModelId(model, permissionModeId, thinkingOptionId)
|
|
934
|
+
: agent === "grok"
|
|
935
|
+
? grokTransportModelId(model, permissionModeId, thinkingOptionId)
|
|
936
|
+
: agent === "omp"
|
|
937
|
+
? ompTransportModelId(model, thinkingOptionId, permissionModeId)
|
|
938
|
+
: agent === "antigravity"
|
|
939
|
+
? antigravityTransportModelId(model, permissionModeId, thinkingOptionId)
|
|
940
|
+
: agent === "kiro-cli"
|
|
941
|
+
? encodeHarnessPluginRoute({
|
|
942
|
+
harnessId: KIRO_CLI_HARNESS_ID,
|
|
943
|
+
...(model ? { model } : {}),
|
|
944
|
+
...(thinkingOptionId ? { thinkingOptionId } : {}),
|
|
945
|
+
...(permissionModeId ? { permissionModeId } : {}),
|
|
946
|
+
})
|
|
947
|
+
: agent === "openclaw" || agent === "hermes" || agent === 'codex-harness' || agent === 'qoder' || agent === 'workbuddy' || agent === 'zcode' || agent === 'trae'
|
|
948
|
+
? encodeHarnessPluginRoute({
|
|
949
|
+
harnessId: harnessIdSchema.parse(agent),
|
|
950
|
+
...(model ? { model } : {}),
|
|
951
|
+
...(thinkingOptionId ? { thinkingOptionId } : {}),
|
|
952
|
+
...(permissionModeId ? { permissionModeId } : {}),
|
|
953
|
+
})
|
|
954
|
+
: transportModelIdForAgent(agent);
|
|
955
|
+
return transportModelId ? { model: transportModelId, reasoningEffort } : officialSelection;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
export function installCurrentRendererAdapter(): {
|
|
959
|
+
status: RendererAdapterStatus;
|
|
960
|
+
modelControl: RendererModelClient | null;
|
|
961
|
+
applyAgent(
|
|
962
|
+
agent: RendererAgent,
|
|
963
|
+
model?: HarnessModelRef,
|
|
964
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
965
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
966
|
+
composer?: Element,
|
|
967
|
+
): boolean;
|
|
968
|
+
dispose(): void;
|
|
969
|
+
} {
|
|
970
|
+
let disposed = false;
|
|
971
|
+
let modelUpdates = 0;
|
|
972
|
+
const liveStatus: RendererAdapterStatus = {
|
|
973
|
+
state: "installing",
|
|
974
|
+
reason: "installing",
|
|
975
|
+
modelUpdates: 0,
|
|
976
|
+
hook: null,
|
|
977
|
+
};
|
|
978
|
+
const updateStatus = (
|
|
979
|
+
state: RendererAdapterState,
|
|
980
|
+
reason: RendererAdapterStatus["reason"],
|
|
981
|
+
hook: RendererAdapterStatus["hook"],
|
|
982
|
+
): void => {
|
|
983
|
+
liveStatus.modelUpdates = modelUpdates;
|
|
984
|
+
transitionRendererAdapterStatus(liveStatus, { state, reason, hook }, () => {
|
|
985
|
+
window.dispatchEvent(new CustomEvent("codexhost:renderer-adapter-status"));
|
|
986
|
+
});
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
const usageSubscription = createThreadUsageSubscriptionRelay();
|
|
990
|
+
const requestRouteResolver = createRendererRequestRouteResolver(
|
|
991
|
+
() => window.__codexhostDraftPrewarmPolicyV1,
|
|
992
|
+
() => findActivePrewarmTargets(document),
|
|
993
|
+
);
|
|
994
|
+
const clientsByTarget = new WeakMap<
|
|
995
|
+
PrewarmTarget,
|
|
996
|
+
{
|
|
997
|
+
client: RendererModelClient;
|
|
998
|
+
policy: RendererDraftPrewarmPolicy | null;
|
|
999
|
+
requestClient: PrewarmTarget["requestClient"];
|
|
1000
|
+
}
|
|
1001
|
+
>();
|
|
1002
|
+
const steeringCleanups = new Set<() => void>();
|
|
1003
|
+
const modelClientForTargets = (
|
|
1004
|
+
targets: readonly PrewarmTarget[],
|
|
1005
|
+
policy: RendererDraftPrewarmPolicy | null = null,
|
|
1006
|
+
): RendererModelClient | null => {
|
|
1007
|
+
const target = targets[0];
|
|
1008
|
+
if (targets.length !== 1 || !target) return null;
|
|
1009
|
+
const cached = clientsByTarget.get(target);
|
|
1010
|
+
if (cached?.policy === policy && cached.requestClient === target.requestClient)
|
|
1011
|
+
return cached.client;
|
|
1012
|
+
const client = createRendererModelClient([target]);
|
|
1013
|
+
if (client) {
|
|
1014
|
+
// A new connection must not inherit unsupported-method observations.
|
|
1015
|
+
// Steering belongs to the manager, so do not install duplicate hooks.
|
|
1016
|
+
if (!cached) {
|
|
1017
|
+
const cleanup = installRendererExternalSteering(target);
|
|
1018
|
+
if (cleanup) steeringCleanups.add(cleanup);
|
|
1019
|
+
}
|
|
1020
|
+
clientsByTarget.set(target, { client, policy, requestClient: target.requestClient });
|
|
1021
|
+
}
|
|
1022
|
+
return client;
|
|
1023
|
+
};
|
|
1024
|
+
let activeRoutePolicy: RendererDraftPrewarmPolicy | null = null;
|
|
1025
|
+
let activeRouteClient: RendererModelClient | null = null;
|
|
1026
|
+
const syncActiveRoute = (route: RendererRequestRoute | null): RendererModelClient | null => {
|
|
1027
|
+
const policy = route?.policy ?? null;
|
|
1028
|
+
const client = route ? modelClientForTargets(route.targets, route.policy) : null;
|
|
1029
|
+
if (activeRoutePolicy === policy && activeRouteClient === client) return client;
|
|
1030
|
+
activeRoutePolicy = policy;
|
|
1031
|
+
activeRouteClient = client;
|
|
1032
|
+
return client;
|
|
1033
|
+
};
|
|
1034
|
+
const currentRequestRoute = (): RendererRequestRoute | null => {
|
|
1035
|
+
const route = requestRouteResolver.resolve();
|
|
1036
|
+
syncActiveRoute(route);
|
|
1037
|
+
return route;
|
|
1038
|
+
};
|
|
1039
|
+
const currentModelClient = (): RendererModelClient => {
|
|
1040
|
+
const client = currentRequestRoute() ? activeRouteClient : null;
|
|
1041
|
+
if (!client) throw new Error("Renderer Model request manager is unavailable");
|
|
1042
|
+
usageSubscription.connect(client);
|
|
1043
|
+
return client;
|
|
1044
|
+
};
|
|
1045
|
+
const modelControl: RendererModelClient = Object.freeze({
|
|
1046
|
+
currentHostId: () => currentRequestRoute()?.policy.hostId ?? null,
|
|
1047
|
+
clientForHost(hostId: string): RendererModelClient | null {
|
|
1048
|
+
const route = currentRequestRoute();
|
|
1049
|
+
if (route?.policy.hostId === hostId)
|
|
1050
|
+
return modelClientForTargets(route.targets, route.policy);
|
|
1051
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
1052
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) return null;
|
|
1053
|
+
const targets = rendererRequestTargetsForHost(findActivePrewarmTargets(document), hostId);
|
|
1054
|
+
return modelClientForTargets(targets ?? []);
|
|
1055
|
+
},
|
|
1056
|
+
listHarnessPlugins: async () => {
|
|
1057
|
+
const client = currentModelClient();
|
|
1058
|
+
if (!client.listHarnessPlugins) throw new Error("Harness plugin directory is unavailable");
|
|
1059
|
+
return client.listHarnessPlugins();
|
|
1060
|
+
},
|
|
1061
|
+
forkThread: (input: ExternalThreadForkParams) => currentModelClient().forkThread(input),
|
|
1062
|
+
switchHarness: (input: ThreadHarnessSwitchParams) => currentModelClient().switchHarness(input),
|
|
1063
|
+
inspectHarness: (input: HarnessInspectParams) => currentModelClient().inspectHarness(input),
|
|
1064
|
+
inspectThread: (input: ThreadInspectionParams) => currentModelClient().inspectThread(input),
|
|
1065
|
+
inspectHarnessCommands: (input: HarnessCommandsInspectParams) =>
|
|
1066
|
+
currentModelClient().inspectHarnessCommands(input),
|
|
1067
|
+
inspectThreadCommands: (input: ThreadCommandsInspectParams) =>
|
|
1068
|
+
currentModelClient().inspectThreadCommands(input),
|
|
1069
|
+
executeThreadCommand: (input: ThreadCommandExecuteParams) =>
|
|
1070
|
+
currentModelClient().executeThreadCommand(input),
|
|
1071
|
+
inspectThreadUsage: (input: ThreadUsageInspectionParams) =>
|
|
1072
|
+
currentModelClient().inspectThreadUsage(input),
|
|
1073
|
+
subscribeThreadUsage: (listener: (update: ThreadUsageInspection) => void) =>
|
|
1074
|
+
usageSubscription.subscribe(listener),
|
|
1075
|
+
listThreadOwnership: (input: ThreadOwnershipListParams) =>
|
|
1076
|
+
currentModelClient().listThreadOwnership(input),
|
|
1077
|
+
selectThreadModel: (input: ThreadModelSelectParams) =>
|
|
1078
|
+
currentModelClient().selectThreadModel(input),
|
|
1079
|
+
selectThreadThinking: (input: ThreadThinkingSelectParams) =>
|
|
1080
|
+
currentModelClient().selectThreadThinking(input),
|
|
1081
|
+
selectThreadPermissionMode: (input: ThreadPermissionModeSelectParams) =>
|
|
1082
|
+
currentModelClient().selectThreadPermissionMode(input),
|
|
1083
|
+
checkUpdate: () => currentModelClient().checkUpdate(),
|
|
1084
|
+
startUpdate: () => currentModelClient().startUpdate(),
|
|
1085
|
+
readUpdateStatus: () => currentModelClient().readUpdateStatus(),
|
|
1086
|
+
inspectCodexAccountUsage: (
|
|
1087
|
+
input: Parameters<NonNullable<RendererModelClient["inspectCodexAccountUsage"]>>[0],
|
|
1088
|
+
) => {
|
|
1089
|
+
const client = currentModelClient();
|
|
1090
|
+
if (!client.inspectCodexAccountUsage) throw new Error("Codex Account Usage is unavailable");
|
|
1091
|
+
return client.inspectCodexAccountUsage(input);
|
|
1092
|
+
},
|
|
1093
|
+
consumeCodexAccountResetCredit: (
|
|
1094
|
+
input: Parameters<NonNullable<RendererModelClient["consumeCodexAccountResetCredit"]>>[0],
|
|
1095
|
+
) => {
|
|
1096
|
+
const client = currentModelClient();
|
|
1097
|
+
if (!client.consumeCodexAccountResetCredit) {
|
|
1098
|
+
throw new Error("Codex Account reset-credit consume is unavailable");
|
|
1099
|
+
}
|
|
1100
|
+
return client.consumeCodexAccountResetCredit(input);
|
|
1101
|
+
},
|
|
1102
|
+
listHarnessAccounts: () => {
|
|
1103
|
+
const client = currentModelClient();
|
|
1104
|
+
if (!client.listHarnessAccounts) throw new Error("Harness account inspection is unavailable");
|
|
1105
|
+
return client.listHarnessAccounts();
|
|
1106
|
+
},
|
|
1107
|
+
listCodexAccounts: () => currentModelClient().listCodexAccounts(),
|
|
1108
|
+
refreshCodexAccounts: () => {
|
|
1109
|
+
const client = currentModelClient();
|
|
1110
|
+
return client.refreshCodexAccounts?.() ?? client.listCodexAccounts();
|
|
1111
|
+
},
|
|
1112
|
+
createCodexAccount: (input: Parameters<RendererModelClient["createCodexAccount"]>[0]) =>
|
|
1113
|
+
currentModelClient().createCodexAccount(input),
|
|
1114
|
+
deleteCodexAccount: (input: Parameters<RendererModelClient["deleteCodexAccount"]>[0]) =>
|
|
1115
|
+
currentModelClient().deleteCodexAccount(input),
|
|
1116
|
+
activateCodexAccount: (input: Parameters<RendererModelClient["activateCodexAccount"]>[0]) =>
|
|
1117
|
+
currentModelClient().activateCodexAccount(input),
|
|
1118
|
+
startCodexAccountLogin: (input: Parameters<RendererModelClient["startCodexAccountLogin"]>[0]) =>
|
|
1119
|
+
currentModelClient().startCodexAccountLogin(input),
|
|
1120
|
+
cancelCodexAccountLogin: (
|
|
1121
|
+
input: Parameters<RendererModelClient["cancelCodexAccountLogin"]>[0],
|
|
1122
|
+
) => currentModelClient().cancelCodexAccountLogin(input),
|
|
1123
|
+
subscribeCodexAccountLogin: (
|
|
1124
|
+
listener: Parameters<RendererModelClient["subscribeCodexAccountLogin"]>[0],
|
|
1125
|
+
) => currentModelClient().subscribeCodexAccountLogin(listener),
|
|
1126
|
+
});
|
|
1127
|
+
const forkControl = installRendererForkControl({
|
|
1128
|
+
getClient: () => modelControl,
|
|
1129
|
+
reportError: (error) => {
|
|
1130
|
+
console.error(
|
|
1131
|
+
"codexhost external Thread Fork failed",
|
|
1132
|
+
error instanceof Error ? error.name : "UnknownError",
|
|
1133
|
+
);
|
|
1134
|
+
},
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
let routingPolicy: RendererDraftPrewarmPolicy | null = null;
|
|
1138
|
+
let policyTimer: number | null = null;
|
|
1139
|
+
let policyRecaptureObserver: MutationObserver | null = null;
|
|
1140
|
+
let hasCapturedRoutingPolicy = false;
|
|
1141
|
+
let selectedRoutingPolicy: RendererDraftPrewarmPolicy | null = null;
|
|
1142
|
+
let selectedCarrier: string | null = null;
|
|
1143
|
+
let desiredCarrier: string | null = null;
|
|
1144
|
+
const stopPolicyCapture = (): void => {
|
|
1145
|
+
if (policyTimer === null) return;
|
|
1146
|
+
window.clearInterval(policyTimer);
|
|
1147
|
+
policyTimer = null;
|
|
1148
|
+
};
|
|
1149
|
+
const stopPolicyRecapture = (): void => {
|
|
1150
|
+
policyRecaptureObserver?.disconnect();
|
|
1151
|
+
policyRecaptureObserver = null;
|
|
1152
|
+
};
|
|
1153
|
+
const captureRoutingPolicy = (): boolean => {
|
|
1154
|
+
const route = currentRequestRoute();
|
|
1155
|
+
if (!route) return false;
|
|
1156
|
+
routingPolicy = route.policy;
|
|
1157
|
+
stopPolicyRecapture();
|
|
1158
|
+
if (selectedRoutingPolicy !== routingPolicy || selectedCarrier !== desiredCarrier) {
|
|
1159
|
+
try {
|
|
1160
|
+
routingPolicy.select(desiredCarrier);
|
|
1161
|
+
} catch {
|
|
1162
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
1163
|
+
return false;
|
|
1164
|
+
}
|
|
1165
|
+
selectedRoutingPolicy = routingPolicy;
|
|
1166
|
+
selectedCarrier = desiredCarrier;
|
|
1167
|
+
}
|
|
1168
|
+
hasCapturedRoutingPolicy = true;
|
|
1169
|
+
stopPolicyCapture();
|
|
1170
|
+
updateStatus("ready", "ready", "request-bridge");
|
|
1171
|
+
return true;
|
|
1172
|
+
};
|
|
1173
|
+
const startPolicyCapture = (): void => {
|
|
1174
|
+
stopPolicyCapture();
|
|
1175
|
+
policyTimer = window.setInterval(captureRoutingPolicy, DRAFT_PREWARM_POLICY_POLL_INTERVAL_MS);
|
|
1176
|
+
};
|
|
1177
|
+
const startPolicyRecapture = (): void => {
|
|
1178
|
+
stopPolicyRecapture();
|
|
1179
|
+
policyRecaptureObserver = new MutationObserver(() => {
|
|
1180
|
+
captureRoutingPolicy();
|
|
1181
|
+
});
|
|
1182
|
+
policyRecaptureObserver.observe(document.documentElement, {
|
|
1183
|
+
attributes: true,
|
|
1184
|
+
attributeFilter: ["hidden", "aria-hidden", "data-codex-composer-root"],
|
|
1185
|
+
characterData: true,
|
|
1186
|
+
childList: true,
|
|
1187
|
+
subtree: true,
|
|
1188
|
+
});
|
|
1189
|
+
};
|
|
1190
|
+
if (!captureRoutingPolicy()) {
|
|
1191
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
1192
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
1193
|
+
if (!isDraftPrewarmPolicyReady(policy) || !hasPolicyRequestTarget(policy)) {
|
|
1194
|
+
startPolicyCapture();
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
const handleRoutingPolicyChange = (): void => {
|
|
1198
|
+
stopPolicyRecapture();
|
|
1199
|
+
if (captureRoutingPolicy()) return;
|
|
1200
|
+
const policy = window.__codexhostDraftPrewarmPolicyV1;
|
|
1201
|
+
if (isDraftPrewarmPolicyReady(policy) && hasPolicyRequestTarget(policy)) {
|
|
1202
|
+
stopPolicyCapture();
|
|
1203
|
+
}
|
|
1204
|
+
if (!hasCapturedRoutingPolicy) return;
|
|
1205
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
1206
|
+
if (isDraftPrewarmPolicyReady(policy) && !hasPolicyRequestTarget(policy)) {
|
|
1207
|
+
startPolicyRecapture();
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
window.addEventListener("codexhost:draft-prewarm-policy-changed", handleRoutingPolicyChange);
|
|
1211
|
+
|
|
1212
|
+
const applyAgent = (
|
|
1213
|
+
agent: RendererAgent,
|
|
1214
|
+
model?: HarnessModelRef,
|
|
1215
|
+
thinkingOptionId?: HarnessThinkingOptionId,
|
|
1216
|
+
permissionModeId?: HarnessPermissionModeId,
|
|
1217
|
+
): boolean => {
|
|
1218
|
+
if (disposed) return false;
|
|
1219
|
+
const selection = modelSelectionForAgent(
|
|
1220
|
+
null,
|
|
1221
|
+
null,
|
|
1222
|
+
agent,
|
|
1223
|
+
model,
|
|
1224
|
+
thinkingOptionId,
|
|
1225
|
+
permissionModeId,
|
|
1226
|
+
);
|
|
1227
|
+
const carrier = selection?.model;
|
|
1228
|
+
if (carrier !== null && carrier !== undefined && typeof carrier !== "string") return false;
|
|
1229
|
+
desiredCarrier = carrier ?? null;
|
|
1230
|
+
const route = currentRequestRoute();
|
|
1231
|
+
if (!route) return false;
|
|
1232
|
+
routingPolicy = route.policy;
|
|
1233
|
+
try {
|
|
1234
|
+
if (route.policy.select(desiredCarrier)) {
|
|
1235
|
+
modelUpdates += 1;
|
|
1236
|
+
liveStatus.modelUpdates = modelUpdates;
|
|
1237
|
+
}
|
|
1238
|
+
selectedRoutingPolicy = route.policy;
|
|
1239
|
+
selectedCarrier = desiredCarrier;
|
|
1240
|
+
} catch {
|
|
1241
|
+
updateStatus("installing", "draft-routing-policy-unavailable", null);
|
|
1242
|
+
return false;
|
|
1243
|
+
}
|
|
1244
|
+
return true;
|
|
1245
|
+
};
|
|
1246
|
+
return {
|
|
1247
|
+
status: liveStatus,
|
|
1248
|
+
modelControl,
|
|
1249
|
+
applyAgent,
|
|
1250
|
+
dispose() {
|
|
1251
|
+
if (disposed) return;
|
|
1252
|
+
disposed = true;
|
|
1253
|
+
stopPolicyCapture();
|
|
1254
|
+
stopPolicyRecapture();
|
|
1255
|
+
window.removeEventListener(
|
|
1256
|
+
"codexhost:draft-prewarm-policy-changed",
|
|
1257
|
+
handleRoutingPolicyChange,
|
|
1258
|
+
);
|
|
1259
|
+
const activeRoutingPolicy = routingPolicy;
|
|
1260
|
+
routingPolicy = null;
|
|
1261
|
+
requestRouteResolver.clear();
|
|
1262
|
+
const cleanups = [
|
|
1263
|
+
() => activeRoutingPolicy?.select(null),
|
|
1264
|
+
() => syncActiveRoute(null),
|
|
1265
|
+
() => forkControl.dispose(),
|
|
1266
|
+
...steeringCleanups,
|
|
1267
|
+
() => usageSubscription.dispose(),
|
|
1268
|
+
];
|
|
1269
|
+
for (const cleanup of cleanups) {
|
|
1270
|
+
try {
|
|
1271
|
+
cleanup();
|
|
1272
|
+
} catch {
|
|
1273
|
+
// Every owned resource must still be released if an external cleanup fails.
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
},
|
|
1277
|
+
};
|
|
1278
|
+
}
|