diff --git a/.github/pr-assets/xai-responses-optin-switch.png b/.github/pr-assets/xai-responses-optin-switch.png new file mode 100644 index 0000000000..8f0947ace7 Binary files /dev/null and b/.github/pr-assets/xai-responses-optin-switch.png differ diff --git a/README.md b/README.md index f6f0770eed..106251a8a4 100644 --- a/README.md +++ b/README.md @@ -129,8 +129,16 @@ see the [installation docs](https://opencodex.me/getting-started/installation/). - **Use any LLM with Codex, Claude Code, Claude Desktop, and Grok Build** — 40+ providers out of the box, each keeping its own native UI. -- **Pool ChatGPT accounts safely** — thread affinity, quota-aware auto-switching, cooldown and +- **Pool ChatGPT accounts** — thread affinity, quota-aware auto-switching, cooldown and fail-closed auth handling. + + > **Provider-policy note:** Account pooling is for routing and operational resilience only; it does + > not guarantee protection from provider rate limits, enforcement, suspension, or other account + > actions. OpenCodex does not endorse using additional accounts to circumvent provider limits or + > sharing account credentials between people. You are responsible for complying with each + > provider's current terms. See the + > [Codex Auth account-pool guidance](https://opencodex.me/guides/web-dashboard/#codex-auth-and-account-pools) + > and [OpenAI's current Terms of Use](https://openai.com/policies/terms-of-use/). - **Combos** — one virtual model id with failover or weighted round-robin across providers. See the [combo guide](https://opencodex.me/guides/combos/). - **Sub-agents on any model** — feature routed models in Codex's sub-agent picker, with v1/v2 diff --git a/devlog/_plan/260814_bug_resolution_campaign/030_wave3_cursor.md b/devlog/_plan/260814_bug_resolution_campaign/030_wave3_cursor.md index 8935facdce..db38b18279 100644 --- a/devlog/_plan/260814_bug_resolution_campaign/030_wave3_cursor.md +++ b/devlog/_plan/260814_bug_resolution_campaign/030_wave3_cursor.md @@ -48,6 +48,21 @@ Cursor tool/continuation/edit 경로의 correctness fix를 - teardown 문제 (정상 완료를 aborted/expectedClose:false로 기록)는 별도 작은 PR로 먼저 고친다 +2026-08-18 로컬 조사/prototype 메모 (fix/cursor-checkpoint-continuation, 아직 upstream PR 아님): + +- 병목의 1차 원인은 JSON 포맷 자체가 아니라, 매 턴 rootPromptMessages/conversationTurns로 + 과거 대화를 다시 만드는 full replay semantics다. +- ConversationStateStructure checkpoint를 다음 conversationState로 재사용하면 no-tool + follow-up에서 로컬 rootBytes가 history와 같이 커지지 않는다. grok-4.6 live 3턴에서 + 2·3턴이 continuationMode=checkpoint였고 ALPHA-7을 기억했다. +- 공식 cursor-agent 같은 계정 대조: 1턴 cacheReadTokens 0 / input 18937, 같은 세션 2턴 + cacheReadTokens 18816 / 새 input 331 / 답 ALPHA-7. OpenCodex Cursor wire는 usedTokens만 + 주므로 이쪽 usage로 cache hit를 주장하면 안 된다. +- tool-result는 마지막 정상 완료 턴 checkpoint + suffix replay가 live에서 동작했다. + client-tool suspend 턴 자체는 온전한 checkpoint가 없어 commit하지 않는다. +- 아직 미해결: 큰 context / 429 / kimi-k3 premature completion 재현, stateful live MCP + bridge, 정상 완료 teardown을 aborted로 분류하는 별건. + ### Step 5: #1623 분할 (behavior fix 안정화 후) 1. refactor/adapter-registry-authority diff --git a/devlog/_plan/260820_bug_pr_backlog_consolidation/090_merge_log.md b/devlog/_plan/260820_bug_pr_backlog_consolidation/090_merge_log.md new file mode 100644 index 0000000000..aa1ffca170 --- /dev/null +++ b/devlog/_plan/260820_bug_pr_backlog_consolidation/090_merge_log.md @@ -0,0 +1,119 @@ +# 090 — Merge log: the bug-PR backlog landing on dev + +Unit: 260820_bug_pr_backlog_consolidation +Work-phases: wp21-wp25. +dev before: `31ee7a683`. dev after: `a584890f8`. + +## The override that was not needed + +All 19 PRs sat at CHANGES_REQUESTED from @Ingwannu with green CI, and the plan was to merge +with admin authority. Three independent read-only lanes read every blocking review first, and +the answer was the same in all three: **the objection was factually current, not stale.** + +The recurring complaint was "this head is N commits behind dev". Measured, it was true +everywhere — 16 to 25 commits, and `dev` had itself advanced to `31ee7a683` while the reviews +were being written. A green check on a stale head validates an integration state that no longer +exists, which is a real merge-readiness defect rather than a formality to wave through. + +So the resolution was to rebase all 19 branches onto current `dev`, not to override. Admin +authority can bypass a gate; it cannot make an untested integration state tested. + +Two reviews named genuine code defects, and both were fixed rather than overridden: + +- **#2166** — `addRequestLog` is exported and bypassed the sanitizer: the reviewer reproduced a + raw 111-character value in the `/api/logs` ring against a sanitized 37-character value on + disk. Fixed at the shared ingress so both surfaces read from one normalized entry, with the + direct-ingress regression the reviewer asked for. +- **#2162** — a prompt mutation writing into the outbound user turn needed its content-shape + boundaries pinned. Added: an already-framed turn stays single, image-only content keeps its + image block behind the preamble, assistant-only block content keeps its tail before the + synthesized `(continue)` turn. + +One more objection dissolved on rebase: #2148 was carrying eight `devlog/_plan/` planning files +inherited from its branch point. The rebase removed them. + +## What landed + +19 PRs, merged bottom-up. Every merge commit verified present in `git log origin/dev`. + +| PR | dev merge commit | Absorbed from | +|---|---|---| +| #2134 | `930840ca4` | maintainer fix | +| #2160 | `114e9e543` | #2067 @waw4303 | +| #2162 | `087c3c368` | #2082 @yzxcj797 | +| #2164 | `31750b094` | #2027 @yzxcj797 | +| #2165 | `41689b374` | #2155 @waw4303 | +| #2166 | `5fbe65570` | #2163 @Ingwannu | +| #2137 | `be12328bc` | issue #2132 | +| #2146 | `aa07bc308` | #2101 @Ingwannu | +| #2138 | `81492fd10` | #2102 @lilinxiong | +| #2140 | `3ad9c7bf4` | #2100 + #2077 @ntdatt812 | +| #2141 | `1cc35c560` | #2056 @Ingwannu | +| #2142 | `52a463dd6` | #2131 @bet4it | +| #2144 | `8c8a66816` | #2105 @lilinxiong | +| #2145 | `83d5ffa3c` | #2040 @Ingwannu | +| #2147 | `7fc50846b` | #2104 @olddonkey | +| #2148 | `86ed9ed83` | #2109 + #2110 @drakonkat | +| #2149 | `17e8e916b` | #2053 @Ingwannu | +| #2150 | `9a7801547` | #2127 @agentHits | +| #2151 | `a584890f8` | #2075 @olddonkey | + +Verification that the rebased content is what actually landed, split by what is still +re-runnable: + +- **Re-runnable today:** every merge SHA in the table above satisfies + `git merge-base --is-ancestor origin/dev` (verified 2026-08-21, 19/19 true) — the + recorded merge commits are exactly the commits on `dev`, so the landed content is the + table's content by construction. +- **Historical assertion, no longer re-runnable:** six of the merges recorded a pre-rebase + branch SHA in their description. At merge time each rebased branch was compared with + `git diff --name-only origin/dev -- ` and + returned 0 differing files. The source branches were deleted in the wp0 cleanup + (260820 unit, executed record), so those comparisons cannot be reproduced from this log; + they stand as recorded assertions, not evidence, and the re-runnable ancestor check above + is the durable audit trail. + +## Security surfaces, named rather than merged silently + +`MAINTAINERS.md` reserves auth, credential handling, OAuth, workflows, and release automation +for explicit human review. Seven of the merged PRs touch that surface, and the user's merge +authorization is the human decision of record for each: + +- **#2137 / #2146** — bearer admission and stored-credential substitution; entitlement-gated + model discovery sends the selected account's access token. +- **#2144** — decides whether the shell hook exposing `ANTHROPIC_AUTH_TOKEN` is installed. +- **#2145** — lowers third-party `function_call` output and restores it as a client-executed + private `tool_search_call`. +- **#2147** — OAuth 401 refresh and access-token replay. +- **#2148** — operator-selected destinations for Anthropic/Antigravity OAuth bearers. The + transport gate still rejects public cleartext HTTP; only explicitly opted-in local/private + relays may use it. +- **#2149** — OAuth credential commit ownership under the store lock. + +## Issue closure + +Every issue named by a merged PR is closed: #2133, #2132, #2092, #2047, #1950, #2097, #1886, +#2125, #2074, #1924, plus the superseded contributor PRs. Verified by `gh api` state, not by +assuming GitHub auto-closed them — these PRs targeted `dev`, not `main`, so auto-close does not +fire. + +## Release readiness — not a release + +At `a584890f8`: + +- `bun run test` — 13716 pass / 10 skip / 0 fail across 866 files. +- `bun x tsc --noEmit` — exit 0. +- `bun run privacy:scan` — passed. +- `package.json` version line: **2.27.0** (unchanged by this campaign). + +Changed surfaces: provider registry and transport headers, quota dispatch, routing capability +resolution, the Anthropic/OpenAI-chat/Google adapters, Responses core and compact, OAuth store +and credential commit, request logging and usage persistence, subagent roster management. + +Not done, and deliberately: no `scripts/release.ts`, no npm publish, no tag, no change to +`main` or `preview`. Release execution needs its own authorization. + +## Still open + +**#2054** (@keepitmello) stays open by explicit instruction, carrying the wire-probe request. +**#2167** (@ntdatt812) arrived after this campaign and is untriaged. diff --git a/devlog/_plan/260820_bug_pr_backlog_consolidation/110_three_bug_issues.md b/devlog/_plan/260820_bug_pr_backlog_consolidation/110_three_bug_issues.md new file mode 100644 index 0000000000..73bebc289d --- /dev/null +++ b/devlog/_plan/260820_bug_pr_backlog_consolidation/110_three_bug_issues.md @@ -0,0 +1,105 @@ +# 110 — Three open bug issues: #2152, #2157, #2156 + +Unit: 260820_bug_pr_backlog_consolidation +Verification host: `ssh lidge:~/ci-wp3/opencodex`. + +Three issues, three different shapes of answer. Two shipped fixes; one is honestly blocked. + +## #2152 — Windows CI, three groups (PR #2178) + +Three read-only lanes read the three groups. The shape PR #2178 already had was right, and two +of the issue's own premises turned out to be wrong — the fix follows the evidence: + +- **Group 1** is not "the case budget is too small". `A-reduced` failed at 79,978 ms against a + 150 s ceiling, so the outer budget was never the constraint. The real abort came from + `Fixture.request`'s unscaled 10 s `AbortSignal` firing from inside. And `E` does not start + `ocx` at all — it starts two lock helpers, and its holder released after a fixed 3 s wait + that a Windows contender's spawn can outlast. +- **Group 2** is not "an unprivileged Windows user cannot create symlinks". The runner can, so + `canSymlink` was true and the cases ran — then failed on Unix mode semantics that a Windows + directory cannot satisfy. Production already returns `windows_skip` for exactly that reason, + which is what makes the platform guard a correct skip rather than a masked failure. +- **Group 3** needed the crash retry the macOS leg already had. + +### The defect I found in the fix + +Group 3's retry grepped for `panic(thread`. This repository already worked that out and wrote +it down: `devlog/_fin/260731_pr_issue_triage_round/050_windows_ci_flake_rca.md:172` says not to +key on it, because Bun emits **both** `panic(thread 2852)` and `panic(main thread)` for the +same failure, and names `Internal assertion failure` as the stable fingerprint. Probed: + +```text +MATCH panic(thread 3960): Internal assertion failure +MISS panic(main thread): Internal assertion failure +MISS panic(main thread): PANIC: reached unreachable code +``` + +The retry would have failed the shard on roughly half the crashes it exists to absorb, while +looking correct. + +Three copies of that signature list exist — macOS inline, the new Windows inline, and +`is_bun_runtime_crash` — and the workflow comment already said to keep them in sync with +nothing enforcing it. They had drifted. All three now match, and the contract test pins **the +sync itself**, not the literal text, so the same drift cannot recur. RED-proven: restoring the +bad signature fails it with `windows:Internal assertion failure:false`. + +`hasShellCommandHead` was added because the existing exact-whole-line matcher rejected the +`| tee` the retry requires — that is why the Windows step assertion went red — while still +rejecting an echoed or commented-out copy. + +**What no local run can prove:** whether 45 s suffices under real Windows contention, the actual +skip result on the runner, and `PIPESTATUS` under Git Bash. Those need a `workflow_dispatch`, +and a useful proof run must exercise the crash path — a green Windows run shows the suite runs, +not that the retry fires. + +## #2157 — shadow-helper observability (PR #2179) + +The dashboard half of the attribution field #2166 landed. Delivered. + +## #2156 — muse-spark truncation: BLOCKED, deliberately + +PR #2180 was opened claiming to fix this. An adversarial review found the attribution wrong, and +the source agrees: + +- A stall abort emits `response.incomplete` / `upstream_stall_timeout` (`bridge.ts:1371-1396`), + after which the bridge has cancelled upstream, closed, and explicitly discards any late + adapter event (`bridge.ts:837-845`). +- The reporter's error is emitted only after `reader.read()` returns EOF with tool calls still + pending (`openai-chat.ts:1819-1827`), surfacing as `response.failed`. + +Different path, different client frame. The heartbeat **cannot** produce the reported error. + +What the heartbeat does fix is real and worth landing alone: tool-call deltas are buffered, the +bridge arms its watchdog on adapter activity rather than socket activity, so a large argument +payload was indistinguishable from a hung upstream. The `#2156` references were reworded to +"found while investigating", and the closing keyword removed. + +**Second finding, partially addressed.** Making the adapter emit one heartbeat per delta +exposed retention in `guardTerminalEventStream`'s `seen`, which feeds both the continuation +analysis and the rebuilt request. Two event classes must be distinguished: #2180 stopped +retaining `heartbeat` events, but the terminal guard still retains every OTHER nonterminal +event (tool-call deltas included), so a large argument payload can still grow `seen` without +bound wherever `terminalContinuationGuard` is on. The empty-completion guard passes heartbeats +through unretained; matching it for the remaining nonterminal classes is follow-up work, not +something this record's PR landed. + +**Why blocked rather than fixed.** The adapter is reporting truthfully: that stream really did +end. What cannot be determined from here is why it ended for ocx and not for Pi direct. +`hadUsage: false` is suggestive — ocx does send `stream_options.include_usage` — but a provider +may simply ignore that flag, so it is not decisive either way. + +Asked the reporter for the one thing that settles it: redacted raw SSE captures from a +Pi-direct success and an ocx failure for an equivalent request, through socket close, and +whether either carried `finish_reason`, `[DONE]`, or a usage-only final chunk. If ocx's +upstream closes without a terminal frame while Pi's does not, the difference is in what we send +or how we read it and it is ours. If both close identically and Pi is merely more tolerant, the +right answer is the buffered-mode fallback the reporter suggested — and that choice should rest +on their capture, not on a guess. + +## Verification + +At the branch tips, on `ssh lidge`: + +- #2178: `bun test` 13719 pass / 15 skip / 0 fail; `tests/ci-workflows.test.ts` 132 pass / 0 fail. +- #2180: `bun test` 13722 pass / 15 skip / 0 fail; focused trio 112 pass / 0 fail. +- `bun x tsc --noEmit` exit 0 and `bun run privacy:scan` passed on both. diff --git a/devlog/_plan/260820_bug_pr_backlog_consolidation/120_release_2280.md b/devlog/_plan/260820_bug_pr_backlog_consolidation/120_release_2280.md new file mode 100644 index 0000000000..5c9852a6d2 --- /dev/null +++ b/devlog/_plan/260820_bug_pr_backlog_consolidation/120_release_2280.md @@ -0,0 +1,109 @@ +# 120 — v2.28.0 release + +Unit: 260820_bug_pr_backlog_consolidation + +Published: `@bitkyc08/opencodex@2.28.0` as npm `latest`. + +| Artifact | Value | +|---|---| +| Release commit | `584059132` (main) | +| Tag | `v2.28.0` → `5840591322117f3ee9568b35b135a6d4339f7711` | +| GitHub release | `v2.28.0`, 2026-08-20T09:17:50Z | +| Release workflow | run `32355161140`, **success**, head `584059132` | +| npm dist-tags | `latest: 2.28.0` | +| preview line | `2.28.0-preview.20260820` at `d2c700c1a` | + +## The CI stability claim, as measured rather than asserted + +The release gate in `release.yml` is deliberately narrow: it requires a **successful push-event +`ci.yml` run for the exact release SHA on the release branch**. A PR run for the same SHA does +not qualify, because it ran against a merge ref under a different trigger context. + +That gate was met: `main` push-event CI is **success at `584059132`** — the exact commit the +tag points at. + +**`dev` CI is red at `96f288d59`, and that was checked rather than waved past.** The failures +are Windows-only: + +- `windows 1/4`: WP13 composed `E` (54,074 ms) and `Restore truth` (45,197 ms). +- `windows 2/4`: journal-ownership start/ensure, and CL-10 deterministic bundle failing inside + `publishPrivateFileExclusive` on a `D:\` path. + +Every non-Windows job in that same run succeeded. The Windows leg is `workflow_dispatch`-only +by design and is explicitly excluded from the release gate — `ci.yml:544-546` states that +`release.yml` gates on Linux + macOS + gates, and that "Windows re-enters the gate when the +tracked failures are fixed, not before" (issue #1059). These are the pre-existing failures +#2152 catalogues, not a regression from this range. + +So: **not a green Windows leg, and not claimed as one.** The release shipped on the gate the +repository actually defines, with the red leg named and attributed. + +## Two things the release helper caught that a manual publish would not have + +**The local gate failed on missing GUI dependencies, not on a defect.** The first run failed 7 +tests with `Cannot find package 'react'`. CI installs twice — root and then `gui/` — and builds +the GUI, because tests that fetch the served dashboard read their session bootstrap out of +`gui/dist/index.html`. The `ci.yml` comment at line 280 predicts this exact failure. After +`cd gui && bun install` plus `bun run build`, the gate passed and the publish proceeded. + +**The helper is re-entrant and it proved it.** A later re-run refused with "release version +2.28.0 is already partially or fully used", listing npm, the remote tag, and the GitHub release. +That is the metadata preflight working as intended: it is what turned an ambiguous "did that +publish land?" into a verified yes, and it is why the second attempt could not double-publish. + +## Verification performed + +``` +npm view @bitkyc08/opencodex version -> 2.28.0 +npm view ... dist-tags -> latest: 2.28.0 +git tag -l v2.28.0 -> v2.28.0 +gh release view v2.28.0 -> present +git merge-base --is-ancestor 584059132 origin/main -> YES +gh run view 32355161140 -> success @ 584059132 +``` + +A pushed commit and a dispatched workflow were not treated as a completed release; each artifact +above was read back from its own authority. + +## The preview channel, published after this record was first written + +At the time the section above was written, `preview` carried the version commit but npm still +read `2.26.0-preview.20260819` — the channel had been trailing `latest` by a full release. It +has since been published on the same path. + +| Artifact | Value | +|---|---| +| Release commit | `d2c700c1a` (preview) | +| Tag | `v2.28.0-preview.20260820` | +| GitHub release | `v2.28.0-preview.20260820`, pre-release, 2026-08-20T10:54:38Z | +| Release workflow | run `32361122670`, **success** | +| npm dist-tags | `preview: 2.28.0-preview.20260820` | + +Both channels now sit on the same content, which is what `preview` is for and what it had +stopped being while it lagged a release behind. + +The helper enforces the channel pairing itself rather than trusting the invocation: a +`preview` branch release must carry a `-preview.` version and publish to the `preview` +dist-tag, and `main` must be stable semver on `latest`. There is no argument combination that +crosses them. + +**The last dispatch of this publish failed, and that failure is the guard working.** Run +`32361621459` refused with "v2.28.0-preview.20260820 already exists. Refusing to publish a +version with pre-existing Git metadata." A local shell had died mid-suite and the release was +restarted; by then run `32361122670` had already published. The refusal is what turned a +possible double-publish into a no-op, and it is the same preflight that caught the stable +re-run described above. + +## Two Linux failures that were not defects + +`test 1/4` failed twice on `Codex autostart shim > an aged lock held by a live restore owner +is never reclaimed`, once on the stable release PR and once on the preview one. Both times it +hit the 60 s lane ceiling; both times it passed on re-run, and it passes locally in a 20 s +single-file run. The case spawns two real Bun processes and has one wait for the other's lock, +so it is spawn-latency-bound on a contended runner rather than assertion-bound. It carries no +budget of its own, unlike the cases in `tests/helpers/test-budget.ts`. + +Worth naming rather than burying: two occurrences on the same case is a pattern, not noise. It +is not a release blocker — nothing about the shipped code changed between the red and green +runs — but it belongs on the same list as the Windows spawn-cost failures in #2152, and giving +it an intrinsic budget is the obvious next step. diff --git a/devlog/_plan/260820_sidecar_selection_unification/000_unit_overview.md b/devlog/_plan/260820_sidecar_selection_unification/000_unit_overview.md new file mode 100644 index 0000000000..c9e0c93b72 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/000_unit_overview.md @@ -0,0 +1,56 @@ +# 260820 — Sidecar selection unification (#2188) + +Roadmap for implementing issue #2188 as a stacked PR chain onto dev. +Session 01a01f4b; goalplan implement-github-issue-2188-feat-sidecar-unify-w. + +## Docs +- 000 (this file) — unit overview + stack map. +- 000_wp0 — branch/worktree cleanup record (executed, closed). +- 001 — research: current selection state at dev f2ebd3067. +- 010 — Layer 1: src/sidecar/auth.ts shared auth + slots (branch codex/sidecar-auth-slots → dev). +- 020 — Layer 2: src/sidecar/candidates.ts picker set + vision filter (codex/sidecar-picker-candidates → L1). +- 030 — Layer 3: web-search backend registry + candidate ∩ (no default-backend change) (codex/sidecar-websearch-slots → L2). +- 031 — future-backend research table + probe contracts (doc-only, inside L3 PR). +- 040 — Layer 4: write gates + GUI lists (codex/sidecar-write-gates → L3). +- 050 — Layer 5: ocx agent sidecar --list + docs-site + full validation (codex/sidecar-cli → L4). + +## Stack invariants (DEV-STACK) +Bottom targets dev; each child targets the branch below. Merge bottom-up; retarget children after parent lands. Each layer: own tests green + typecheck before PR; full suite at top layer. Every A/C gate: xai/grok-4.6 read-only reviewer, verdict binding. + +## Out of scope (issue-fixed) +Gemini/Grok/Zen/Exa executors, #2190 x_search, #398, types.ts-split rebases. + + +## AMENDMENT 1 (post-audit, auditor Hegel VERDICT: fail — all four blockers accepted) + +### B1 — isCodexAuth must mean LOGIN, not provider presence (fixes 010) +```ts +// src/sidecar/auth.ts +isCodexAuth = listOpenAiForwardSidecarCandidates(config).length > 0 + && ( isCodexAccountUsable(config, MAIN_CODEX_ACCOUNT_ID) // live ~/.codex auth.json token + || (config.codexAccounts ?? []).some(a => isSelectableCodexPoolAccount(a) + && isCodexAccountUsable(config, a.id)) ) // any usable pool credential +``` +Symmetric with the Anthropic predicate (stored OAuth + !needsReauth). Uses src/codex/account-usability.ts:17 isCodexAccountUsable; no header/request context needed. Test: forward provider present but no live token & no pool creds → isCodexAuth false → Luna slot absent. + +### B2 — extend ocx agent sidecar, do NOT add ocx sidecar (fixes 001 + 050) +001 correction: src/cli/agent.ts:23 already ships `ocx agent sidecar ` → PUT /api/sidecar-settings. Layer 5 extends it: +- `ocx agent sidecar web --list` / `vision --list` print the exact candidate sets via a new GET consumer (same functions as GUI). +- Writes already flow through the PUT gate added in L4 (server-side gate covers CLI automatically — the "CLI cannot bypass" property comes from gating the shared route, not from a parallel client check). +- No new top-level command. 050's src/cli/sidecar.ts is WITHDRAWN. + +### B3 — claude-code webSearch write gate is REQUIRED in L4 (fixes 040) +- src/server/management/agent-settings-routes.ts:1064 writes webSearchSidecar.model ungated → same membership gate as /api/sidecar-settings (shared helper in src/server/management/web-search-sidecar-options.ts, mirroring vision-sidecar-options.ts placement; extraction happens IN L4, so L5 never restacks routes — also resolves the L5 write-gate.ts smell). +- `ocx claude config set --web-model` rides the same route → covered. +- Out of scope (explicit): `ocx config set webSearchSidecar.model` raw JSON writes bypass management gates by design (operator escape hatch, same as vision today). +- GUI contract: GET must send webSearchModels: [] when empty, never omit (dashboard-shared.ts:273 omission fallback would show the full union). Persisted-but-now-illegal model: display-grandfather into options (same as vision GET :115) but reject NEW writes. + +### B4 — default-backend decision split & pinned (fixes 030) +- resolveSidecarBackend(explicit) keeps today's contract: unset → openai, no auth argument (web-search-anthropic.test.ts:58 assertion unchanged). +- resolveVisionBackend keeps today's contract: unset → anthropic when OAuth credential exists. +- The "전역 플래그로 맞춘다" issue sentence is satisfied by both resolvers CONSUMING resolveSidecarAuth for credential presence (shared auth state), NOT by unifying their default preference. Changing dual-auth default preference is a user-facing behavior change #2188 never ordered → OUT OF SCOPE, recorded for a follow-up issue. +- L3 no longer touches src/vision/index.ts at all (removes the cross-surface smell). + +### Corrections +- 001: isCodexAuthContextUsable is auth-context.ts:612. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/000_wp0_branch_worktree_cleanup.md b/devlog/_plan/260820_sidecar_selection_unification/000_wp0_branch_worktree_cleanup.md new file mode 100644 index 0000000000..c8a0370614 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/000_wp0_branch_worktree_cleanup.md @@ -0,0 +1,112 @@ +# WP0 cleanup — EXECUTED RECORD (session 01a01f4b, performed 2026-08-20) + +STATUS: HISTORICAL. Every deletion below was executed during wp0 and verified against +live state afterwards (post-check 2026-08-21: 33 local branches remain, 0 deleted +remote refs resurrected, 9 worktrees). Nothing in this file is a pending command. +Anyone repeating a cleanup of this shape MUST run the preflight template at the end +against CURRENT state first; this snapshot is not reusable as a target list. + +## Protected set (mechanical, applied before every batch) + +The protected set was computed mechanically, not by eye, and deletion aborted on any +intersection: `dev`, `main`, `preview`, every open-PR head (31 at snapshot time), +every branch checked out in any worktree, and every dirty worktree. KEEP entries +below are the rows the protected set excluded from their surrounding batch. + +## Worktrees removed (were all clean; content preserved in dev or a surviving ref) + +- /private/tmp/ocx-m2148.LzD2/wt (absorb-baseurl-override, merged) +- tmp.bxVhqaJyPc/sweeper (tmp-reclaim-1-sweeper, merged) +- tmp.bzZ2ssU8WM/wp1b (split-wp1b-type-clusters, merged) +- tmp.gLNBuhAyoP (detached d0cd99672, merge of two dev ancestors, nothing unique) +- tmp.LfX0NlBXvp/r1876 (ingw/fix-windows-v2-catalog-blocking-1852, merged) +- tmp.Mb171xHMCb/r2031 (ingw/fix-mimo-vision-1927, merged) +- tmp.pQMnjf3VMg/wp1 (split-wp1-types, merged) +- tmp.vSBe0MZ0LP/w2080 (pr2080, PR merged) +- tmp.xfjQ3jxADE/w1934 (pr1934, PR merged) +- tmp.2IOChwQmxR/wp1b + tmp.t3YTdy1JDC/wp1b (detached b2ac2500c) — removed ONLY + after preservation branch wip/wp1b-superseded-b2ac2500c was created at b2ac2500c + and verified (unique cherry patches; superseded by a0f8c0135 in dev). +- ~/.codex/worktrees/3a35 (devlog-release-2280, merged) +- ~/.codex/worktrees/3b3b (cursor-call-release-note-2, merged, upstream gone) +- ~/.codex/worktrees/83d5 (tmp-reclaim-2-doctor, merged) +- ~/.codex/worktrees/c6d8 (zcode-client, merged) +- ~/.codex/worktrees/fe69 (detached 63bfd149d, clean, reachable from many branches) +- ~/.codex/worktrees/land-1842 (clean, PR #1842 CLOSED, 0 unique patches) +- .tmp/pr-2045-review (b92bb611c; PR2045 merged into dev as 0161a66d9) +- .tmp/pr1903-review-8c38989f4 (PR1903 merged; commit kept by remotes/review/pr1903) + +## Worktrees kept (dirty or otherwise protected — never in a removal batch) + +- /private/tmp/opencodex-pr2068.uXcKNC (detached 5a4068bbd, kept by branch + pr2068-check; PR 2068 OPEN) +- tmp.UFYNSQT3qw/land1920 (DIRTY, 2 changes + 3 unique commits) +- ~/.codex/worktrees/648b (DIRTY, 1 change) +- ~/.codex/worktrees/71a2 (DIRTY, 1 change; split-wp2a-config-names stays checked out) + +## Local branches deleted + +- Merged into origin/dev (git branch --merged proof at snapshot): all 46 merged + branches except dev and split-wp2a-config-names (checked out in a kept worktree). +- Unmerged but 0 unique patches vs dev (git cherry all '-'): + absorb-account-entitlement-stacked, absorb-capability-evidence, + absorb-k12-short-window, absorb-xai-oauth-streaming, + consolidate-prompt-cache-retention, fix-bearer-admission-2132, land-1842 + (PR closed), land-1876, ocx/integration, ocx/verify-2167. + +## Local branches kept (unique commits or open PR) + +combo-quota-badges (PR1704 OPEN), compat-multiagent-v2-catalog (4u), devlog-merge-log +(1u), devlog-three-issues (PR2181 OPEN), external-vision (1u), +issue-quality-provider-defect-bug-label (1u), land-1920 (3u+dirty wt), +cursor-call-prerebase-260818 (2u), ocx-dev-verify (1u), ocx/rebuild-2178 (1u), wip/* +(unique, incl. wip/wp1b-superseded-b2ac2500c), pr2053-check (2u), pr2056-check (1u), +pr2068-check (PR OPEN), pr2072-check (PR OPEN), pr2101-probe (5u), pr2105tmp (3u), +codex/merge-loop-closeout (2 unique local commits), main, preview, dev. + +## Remote branches deleted (origin) + +- 36 merged-into-origin/dev refs, none an open-PR head. The original 37-row list + mistakenly included codex/merge-loop-closeout; the executed batch EXCLUDED it (it + is a local-only KEEP with 2 unique commits and had no remote ref to delete): + codex/absorb-agentrouter-language-framing, codex/absorb-antigravity-thought-signatures, + codex/absorb-baseurl-override, codex/absorb-claude-shell-hook-gate, + codex/absorb-fastwire-native-chat, codex/absorb-oauth-superseded-commit, + codex/absorb-openai-chat-padding-repeats, codex/absorb-opencode-free-static-headers, + codex/absorb-opencode-go-quota-siblings, codex/absorb-responses-id-backfill, + codex/absorb-shadow-helper-attribution, codex/absorb-tool-search-passthrough, + codex/audit-closeout, codex/audit-record, codex/audit-shadow-marker-leak, + codex/audit-tool-search-id, codex/devlog-audit, codex/devlog-release-2280, + codex/fix-admission-bearer-transport, codex/fix-audit-record-scan, + codex/fix-privacy-scan-devlog, codex/fix-subagent-roster-truncation, + codex/fix-windows-ci-shards, codex/harden-core-lab-guard, + codex/logs-intercepted-helper-attribution, codex/merge-loop-outcome, + codex/openai-chat-tool-call-heartbeat, codex/promote-2.28.0, codex/split-wp1-types, + codex/split-wp1b-type-clusters, codex/split-wp2a-config-names, + codex/sync-preview-2.28.0, codex/windows-shard-truncation-and-budgets, + ingw/docs-tool-search-troubleshooting-1872, ingw/fix-mimo-vision-1927, + ingw/fix-windows-v2-catalog-blocking-1852 +- Unmerged, 0 unique, PR closed/merged: codex/absorb-account-entitlement-stacked, + codex/absorb-capability-evidence, codex/absorb-k12-short-window, + codex/absorb-xai-oauth-streaming, codex/consolidate-prompt-cache-retention, + codex/fix-bearer-admission-2132, codex/land-1842, codex/land-1876 + +## Preflight template (mandatory for any future cleanup batch) + +Run immediately before EACH delete batch; abort the batch on any intersection: + +1. `git worktree list --porcelain` — collect worktree paths and checked-out branches + (this reports metadata only, NOT status). Then for EACH listed path run + `git -C status --porcelain`; any output marks that worktree dirty. + Protect both the dirty path and its attached branch (detached dirty worktrees + protect the path itself). +2. `gh pr list --state open --json headRefName` — collect every open-PR head. +3. Protected = {dev, main, preview} ∪ open-PR heads ∪ checked-out branches ∪ + dirty-worktree branches ∪ dirty-worktree PATHS (a detached dirty worktree has + no branch — its path itself is the protected row). `comm -12` the sorted + candidate list against sorted Protected; any overlap aborts the whole batch, + not just the row. +4. For unmerged candidates, re-prove 0 unique patches with `git cherry dev ` + at execution time; a snapshot proof is stale the moment the tree moves. +5. Detached commits require a durable preservation ref (branch or tag) verified with + `git rev-parse` BEFORE the containing worktree is removed. diff --git a/devlog/_plan/260820_sidecar_selection_unification/001_research_current_state.md b/devlog/_plan/260820_sidecar_selection_unification/001_research_current_state.md new file mode 100644 index 0000000000..147d1e4e6c --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/001_research_current_state.md @@ -0,0 +1,46 @@ +# 001 — Research: current sidecar selection state (#2188) + +Verified against dev @ f2ebd3067 (2026-08-20). + +## Auth pieces (scattered today) +- Codex/ChatGPT: `listOpenAiForwardSidecarCandidates` (src/providers/openai-sidecar.ts:56) — canonical forward provider, pinned baseUrl; `isCodexAuthContextUsable` (src/codex/auth-context.ts:613) — per-context account usability. +- Anthropic: `findAnthropicSidecarProvider` (src/web-search/index.ts:87) and `findAnthropicVisionProvider` (src/vision/index.ts:219) — DUPLICATED predicate: enabled + adapter==="anthropic" + authMode==="oauth" + active account needsReauth!==true. + +## Backend resolution asymmetry (issue-confirmed) +- Web-search `resolveSidecarBackend` (src/web-search/index.ts:104-108): explicit anthropic else openai. types/config.ts:787-796 comment claims "unset prefers anthropic" — WRONG vs code. +- Vision `resolveVisionBackend` (src/vision/index.ts:231-236): unset prefers anthropic when credential exists. Opposite default. + +## Picker sets +- `visibleNativeSlugs` (src/codex/catalog/metadata.ts:331): nativeOpenAiSlugs − disabled − alias-shadowed. +- `listManagementModelRows` (src/server/management/model-rows.ts:50): native rows (incl. disabled, flagged) + account-bound + routed catalog rows. +- `visionCandidateRows` (src/server/management/vision-sidecar-options.ts:45): rows.filter(disabled !== true) — close to picker policy but no auth-slot concept. + +## Vision candidate expansion defect +- `visionEligibleModelOptions` (src/vision/eligibility.ts:201): iterates ALL passed candidates + baselines. Candidates from visionCandidateRows = full catalog (all providers' rows), not picker-limited native set; anthropic side gated only by provider name match. + +## Write gates +- Vision: PUT /api/sidecar-settings (config-routes.ts:584) rejects via `visionDescriberIsProvablyBlind`. Claude-code override shares module. +- Web-search: config-routes.ts:604-606 persists webSearch.model verbatim. NO GATE. + +## GUI +- gui/src/pages/dashboard-overview-sections.tsx + use-dashboard-data.ts render webSearch/vision sidecar settings; GET /api/sidecar-settings returns visionModels options but NO webSearchModels options list. + +## CLI +- No ocx sidecar command exists (src/cli/ has no sidecar.ts; only GUI/PUT paths). + +## Tests nearby +tests/vision-eligibility.test.ts, tests/sidecar-settings-vision-filter.test.ts, tests/web-search.test.ts, tests/sidecar-settings-vision-controls.test.ts, tests/claude-sidecar-override.test.ts. + +## Executors that exist today (probe-relevant) +- openai: src/web-search/executor.ts (ChatGPT forward /responses hosted web_search). +- anthropic: src/web-search/anthropic-executor.ts (web_search_20250305 via OAuth Messages). +- NO gemini/grok/zen/exa executor → per #2188 filter rule 2, only openai+anthropic can be active web-search backends in this unit. + + +## CORRECTION (post-audit) +- isCodexAuthContextUsable is src/codex/auth-context.ts:612 (not 613). +- CLI: `ocx agent sidecar ` ALREADY EXISTS (src/cli/agent.ts:23) writing PUT /api/sidecar-settings. The gap is only: no --list surface, and the PUT it calls has no web-search membership gate. "No ocx sidecar command exists" above is WRONG. +- Additional ungated write path: PUT /api/claude-code writes webSearchSidecar.model verbatim (src/server/management/agent-settings-routes.ts:1064); `ocx claude config set --web-model` rides it. +- GUI contract: dashboard-shared.ts:273 — an OMITTED visionModels key falls back to the full openai+anthropic union; [] means none. Any new webSearchModels key must always be present. +- GET /api/sidecar-settings grandfathers the persisted vision model into options (config-routes.ts:115). + diff --git a/devlog/_plan/260820_sidecar_selection_unification/002_protocol_research.md b/devlog/_plan/260820_sidecar_selection_unification/002_protocol_research.md new file mode 100644 index 0000000000..93b0a78ab5 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/002_protocol_research.md @@ -0,0 +1,68 @@ +# 002 — Hosted web-search protocol research (규약, verified 2026-08-20) + +Luna swarm (5 lanes) + primary-source verification. All findings below were source-opened (official docs) unless flagged lead. Supersedes the doc-only table in 031 with verified wire contracts. + +## OpenAI Responses (current openai backend) +- Tool: `{"type":"web_search"}` (legacy: web_search_preview; preview models gpt-4o-*-search-preview shut down 2026-07-23). +- Output item `web_search_call`, id prefix `ws_`; action.type ∈ search|open_page|find_in_page; sources via include: ["web_search_call.action.sources"]. +- filters.allowed_domains / blocked_domains ≤ 100 each (web_search only, not preview); external_web_access toggle. +- SSE: response.web_search_call.in_progress|searching|completed (item_id, output_index, sequence_number). +- $10/1k calls (+ content tokens). [developers.openai.com web-search guide; platform pricing] + +## Anthropic Messages (current anthropic backend) +- Tool versions: web_search_20250305 (basic, direct-call default, ZDR-eligible), web_search_20260209 (dynamic filtering via code_execution_20260120; allowed_callers defaults to code-exec — direct use requires allowed_callers:["direct"]), web_search_20260318 (response-inclusion control). 20250305 NOT deprecated. +- Blocks: server_tool_use (id prefix srvtoolu_) → web_search_tool_result (tool_use_id pairing); encrypted_content MUST be replayed unchanged in continuations or 400. +- SSE: content_block_start(server_tool_use) → input_json_delta → content_block_stop → content_block_start(web_search_tool_result); usage server_tool_use.web_search_requests in message_delta. +- max_uses cap → web_search_tool_result_error(max_uses_exceeded); org-level enablement required else 400. +- NOT on Bedrock; Vertex basic-only. $10/1k searches, failures unbilled. [platform.claude.com web-search-tool, server-tools, streaming] + +## xAI Grok Responses (future backend candidate) +- POST api.x.ai/v1/responses; tools `{"type":"web_search"}` / `{"type":"x_search"}`; output items web_search_call / x_search_call (server-executed, NOT function_call). +- web_search: filters.allowed_domains ≤ 5, allowed/excluded mutually exclusive. x_search: allowed_x_handles ≤ 20 on tool object (NOT nested under filters). +- include: web_search_call.action.sources documented; x_search_call sources selector UNDOCUMENTED → live probe required. Id prefixes undocumented → treat opaque, live probe required (matches #2190). +- Responses SSE event names NOT documented (only SDK chunk.tool_calls) → probe required before relay implementation. +- Live Search: no formal deprecation notice found (issue #2188 text says 2026-01 deprecate — docs do not confirm; treat as legacy either way). $5/1k per tool. [docs.x.ai tools/*, pricing, release-notes] + +## Google Gemini (future backend candidate) +- Legacy generateContent: tools [{google_search: {}}] (older models: google_search_retrieval); response candidates[].groundingMetadata {webSearchQueries, searchEntryPoint.renderedContent, groundingChunks[].web{uri,title}, groundingSupports[].segment+groundingChunkIndices}. Chunk indices accumulate across stream. +- Interactions API: tools [{type:"google_search"}]; steps google_search_call (id ex. search_call_19201, arguments.queries[], search_type web_search|image_search|enterprise_web_search, optional signature) → google_search_result (call_id) → model_output with inline URL annotations. SSE: interaction.created, step.start|delta|stop, interaction.completed, done. +- Stateless clients must replay id + encrypted signature manually. Tool-choice: validated mode required with tool-context circulation; auto unsupported. +- Auth x-goog-api-key; standard-key support ends 2026-09. Pricing: Gemini 3.x 5,000 free searches/mo then $14/1k per actual query; ≤2.5 models $35/1k per grounded prompt. [ai.google.dev grounding, interactions-api, pricing] + +## Non-LLM vendors (Exa-class lane, #414) +- Exa: POST api.exa.ai/search, x-api-key or Bearer; {query, type, numResults, contents} → {requestId, results[{title,url,id,publishedDate,text/highlights/summary}], costDollars}. SSE only with outputSchema (OpenAI chat-chunk shaped). +- Tavily: POST api.tavily.com/search, Bearer tvly-*; plain JSON, no SSE. $0.008/credit. +- Brave: GET api.search.brave.com/res/v1/web/search, X-Subscription-Token; plain JSON. $5/1k. +- OpenCode upstream now uses MCP JSON-RPC (mcp.exa.ai/mcp, search.parallel.ai/mcp; tools/call name="web_search") — NOT a Responses hosted tool. Zen /zen/go/v1/responses hosted web_search: LEAD ONLY, inconsistent SSE observed, {"type":"remote_tool"} rejected by backend; #1616's probe claim needs fresh re-verification before any Zen backend work. + +## Consequences for this unit +1. 031's future-descriptor probe contracts updated by this doc (xAI/Gemini both need live probes for SSE + id shapes; Zen demoted to lead). +2. Anthropic executor (anthropic-executor.ts) currently pins web_search_20250305 — fine (not deprecated, ZDR-eligible, direct default). Upgrading to 20260209 would REQUIRE allowed_callers:["direct"] — record as follow-up, not this unit. +3. encrypted_content replay + srvtoolu_ pairing are existing executor obligations — verify tests cover replay-unchanged before touching anthropic paths in L3. + + +## LIVE PROBE RESULTS (2026-08-21, this machine, ocx credentials) + +All five lanes verified live. Raw scripts in .tmp/probes/ (gitignored scratch). + +### OpenAI (ChatGPT forward) — PASS, shipped executor +runWebSearch via main-account token against chatgpt.com/backend-api/codex/responses, model gpt-5.6-luna: 287 text chars, 2 sources with url+title. Executor path proven end to end. + +### Anthropic (stored OAuth) — PASS, shipped executor +runAnthropicWebSearch via anthropic OAuth, model claude-haiku-4-5, web_search_20250305: 150 result chars, outcome keys {text, sources}. Executor path proven end to end. + +### xAI Responses (Grok OAuth, api.x.ai/v1/responses, grok-4.6) — PASS with two contract findings +- web_search: HTTP 200. SSE events response.web_search_call.in_progress|searching|completed (6 each), item types reasoning/web_search_call/message, id prefixes rs_/ws_/msg_. Matches the OpenAI-shaped contract 002 predicted; the undocumented SSE names are now probe-confirmed. +- x_search: HTTP 200 BUT the server emits it as custom_tool_call items (ctc_ prefix) with response.custom_tool_call_input.delta/done events — NOT x_search_call as docs.x.ai implies for Responses. allowed_x_handles accepted (200). Consequence for #2190: the OAuth transport's wire item is custom_tool_call; #2173's ctc_ prefix handling already covers the id family, but a dedicated x_search_call extractor would see nothing on this transport. Re-probe with an api.x.ai API key before assuming parity. + +### Gemini (Antigravity CCA OAuth) — PASS +v1internal:generateContent envelope (project from stored credential, ANTIGRAVITY_REQUEST_UA, wireModelId gemini-3.7-flash-tiered) with tools [{google_search:{}}]: HTTP 200, grounded answer, groundingMetadata {webSearchQueries:2, groundingChunks:2, groundingSupports:1, searchEntryPoint present}. Plain "antigravity" UA gets 404 (fingerprint gate) — any future executor must reuse the adapter's UA + envelope builder. +NOTE: this proves the CCA transport grounds; AI-Studio-key transport (x-goog-api-key) remains unprobed (no key on this machine). + +### Exa /search — PASS (new account, key stored at ~/.opencodex/.exa-probe-key, 0600) +POST api.exa.ai/search x-api-key: HTTP 200, {requestId(32-hex), resolvedSearchType, results[3]{id,title,url,publishedDate,text,image,favicon}, searchTime, costDollars{total:0.007}}. result.id === result.url confirmed. resolvedSearchType still present despite docs marking it deprecated. Non-LLM JSON lane shape confirmed for a future SidecarOutcome mapping. + +### Registry consequences +- xAI + Gemini(CCA) + Exa all clear the "live probe" half of the WEB_SEARCH_BACKENDS activation bar. Still missing: executors + wire mapping (extractor/relay) per backend — activation stays blocked on the executor half, as designed. +- The x_search custom_tool_call finding narrows #2190 step 1: OAuth-transport probes are done, API-key transport still required. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/003_grok_tools_research.md b/devlog/_plan/260820_sidecar_selection_unification/003_grok_tools_research.md new file mode 100644 index 0000000000..2c41d988e9 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/003_grok_tools_research.md @@ -0,0 +1,36 @@ +# 003 — Grok built-in tool deep research (2026-08-21, Luna swarm 2 + live OAuth probes) + +## Full built-in tool inventory (docs.x.ai, primary) +| Tool | tools[].type | Output item | Price | +|---|---|---|---| +| Web search | web_search | web_search_call | $5/1k | +| X search | x_search | x_search_call (docs) / custom_tool_call (observed) | $5/1k | +| Code execution | code_interpreter | code_interpreter_call | $5/1k | +| Collections/RAG | file_search | file_search_call | $2.50/1k | +| Remote MCP | mcp | mcp_call | tokens only | +| Image generation | image_generation | image_generation_call | Imagine rates | +Internal server-side sub-tools (not request types): search_images, view_image, view_x_video, attachment_search ($10/1k when files attached). + +## Live OAuth-transport captures (this machine, grok-4.6) +- web_search + include ["web_search_call.action.sources"]: ws_ item carries action {type:"search", query, sources:[{type:"url",url}...]}. VERIFIED live. +- Annotation SSE envelope (VERIFIED live): response.output_text.annotation.added { annotation: {type:"url_citation", url, start_index, end_index, title}, item_id: msg_..., annotation_index, content_index, output_index }. +- x_search: server emits custom_tool_call items — names observed live: x_user_search; community capture (Vercel ai#10607, API-KEY transport): x_semantic_search. id prefix ctc_, call_id prefix xs_call-. NOT x_search_call on either transport in practice → parse annotations for sources, tolerate both discriminators. +- Inline citation text format: [[N]](url); disable via include ["no_inline_citations"]. +- response.citations array documented as always-returned post-tool-execution (docs) — not asserted in our stream capture; treat as secondary channel. + +## Params (validated limits) +- web_search: filters.allowed_domains XOR excluded_domains, ≤5 each; enable_image_search, enable_image_understanding. +- x_search: allowed_x_handles XOR excluded_x_handles, ≤20 each; from_date/to_date ISO-8601 inclusive; enable_image_understanding, enable_video_understanding (video is X-only). +- max_turns bounds agentic turns; multiple tool calls can run parallel within a turn; multiple output indexes per response (SDK changelog fix) → reducer-style parsing, never assume 1 tool item. +- tool_choice forced form documented only for functions — do NOT assume forced built-ins. +- action may be ABSENT on response.output_item.added (skeleton-first; fills at .searching) → optional field. + +## Transport verdict +OAuth (Grok CLI creds via auth.x.ai) hits the same api.x.ai/v1/responses with Bearer; hosted-tool JSON identical; entitlement 403 is the failure mode distinct from wire errors. API key is the documented default. Our executor uses the stored xai OAuth (present on this machine), fail-closed on 401/403. + +## Executor consequences (070) +1. Sources = union of (a) message annotations url_citation urls, (b) ws action.sources urls when include requested. Dedupe by url. +2. Accept both x_search_call and custom_tool_call (name x_*) as x-search activity markers; never fail parse on unknown item types. +3. Buffer text from response.output_text.delta on msg items; strip [[N]](url) markers optional — keep text as-is (they're valid markdown), collect annotations as sources. +4. Bound raw SSE bytes like parseSidecarSSE does; timeout via settings.timeoutMs. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/010_layer1_sidecar_auth.md b/devlog/_plan/260820_sidecar_selection_unification/010_layer1_sidecar_auth.md new file mode 100644 index 0000000000..ebe01e14ef --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/010_layer1_sidecar_auth.md @@ -0,0 +1,40 @@ +# 010 — Layer 1: shared sidecar auth module (wp2) + +Branch: codex/sidecar-auth-slots (base: dev). PR bottom of stack, targets dev. + +## New file: src/sidecar/auth.ts +```ts +export interface SidecarAuthState { + isCodexAuth: boolean; // ChatGPT LOGIN usable (not mere provider presence) + isAnthropicAuth: boolean; // enabled anthropic-adapter OAuth provider w/ active !needsReauth account + anthropicProviderName?: string; + anthropicProvider?: OcxProviderConfig; +} +export function resolveSidecarAuth(config: OcxConfig): SidecarAuthState +// isCodexAuth = listOpenAiForwardSidecarCandidates(config).length > 0 +// && ( isCodexAccountUsable(config, MAIN_CODEX_ACCOUNT_ID) // live ~/.codex/auth.json token +// || (config.codexAccounts ?? []).some(a => +// isSelectableCodexPoolAccount(a) && isCodexAccountUsable(config, a.id)) ) +// (src/codex/account-usability.ts:17 — request-context-free, symmetric with Anthropic) +// isAnthropicAuth + provider = the shared predicate now duplicated in +// findAnthropicSidecarProvider (web-search/index.ts:87) and findAnthropicVisionProvider (vision/index.ts:219) + +export const AUTH_SLOT_MODELS = { codex: "gpt-5.6-luna", anthropic: "claude-haiku-4-5" } as const; +export function sidecarAuthSlots(auth: SidecarAuthState): Array<{ provider: string; id: string; slot: "codex" | "anthropic" }> +// codex slot when isCodexAuth; anthropic slot (provider = anthropicProviderName) when isAnthropicAuth +``` + +## Refactors (behavior-preserving) +- src/web-search/index.ts: findAnthropicSidecarProvider delegates to resolveSidecarAuth (keep export). +- src/vision/index.ts: findAnthropicVisionProvider delegates likewise. +- No caller behavior change in this layer. + +## Tests: tests/sidecar-auth.test.ts +- isCodexAuth FALSE when forward provider exists but no live main token and no usable pool account (the B1 pin). +- isCodexAuth TRUE with live main token; TRUE with usable selectable pool credential only. +- isAnthropicAuth false when: disabled, wrong adapter, key auth, needsReauth active account, no account set. +- Slots: hidden/disabled Luna & Haiku still emitted when auth present (core #2188 invariant). +- Delegation equivalence for both find* helpers. + +## Verify: bun x tsc --noEmit && bun test tests/sidecar-auth.test.ts tests/web-search.test.ts tests/vision-eligibility.test.ts + diff --git a/devlog/_plan/260820_sidecar_selection_unification/020_layer2_picker_candidates.md b/devlog/_plan/260820_sidecar_selection_unification/020_layer2_picker_candidates.md new file mode 100644 index 0000000000..7c04dac326 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/020_layer2_picker_candidates.md @@ -0,0 +1,27 @@ +# 020 — Layer 2: unified picker candidate function + vision set (wp3) + +Branch: codex/sidecar-picker-candidates (base: codex/sidecar-auth-slots). + +## New file: src/sidecar/candidates.ts +```ts +export interface SidecarCandidate { provider: string; id: string; native?: boolean; inputModalities?: string[]; authSlot?: boolean } +export async function pickerVisibleSidecarCandidates(config: OcxConfig, auth: SidecarAuthState): Promise +// = listManagementModelRows(config).filter(disabled !== true) (catalog outage → []) +// ∪ sidecarAuthSlots(auth) marked authSlot: true (added even when hidden/disabled/absent) +// de-dup by provider+id; auth-slot flag wins. +export function visionSidecarCandidates(config, all: SidecarCandidate[]): SidecarCandidate[] +// = all − provably text-only (modelAcceptsImageInput(config, c) === false) +// auth slots carry inputModalities ["text","image"] like baselineCandidate today. +``` + +## Changes +- src/server/management/vision-sidecar-options.ts: visionCandidateRows → wrapper over pickerVisibleSidecarCandidates (keeps export shape); visionModelOptionsFrom feeds visionEligibleModelOptions ONLY picker-visible+auth-slot candidates. Baseline injection in visionEligibleModelOptions stays but baselines == auth slots when auth present; without auth, current baseline fallback preserved (no regression for fresh installs). +- Keep visionDescriberIsProvablyBlind gate semantics unchanged (write gate ≠ suggestion list). + +## Tests: tests/sidecar-candidates.test.ts (+ update sidecar-settings-vision-filter.test.ts) +- Hidden native slug (disabledModels) disappears from options; Luna survives via auth slot. +- Routed provider's catalog row visible in rows appears; text-only proven row excluded. +- Catalog outage → auth slots + baselines only. + +## Verify: bun x tsc --noEmit && bun test tests/sidecar-candidates.test.ts tests/sidecar-settings-vision-filter.test.ts tests/vision-eligibility.test.ts tests/catalog-vision-sidecar-modalities.test.ts + diff --git a/devlog/_plan/260820_sidecar_selection_unification/030_layer3_websearch_slots.md b/devlog/_plan/260820_sidecar_selection_unification/030_layer3_websearch_slots.md new file mode 100644 index 0000000000..fbdf3cec87 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/030_layer3_websearch_slots.md @@ -0,0 +1,33 @@ +# 030 — Layer 3: web-search candidate set + backend registry (wp4) + +Branch: codex/sidecar-websearch-slots (base: codex/sidecar-picker-candidates). + +## New file: src/web-search/backends.ts (probe/executor registry) +```ts +export interface WebSearchBackendDescriptor { + backend: "openai" | "anthropic"; + hasExecutor: true; + probe: "chatgpt-forward" | "anthropic-oauth"; // auth presence == probe for these two + eligibleModel(candidate: SidecarCandidate): boolean; +} +export const WEB_SEARCH_BACKENDS: WebSearchBackendDescriptor[] // openai + anthropic only (001/002: no other executor) +export function webSearchSidecarCandidates(config, auth, all: SidecarCandidate[]): SidecarCandidate[] +// = (picker-visible ∪ auth slots) ∩ (backend active: auth flag true + executor exists + model family matches) +// openai backend: native rows + Luna slot; anthropic backend: anthropicProviderName rows + Haiku slot. +``` +Future backends (Gemini/Grok/Zen/Exa): descriptor probe contracts recorded in 002/031; NOT registered. + +## Config/docs alignment (NO default-behavior change — B4) +- src/types/config.ts:787-796: fix the lying comment to match code ("unset resolves to openai"). +- resolveSidecarBackend keeps EXACT contract: unset → openai, explicit-only anthropic (web-search-anthropic.test.ts:58 assertion UNTOUCHED). +- resolveVisionBackend UNTOUCHED (unset → anthropic-if-credential). L3 does NOT edit src/vision/index.ts. +- planWebSearch consumes resolveSidecarAuth for credential presence (replacing its inline findAnthropicSidecarProvider call) — presence only, not preference. resolveDefaultSidecarBackend is WITHDRAWN; dual-auth preference unification deferred to a follow-up issue. +- DEFAULT_SIDECAR_MODEL stays gpt-5.6-luna; DEFAULT_ANTHROPIC_SIDECAR_MODEL stays claude-sonnet-5; auth SLOTS stay Luna/Haiku (issue text). + +## Tests: tests/web-search-candidates.test.ts +- No Codex login (provider present, no token) → openai side inactive → native rows + Luna absent; Haiku present when anthropic auth. +- Hidden Luna + Codex login → present. Model outside both backend families → absent. +- resolveSidecarBackend(undefined) === "openai" still green (existing test untouched). + +## Verify: bun x tsc --noEmit && bun test tests/web-search-candidates.test.ts tests/web-search.test.ts tests/web-search-anthropic.test.ts + diff --git a/devlog/_plan/260820_sidecar_selection_unification/031_future_backend_research.md b/devlog/_plan/260820_sidecar_selection_unification/031_future_backend_research.md new file mode 100644 index 0000000000..acd147df65 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/031_future_backend_research.md @@ -0,0 +1,13 @@ +# 031 — Future web-search backend research table (doc-only) + +Recorded from issue #2188 research (2026-08-20, docs not live probes). These are NOT registered backends; each needs live probe + executor before entering WEB_SEARCH_BACKENDS (filter rule 2). + +| Candidate | Protocol | Tool/endpoint | Probe contract before activation | +| --- | --- | --- | --- | +| Gemini | Gemini/Interactions | google_search grounding | API-key probe: grounding metadata + citations round-trip; simultaneous-tool limit check | +| xAI Grok | Responses | { type: "web_search" } | api.x.ai key probe: 200 + web_search_call item + allowed_domains behavior | +| OpenCode Zen | Responses | hosted web_search | POST …/zen/go/v1/responses probe (#1616 evidence 2026-08-13) re-verified fresh | +| Exa-class vendors | own Search API | JSON → SidecarOutcome mapping | not an LLM; separate lane from hosted-tool probes (#414) | + +Each future descriptor must state: probe fn, executor module, eligibleModel predicate, id/citation wire mapping. Until then the union in config stays "openai" | "anthropic". + diff --git a/devlog/_plan/260820_sidecar_selection_unification/040_layer4_write_gates_gui.md b/devlog/_plan/260820_sidecar_selection_unification/040_layer4_write_gates_gui.md new file mode 100644 index 0000000000..d7a96e80dc --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/040_layer4_write_gates_gui.md @@ -0,0 +1,26 @@ +# 040 — Layer 4: management API write gates + GUI lists (wp5) + +Branch: codex/sidecar-write-gates (base: codex/sidecar-websearch-slots). + +## New file: src/server/management/web-search-sidecar-options.ts (extraction happens HERE, not L5) +- webSearchModelOptionsFor(config): candidate option list from webSearchSidecarCandidates. +- webSearchModelIsRejected(config, requested): membership gate — reject when requested is neither a candidate nor an auth-slot model; empty string always allowed (clears). +- Shared by BOTH routes below (mirrors vision-sidecar-options.ts pattern). + +## Server +- config-routes.ts GET /api/sidecar-settings: add webSearchModels — ALWAYS present, [] when empty (dashboard-shared.ts:273 omission fallback). Display-grandfather the persisted model into options (parity with vision GET :115) while rejecting NEW illegal writes. +- PUT /api/sidecar-settings webSearch.model: 400 with error naming the filter when webSearchModelIsRejected. +- PUT /api/claude-code (agent-settings-routes.ts:1064): SAME gate, REQUIRED — covers ocx claude config set --web-model. +- Out of scope (explicit): ocx config set webSearchSidecar.model raw JSON writes (operator escape hatch, same as vision). +- Vision PUT unchanged (provably-blind gate stays). + +## GUI +- use-dashboard-data.ts / dashboard-overview-sections.tsx: web-search model select consumes webSearchModels; [] renders empty-state, not full union. +- gui screenshot REQUIRED in PR body (enforce-target). + +## Tests +- new tests/sidecar-settings-web-search-gate.test.ts: PUT rejected for non-candidate; accepted for candidate + auth-slot; empty clears; claude-code route rejects the same id (今日 persists "claude-search" — update that fixture); GET always carries webSearchModels key. +- bun run lint:gui. + +## Verify: bun x tsc --noEmit && bun test tests/sidecar-settings-web-search-gate.test.ts tests/sidecar-settings-vision-controls.test.ts tests/claude-sidecar-override.test.ts && bun run lint:gui + diff --git a/devlog/_plan/260820_sidecar_selection_unification/050_layer5_cli_and_final.md b/devlog/_plan/260820_sidecar_selection_unification/050_layer5_cli_and_final.md new file mode 100644 index 0000000000..6cce459a02 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/050_layer5_cli_and_final.md @@ -0,0 +1,18 @@ +# 050 — Layer 5: CLI --list + docs + top-layer full validation (wp6) + +Branch: codex/sidecar-cli (base: codex/sidecar-write-gates). + +## CLI (extend EXISTING command — no new top-level command; src/cli/sidecar.ts WITHDRAWN) +- src/cli/agent.ts `ocx agent sidecar ` gains `--list`: prints the candidate sets from GET /api/sidecar-settings (webSearchModels / visionModels) — the exact sets the GUI sees, produced by the same server functions. +- Parse --list BEFORE the existing rejectArgs call (auditor note). +- Writes need no client-side gate: L4's server-side gate on the shared PUT covers CLI automatically. + +## Docs +- docs-site: web-search + vision pages updated (selection rules, auth slots, --list). English source only. + +## Final verification (top layer) +- bun run typecheck && bun run test (FULL suite) && bun run privacy:scan && bun run lint:gui +- gh pr list chain state recorded in goalplan c7. + +## Tests: extend existing CLI/agent tests for --list output parity with GET payload. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/060_layer6_backend_union.md b/devlog/_plan/260820_sidecar_selection_unification/060_layer6_backend_union.md new file mode 100644 index 0000000000..8083327c93 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/060_layer6_backend_union.md @@ -0,0 +1,24 @@ +# 060 — Layer 6: backend union widening, INERT (wp2) [rev 2, post-audit] + +Branch: codex/sidecar-backend-union (base: codex/sidecar-cli). + +## Principle (audit F1): union ≠ activation. This layer is INERT for new ids. +- src/types/config.ts backend union: "openai" | "anthropic" | "xai" | "gemini" | "exa". Comment: unset ALWAYS openai; new ids explicit-only AND inactive until their executor layer lands. +- src/web-search/index.ts: + - export type WebSearchBackendId = union above. + - resolveSidecarBackend stays PURE: known id → itself, else/undefined → "openai". + - planWebSearch: for "xai"|"gemini"|"exa" return undefined UNCONDITIONALLY in this layer (fail-closed inert — no plan means the normal routed path, identical to today's unknown-backend behavior). Each executor layer replaces its arm with the real credential-gated plan. This keeps L6 standalone-CI-green with zero dispatch risk (audit F1). + - shouldResolveOpenAiWebSearchSidecar: verify unchanged semantics (backend !== openai → false) for new ids — add test. +- config-routes.ts + agent-settings-routes.ts backend validation strings widened (webSearch only; claude-code override webSearchSidecar.backend union widened in the SAME commit — audit F3 partial: binary types in claude-code section body). +- gui claude-code-types.ts / dashboard-shared.ts SidecarBackend type: NOT widened here (GUI backend selector redesign is explicitly deferred to a follow-up issue — new backends are config/CLI-explicit only; document in docs-site later layer). Audit F3 resolution: GUI cannot select new backends in this program; the write gate + options stay model-centric for openai/anthropic; for xai/gemini the model field is honored, for exa ignored. File a follow-up issue for the GUI backend selector at program end. +- exaApiKey config field: added here as OcxWebSearchSidecarConfig.exaApiKey?: string with: PUT accepts string (empty clears), GET NEVER echoes it (assert), redact.ts gains "exaApiKey" in its key list (audit F4) + structured redaction test. +- structure/04_transports-and-sidecars.md + 05_gui-and-management-api.md: update the two-backend claims (audit F7). + +## Tests: tests/web-search-backend-union.test.ts +- resolveSidecarBackend(undefined)==="openai" pin; ("xai")==="xai". +- planWebSearch xai/gemini/exa → undefined (inert pin, will be flipped per layer). +- shouldResolveOpenAiWebSearchSidecar false for new ids. +- PUT backend "xai" ok / "zen" 400; exaApiKey set/clear; GET omits exaApiKey; redactSecrets strips exaApiKey. + +## Verify (audit F7): bun x tsc --noEmit && bun run test (FULL) per layer from now on. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/070_layer7_xai_executor.md b/devlog/_plan/260820_sidecar_selection_unification/070_layer7_xai_executor.md new file mode 100644 index 0000000000..c5b5aecff8 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/070_layer7_xai_executor.md @@ -0,0 +1,34 @@ +# 070 — Layer 7: xAI executor + x_search opt-in (wp3) [rev 2, consolidated] + +Branch: codex/sidecar-xai-executor (base: codex/sidecar-backend-union). + +## New file: src/web-search/xai-executor.ts (research: 003; wire probes 2026-08-21 all HTTP 200) +```ts +export interface XaiSearchOptions { xSearch?: boolean; allowedXHandles?: string[]; excludedXHandles?: string[]; fromDate?: string; toDate?: string; } +export function validateXaiSearchOptions(o): string | undefined // 20-handle cap, allow XOR exclude, ISO date shape +export async function runXaiWebSearch(query, providerName, provider, settings, options, abortSignal?): Promise +``` +- Token: getValidAccessToken(providerName) (stored xai OAuth). 401/403 → error outcome with entitlement-distinct message. Never throws. +- POST https://api.x.ai/v1/responses (canonical; provider.baseUrl consulted only if it matches the api.x.ai origin, else pinned) with redirect: "manual". +- Body: { model: settings.model (default "grok-4.6"), input: [{role:"user", content: query}], tools: [{type:"web_search"}, ...(options.xSearch ? [{type:"x_search", allowed_x_handles?/excluded_x_handles?/from_date?/to_date?}] : [])], include: ["web_search_call.action.sources"], reasoning: { effort: settings.reasoning }, stream: true }. All shapes probe-verified (reasoning+tools 200; both tools in one request 200; handles+dates 200) — no contingency paths. +- SSE reducer (003 rules): text ← response.output_text.delta on message items; sources ← url_citation annotations ∪ web_search_call action.sources, deduped by url; tolerate BOTH custom_tool_call and x_search_call items; action optional on output_item.added (skeleton-first); bound raw bytes like parse.ts; reasoning deltas ignored. + +## Config +- OcxWebSearchSidecarConfig gains xSearch?: { enabled?: boolean; allowedXHandles?: string[]; excludedXHandles?: string[]; fromDate?: string; toDate?: string }. +- PUT /api/sidecar-settings validates (400 on >20 handles, allow+exclude both set, malformed date); executor re-validates (defense in depth). GET echoes xSearch (no secrets involved). + +## Dispatch wiring (the audited path) +- SidecarPlan gains xaiSidecar?: { providerName: string; provider: OcxProviderConfig }. +- planWebSearch "xai" arm becomes REAL (flips 060's inert undefined): enabled provider named/oauthId "xai" + getAccountSet active !needsReauth → plan with xaiSidecar; else undefined (fail-closed). +- src/server/responses/core.ts (~:3583, where SidecarPlan unpacks into WebSearchLoopDeps): pass backend + xaiSidecar through. +- loop.ts: WebSearchLoopDeps gains xaiSidecar; dispatch switch gains "xai" arm → runXaiWebSearch with cfg.xSearch options. +- backends.ts registry: { backend:"xai", isActive: stored xai OAuth usable, eligibleModel: candidate.provider === "xai" }. + +## Tests: tests/xai-web-search.test.ts + loop integration +- validateXaiSearchOptions: 21 handles error; allow+exclude error; bad date error. +- SSE fixtures from live capture shapes: text assembly, source dedupe (annotations ∪ action.sources), custom_tool_call tolerated, absent action tolerated. +- 401 fixture → error outcome, no throw. PUT xSearch validation 400s. +- Loop-level integration: backend "xai" dispatches the xai executor (mocked), not runWebSearch. + +## Verify (per-layer full gate): bun x tsc --noEmit && bun run test && live probe via the actual executor (attest evidence). + diff --git a/devlog/_plan/260820_sidecar_selection_unification/080_layer8_gemini_executor.md b/devlog/_plan/260820_sidecar_selection_unification/080_layer8_gemini_executor.md new file mode 100644 index 0000000000..54e8e2813c --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/080_layer8_gemini_executor.md @@ -0,0 +1,24 @@ +# 080 — Layer 8: Gemini CCA executor (wp4) [rev 2, consolidated] + +Branch: codex/sidecar-gemini-executor (base: codex/sidecar-xai-executor). + +## New file: src/web-search/gemini-executor.ts (probe: 002 LIVE PROBE) +```ts +export async function runGeminiWebSearch(query, providerName, provider, settings, abortSignal?): Promise +``` +- Credential: getValidAccessTokenSnapshot(providerName) + projectId from the active stored credential. Missing projectId → error outcome naming re-login. Never throws. +- Destination PINNED to the registry canonical CCA endpoint exactly as src/server/images.ts:211 does — provider.baseUrl is NOT trusted for the OAuth-bearing request (mutable-URL credential leak). redirect: "manual". +- POST {pinned}/v1internal:generateContent (non-stream; grounded answers are short) with envelope: { model: wireModelId, userAgent: "antigravity", requestType: "agent", project, requestId: "agent-"+uuid, request: { contents: [user query], tools: [{google_search:{}}], sessionId: uuid, generationConfig?: { thinkingConfig: { thinkingLevel } } } }. +- Reasoning: settings.reasoning maps through resolveAntigravityEffortWireModel(settings.model default "gemini-3.7-flash", effort, pinnedBase) → { wireModelId, thinkingLevel }; thinkingLevel set when returned, NOT discarded. +- Headers: User-Agent: ANTIGRAVITY_REQUEST_UA (002: plain UA gets 404), Authorization Bearer. +- Mapping: candidates[0].content.parts[].text joined → text; groundingMetadata.groundingChunks[].web {uri,title} → sources; absent metadata → sources []. +- Imports: ONLY google-antigravity-wire (UA) + providers/antigravity-models (wire model) — auditor-verified lean, no google.ts drag, no cycle. + +## Dispatch wiring (mirrors 070) +- SidecarPlan.geminiSidecar; planWebSearch "gemini" arm real (google-antigravity provider enabled + OAuth + projectId → plan; else undefined); core.ts handoff; loop.ts arm; registry { backend:"gemini", isActive: OAuth usable + projectId present, eligibleModel: candidate.provider === "google-antigravity" }. + +## Tests: tests/gemini-web-search.test.ts + loop integration +- Fixture (002 capture) → text + sources; absent groundingMetadata → []; missing projectId → error; envelope assertion incl. thinkingConfig when effort maps; destination-pinning assertion (baseUrl override ignored). + +## Verify (per-layer full gate): bun x tsc --noEmit && bun run test && live probe via executor. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/090_layer9_exa_executor.md b/devlog/_plan/260820_sidecar_selection_unification/090_layer9_exa_executor.md new file mode 100644 index 0000000000..9c2a66b7c9 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/090_layer9_exa_executor.md @@ -0,0 +1,28 @@ +# 090 — Layer 9: Exa executor + top validation (wp5) [rev 2, consolidated] + +Branch: codex/sidecar-exa-executor (base: codex/sidecar-gemini-executor). + +## New file: src/web-search/exa-executor.ts (probe: 002 — non-LLM lane) +```ts +export async function runExaWebSearch(query, apiKey, settings, abortSignal?): Promise +``` +- POST https://api.exa.ai/search, headers x-api-key, redirect: "manual" (Bun forwards custom headers across redirects). Body { query, numResults: 5, contents: { text: { maxCharacters: 1000 } } }. +- Mapping: results[] → sources [{url, title}]; text = per-result "Title — snippet (url)" digest (Exa returns no prose; the routed model synthesizes). resolvedSearchType/costDollars ignored. +- ALL upstream error strings pass redactSecretString; a canary-key test asserts the key never reaches the outcome. + +## Key handoff (audited path) +- core.ts reads config.webSearchSidecar.exaApiKey at plan-unpack; WebSearchLoopDeps.exaApiKey?: string; SidecarPlan carries only exaConfigured: true. loop.ts "exa" arm → runExaWebSearch(query, deps.exaApiKey, ...). +- redact.ts "exaApiKey" entry + GET-never-echo landed in 060; this layer adds the runtime canary test. + +## GUI stance (fixed in 060) +- No GUI backend selector this program; exa is config/CLI-explicit. exa has no model candidates (eligibleModel: () => false); webSearchModels for openai/anthropic backends unchanged. Follow-up GUI-selector issue filed at program end. + +## Docs +- docs-site guides/sidecars.md + reference/configuration/server.md: new-backends section (explicit-only, credentials, x_search opt-in, exa key). English only. + +## Final verification (top of stack) +- bun run typecheck && bun run test (FULL) && bun run privacy:scan && bun run lint:gui. +- Live executor probes for all three backends as attest evidence; gh pr list chain → goalplan c6. + +## Tests: tests/exa-web-search.test.ts — fixture mapping, error non-throw, canary-key redaction. + diff --git a/devlog/_plan/260820_sidecar_selection_unification/100_chat_default_regression.md b/devlog/_plan/260820_sidecar_selection_unification/100_chat_default_regression.md new file mode 100644 index 0000000000..c73c63831a --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/100_chat_default_regression.md @@ -0,0 +1,56 @@ +# 100 — Chat-default regression for Grok 4.5/4.6 (#2227 integration unit) + +Audited: 3-round adversarial plan audit (sol-medium), round-3 PASS. Amendment of this +unit's roadmap for the integration merge-train; consumes user directives from 260821. + +## Decision + +Third-party Responses APIs are supported only as first-class surfaces. Outside OpenAI, +the default wire is `openai-chat`. xAI's own CLI defaults to Chat; its Responses dialect +rejects opaque reasoning continuation/compaction state on later turns (#2240 regression +axis, 4-layer sanitize chase in #2217). Chat translation structurally filters private +extensions instead of chasing them. + +- ADOPT #2227: `modelWireDefaults` for grok-4.6/grok-4.5 flip `openai-responses` -> + `openai-chat` (src/providers/registry.ts:1032/1038 area), structure/04 rewrite, test + conversions to explicit `modelAdapters` opt-in framing. +- DeepSeek is OUT OF SCOPE (user decision 260821): deepseek-v4-flash/pro keep their + Responses defaults (registry.ts:1563-1564). Add a focused non-regression test locking + both V4 entries to `openai-responses` so this train cannot drift them. +- The Responses implementation is NOT deleted; it becomes the opt-in lane (doc 130). + +## Atomic merge unit (audit blocker R2-B1) + +The #2227 flip and the service_tier policy fix land as ONE merge unit — no intermediate +dev head may exist where OAuth opt-in Responses leaks caller service_tier: + +1. Cherry-pick/merge #2227's registry + structure/04 + test changes onto the post-stack + dev head (anchor: doc 110 global order). +2. In the same unit, fix the fastwire.ts:151 bypass: configured `modelAdapters` must not + skip the registry OAuth policy. Per audit round-3 note: make the OAuth registry tier + policy UNCONDITIONAL for the matching xAI route rather than introducing a new config + field — `modelAdapters` values are wire ids only. +3. Regression matrix locked in tests (5 rows): + | route | expectation | + |---|---| + | OAuth default | chat wire | + | OAuth explicit Responses (modelAdapters) | responses wire, caller service_tier dropped | + | API-key default | chat wire; no tier injected; caller service_tier not forwarded unless a capability declares it | + | API-key explicit Responses (modelAdapters) | responses wire; PRESERVE current dev semantics: absent tier stays absent, caller-supplied service_tier forwards verbatim (resolver proof: forwardCallerTier true on this route today; #2072 deferred) | + | DeepSeek V4 flash/pro | responses default unchanged | + +## Reasoning-streaming proof (#1886 origin) + +#1886 moved grok to Responses because Chat translation showed a blank screen during long +reasoning turns. The regression must prove the Chat path now streams reasoning as an E2E +SSE assertion, not unit-only: an early upstream `reasoning_content` delta must be +observed on Codex's reasoning-summary SSE channel BEFORE the completion is released. +Test shape: mock xAI chat stream emitting reasoning_content deltas first; assert the +bridged Responses SSE emits reasoning summary deltas before `response.completed`. +Follow with one live probe through the running proxy. + +## Out of scope + +- #2072 API-key Fast/priority policy: DEFERRED (open, conflicting, its own review + cycle). The opt-in switch spec (doc 130) does not depend on it. +- DeepSeek wire changes: none. diff --git a/devlog/_plan/260820_sidecar_selection_unification/110_global_merge_order.md b/devlog/_plan/260820_sidecar_selection_unification/110_global_merge_order.md new file mode 100644 index 0000000000..6097564eb5 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/110_global_merge_order.md @@ -0,0 +1,62 @@ +# 110 — Global cross-train triage matrix and merge order + +One global order (audit R1-B5): the sidecar stack lands FIRST (9 stacked branches; +cascading a rebase through them is the expensive direction), then the lighter triage +PRs rebase onto the post-stack dev head one at a time. Every individual merge requires +maintainer approval + required CI green (MAINTAINERS.md) — the user's 'CI as lagging +indicator' applies only to repair iterations between pushes, never to the merge click +itself (audit R1-B4). + +## Global order + +1. Sidecar stack bottom-up: #2203 -> #2204 -> #2206 -> #2209 -> #2211 -> #2238 -> + #2242 -> #2243 -> #2245 (details + blocker inventory: doc 120). +2. #2227 integration unit (Chat default + unconditional OAuth tier policy, doc 100). +3. #2217 RESHAPED (not raw): rebase onto post-#2227 dev, reframe tests/docs as opt-in + hardening, gate the compat rewrite to the opt-in Responses route. +4. Doc-130 atomic opt-in switch (wp11). +5. Remaining Responses fixes: #2237, #2229, #2228 (do not depend on the Responses + default; still valuable for the opt-in lane and other Responses routes). +6. luvs01 / Ingwannu / docs PRs (matrix below). +7. Release prep (doc 140) -> lidge final gate (doc 150). + +## Triage matrix (dispositions) + +| PR | author | disposition | rationale | +|---|---|---|---| +| #2227 | olddonkey | MERGE (as doc-100 atomic unit) | owns the chat default | +| #2217 | olddonkey | RESHAPE then merge | opt-in-lane hardening; raw form encodes Responses-as-default | +| #2237 | olddonkey | MERGE after #2227 | null reasoning channel drop; wire-agnostic | +| #2229 | olddonkey | MERGE after #2227 | encrypted_content reshape guard; opt-in lane | +| #2228 | olddonkey | MERGE after #2227 | compaction blob provenance; wire-agnostic | +| #2214 | luvs01 | MERGE (address CHANGES_REQUESTED) | continuation binding bug | +| #2236 | luvs01 | MERGE (address CHANGES_REQUESTED) | catalog comment preservation | +| #2226 | luvs01 | MERGE after hygiene unblocked | secret redaction in events | +| #2196 | Ingwannu | MERGE | maintainer chore, privacy-bounded diagnostics | +| #2207 | Ingwannu | MERGE | google tool-result adjacency bug | +| #2202 | Ingwannu | MERGE | claude roster sync bug | +| #2181 | lidge-jun | MERGE (address CHANGES_REQUESTED) | devlog docs | +| #2168 | lidge-jun | MERGE (address CHANGES_REQUESTED) | devlog docs | +| #2235 | umyunsang | REVIEW-ONLY this train | contributor draft gate owns it | +| #2220 | Hylouis233 | REVIEW-ONLY this train | draft, capability sync | +| #2230 | ppvia | OUT (hygiene-blocked draft) | own cycle | +| #2222 | MarcTCruz | OUT (hygiene-blocked draft) | own cycle | +| #2216 | leon80900 | CLOSE-DIRECT (wrong branch, targets main) | ask re-file onto dev | +| #2215 | parkjs101 | OUT (docs draft, changes requested) | own cycle | +| #2213 | louis-tepe | OUT (draft, overlaps doc-130 design) | revisit post-switch | +| #2072 | olddonkey | DEFERRED (audit R2-B2) | Fast policy composes later; must re-verify against both wires | + +## New wave (user expansion 260821, lands in step 5-6 order after the chat-default unit) + +| PR | author | disposition | rationale | +|---|---|---|---| +| #2248 | olddonkey | MERGE after #2227 unit | cross-backend reasoning strip on model switch; wire-agnostic hygiene | +| #2249 | olddonkey | MERGE after #2228 line | compaction blob serving-identity comparison; composes with provenance fix | +| #2251 | olddonkey | MERGE after #2227 unit | recovery when upstream rejects foreign opaque state | +| #2252 | olddonkey | MERGE | strip output-only reasoning status unconditionally; small + wire-agnostic | +| #2254 | olddonkey | RECONCILE with doc 130 | restores Grok Responses on the native passthrough route — must compose with the chat default + opt-in switch, not fight them; adjudicate against the doc-100 matrix | +| #2250 | lilinxiong | MERGE (bug) | integrations honor OFF for Claude Desktop drift + Grok ensure | +| #2253 | lilinxiong | MERGE (bug, gui) | dropdown opacity; needs screenshot per PR gate | + +Rebase anchors are named at execution time in each phase's B (exact dev head SHA), +with cascade verification (typecheck + focused suites) after every land. diff --git a/devlog/_plan/260820_sidecar_selection_unification/120_sidecar_chain_merge.md b/devlog/_plan/260820_sidecar_selection_unification/120_sidecar_chain_merge.md new file mode 100644 index 0000000000..cd15bcea61 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/120_sidecar_chain_merge.md @@ -0,0 +1,80 @@ +# 120 — Sidecar chain merge execution (L1-L9 into dev) + +Order: #2203 -> #2204 -> #2206 -> #2209 -> #2211 -> #2238 -> #2242 -> #2243 -> #2245. +Each merge: resolve CHANGES_REQUESTED, obtain maintainer approval, required CI green, +squash-merge into its base, retarget the next child, cascade-verify (typecheck + +focused suites), then proceed. Mid-stream lidge suites are lagging indicators between +pushes; the merge click itself is gated (MAINTAINERS.md). + +## Current blocker inventory (fresh, 260821) + +- #2203 (L1, CHANGES_REQUESTED Ingwannu): blocker is the tracked cleanup doc + 000_wp0_branch_worktree_cleanup.md — contradictory KEEP/REMOVE entries, no preflight, + incomplete protected set, b2ac2500c preservation, codex/merge-loop-closeout listed + both ways. Fix: rewrite the doc as a non-executable historical record (all deletions + already executed in wp0) with a mechanical protected-set preflight template; or mark + every command block as executed-snapshot. No runtime code change. +- #2204, #2206 (L2, L3): APPROVED. Rebase-carry only. +- #2209 (L4, CHANGES_REQUESTED): runtime blocker — webSearchModelOptionsFrom drops + backend provenance; auth-slot model can persist {backend:'openai', + model:'claude-haiku-4-5'}. Fix: return (backend, model) pairs, validate the pair in + both PUT routes, teach sidecarBackendForModel the auth-slot rows. +- #2211 (L5, CHANGES_REQUESTED): carry the L4 provenance field through the CLI + contract — show backend in `web --list` human output and validate pairs on write. +- #2238 (L6, CHANGES_REQUESTED, head a05f23fa9) — three reviewed blockers: + 1. stripOpenAiOnlyWebSearchFields fires for every non-ChatGPT-forward Responses + provider; official OpenAI API-key traffic loses external_web_access / + search_context_size. Gate on xAI-specific provider identity/capability and add + a buildRequest regression proving OpenAI API-key tools retain both fields. + 2. English config reference + CLI help still advertise only the old backend pair; + document the xai/gemini/exa arms as explicit-only/inert; keep translations + consistent. + 3. exaApiKey only in SENSITIVE_KEY_PATTERN: add it to the shared colon/query/JSON + string-redaction grammar with all three canaries in tests/redact.test.ts. +- #2242 (L7, CHANGES_REQUESTED, head 0f2d670c0) — five reviewed blockers: + 1. runXaiWebSearch misses cancelBodyOnAbort after fetchWithResetRetry resolves + (abort-before-reader race). + 2. parseXaiResponsesSSE must cancel the upstream body at the byte bound, not just + release the reader lock. + 3. the management PUT mutates config.webSearchSidecar before xSearch validation + (400 after live state change) — stage and validate the complete candidate first. + 4. malformed xSearch fields are silently omitted — reject invalid handle arrays, + dates, and enabled values instead of broadening the search with a 200. + 5. public docs + the type comment still call xai inert; update the English source + and translations. Add no-partial-mutation and oversized-stream regressions. +- #2243 (L8, CHANGES_REQUESTED): three runtime blockers per review + red macOS CI + shard — full RCA in the phase B, fixes + rerun. +- #2245 (L9): reviewer PASS locally; needs maintainer approval; one failing test shard + reported on CI — reproduce, fix, re-push. + +Execution sequence (explicit — the wp numbers are not the order): wp9 (this doc, +sidecar chain) -> wp8 (triage PRs per doc 110) -> wp11 (doc 130 switch) -> wp10 +(docs 140/150). + +## Execution record (wp9 B-phase, 260821) + +Every recorded blocker resolved and pushed; Ingwannu re-review re-requested on all +six layers. Worker lanes ran in parallel worktrees under .tmp/ (four sol-medium +subagents + one direct fix): + +- #2203 d505dacc7 — cleanup doc recast as an executed historical record; corrected + 36-ref remote list (merge-loop-closeout excluded); 5-step preflight template. +- #2209 98eaba601 — options carry (backend, model) pairs; both PUT routes validate + effective pairs; auth-slot Anthropic persists anthropic/claude-haiku-4-5. + Suites 50/0 + 30/0, GUI 9/0, gate 13/0. +- #2211 84357bd2b (parent merge) + 2a610909f — backend-tagged `web --list`, + provenance-aware pair writes, clear rejection errors. CLI suites 401/0. +- #2238 19376f737 — strip gated on supportsOpenAiWebSearchToolFields:false (xAI + registry declares it; OpenAI API-key traffic keeps both fields — regression red + pre-fix); docs/CLI-help union across 8 locales; exaApiKey in the shared + colon/query/JSON redaction grammar, 3 canaries (JSON canary red pre-fix). +- #2242 b2c2054b5 — cancelBodyOnAbort after resolve; byte-bound upstream body + cancel; staged atomic PUT validation (no-partial-mutation); malformed xSearch + rejected with 400; docs/type-comment de-inerted. 47/0 + 12/0. +- #2243 249cc91a3 — atomic token/project snapshot; post-header abort guard; + bounded 64KiB UTF-8 JSON reads. 4 regressions red pre-fix; 50/0, privacy green. + +Remaining before merge clicks: Ingwannu approvals + green required CI per layer +(#2245's earlier shard failure not reproduced at the current head — checks green +except queued/pending reruns). Lidge full suite relaunched at stack top +(/tmp/ocx-gate-stack.log) as the lagging indicator. diff --git a/devlog/_plan/260820_sidecar_selection_unification/130_xai_responses_optin_switch.md b/devlog/_plan/260820_sidecar_selection_unification/130_xai_responses_optin_switch.md new file mode 100644 index 0000000000..e690ede50d --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/130_xai_responses_optin_switch.md @@ -0,0 +1,27 @@ +# 130 — xAI Responses opt-in switch (atomic persistence + GUI) + +The Responses implementation survives as an explicit opt-in lane, like the x_search +opt-in block. Default: chat (post-#2227). Surface: xai is ONE provider id +(registry.ts:1000); the 'two pages' are the auth-mode-scoped sections (OAuth account + +API key) of the same provider workspace. + +## Contract (audit R1-B2) + +- Config truth: `modelAdapters` entries for grok-4.5 + grok-4.6 -> 'openai-responses'. +- Atomic management API: extend the provider PATCH surface (provider-routes.ts:378 area + + gui provider-workspace DTO types.ts:88) with a split write/read contract: + - WRITE (PATCH input): `xaiResponsesOptIn: boolean` — sets/clears BOTH grok model + entries in one config transaction, preserving unrelated modelAdapters overrides. + - READ (GET/echo DTO): `xaiResponsesOptInState: true | false | "mixed"` — partial + pre-existing state (one model set, one not) reads "mixed"; the first boolean + write normalizes both entries and the echo returns the effective state. +- GUI: one switch rendered in both auth-mode sections; mixed state shows indeterminate. +- Tier policy: the doc-100 unit already made the OAuth registry tier policy + unconditional; the switch adds NO tier behavior. API-key route: opt-in flips wire + only; everything else keeps current dev semantics (#2072 deferred). +- #2217 sanitize layers arm only on this opt-in Responses route (RESHAPE disposition). +- Tests: atomic set/clear, override preservation, mixed-state normalization, effective- + state echo, GUI switch render + PATCH round-trip, opt-in wire selection E2E. +- Docs-site: provider page gains the switch row; structure/04 notes the opt-in lane. + +Execution phase: wp11 (after #2227 unit + reshaped #2217; before release prep). diff --git a/devlog/_plan/260820_sidecar_selection_unification/140_release_prep.md b/devlog/_plan/260820_sidecar_selection_unification/140_release_prep.md new file mode 100644 index 0000000000..590e681966 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/140_release_prep.md @@ -0,0 +1,7 @@ +# 140 — dev release prep + +After wp11 lands. Version bump per release train conventions; release notes cover: +sidecar unification (L1-L9), chat-default regression + opt-in switch, responses fixes +(#2237/#2229/#2228, reshaped #2217), maintainer fixes (#2196/#2207/#2202), luvs01 +fixes (#2214/#2236/#2226), devlog docs (#2181/#2168). scripts/release.ts is the +authority; no release action without the doc-150 gate green. diff --git a/devlog/_plan/260820_sidecar_selection_unification/141_release_prep_artifact.md b/devlog/_plan/260820_sidecar_selection_unification/141_release_prep_artifact.md new file mode 100644 index 0000000000..9c95f8b319 --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/141_release_prep_artifact.md @@ -0,0 +1,67 @@ +# 140A — Release prep artifact (next dev release, prepared 260821) + +Recommended version: 2.28.0 (feature train on top of 2.27.0; 196+ commits). +Release command (maintainer-controlled): bun scripts/release.ts 2.28.0 --publish +(default is dry-run publish; the workflow bump/commit/push is real either way). + +## Release-note skeleton + +### Web-search / sidecar unification (#2188, L1-L9) +- Shared sidecar auth slots + unified picker candidates (#2203, #2204). +- Web-search backend registry with executor-runnable candidate sets (#2206). +- (backend, model) pair contract end-to-end: write gates, GUI lists, CLI + provenance (#2209, #2211). +- Widened backend union openai|anthropic|xai|gemini|exa with capability-gated + OpenAI field stripping and exaApiKey redaction grammar (#2238). +- Live xAI executor with opt-in x_search (staged PUT validation, byte-bound + stream cancel) (#2242). +- Live Gemini CCA executor (atomic token/project snapshot, bounded reads) (#2243). +- Exa executor: the first non-LLM search lane (literal-key scrub) (#2245). + +### xAI wire policy +- Chat is the OAuth default for grok-4.5/4.6; unconditional OAuth tier policy + (caller service_tier cannot leak through modelAdapters) (#2255, credits #2227). +- Responses survives as an explicit lane: routed-destination sanitize + + opaque-state recovery series (#2258, credits #2254's 22-commit series). +- GUI opt-in switch for the Grok Responses lane, atomic dual-entry + persistence + tri-state read (#2266). +- Post-merge reconciliations: capability-gated external_web_access (#2262, + caught by the lidge lagging gate), raw-config capability declaration (#2263). + +### Fixes +- Continuation bound to the final serving route incl. key-pool rotation (#2214). +- TOML root-boundary lexical scanning preserves commented catalog assignments (#2236). +- Google tool-result adjacency repair (#2207); Claude roster startup sync (#2202). +- OAuth structured-event secret redaction (#2226); affinity diagnostics (#2196). +- Integrations honor OFF with race-free ensure (#2259, credits #2250). +- GUI dropdown opacity (#2253). + +### Docs +- Devlog: three-issue round record (#2181), backlog merge log (#2168), + the 100-150 integration-train roadmap. + +## Bug-backlog train additions (260821, second loop) + +- #2269 — pool-switch ciphertext stripping locked + null-code encrypted-content + rejection recovery (fixes #2247). +- #2271 — opencode-go /goal stream drops: namespace-flattening regression locked, + openaiChatEofTolerance opt-in for complete tool-call EOF (fixes #2260). +- #2246 — google part-field contract enforcement (fixes #2233, maintainer PR + rebased+landed). +- #2273 — deferred serving-identity commit + passthrough findings (credits #2264). +- #2274 — zcode openai-compatible protocol, prefix-cache restore (credits #2261). +- #2276 — MCode capability sync + writer locking (credits #2220). +- #2277 — Cursor checkpoint reuse, fail-closed explicit refs (credits #2054). +- Superseded/closed: #2267 (by #2262). Deferred to human security review: #2222. +- Issues closed with evidence: #2247 #2260 #2233 #2240 #2188 #2190. + +RELEASE STATE: READY, NOT EXECUTED (user directive). One command away: +`bun scripts/release.ts 2.28.0` (dry-run publish) or `--publish` — maintainer's call. + +## Gate evidence (doc 150) +- lidge full suite at 6aecc8f15: see /tmp/ocx-gate-final.log (this doc's D attest). +- Local: tsc, oxlint (lint:gui), privacy:scan, build:gui + prepare-package green. +- GitHub Actions on the final dev head: observed at the blocking gate. +- Deferred: #2072 (API-key Fast policy) composes post-train; hygiene-blocked + drafts (#2222 #2230 #2244) and REVIEW-ONLY items (#2235 #2220 #2215 #2213) + continue their own cycles. diff --git a/devlog/_plan/260820_sidecar_selection_unification/150_lidge_final_gate.md b/devlog/_plan/260820_sidecar_selection_unification/150_lidge_final_gate.md new file mode 100644 index 0000000000..f1e2666fdf --- /dev/null +++ b/devlog/_plan/260820_sidecar_selection_unification/150_lidge_final_gate.md @@ -0,0 +1,17 @@ +# 150 — lidge final aggregate/release gate + +The final AGGREGATE gate before release. It does not replace per-merge gating: docs +110/120 keep approval + required CI blocking for every individual merge; 'lagging +indicator' covers only repair iterations between pushes. At the final dev head: + +- lidge: OCX_TEST_NO_QUEUE=1 bun run test — full suite green (baseline 13808+/0 at L9). +- Local: bun run typecheck, bun run privacy:scan, bun run lint:gui, lint:i18n, GUI + tests, bun run build:gui, and the docs-site build (doc 130 touches GUI and + localized copy, so the full GUI/i18n/docs chain is in the gate). +- GitHub Actions: final dev head green on Linux/Windows/macOS (Windows gate is a + standing release requirement). +- Live probes through the running proxy: OAuth chat default turn, opt-in Responses + turn (no caller service_tier upstream), x_search opt-in turn, exa sidecar turn, + reasoning-streaming E2E (doc 100 matrix). +- Release staged on lidge per release-train conventions; promotion remains + maintainer-controlled. diff --git a/devlog/_plan/260820_sidecar_selection_unification/assets/l4-websearch-picker-filtered.png b/devlog/_plan/260820_sidecar_selection_unification/assets/l4-websearch-picker-filtered.png new file mode 100644 index 0000000000..b577688048 Binary files /dev/null and b/devlog/_plan/260820_sidecar_selection_unification/assets/l4-websearch-picker-filtered.png differ diff --git a/docs-site/src/content/docs/fr/guides/integrations.md b/docs-site/src/content/docs/fr/guides/integrations.md index 269e38e93b..c7f653c885 100644 --- a/docs-site/src/content/docs/fr/guides/integrations.md +++ b/docs-site/src/content/docs/fr/guides/integrations.md @@ -29,6 +29,9 @@ MiniMax Code recherche d’abord `MINIMAX_DATA_DIR`, puis `MAVIS_DATA_DIR`, avan `~/.minimax`. Son bloc géré ne possède que `custom_provider.opencodex`. Il ne modifie ni `defaultModel`, ni la source d’identification MiniMax sélectionnée, ni la connexion MiniMax de l’utilisateur. Après l’avoir connecté, choisissez dans MCode une entrée `custom_provider:opencodex/`. +L’actualisation de l’intégration met également à jour les fenêtres de contexte par modèle et les choix +d’effort de raisonnement faisant autorité ; les capacités inconnues sont omises et l’effort courant, +qui appartient à la session MCode, est préservé. Les chemins respectent les variables de remplacement propres à chaque client, lorsqu'elles existent. Pour OMP, la présence de `OMP_PROFILE` l'emporte sur `PI_PROFILE`, même si sa valeur est explicitement vide. Un @@ -149,6 +152,10 @@ ocx integration client enable --client mcode ocx mcode ``` +Une fois l’intégration connectée, `ocx sync` actualise également le bloc MCode géré avec les fenêtres de +contexte et les niveaux d’effort de raisonnement actuels. Les blocs absents, modifiés par un tiers, non sûrs +ou jamais gérés restent intacts ; réactivez explicitement l’intégration lorsque vous souhaitez la reconnecter. + Le CLI distinct de la plateforme MiniMax (`mmx`) n’est pas une intégration à commutateur de fichier. Ses commandes textuelles utilisent le point de terminaison compatible avec Anthropic de MiniMax ; OpenCodex fournit donc un lanceur isolant les identifiants et limité à l’adresse locale : diff --git a/docs-site/src/content/docs/fr/guides/minimax.md b/docs-site/src/content/docs/fr/guides/minimax.md index 22f301d01e..01d7de2e49 100644 --- a/docs-site/src/content/docs/fr/guides/minimax.md +++ b/docs-site/src/content/docs/fr/guides/minimax.md @@ -34,12 +34,14 @@ custom_provider: baseURL: http://127.0.0.1:10100 authMode: api-key models: - anthropic/claude-opus-5: {} + anthropic/claude-opus-5: + limit: + context: 1000000 ``` -La liste de modèles réellement générée provient du catalogue OpenCodex actif. Le bloc n’écrit aucune clé réelle, ne remplace pas `defaultModel` et ne modifie pas votre connexion MiniMax. Dans MCode, choisissez un modèle sous `custom_provider:opencodex/...`. +La liste de modèles réellement générée, ainsi que les fenêtres de contexte et les niveaux d’effort de raisonnement connus, provient du catalogue OpenCodex actif. Lorsqu’aucune fenêtre de contexte ou échelle d’effort ne fait autorité pour un modèle, le champ correspondant est omis au lieu de recevoir une valeur supposée. MCode conserve l’effort actuellement sélectionné dans la session : OpenCodex exporte donc `effortOptions` sans remplacer cette sélection. Le bloc n’écrit aucune clé réelle, ne remplace pas `defaultModel` et ne modifie pas votre connexion MiniMax. Dans MCode, choisissez un modèle sous `custom_provider:opencodex/...`. -`ocx mcode` vérifie que ce fournisseur pointe vers le proxy actuellement actif avant de lancer le client. Si le port a changé, actualisez le bloc géré en relançant la commande d’activation. Désactivez-le ou restaurez-le au moyen du même système d’intégration audité : +`ocx mcode` vérifie que ce fournisseur pointe vers le proxy actuellement actif avant de lancer le client. Après l’activation initiale, `ocx sync` actualise le bloc géré lorsque le port ou les capacités du catalogue changent. La synchronisation automatique ne crée jamais un bloc non géré, ne recrée pas un bloc que vous avez supprimé et n’écrase pas un fichier modifié après l’écriture d’OpenCodex ; utilisez la commande d’activation lorsque vous souhaitez le reconnecter explicitement. Désactivez-le ou restaurez-le au moyen du même système d’intégration audité : ```bash ocx integration client disable --client mcode diff --git a/docs-site/src/content/docs/fr/guides/sidecars.md b/docs-site/src/content/docs/fr/guides/sidecars.md index 1bd91c107c..c5b7a50b1e 100644 --- a/docs-site/src/content/docs/fr/guides/sidecars.md +++ b/docs-site/src/content/docs/fr/guides/sidecars.md @@ -5,13 +5,13 @@ description: Dotez les modèles routés d’une véritable recherche web et donn Tous les modèles routés ne proposent pas une **recherche web** hébergée ni une **entrée d’image** native. opencodex complète ces capacités au moyen de deux services auxiliaires. Chacun peut s’appuyer sur un fournisseur connecté à ChatGPT (`forward`) ou sur un -fournisseur Anthropic OAuth enregistré. Les erreurs des services auxiliaires sont converties en résultats d’outil limités ou en marqueurs d’image, +fournisseur Anthropic OAuth enregistré ; la recherche web peut aussi utiliser un OAuth Grok enregistré via le moteur `xai` explicite. Les erreurs des services auxiliaires sont converties en résultats d’outil limités ou en marqueurs d’image, au lieu de faire échouer l’intégralité du tour. :::note[Sélection automatique du moteur] -Une valeur `backend` explicite est prioritaire. Lorsqu'elle est omise, opencodex utilise `anthropic` si un fournisseur OAuth Anthropic actif -possède un compte actif qui n'est pas marqué `needsReauth` ; sinon, il utilise `openai`. Une sélection explicite de -`anthropic` sans ces identifiants échoue de manière sûre. `openai` exige à la fois une connexion ChatGPT et un +Une valeur `backend` explicite est prioritaire. Sans valeur, la recherche web utilise toujours `openai` ; Vision utilise +`anthropic` si un compte OAuth Anthropic utilisable existe, sinon `openai`. Une sélection explicite de +`anthropic` ou `xai` sans identifiants utilisables échoue sans repli. `openai` exige à la fois une connexion ChatGPT et un fournisseur `forward` actif. ::: @@ -24,7 +24,8 @@ Lorsque Codex demande un hébergement `web_search` pour un modèle routé sans p 2. Exécute le modèle routé dans une petite **boucle d'agent**. Lorsqu'il appelle `web_search`, opencodex utilise le moteur du service auxiliaire sélectionné : OpenAI exécute l'outil hébergé `web_search` avec `gpt-5.6-luna` par défaut ; Anthropic exécute `web_search_20250305` avec `claude-sonnet-5` par défaut. La réponse en streaming et - les citations deviennent le résultat d’un outil. + les citations deviennent le résultat d’un outil. xAI exécute `web_search` avec `grok-4.6` par défaut et ajoute + `x_search` à la même requête lorsque `xSearch.enabled` vaut true. 3. **Répète la boucle** jusqu'à ce que le modèle réponde ou que le nombre total de recherches réelles atteigne `maxSearchesPerTurn` (par défaut 3), supprime ensuite l'outil de recherche et force une réponse finale. De vrais outils clients tels que `apply_patch` ou le shell mettent fin au tour afin que ces appels parviennent à Codex. diff --git a/docs-site/src/content/docs/fr/reference/cli/agents.md b/docs-site/src/content/docs/fr/reference/cli/agents.md index 6e8fca4411..a97fb04567 100644 --- a/docs-site/src/content/docs/fr/reference/cli/agents.md +++ b/docs-site/src/content/docs/fr/reference/cli/agents.md @@ -164,7 +164,7 @@ Gérez et appliquez la clôture du modèle Grok Build. ## Exportation de la configuration client -### `ocx export --client ` +### `ocx export --client ` Imprimez une configuration client connectée au proxy en cours d'exécution. La commande sérialise le bloc fournisseur `opencodex` — URL de base, liste de modèles et référence d’identifiant du client @@ -175,7 +175,7 @@ les modèles Codex peuvent actuellement voir. | Option | Actions | | --- | --- | -| `--client ` | Requis. Sélectionne le dialecte de configuration client. | +| `--client ` | Requis. Sélectionne le dialecte de configuration client. | | `--json` | Imprimez le document généré en tant que JSON sur la sortie standard pour les scripts. Il s'agit de JSON même lorsque le format natif du client sélectionné est YAML, TOML ou JSON5. | | `--out ` | Écrivez le format de configuration natif du client dans ``. Refuse de remplacer un fichier existant. | | `--force` | Autoriser `--out` à remplacer un fichier existant. | @@ -195,13 +195,16 @@ propres valeurs par défaut à ces lignes. | Client | Destination canonique | Télécharger le nom du fichier | Var.environnement | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` gagne une fois défini) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | none — le bloc porte le littéral `opencodex-loopback` | +| `pi` | `~/.pi/agent/models.json` (`PI_CODING_AGENT_DIR` l'emporte une fois défini ; une valeur relative est refusée) | `pi-models.json` | none — le bloc porte le littéral `opencodex-loopback` | | `omp` | `~/.omp/agent/models.yml` (`OMP_PROFILE` l'emporte sur `PI_PROFILE`, même lorsqu'il est vide ; les profils nommés utilisent le nom du répertoire `PI_CONFIG_DIR` relatif à la maison et ignorent `PI_CODING_AGENT_DIR`, tandis que le profil par défaut laisse `PI_CODING_AGENT_DIR` gagner) | `omp-models.yaml` | aucun — espace réservé de bouclage | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | aucun — espace réservé de bouclage | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml` (`~/.dsh/settings.yaml` par défaut) | `settings.yaml` | none — espace réservé pour le porteur de bouclage non secret | +| `mcode` | `~/.minimax/config.yaml` (`MINIMAX_DATA_DIR`, puis l'ancien `MAVIS_DATA_DIR`, l'emportent une fois définis ; une valeur relative est refusée) | `mcode-config.yaml` | aucun — espace réservé de bouclage | +| `zcode` | `~/.zcode/v2/config.json` (`ZCODE_DATA_DIR` l'emporte une fois défini ; une valeur relative est refusée) | `config.json` | aucun — espace réservé de bouclage | +| `prime` | `~/.prime/agent/models.json` (`PRIME_AGENT_CODING_AGENT_DIR` l'emporte une fois défini ; une valeur relative est refusée) | `prime-models.json` | aucun — espace réservé de bouclage | L'exportation DSH gérée nécessite DSH 0.1.0-rc.6 ou plus récent et ne possède que `llm-pi-ai.providers.opencodex`. DSH recharge à chaud ce fournisseur ; le modèle par défaut de l'utilisateur et diff --git a/docs-site/src/content/docs/fr/reference/configuration/providers.md b/docs-site/src/content/docs/fr/reference/configuration/providers.md index edf41cccc0..336627de70 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/fr/reference/configuration/providers.md @@ -98,6 +98,7 @@ sauvegarde dont le contenu diffère, puis réécrit en identifiants sans préfix | `modelSupportsReasoningSummaries?` | `Record` | Définissez un modèle sur `false` pour arrêter la publicité des résumés et supprimer les champs de livraison du résumé. | | `modelReasoningSummaryDelivery?` | `Record` | Énumération de livraison des réponses par modèle ; réécrit un champ de livraison existant. | | `modelAdapters?` | `Record` | Remplacement du protocole `openai-chat` ou `openai-responses` par modèle pour les passerelles multiprotocoles. Les entrées explicites priment sur les valeurs par défaut du registre. Le préréglage OpenCode Go sélectionne Responses pour `gpt-5.6-luna` tout en laissant les modèles apparentés sur leurs protocoles documentés ; DeepSeek peut sélectionner Responses natif pour `deepseek-v4-flash` ; GitHub Copilot déclare des valeurs par défaut limitées à Responses pour sa famille GPT-5 (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`), car ces modèles rejettent `/chat/completions` pour le trafic des agents. Les modèles sans valeur intégrée par défaut, comme `gpt-5.4-nano`, peuvent être activés ici. Les services en amont à protocole unique et le transfert canonique ChatGPT rejettent ces remplacements. | +| Activation Responses xAI (tableau de bord) | interrupteur | Pour `xai` uniquement, définit ou efface atomiquement les entrées `modelAdapters` de `grok-4.5` et `grok-4.6`. Une seule entrée apparaît comme un état mixte jusqu’à la prochaine écriture. Les autres remplacements et le comportement des tiers restent inchangés. | | `modelPreferHostedTools?` | `Record` | Activation explicite par modèle exact pour les passerelles Responses hors transfert qui réservent un espace de noms aux outils hébergés. Seul `["image_generation"]` est actuellement accepté ; le modèle correspondant doit utiliser le protocole `openai-responses` et prendre en charge cet outil hébergé. Le proxy supprime les déclarations clientes `image_gen` en conflit et réécrit leurs sélecteurs afin de préserver le choix d'outil de l'appelant. Pour les modèles virtuels `-pro` de l'API OpenAI, l'identifiant public sélectionné est comparé en premier et l'identifiant résolu du modèle de base sur le protocole sert de repli. `modelAdapters` résout d'abord l'identifiant public, puis celui de base ; la seconde résolution détermine le protocole final. Les autres modèles conservent le comportement normal des alias. | | `reasoningEffortMap?` | `Record` | Alias ​​de fil à l’échelle du fournisseur pour les étiquettes de raisonnement. | | `modelReasoningEffortMap?` | `Record>` | Alias ​​de fil par modèle pour les étiquettes de raisonnement. | diff --git a/docs-site/src/content/docs/fr/reference/configuration/server.md b/docs-site/src/content/docs/fr/reference/configuration/server.md index b12d07996f..de7256b2b9 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/server.md +++ b/docs-site/src/content/docs/fr/reference/configuration/server.md @@ -209,8 +209,10 @@ l'API Images d'OpenAI et la forme de réponse attendue par Codex. | Champ | Type | Par défaut | Signification | | --- | --- | --- | --- | | `enabled?` | `boolean` | activé lorsqu'il est utilisable | Interrupteur principal. | -| `backend?` | `"openai" \| "anthropic"` | automatique | Une valeur explicite est prioritaire ; sinon, la présence d'identifiants OAuth Anthropic stockés et utilisables sélectionne `anthropic`, puis `openai`. | -| `model?` | `string` | dépendant du backend | `gpt-5.6-luna` pour OpenAI ou `claude-sonnet-5` pour Anthropic. L'héritage explicite `gpt-5.4-mini` migre au démarrage. | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | Une valeur explicite est prioritaire ; l'absence de valeur sélectionne toujours `openai`. `anthropic` et `xai` ne s'exécutent que s'ils sont configurés explicitement ; `gemini` et `exa` restent réservés jusqu'à la livraison de leur executor. | +| `model?` | `string` | dépendant du backend | `gpt-5.6-luna` pour OpenAI, `claude-sonnet-5` pour Anthropic ou `grok-4.6` pour xAI. L'héritage explicite `gpt-5.4-mini` migre au démarrage. | +| `exaApiKey?` | `string` | aucun | Clé opérateur pour le backend `exa`. Écriture seule : les lectures de gestion ne renvoient jamais la valeur stockée. | +| `xSearch?` | `object` | omis | Activation facultative de `x_search` hébergé, propre à xAI : `enabled`, tableaux mutuellement exclusifs `allowedXHandles` / `excludedXHandles` (20 au maximum), et dates ISO `fromDate` / `toDate` (`YYYY-MM-DD`). | | `reasoning?` | `string` | `low` | Effort secondaire. `minimal` est rejeté lors de la recherche sur le Web. | | `maxSearchesPerTurn?` | `number` | `3` | Recherches réelles autorisées par tour de modèle principal. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Date limite d'inactivité du corps brut du modèle routé uniquement pour les fichiers de configuration. Entier 1–2147483647 ; chaque morceau non vide le réinitialise. | @@ -220,7 +222,11 @@ Le moteur OpenAI nécessite une connexion à ChatGPT et un fournisseur ChatGPT ` entrantes depuis Claude injectent l'authentification ChatGPT principale dans la requête interne. Le moteur Anthropic utilise les identifiants actifs stockés auprès d'un fournisseur Anthropic OAuth activé. Si le moteur Anthropic est sélectionné explicitement mais qu'aucun compte n'est utilisable, l'opération échoue de manière sûre au lieu de se rabattre sur un autre moteur. L'exécuteur Anthropic utilise son -outil `web_search_20250305` natif. +outil `web_search_20250305` natif. Le backend xAI nécessite un compte OAuth Grok stocké et utilisable, emploie +`web_search` hébergé et ajoute `x_search` hébergé lorsque `xSearch.enabled` vaut true. Une entrée de gestion +`xSearch` mal formée renvoie `400` ; un bloc persistant mal formé échoue de manière sûre pendant la planification. +Les voies `gemini` et `exa` ne s'activent jamais par découverte d'identifiants ni par fallback ; l'opérateur doit +les sélectionner explicitement. `exaApiKey` est accepté en écriture mais omis des réponses de gestion. Quatre horloges régissent la recherche : base `stallTimeoutSec`, `connectTimeoutMs`, inactivité du modèle routé et délai d'expiration de la recherche hébergée. Le chien de garde efficace du pont est le maximum plus 30 secondes. Le décrochage routé est @@ -231,7 +237,7 @@ une garde d'inactivité, pas un délai de génération total. | Champ | Type | Par défaut | Signification | | --- | --- | --- | --- | | `enabled?` | `boolean` | activé lorsqu'il est utilisable | Commutateur principal de description d'images. | -| `backend?` | `"openai" \| "anthropic"` | automatique | Même sélection, prioritaire lorsqu'elle est explicite et tenant compte des identifiants Anthropic, que pour la recherche Web. | +| `backend?` | `"openai" \| "anthropic"` | automatique | La valeur explicite prévaut ; si elle est omise, un identifiant OAuth Anthropic stocké et utilisable est privilégié, sinon `openai`. | | `model?` | `string` | dépendant du backend | `gpt-5.4-mini` pour OpenAI ou `claude-sonnet-5` pour Anthropic. | | `maxDescriptionsPerTurn?` | `number` | `8` | Nouvelles descriptions des ratés du cache admises par tour principal. `0` désactive les appels ; les valeurs non valides utilisent la valeur par défaut. | | `timeoutMs?` | `number` | `45000` | Délai d'expiration de la récupération par le service auxiliaire. Entier 1–2147483647. | diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index 7c3a86dea3..81d0e0eaea 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -263,8 +263,8 @@ When both `tierModels.haiku` and `smallFastModel` are absent, OpenCodex leaves b ## Roster agents (injectAgents) -`ocx claude` (and the system-env daemon) syncs your featured subagent roster (Subagents tab, -up to 5 models) plus `ocx-self` into `~/.claude/agents/ocx-*.md`. +Proxy startup/ensure, `ocx claude`, and relevant dashboard saves sync your featured subagent roster +(Subagents tab, up to 5 models) plus `ocx-self` into `~/.claude/agents/ocx-*.md`. - **`ocx-self`** pins your `/model` picker default (falling back to `claudeCode.model`); omitted when neither exists. It does NOT use model inheritance. @@ -276,7 +276,8 @@ up to 5 models) plus `ocx-self` into `~/.claude/agents/ocx-*.md`. overwritten or pruned; your own agents are never touched. - Files are atomically synced per file (write + rename). - `enabled: false` or `injectAgents: false` prunes all verified-owned definitions. -- GUI PUT and roster changes resync immediately; launcher/system-env sync at launch. +- GUI PUT and roster changes resync immediately; every foreground or background proxy start/ensure + reconciles the owned files before a later Claude Code launch reads them. Dispatch: `subagent_type: "ocx-gpt-5-6-sol"`. 1M-capable targets carry `[1m]` automatically. @@ -332,8 +333,9 @@ Both sidecars can use either backend: | `openai` | A small GPT model through the ChatGPT `forward` provider | A ChatGPT login and an enabled `authMode: "forward"` provider | | `anthropic` | Claude through stored Anthropic OAuth; web search uses `web_search_20250305` and vision sends the image to Claude for description | An enabled `adapter: "anthropic"`, `authMode: "oauth"` provider whose active stored account is not marked `needsReauth` | -An explicit `backend` always wins. When it is omitted, opencodex selects `anthropic` if a usable -stored Anthropic OAuth account exists; otherwise it selects `openai`. Explicitly selecting +An explicit `backend` always wins. When it is omitted, the **web-search** sidecar always selects +`openai` (`anthropic` runs only when explicitly configured), while the **vision** sidecar selects +`anthropic` if a usable stored Anthropic OAuth account exists, otherwise `openai`. Explicitly selecting `anthropic` without a usable credential **fails closed**: opencodex does not silently borrow ChatGPT credentials or switch backends. The OpenAI backend likewise stays off without both login auth and a forward provider. diff --git a/docs-site/src/content/docs/guides/integrations.md b/docs-site/src/content/docs/guides/integrations.md index f8b2c578d8..40d1e1b78c 100644 --- a/docs-site/src/content/docs/guides/integrations.md +++ b/docs-site/src/content/docs/guides/integrations.md @@ -1,10 +1,10 @@ --- title: Integrations -description: Connect opencodex to OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, Gajae Code, DeepSeek Harness and MiniMax Code from the dashboard — one switch per client, with a backup taken before every write. +description: Connect opencodex to OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, Gajae Code, DeepSeek Harness, MiniMax Code and Prime Agent from the dashboard — one switch per client, with a backup taken before every write. --- The **Integrations** tab writes opencodex's provider block into a client's own config -file, and removes it again. Nine clients work this way, each with a switch: +file, and removes it again. Ten clients work this way, each with a switch: | Client | Config file | Format | When the change takes effect | Credential | |---|---|---|---|---| @@ -17,6 +17,7 @@ file, and removes it again. Nine clients work this way, each with a switch: | Gajae Code | `~/.gjc/agent/models.yml` | YAML | new sessions, or when you open `/model` |`OPENCODEX_GAJAE_API_KEY` | | DeepSeek Harness (DSH) | `$DSH_HOME/settings.yaml` (default `~/.dsh/settings.yaml`) | YAML | hot reload | non-secret loopback bearer placeholder | | MiniMax Code | `~/.minimax/config.yaml` | YAML | new sessions, or after opening the model picker | loopback placeholder | +| Prime Agent | `~/.prime/agent/models.json` | JSON | new sessions | loopback placeholder | Managed DSH support has a compatibility floor of **DSH 0.1.0-rc.6**. OpenCodex owns only `llm-pi-ai.providers.opencodex`; Apply and Refresh replace that fragment, Disable removes only that @@ -28,7 +29,16 @@ MiniMax Code follows `MINIMAX_DATA_DIR`, then `MAVIS_DATA_DIR`, before falling back to `~/.minimax`. Its managed block owns only `custom_provider.opencodex`. It does not change `defaultModel`, the selected MiniMax credential source, or the user's MiniMax login. Choose a `custom_provider:opencodex/` -entry in MCode after connecting it. +entry in MCode after connecting it. Refreshing the integration also refreshes +authoritative per-model context windows and reasoning-effort choices; unknown +capabilities are omitted, and MCode's session-owned current effort is preserved. + +Prime Agent follows `PRIME_AGENT_CODING_AGENT_DIR` before falling back to +`~/.prime/agent`; a relative value is refused so the proxy and the agent cannot +disagree about which file is meant. Its managed block owns only +`providers.opencodex`, so other providers and any `modelOverrides` you have set +stay untouched. Prime Agent reads `models.json` when a session starts, so start +a new session after connecting it. Paths honor each client's own environment override where it has one. For OMP, `OMP_PROFILE` wins over `PI_PROFILE` by presence, even when explicitly empty. A named profile @@ -113,11 +123,12 @@ changed value and calling it success. You will see the file named and nothing on disk will have moved. Editing that file by hand still works; it is only our automatic rewrite that declines. -**Pi, Kimi Code, Gajae Code, MiniMax Code and the managed DSH integration only work against a loopback bind.** +**Pi, Kimi Code, Gajae Code, MiniMax Code, Prime Agent and the managed DSH integration only work against a loopback bind.** The first four have no config field for the `x-opencodex-api-key` header a non-loopback bind requires. DSH has a generic headers map, but rc.6 does not document that dedicated admission header as a supported integration contract, so the managed writer fails closed instead of -guessing. Give them loopback access through an SSH tunnel or a local forwarder that adds the header. +guessing. Prime Agent's provider block does accept headers, but remote credential wiring is +deferred from its initial integration. Give them loopback access through an SSH tunnel or a local forwarder that adds the header. **The generated OMP integration is also deliberately loopback-only.** OMP does support provider-level headers, but this initial integration does not emit remote @@ -152,6 +163,10 @@ ocx integration client enable --client mcode ocx mcode ``` +Once connected, `ocx sync` also refreshes the owned MCode block with current context +windows and reasoning-effort ladders. It leaves missing, foreign-edited, unsafe, and +never-owned blocks untouched; re-enable explicitly when you intend to reconnect one. + The separate MiniMax platform CLI (`mmx`) is not a file-toggle integration. Its text commands use MiniMax's Anthropic-compatible endpoint, so OpenCodex provides a credential-isolated, loopback-only launcher: diff --git a/docs-site/src/content/docs/guides/minimax.md b/docs-site/src/content/docs/guides/minimax.md index b7ad0fdd2c..b09247dabf 100644 --- a/docs-site/src/content/docs/guides/minimax.md +++ b/docs-site/src/content/docs/guides/minimax.md @@ -37,16 +37,25 @@ custom_provider: baseURL: http://127.0.0.1:10100 authMode: api-key models: - anthropic/claude-opus-5: {} + anthropic/claude-opus-5: + limit: + context: 1000000 ``` -The real generated model list comes from the running OpenCodex catalog. The block does -not write a real key, does not replace `defaultModel`, and does not change your MiniMax -login. In MCode, choose a model under `custom_provider:opencodex/...`. +The real generated model list and its known context windows and reasoning-effort ladders +come from the running OpenCodex catalog. A model with no authoritative context window or +effort ladder omits that field instead of receiving a guessed value. MCode keeps the +currently selected effort in the session, so OpenCodex exports `effortOptions` without +overwriting that selection. The block does not write a real key, does not replace +`defaultModel`, and does not change your MiniMax login. In MCode, choose a model under +`custom_provider:opencodex/...`. `ocx mcode` verifies that this provider points at the currently running proxy before it -launches the client. If the port changed, refresh the managed block by running the enable -command again. Disable or restore it through the same audited integration system: +launches the client. After the one-time enable, `ocx sync` refreshes the owned block when +the port or catalog capabilities change. Automatic sync never creates an unowned block, +recreates one you removed, or overwrites a file that changed after OpenCodex wrote it; use +the enable command when you intentionally want to reconnect. Disable or restore it through +the same audited integration system: ```bash ocx integration client disable --client mcode diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index e1451dcfbd..d1eec12e1a 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -189,6 +189,15 @@ headers — see [Adapters](/reference/adapters/)). Pool mode overwrites only aut client identity (for example `originator`, session, or thread headers) when the caller did not send them. +For account-switch compatibility diagnosis, enabling provider debug (`ocx debug provider on`) adds +one `[ocx:codex:affinity]` line per canonical ChatGPT forward response. The line contains header +presence, coarse size buckets, process-local HMAC equality tags, safe summaries of known top-level +turn fields, and a count of unknown turn fields. It never includes raw credentials, account ids, +attestation values, thread/session ids, turn metadata, or request bodies; the tags intentionally +change after every proxy restart. Use `ocx debug provider logs -f` while +reproducing the two requests, then run `ocx debug provider off`. This capture is observation-only and +does not strip metadata, retry a request, switch accounts, reset a thread, or otherwise affect routing. + **Diagnostics and reauth.** Human `ocx status` prints an OAuth health block (redacted account ids, no tokens). `ocx doctor` adds an OAuth reliability section with writable-store / single-flight checks and WARN rows that include a recovery Action. When an OAuth provider account needs reauthentication, run diff --git a/docs-site/src/content/docs/guides/sidecars.md b/docs-site/src/content/docs/guides/sidecars.md index ab533d2110..d92316d796 100644 --- a/docs-site/src/content/docs/guides/sidecars.md +++ b/docs-site/src/content/docs/guides/sidecars.md @@ -4,17 +4,32 @@ description: Give routed models real web search and text-only models image under --- Routed models do not all expose hosted **web search** or native **image input**. opencodex backfills -those capabilities with two sidecars. Each can run through a ChatGPT-login (`forward`) provider or a -stored Anthropic OAuth provider. Sidecar errors become bounded tool results or image markers instead -of failing the whole turn. +those capabilities with two sidecars. Both support a ChatGPT-login (`forward`) provider or stored +Anthropic OAuth provider; web search can additionally use stored Grok OAuth through the explicit +`xai` backend. Sidecar errors become bounded tool results or image markers instead of failing the +whole turn. :::note[Automatic backend selection] -Explicit `backend` config wins. When unset, opencodex uses `anthropic` if an enabled Anthropic OAuth -provider has an active account not marked `needsReauth`; otherwise it uses `openai`. Explicit -`anthropic` without that credential fails closed. `openai` requires both ChatGPT login auth and an -enabled `forward` provider. +Explicit `backend` config wins. The two sidecars default differently when `backend` is unset: +**web search** always defaults to `openai` — `anthropic` runs only when explicitly configured. +**Vision** defaults to `anthropic` if an enabled Anthropic OAuth provider has an active account not +marked `needsReauth`, otherwise `openai`. Explicit `anthropic` without that credential fails +closed. Explicit `xai` requires a usable stored Grok OAuth account and does not fall back. `openai` +requires both ChatGPT login auth and an enabled `forward` provider. ::: +### Additional web-search backends (explicit-only) + +Three more web-search backends exist beyond the ChatGPT and Claude paths. Each is +**explicit-only** — it never activates from credential presence — and **fails closed**: +a missing credential produces no sidecar plan and the request takes the normal routed path. + +| Backend | Runs | Credential | Notes | +| --- | --- | --- | --- | +| `xai` | Grok hosted `web_search` (+ opt-in `x_search`) on `api.x.ai` Responses | Stored Grok OAuth (`ocx login xai`) | `webSearchSidecar.xSearch` enables X search with `allowedXHandles`/`excludedXHandles` (max 20, mutually exclusive) and ISO `fromDate`/`toDate`. Default model `grok-4.6`. | +| `gemini` | `google_search` grounding on the Antigravity transport | Stored Antigravity OAuth with a discovered project (`ocx login google-antigravity`) | Default model `gemini-3.7-flash`; reasoning maps to the tiered thinking level. | +| `exa` | Exa Search API (non-LLM result digest) | `webSearchSidecar.exaApiKey` | The key is write-only through the management API (never echoed, redacted from logs). No sidecar model applies. | + ## Web-search sidecar When Codex requests hosted `web_search` for a non-passthrough routed model, opencodex: @@ -24,7 +39,8 @@ When Codex requests hosted `web_search` for a non-passthrough routed model, open 2. Runs the routed model in a small **agentic loop**. When it calls `web_search`, opencodex uses the selected sidecar backend: OpenAI runs hosted `web_search` with `gpt-5.6-luna` by default; Anthropic runs `web_search_20250305` with `claude-sonnet-5` by default. The streamed answer and - citations become a tool result. + citations become a tool result. xAI runs Grok hosted `web_search` with `grok-4.6` by default and, + when enabled, adds hosted `x_search` to the same request. 3. **Loops** until the model answers or the total real-query budget reaches `maxSearchesPerTurn` (default 3), then removes the search tool and forces a final answer. Real client tools such as `apply_patch` or shell finalize the turn so those calls reach Codex. @@ -69,6 +85,28 @@ relevant images in words and include their source URLs. } ``` +The explicit xAI backend uses the stored credential created by `ocx login xai`. Its optional +`xSearch` block enables X search and may restrict it to one handle list and an ISO date range: + +```json +{ + "webSearchSidecar": { + "backend": "xai", + "model": "grok-4.6", + "xSearch": { + "enabled": true, + "allowedXHandles": ["xai"], + "fromDate": "2026-08-01", + "toDate": "2026-08-21" + } + } +} +``` + +`allowedXHandles` and `excludedXHandles` are mutually exclusive and each accepts at most 20 +strings. Dates use `YYYY-MM-DD`. Malformed management writes return `400`; persisted malformed +blocks fail closed at planning time instead of silently broadening the search. + `minimal` reasoning is not used because the hosted backend rejects tools at that effort. A failed search is returned to the routed model as a bounded error result, allowing it to answer from the context it already has. diff --git a/docs-site/src/content/docs/guides/web-dashboard.md b/docs-site/src/content/docs/guides/web-dashboard.md index a32643fbb6..6c2ca81e05 100644 --- a/docs-site/src/content/docs/guides/web-dashboard.md +++ b/docs-site/src/content/docs/guides/web-dashboard.md @@ -110,6 +110,17 @@ In-flight requests keep their captured credentials, and a 401/403 reauthenticati may clear affinity and rotate to another eligible Pool account. This is separate from `openai-apikey` and other providers. +:::caution[Provider-policy responsibility] +The account pool is a technical account-management, routing, and resilience feature. It does not +claim that having multiple accounts is itself prohibited; compliance depends on the account setup and +use pattern. OpenCodex does not endorse using additional accounts to circumvent rate limits, quotas, +plan limits, or other provider restrictions, or sharing account credentials between people. You are +responsible for complying with the provider's current terms for every connected account and use +pattern. Provider restrictions, suspension, or termination are outside OpenCodex's control; +maintainers do not provide policy advice and cannot resolve provider enforcement. Review +[OpenAI's current Terms of Use](https://openai.com/policies/terms-of-use/). +::: + - Manually choosing an account applies immediately: an already-bound thread moves to it on its next request, and only requests already in flight keep the account they captured. A manual choice is also pinned: the card shows a **PINNED** badge, and a higher selection order cannot preempt that account diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 532419e23f..bc7e84e39d 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -142,7 +142,7 @@ Claude ページで圧縮値を調整できます。**警告:** モデルの実 ## ロスターエージェント(injectAgents) -`ocx claude` とシステム環境デーモンは推奨サブエージェントロスター(Subagents タブ、最大 5 モデル)と +プロキシの起動/ensure、`ocx claude`、関連するダッシュボード保存は推奨サブエージェントロスター(Subagents タブ、最大 5 モデル)と `ocx-self` を `~/.claude/agents/ocx-*.md` に同期します。 - **`ocx-self`** は `/model` ピッカーのデフォルトを固定し、値がない場合は `claudeCode.model` を使います。 diff --git a/docs-site/src/content/docs/ja/guides/sidecars.md b/docs-site/src/content/docs/ja/guides/sidecars.md index b30a8ea35e..7a44113a5d 100644 --- a/docs-site/src/content/docs/ja/guides/sidecars.md +++ b/docs-site/src/content/docs/ja/guides/sidecars.md @@ -5,13 +5,13 @@ description: ネイティブ ChatGPT サイドカー経由でルーティング ルーティングモデルごとにホスト型**ウェブ検索**やネイティブ**画像入力**のサポート範囲が異なります。opencodex は ChatGPT ログイン(`forward`)プロバイダーまたは保存された Anthropic OAuth プロバイダーを使う 2 つの -サイドカーで不足機能を補います。サイドカーエラーはターン全体を失敗させず、長さ制限付きのツール +サイドカーで不足機能を補い、ウェブ検索は明示的な `xai` バックエンドで保存済み Grok OAuth も利用できます。サイドカーエラーはターン全体を失敗させず、長さ制限付きのツール 結果や画像案内文に差し替わります。 :::note[バックエンド自動選択] -`backend` を明示するとその値が優先します。省略するとアクティブアカウントが `needsReauth` 状態でない Anthropic -OAuth プロバイダーがあるとき `anthropic`、ないとき `openai` を使います。使える認証情報なしに -`anthropic` を明示すると失敗後停止します。`openai` は ChatGPT ログインと有効化された `forward` +`backend` を明示するとその値が優先します。ウェブ検索は省略時に常に `openai`、Vision は利用可能な +Anthropic OAuth アカウントがあれば `anthropic`、なければ `openai` を使います。利用可能な認証情報なしに +`anthropic` または `xai` を明示するとフォールバックせず失敗します。`openai` は ChatGPT ログインと有効化された `forward` プロバイダーが両方必要です。 ::: @@ -24,8 +24,9 @@ Codex がパススルーでないルーティングモデルにホスト型 `web 公開します。元のホスト型ツールのオプションはサイドカー呼び出しにそのまま使います。 2. ルーティングモデルを小さな**エージェントループ**で実行します。モデルが `web_search` を呼ぶと選んだ バックエンドを使います。OpenAI はデフォルト `gpt-5.6-luna` でホスト型 `web_search` を実行し、 - Anthropic はデフォルト `claude-sonnet-5` で `web_search_20250305` を実行します。ストリーミング回答と - 引用をパースした結果をツール結果として返します。 + Anthropic はデフォルト `claude-sonnet-5` で `web_search_20250305` を実行します。xAI はデフォルト + `grok-4.6` で hosted `web_search` を実行し、`xSearch.enabled` が true の場合は同じリクエストに + `x_search` を追加します。ストリーミング回答と引用をパースした結果をツール結果として返します。 3. モデルが答えるか実際の検索クエリの総数が `maxSearchesPerTurn`(デフォルト 3)に達するまで **反復**します。限度に達すると検索ツールを削除し最終回答を強制します。`apply_patch` や shell のような実際のクライアントツールが出たらターンを終了し該当呼び出しが Codex に渡るようにします。 diff --git a/docs-site/src/content/docs/ja/reference/cli/agents.md b/docs-site/src/content/docs/ja/reference/cli/agents.md index 7ea3a3deb1..b0d0c8ec53 100644 --- a/docs-site/src/content/docs/ja/reference/cli/agents.md +++ b/docs-site/src/content/docs/ja/reference/cli/agents.md @@ -125,7 +125,7 @@ Grok Build モデル フェンスを管理および適用します。 ## クライアント設定のエクスポート -### `ocx export --client ` +### `ocx export --client ` 実行中のプロキシに接続するクライアント設定を出力します。このコマンドは、ベース URL、モデル一覧、およびクライアントに応じた認証情報参照または `opencodex-loopback` プレースホルダーを含む `opencodex` プロバイダーブロックを、選択したクライアントのネイティブ形式でシリアル化します。 @@ -133,7 +133,7 @@ Grok Build モデル フェンスを管理および適用します。 |旗 |アクション | | --- | --- | -| `--client ` |必須。クライアントの設定形式を選択します。 | +| `--client ` |必須。クライアントの設定形式を選択します。 | | `--json` |構成 JSON のみを標準出力に出力するため、リダイレクトはバイト正確な出力をキャプチャします。 `--out` 書き込みメモを含むすべての診断は stderr に送られます。 | | `--out ` |設定を `` に書き込みます。既存のファイルの置き換えを拒否します。 | | `--force` | `--out` が既存のファイルを置き換えることを許可します。 | @@ -150,13 +150,16 @@ ocx export --client opencode --out ~/opencodex-opencode.json |クライアント |正規の宛先 |ダウンロードファイル名 |環境変数 | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (設定すると `XDG_CONFIG_HOME` が勝ち) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | なし - ブロックにリテラル `opencodex-loopback` が入ります | +| `pi` | `~/.pi/agent/models.json` (`PI_CODING_AGENT_DIR` が設定時に優先。相対値は拒否されます) | `pi-models.json` | なし - ブロックにリテラル `opencodex-loopback` が入ります | | `omp` | `~/.omp/agent/models.yml` (デフォルト。空の場合も `OMP_PROFILE` が `PI_PROFILE` より優先されます) | `omp-models.yaml` | なし - リテラル `opencodex-loopback` | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | なし - loopback placeholder | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml`(既定 `~/.dsh/settings.yaml`) | `settings.yaml` | なし — 秘密ではないループバック bearer プレースホルダー | +| `mcode` | `~/.minimax/config.yaml` (`MINIMAX_DATA_DIR`、次に旧 `MAVIS_DATA_DIR` が設定時に優先。相対値は拒否されます) | `mcode-config.yaml` | なし — loopback placeholder | +| `zcode` | `~/.zcode/v2/config.json` (`ZCODE_DATA_DIR` が設定時に優先。相対値は拒否されます) | `config.json` | なし — loopback placeholder | +| `prime` | `~/.prime/agent/models.json` (`PRIME_AGENT_CODING_AGENT_DIR` が設定時に優先。相対値は拒否されます) | `prime-models.json` | なし — loopback placeholder | opencode は `{env:OPENCODEX_OPENCODE_API_KEY}` を補間します。opencodex が生成する Pi のエクスポートには環境変数が不要で、リテラルのプレースホルダー `opencodex-loopback` が入ります。この値は必須です。Pi はモデル リストを構築する際に `apiKey` を解決し、既存の設定に未設定の環境変数参照がある場合はプロバイダー全体を隠すためです。ループバックでは、生成されたプレースホルダーをプロキシが検査することはありません。 @@ -164,7 +167,7 @@ opencode は `{env:OPENCODEX_OPENCODE_API_KEY}` を補間します。opencodex `ocx export` は実際のクライアント設定を書き込むことはありません。宛先は手動でマージできるように出力されます。`--out` は、`--force` なしで既存のファイルを上書きすることを拒否します。これは、設定を置き換えると、その中にすでに含まれている他のプロバイダー、エージェント、および MCP エントリが破壊されるためです。 ::: -キーはシリアル化されません。opencode、Hermes、OpenClaw、Gajae の設定には環境参照のみが含まれるためシークレットは環境内に残り、Pi、OMP、Kimi、DSH の設定には認証情報ではなくループバック用プレースホルダーが入ります。ループバック プロキシ (`127.0.0.1`、デフォルト) にはアドミッション キーはまったく必要ありません。プロキシがループバックを超えてバインドする場合は、対応する `OPENCODEX_OPENCODE_API_KEY`、`OPENCODEX_HERMES_API_KEY`、または `OPENCODEX_OPENCLAW_API_KEY` を設定します。`OPENCODEX_GAJAE_API_KEY` は Gajae の provider 認証値を環境から渡しますが、remote admission header は送れないため、生成される Gajae 統合は Pi、OMP、Kimi、DSH と同様にループバック専用です。アドミッションキーの発行方法については、[リモートアクセス](/reference/configuration/#remote-access) を参照してください。上流プロバイダー自体のキーは完全に別のものであり、[プロバイダー](/guides/providers/) ごとに構成されます。 +キーはシリアル化されません。生成される設定には、文書化された環境参照か、秘密ではないループバック用プレースホルダーのいずれかが入ります。ループバック プロキシ (`127.0.0.1`、デフォルト) にはアドミッション キーはまったく必要ありません。プロキシがループバックを超えてバインドする場合は、対応する `OPENCODEX_OPENCODE_API_KEY`、`OPENCODEX_HERMES_API_KEY`、または `OPENCODEX_OPENCLAW_API_KEY` を設定します。`OPENCODEX_GAJAE_API_KEY` は Gajae の provider 認証値を環境から渡しますが、remote admission header は送れないため、生成される Gajae 統合はループバック専用のままです。アドミッションキーの発行方法については、[リモートアクセス](/reference/configuration/#remote-access) を参照してください。上流プロバイダー自体のキーは完全に別のものであり、[プロバイダー](/guides/providers/) ごとに構成されます。 同じペイロードが `GET /api/client-config` によって提供され、ダッシュボードの [API] タブにレンダリングされるため、CLI、API、および GUI は同じバイトを使用します。 diff --git a/docs-site/src/content/docs/ja/reference/configuration/providers.md b/docs-site/src/content/docs/ja/reference/configuration/providers.md index 5a02ccc2f5..27cf1406ec 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ja/reference/configuration/providers.md @@ -86,6 +86,7 @@ account を削除しても mapping は保持され、同じ id を再追加す | `modelSupportsReasoningSummaries?` | `Record` |モデルを `false` に設定して、概要の広告を停止し、概要配信フィールドを削除します。 | | `modelReasoningSummaryDelivery?` | `Record` |モデルごとの応答配信列挙型。既存の配信フィールドを書き換えます。 | | `modelAdapters?` | `Record` | 混合配線ゲートウェイのモデルごとの `openai-chat` または `openai-responses` 配線オーバーライド。明示的なエントリはレジストリのデフォルトを破ります。DeepSeek のプリセットは `deepseek-v4-flash` のネイティブ Responses を選択でき、GitHub Copilot は GPT-5 ファミリー (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) を Responses 専用デフォルトとして宣言します。これらのモデルはエージェント トラフィックで `/chat/completions` を拒否するためです。`gpt-5.4-nano` のようなビルトイン デフォルトのないモデルはここでオプトインできます。単線アップストリーム ピンと正規の ChatGPT 転送はオーバーライドを拒否します。 | +| xAI Responses オプトイン(ダッシュボード) | スイッチ | `xai` のみで、`grok-4.5` と `grok-4.6` の `modelAdapters` エントリを原子的に設定または削除します。片方だけの場合は、次のスイッチ操作で両方が正規化されるまで混合状態を表示します。他のオーバーライドと tier 動作は変わりません。 | | `modelPreferHostedTools?` | `Record` | hosted tool namespace を予約する非 forward Responses gateway 向けの完全一致モデル opt-in。現在は `["image_generation"]` のみを受け付けます。一致したモデルは `openai-responses` wire を使い、その hosted tool をサポートする必要があります。競合するクライアント `image_gen` 宣言を除去し、呼び出し元の tool choice を維持するため selector も書き換えます。OpenAI API の仮想 `-pro` モデルでは、まず選択した公開 ID に一致させ、解決後のベース wire-model ID をフォールバックとして使用します。`modelAdapters` は公開 ID、次にベース ID の順に解決し、後者の結果が最終 wire を決めます。未設定のモデルは通常の alias 動作を維持します。 | | `reasoningEffortMap?` | `Record` |ラベルを推論するためのプロバイダー全体のワイヤ エイリアス。 | | `modelReasoningEffortMap?` | `Record>` |推論ラベルのモデルごとのワイヤ エイリアス。 | diff --git a/docs-site/src/content/docs/ja/reference/configuration/server.md b/docs-site/src/content/docs/ja/reference/configuration/server.md index 673a2c75c7..cacde58f65 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/server.md +++ b/docs-site/src/content/docs/ja/reference/configuration/server.md @@ -133,14 +133,16 @@ Codex は、タイトルやコミット メッセージなどのタスクに小 |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | | `enabled?` | `boolean` |使用可能な場合はオン |マスタースイッチ。 | -| `backend?` | `"openai" \| "anthropic"` |自動 |明示的な勝利。それ以外の場合は使用可能な保存された Anthropic OAuth は `anthropic` を選択し、次に `openai` を選択します。 | -| `model?` | `string` |バックエンド依存 | OpenAI の場合は `gpt-5.6-luna`、Anthropic の場合は `claude-sonnet-5`。従来の明示的な `gpt-5.4-mini` は開始時に移行されます。 | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | 明示設定が優先され、未設定なら常に `openai` です。`anthropic` と `xai` は明示設定時のみ実行され、`gemini` と `exa` は executor が提供されるまで予約値です。 | +| `model?` | `string` |バックエンド依存 | OpenAI は `gpt-5.6-luna`、Anthropic は `claude-sonnet-5`、xAI は `grok-4.6`。従来の明示的な `gpt-5.4-mini` は開始時に移行されます。 | +| `exaApiKey?` | `string` | なし | `exa` バックエンドのオペレーターキー。書き込み専用で、管理 API の読み取りでは保存値を返しません。 | +| `xSearch?` | `object` | 省略 | xAI 専用の hosted `x_search` opt-in。`enabled`、相互排他的な `allowedXHandles` / `excludedXHandles` 配列(最大 20 件)、ISO の `fromDate` / `toDate`(`YYYY-MM-DD`)を指定します。 | | `reasoning?` | `string` | `low` |サイドカーの取り組み。 `minimal` は Web 検索で拒否されます。 | | `maxSearchesPerTurn?` | `number` | `3` |メインモデルのターンごとに許可される実際の検索。 | | `routedModelStallTimeoutMs?` | `number` | `200000` |設定ファイルのみのルーテッド モデルの raw ボディの非アクティブ期限。整数 1 ~ 2147483647。空でないすべてのチャンクがリセットされます。 | | `timeoutMs?` | `number` | `60000` | 1 つのホストされた検索の期限。 | -OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forward` プロバイダーが必要です。クロードインバウンドのルーティングされたリプレイは、メインの ChatGPT 認証を内部リクエストに挿入します。 Anthropic バックエンドは、有効な Anthropic OAuth プロバイダーからのアクティブに保存された資格情報を使用します。使用可能なアカウントがない、明示的に選択された Anthropic バックエンドは、フォールバックせずに失敗して閉じられます。 Anthropic executor は、ネイティブの `web_search_20250305` ツールを使用します。 +OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forward` プロバイダーが必要です。クロードインバウンドのルーティングされたリプレイは、メインの ChatGPT 認証を内部リクエストに挿入します。 Anthropic バックエンドは、有効な Anthropic OAuth プロバイダーからのアクティブに保存された資格情報を使用します。使用可能なアカウントがない、明示的に選択された Anthropic バックエンドは、フォールバックせずに失敗して閉じられます。 Anthropic executor は、ネイティブの `web_search_20250305` ツールを使用します。xAI バックエンドには使用可能な保存済み Grok OAuth アカウントが必要で、hosted `web_search` を使用し、`xSearch.enabled` が true の場合は hosted `x_search` を追加します。不正な `xSearch` 管理入力は `400` を返し、不正な永続化ブロックは計画時に fail closed します。`gemini` と `exa` は資格情報の検出やフォールバックからは決して有効にならず、オペレーターが明示的に選択する必要があります。`exaApiKey` は書き込み時に受け付けますが、管理レスポンスからは省略されます。 検索は 4 つのクロック (ベース `stallTimeoutSec`、`connectTimeoutMs`、ルーテッド モデルの非アクティビティ、ホスト型検索のタイムアウト) によって制御されます。有効なブリッジ ウォッチドッグは、最大プラス 30 秒です。ルート ストールは非アクティブ ガードであり、総生成期限ではありません。 @@ -149,7 +151,7 @@ OpenAI バックエンドには、ChatGPT ログインと有効な ChatGPT `forw |フィールド |タイプ |デフォルト |意味 | | --- | --- | --- | --- | | `enabled?` | `boolean` |使用可能な場合はオン |マスターイメージと説明のスイッチ。 | -| `backend?` | `"openai" \| "anthropic"` |自動 | Web 検索と同じ、明示的優先、人間認証情報を意識した選択。 | +| `backend?` | `"openai" \| "anthropic"` |自動 | 明示的な値が優先されます。未設定の場合、使用可能な保存済み Anthropic OAuth 認証情報が優先され、それ以外は `openai` になります。 | | `model?` | `string` |バックエンド依存 | OpenAI の場合は `gpt-5.4-mini`、Anthropic の場合は `claude-sonnet-5`。 | | `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses の推論負荷。Anthropic は無視します。 | | `maxDescriptionsPerTurn?` | `number` | `8` |新しい説明のキャッシュミスはメインターンごとに許可されます。 `0` は通話を無効にします。無効な値にはデフォルトが使用されます。 | diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index c5aae96d36..0183b5b72f 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -179,7 +179,7 @@ Claude 페이지에서 압축 값을 조절할 수 있어요. **경고:** 모델 ## 로스터 에이전트(injectAgents) -`ocx claude`와 시스템 환경 데몬은 추천 서브에이전트 로스터(Subagents 탭, 최대 5개 모델)와 +프록시 시작/ensure, `ocx claude`, 관련 대시보드 저장은 추천 서브에이전트 로스터(Subagents 탭, 최대 5개 모델)와 `ocx-self`를 `~/.claude/agents/ocx-*.md`에 동기화해요. - **`ocx-self`**는 `/model` 선택기의 기본값을 고정하고, 값이 없으면 `claudeCode.model`을 사용해요. diff --git a/docs-site/src/content/docs/ko/guides/sidecars.md b/docs-site/src/content/docs/ko/guides/sidecars.md index df1fdb841f..e75e0521e5 100644 --- a/docs-site/src/content/docs/ko/guides/sidecars.md +++ b/docs-site/src/content/docs/ko/guides/sidecars.md @@ -5,13 +5,14 @@ description: 네이티브 ChatGPT 사이드카를 통해 라우팅 모델에 실 라우팅 모델마다 호스팅 **웹 검색**이나 네이티브 **이미지 입력** 지원 범위가 다릅니다. opencodex는 ChatGPT 로그인(`forward`) 프로바이더나 저장된 Anthropic OAuth 프로바이더를 사용하는 두 -사이드카로 부족한 기능을 보완합니다. 사이드카 오류는 턴 전체를 실패시키지 않고 길이가 제한된 도구 +사이드카로 부족한 기능을 보완하며, 웹 검색은 명시적인 `xai` 백엔드로 저장된 Grok OAuth도 사용할 수 +있습니다. 사이드카 오류는 턴 전체를 실패시키지 않고 길이가 제한된 도구 결과나 이미지 안내문으로 바뀝니다. :::note[백엔드 자동 선택] -`backend`를 명시하면 그 값이 우선합니다. 생략하면 활성 계정이 `needsReauth` 상태가 아닌 Anthropic -OAuth 프로바이더가 있을 때 `anthropic`, 없을 때 `openai`를 사용합니다. 쓸 수 있는 자격 증명 없이 -`anthropic`을 명시하면 실패 후 중단합니다. `openai`는 ChatGPT 로그인과 활성화된 `forward` +`backend`를 명시하면 그 값이 우선합니다. 웹 검색은 생략 시 항상 `openai`를 사용하고, 비전은 사용 +가능한 Anthropic OAuth 계정이 있으면 `anthropic`, 없으면 `openai`를 사용합니다. 쓸 수 있는 자격 +증명 없이 `anthropic` 또는 `xai`를 명시하면 폴백 없이 실패합니다. `openai`는 ChatGPT 로그인과 활성화된 `forward` 프로바이더가 모두 필요합니다. ::: @@ -24,8 +25,9 @@ Codex가 패스스루가 아닌 라우팅 모델에 호스팅 `web_search`를 노출합니다. 원래 호스팅 도구의 옵션은 사이드카 호출에 그대로 사용합니다. 2. 라우팅 모델을 작은 **에이전트 루프**에서 실행합니다. 모델이 `web_search`를 호출하면 선택한 백엔드를 사용합니다. OpenAI는 기본 `gpt-5.6-luna`로 호스팅 `web_search`를 실행하고, - Anthropic은 기본 `claude-sonnet-5`로 `web_search_20250305`를 실행합니다. 스트리밍 답변과 - 인용을 파싱한 결과는 도구 결과로 돌려줍니다. + Anthropic은 기본 `claude-sonnet-5`로 `web_search_20250305`를 실행합니다. xAI는 기본 + `grok-4.6`으로 호스팅 `web_search`를 실행하고, `xSearch.enabled`가 true이면 같은 요청에 + `x_search`를 추가합니다. 스트리밍 답변과 인용을 파싱한 결과는 도구 결과로 돌려줍니다. 3. 모델이 답하거나 실제 검색 쿼리의 총합이 `maxSearchesPerTurn`(기본값 3)에 도달할 때까지 **반복**합니다. 한도에 닿으면 검색 도구를 제거하고 최종 답변을 강제합니다. `apply_patch`나 shell 같은 실제 클라이언트 도구가 나오면 턴을 끝내 해당 호출이 Codex에 전달되게 합니다. diff --git a/docs-site/src/content/docs/ko/reference/adapters.md b/docs-site/src/content/docs/ko/reference/adapters.md index 06eedf2773..abf353b871 100644 --- a/docs-site/src/content/docs/ko/reference/adapters.md +++ b/docs-site/src/content/docs/ko/reference/adapters.md @@ -149,6 +149,13 @@ commentary로 유지하고 비공개 완료 툴을 한 번 검증합니다. - content-addressed blob으로 대화 상태를 재생하고 서버 툴 호출을 Codex에 다시 매핑합니다. protobuf `GetUsableModels` RPC로 실시간 Cursor 모델을 찾으며, run 요청이 wire에 commit되기 전까지만 재시도합니다. +- 도구 없이 정상 완료된 턴 뒤에는 Cursor가 돌려준 ConversationStateStructure를 프로세스 로컬 + store에 보관하고, 검증된 선형 이어말하기에서는 전체 root history를 다시 만들지 않고 그 + checkpoint를 재사용합니다. tool-result 턴은 마지막 정상 완료 턴의 checkpoint에 커버되지 않은 + suffix만 붙입니다. compaction, helper/shadow 격리, 계정/모델 불일치, 없는 ref, decode 실패, + forced-fresh 복구, invalid_argument 재시도는 기존 full replay로 돌아갑니다. 프로세스 재시작은 + 메모리 store를 버리고 full replay합니다. Cursor Connect는 권위 있는 cache_read_tokens를 주지 + 않으므로 OpenCodex usage만 보고 cache hit라고 단정하지 않습니다. - `cursor/grok-4.5-fast`는 선택 가능한 모델로 유지하되, Cursor에는 정식 `grok-4.5` 모델을 보내고 별도의 `effort`, `fast=true` 값은 `requested_model.parameters`에 담습니다. - Cursor 네이티브 로컬 파일시스템/shell/network 실행은 기본적으로 거부합니다. 명시적인 diff --git a/docs-site/src/content/docs/ko/reference/cli/agents.md b/docs-site/src/content/docs/ko/reference/cli/agents.md index 80325145c4..22ba1bc2c5 100644 --- a/docs-site/src/content/docs/ko/reference/cli/agents.md +++ b/docs-site/src/content/docs/ko/reference/cli/agents.md @@ -131,7 +131,7 @@ Grok Build model fence를 관리하고 적용합니다. ## 클라이언트 설정 내보내기 -### `ocx export --client ` +### `ocx export --client ` 실행 중인 프록시에 연결할 client config를 출력합니다. 이 명령은 base URL, model list, 그리고 client에 따라 credential reference 또는 `opencodex-loopback` placeholder를 포함한 `opencodex` provider block을 선택한 client의 네이티브 형식으로 직렬화합니다. @@ -139,7 +139,7 @@ Grok Build model fence를 관리하고 적용합니다. | 플래그 | 동작 | | --- | --- | -| `--client ` | 필수입니다. 클라이언트 설정 형식을 선택합니다. | +| `--client ` | 필수입니다. 클라이언트 설정 형식을 선택합니다. | | `--json` | config JSON만 stdout에 출력하므로, redirect가 byte-exact 출력을 캡처합니다. `--out` write note를 포함한 모든 진단 메시지는 stderr로 갑니다. | | `--out ` | config를 ``에 씁니다. 기존 파일이 있으면 덮어쓰지 않습니다. | | `--force` | `--out`이 기존 파일을 덮어쓰도록 허용합니다. | @@ -156,13 +156,16 @@ ocx export --client opencode --out ~/opencodex-opencode.json | 클라이언트 | 표준 대상 경로 | 다운로드 파일명 | 환경 변수 | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME`이 설정되어 있으면 우선합니다) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | 없음 - 블록에 리터럴 `opencodex-loopback`이 들어갑니다 | +| `pi` | `~/.pi/agent/models.json` (`PI_CODING_AGENT_DIR`가 설정되면 우선. 상대 경로는 거부됩니다) | `pi-models.json` | 없음 - 블록에 리터럴 `opencodex-loopback`이 들어갑니다 | | `omp` | `~/.omp/agent/models.yml` (기본값. 빈 값이어도 `OMP_PROFILE`이 `PI_PROFILE`보다 우선합니다) | `omp-models.yaml` | 없음 - 리터럴 `opencodex-loopback` | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | 없음 - loopback placeholder | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml`(기본값 `~/.dsh/settings.yaml`) | `settings.yaml` | 없음 — 비밀이 아닌 loopback bearer placeholder | +| `mcode` | `~/.minimax/config.yaml` (`MINIMAX_DATA_DIR`, 그다음 레거시 `MAVIS_DATA_DIR`가 설정되면 우선. 상대 경로는 거부됩니다) | `mcode-config.yaml` | 없음 — loopback placeholder | +| `zcode` | `~/.zcode/v2/config.json` (`ZCODE_DATA_DIR`가 설정되면 우선. 상대 경로는 거부됩니다) | `config.json` | 없음 — loopback placeholder | +| `prime` | `~/.prime/agent/models.json` (`PRIME_AGENT_CODING_AGENT_DIR`가 설정되면 우선. 상대 경로는 거부됩니다) | `prime-models.json` | 없음 — loopback placeholder | opencode는 `{env:OPENCODEX_OPENCODE_API_KEY}`를 보간합니다. opencodex가 생성한 Pi 블록에는 환경 변수가 필요 없으며, 리터럴 placeholder인 `opencodex-loopback`이 들어갑니다. 이 값은 필수입니다. Pi는 모델 목록을 만들 때 `apiKey`를 해석하고, 기존 config에 설정되지 않은 env 참조가 있으면 provider 전체를 숨기기 때문입니다. 루프백에서 proxy는 생성된 placeholder를 검사하지 않습니다. @@ -170,7 +173,7 @@ opencode는 `{env:OPENCODEX_OPENCODE_API_KEY}`를 보간합니다. opencodex가 `ocx export`는 실제 client config를 절대 쓰지 않습니다. 대상 경로는 손으로 병합하라고 출력되며, `--out`은 `--force` 없이 기존 파일을 덮어쓰지 않습니다. config를 바꾸어 덮어쓰면 이미 들어 있던 다른 provider, agent, MCP entry가 사라지기 때문입니다. ::: -어떤 key도 직렬화되지 않습니다. opencode, Hermes, OpenClaw, Gajae config에는 env reference만 들어가므로 secret은 환경 변수에 남고, Pi, OMP, Kimi, DSH config에는 인증 정보가 아니라 loopback placeholder가 들어갑니다. loopback proxy(`127.0.0.1`, 기본값)는 admission key가 전혀 필요하지 않습니다. proxy가 loopback을 넘어 바인딩할 때는 해당하는 `OPENCODEX_OPENCODE_API_KEY`, `OPENCODEX_HERMES_API_KEY`, `OPENCODEX_OPENCLAW_API_KEY`를 설정하십시오. `OPENCODEX_GAJAE_API_KEY`는 Gajae provider 인증 값을 환경에서 전달하지만 remote admission header를 보낼 수는 없으므로, 생성되는 Gajae 통합은 Pi, OMP, Kimi, DSH와 마찬가지로 loopback 전용입니다. admission key가 어떻게 발급되는지는 [Remote access](/reference/configuration/#remote-access)를 보십시오. upstream provider 자체의 key는 완전히 별개의 것으로, 각 [Providers](/guides/providers/)에 맞게 설정합니다. +어떤 key도 직렬화되지 않습니다. 생성되는 config에는 문서화된 env reference 또는 비밀이 아닌 loopback placeholder 중 하나가 들어갑니다. loopback proxy(`127.0.0.1`, 기본값)는 admission key가 전혀 필요하지 않습니다. proxy가 loopback을 넘어 바인딩할 때는 해당하는 `OPENCODEX_OPENCODE_API_KEY`, `OPENCODEX_HERMES_API_KEY`, `OPENCODEX_OPENCLAW_API_KEY`를 설정하십시오. `OPENCODEX_GAJAE_API_KEY`는 Gajae provider 인증 값을 환경에서 전달하지만 remote admission header를 보낼 수는 없으므로, 생성되는 Gajae 통합은 loopback 전용으로 남습니다. admission key가 어떻게 발급되는지는 [Remote access](/reference/configuration/#remote-access)를 보십시오. upstream provider 자체의 key는 완전히 별개의 것으로, 각 [Providers](/guides/providers/)에 맞게 설정합니다. 같은 payload는 `GET /api/client-config`로 제공되고 dashboard의 API 탭에도 렌더링되므로, CLI, API, GUI가 모두 같은 바이트를 사용합니다. diff --git a/docs-site/src/content/docs/ko/reference/configuration/providers.md b/docs-site/src/content/docs/ko/reference/configuration/providers.md index d33312e176..707129b2ed 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ko/reference/configuration/providers.md @@ -86,6 +86,7 @@ managed map을 활성화하면 privacy-safe selector를 만들고, 이후 계정 | `modelSupportsReasoningSummaries?` | `Record` | 모델을 `false`로 두면 summary 광고를 멈추고 summary 전달 필드를 제거합니다. | | `modelReasoningSummaryDelivery?` | `Record` | 모델별 Responses 전달 enum입니다. 기존 delivery 필드를 다시 씁니다. | | `modelAdapters?` | `Record` | 혼합 와이어 게이트웨이를 위한 모델별 `openai-chat` 또는 `openai-responses` 와이어 재정의입니다. 명시적 항목이 레지스트리 기본값보다 우선합니다. DeepSeek 프리셋은 `deepseek-v4-flash`에 네이티브 Responses를 선택할 수 있고, GitHub Copilot은 GPT-5 계열(`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`)을 Responses 전용 기본값으로 선언합니다. 이 모델들은 에이전트 트래픽에서 `/chat/completions`를 거부하기 때문입니다. `gpt-5.4-nano`처럼 기본값이 없는 모델은 여기서 직접 옵트인할 수 있습니다. 단일 와이어 상위 항목과 정식 ChatGPT forward는 재정의를 거부합니다. | +| xAI Responses 옵트인(대시보드) | 스위치 | `xai`에서만 `grok-4.5`와 `grok-4.6`의 `modelAdapters` 항목을 원자적으로 설정하거나 지웁니다. 한 항목만 있으면 다음 스위치 쓰기가 둘을 정규화할 때까지 혼합 상태로 표시됩니다. 다른 재정의와 티어 동작은 바뀌지 않습니다. | | `modelPreferHostedTools?` | `Record` | hosted tool namespace를 예약하는 non-forward Responses gateway용 정확한 모델 ID opt-in입니다. 현재 `["image_generation"]`만 허용하며, 일치하는 모델은 `openai-responses` wire를 사용하고 해당 hosted tool을 지원해야 합니다. 충돌하는 클라이언트 `image_gen` 선언을 제거하고 호출자의 tool choice를 유지하도록 selector도 다시 씁니다. OpenAI API 가상 `-pro` 모델은 선택한 공개 ID를 먼저 일치시키고, 해석된 기본 wire-model ID를 대체값으로 사용합니다. `modelAdapters`는 공개 ID를 먼저, 그 다음 기본 ID를 해석하며, 두 번째 결과가 최종 wire를 결정합니다. 설정하지 않은 모델은 일반 alias 동작을 유지합니다. | | `reasoningEffortMap?` | `Record` | reasoning 레이블의 공급자 전반 와이어 별칭입니다. | | `modelReasoningEffortMap?` | `Record>` | reasoning 레이블의 모델별 와이어 별칭입니다. | diff --git a/docs-site/src/content/docs/ko/reference/configuration/server.md b/docs-site/src/content/docs/ko/reference/configuration/server.md index ab23a6bcdc..fe3526537f 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/server.md +++ b/docs-site/src/content/docs/ko/reference/configuration/server.md @@ -133,14 +133,16 @@ Codex는 제목과 커밋 메시지 같은 작업에 작은 보조 모델을 사 | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | 주 스위치입니다. | -| `backend?` | `"openai" \| "anthropic"` | auto | 명시값이 우선입니다. 그 외에는 사용 가능한 저장된 Anthropic OAuth가 있으면 `anthropic`을, 아니면 `openai`를 선택합니다. | -| `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.6-luna`, Anthropic은 `claude-sonnet-5`입니다. 레거시로 명시된 `gpt-5.4-mini`는 시작 시 마이그레이션됩니다. | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | 명시값이 우선입니다. 생략하면 항상 `openai`입니다. `anthropic`과 `xai`는 명시적으로 설정할 때만 실행되며, `gemini`와 `exa`는 executor가 제공될 때까지 예약 상태입니다. | +| `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.6-luna`, Anthropic은 `claude-sonnet-5`, xAI는 `grok-4.6`입니다. 레거시로 명시된 `gpt-5.4-mini`는 시작 시 마이그레이션됩니다. | +| `exaApiKey?` | `string` | 없음 | `exa` 백엔드용 운영자 키입니다. 쓰기 전용이며 관리 API 조회에서는 저장된 값을 반환하지 않습니다. | +| `xSearch?` | `object` | 생략 | xAI 전용 `x_search` opt-in입니다. `enabled`, 서로 배타적인 `allowedXHandles` / `excludedXHandles` 배열(최대 20개), ISO `fromDate` / `toDate`(`YYYY-MM-DD`)를 지원합니다. | | `reasoning?` | `string` | `low` | 사이드카 노력 수준입니다. `minimal`은 web search와 함께 거부됩니다. | | `maxSearchesPerTurn?` | `number` | `3` | 메인 모델 턴당 허용되는 실제 검색 수입니다. | | `routedModelStallTimeoutMs?` | `number` | `200000` | 설정 파일 전용 routed-model 원시 본문 비활성 기한입니다. 정수 1–2147483647이며, 비어 있지 않은 모든 청크가 이를 다시 시작합니다. | | `timeoutMs?` | `number` | `60000` | 한 번의 hosted search에 대한 기한입니다. | -OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider를 요구합니다. Claude-inbound routed replay는 메인 ChatGPT 인증을 내부 요청에 주입합니다. Anthropic 백엔드는 활성화된 Anthropic OAuth provider에서 현재 저장된 자격 증명을 사용합니다. 명시적으로 선택한 Anthropic 백엔드에 사용할 수 있는 계정이 없으면 폴백하지 않고 닫힌 상태로 실패합니다. Anthropic 실행기는 자체 `web_search_20250305` 도구를 사용합니다. +OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider를 요구합니다. Claude-inbound routed replay는 메인 ChatGPT 인증을 내부 요청에 주입합니다. Anthropic 백엔드는 활성화된 Anthropic OAuth provider에서 현재 저장된 자격 증명을 사용합니다. 명시적으로 선택한 Anthropic 백엔드에 사용할 수 있는 계정이 없으면 폴백하지 않고 닫힌 상태로 실패합니다. Anthropic 실행기는 자체 `web_search_20250305` 도구를 사용합니다. xAI 백엔드는 사용 가능한 저장된 Grok OAuth 계정을 요구하고 hosted `web_search`를 사용하며, `xSearch.enabled`가 true이면 hosted `x_search`를 추가합니다. 잘못된 `xSearch` 관리 입력은 `400`을 반환하고, 잘못 저장된 블록은 계획 단계에서 닫힌 상태로 실패합니다. `gemini`와 `exa`는 자격 증명 탐색이나 폴백으로 절대 활성화되지 않으며 운영자가 명시적으로 선택해야 합니다. `exaApiKey`는 쓰기에서 허용되지만 관리 응답에서는 생략됩니다. 검색에는 네 가지 시계가 작동합니다: 기본 `stallTimeoutSec`, `connectTimeoutMs`, routed-model 비활성 시간, 그리고 hosted-search 제한 시간입니다. 실제 bridge watchdog은 이들 중 최댓값에 30초를 더한 값입니다. Routed stall은 비활성 가드이지, 전체 생성 기한이 아닙니다. @@ -149,7 +151,7 @@ OpenAI 백엔드는 ChatGPT 로그인과 활성화된 ChatGPT `forward` provider | 필드 | 형식 | 기본값 | 의미 | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | 주 이미지 설명 스위치입니다. | -| `backend?` | `"openai" \| "anthropic"` | auto | web search와 같은, 명시값 우선 및 Anthropic 자격 증명 인식 선택 방식입니다. | +| `backend?` | `"openai" \| "anthropic"` | auto | 명시값이 우선하며, 미설정 시 사용 가능한 저장된 Anthropic OAuth 자격 증명을 우선하고 없으면 `openai`를 사용합니다. | | `model?` | `string` | backend-dependent | OpenAI는 `gpt-5.4-mini`, Anthropic은 `claude-sonnet-5`입니다. | | `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses 추론 강도입니다. Anthropic은 무시합니다. | | `maxDescriptionsPerTurn?` | `number` | `8` | 메인 턴당 허용되는 새 설명 캐시 미스 수입니다. `0`이면 호출이 비활성화되며, 잘못된 값은 기본값을 사용합니다. | diff --git a/docs-site/src/content/docs/reference/adapters.md b/docs-site/src/content/docs/reference/adapters.md index 0895ad07e8..29859992f7 100644 --- a/docs-site/src/content/docs/reference/adapters.md +++ b/docs-site/src/content/docs/reference/adapters.md @@ -116,6 +116,19 @@ of the HTTP retry loop. opaque `thoughtSignature` values so tool-result continuations retain Gemini reasoning continuity. The signature cache is snapshotted to the config directory, so continuations also survive proxy restarts. +- **Malformed response shapes fail closed.** A claimed candidate, its `content`, or its + `content.parts` that is not the documented container terminates the turn with a + `google response contained invalid …` error naming the structural reason and the offending + value's type — never its contents. Absence is handled separately from corruption: an absent, + `null` or empty `content` or `parts` still completes the turn normally, a streaming chunk whose + `candidates` is absent, `null` or empty is skipped so the turn completes on a later terminal + frame, and a buffered response that carries no candidate at all returns + `google response contained no candidates`. A root `data: null` keepalive frame is still skipped as + padding. +- Tool-call batches are closed by one immediately adjacent user turn containing one ordered + `functionResponse` per representable call. Interrupted histories receive an explicit missing-result marker; + duplicate or standalone results are preserved as marked text (and image siblings) rather than + emitted as invalid unpaired `functionResponse` parts. - **Inline image output:** when the model is one of the explicit image-capable chat IDs (`gemini-3.1-flash-image`, `gemini-2.0-flash-preview-image-generation`, or `gemini-3-pro-image-preview`), the adapter sends `responseModalities: ["TEXT", "IMAGE"]`. @@ -205,6 +218,14 @@ compatibility pair: `agent.v1.AgentService/RunSSE` for server output and - Replays conversation state through content-addressed blobs, maps server tool calls back to Codex, discovers live Cursor models through the protobuf `GetUsableModels` RPC, and retries only before a run request is committed to the wire. +- After a successful no-tool turn, the adapter keeps Cursor's returned ConversationStateStructure + in a process-local store and reuses that checkpoint on the next validated linear continuation + instead of rebuilding the full root history. Tool-result turns reuse the last completed-turn + checkpoint plus only the uncovered suffix when the covered message boundary is known. + Compaction, helper/shadow isolation, account/model mismatch, missing refs, decode failures, + forced-fresh recovery, and invalid_argument retries fall back to the existing full replay. A + process restart drops the in-memory store and full-replays. Cursor Connect still does not expose + authoritative cache_read_tokens, so OpenCodex usage is not a cache-hit counter. - Honors `upstreamHttpVersion` for both live model discovery and inference. `auto`, `http2`, and `h2` preserve the existing HTTP/2 transport; only `http1.1` and `h1` select compatibility mode. - Exposes Cursor Router as `cursor/auto` plus explicit `cursor/auto-cost`, diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index e09159d1c5..8006f2fcaf 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -17,6 +17,22 @@ surface modes, delegation, effort, and fallback behavior fit together. ocx agent subagents set ark/model-a,openai/gpt-5.5 ``` +`ocx agent sidecar web --list` and `ocx agent sidecar vision --list` print the models the +server currently offers for each sidecar — the exact filtered set the dashboard picker shows +(picker-visible rows plus the login-entitled Luna/Haiku auth slots, intersected with executor +availability for web search, minus provably text-only models for vision). Human-readable lists +show each model's backend in brackets. A web-search `--model` write resolves that server-offered +row and persists its backend and model together, so switching to an Anthropic option cannot keep +an OpenAI backend (or vice versa). Writes go to the same management route as the GUI and are +subject to the same per-sidecar gate: web search refuses a backend/model pair outside the listed +set (closed membership), while vision refuses only a model provably unable to see (unknown ids +stay writable). + +```bash +ocx agent sidecar web --list +ocx agent sidecar web --model gpt-5.6-luna +``` + ### `ocx v2 |keep-native-v1 |threads |mode-hint >` Manage the Codex `multi_agent_v2` feature flag and the three-state multi-agent surface mode. @@ -169,7 +185,7 @@ Manage and apply the Grok Build model fence. ## Client config export -### `ocx export --client ` +### `ocx export --client ` Print a client config wired to the running proxy. The command serializes the `opencodex` provider block — base URL, model list, and the client's credential @@ -180,7 +196,7 @@ models Codex can currently see. | Flag | Action | | --- | --- | -| `--client ` | Required. Selects the client config dialect. | +| `--client ` | Required. Selects the client config dialect. | | `--json` | Print the generated document as JSON on stdout for scripts. This is JSON even when the selected client's native format is YAML, TOML, or JSON5. | | `--out ` | Write the client's native config format to ``. Refuses to replace an existing file. | | `--force` | Allow `--out` to replace an existing file. | @@ -199,13 +215,16 @@ client applies its own defaults for those). | Client | Canonical destination | Download filename | Env var | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` wins when set) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | none — the block carries the literal `opencodex-loopback` | +| `pi` | `~/.pi/agent/models.json` (`PI_CODING_AGENT_DIR` wins when set; a relative value is refused) | `pi-models.json` | none — the block carries the literal `opencodex-loopback` | | `omp` | `~/.omp/agent/models.yml` (`OMP_PROFILE` wins over `PI_PROFILE`, even when empty; named profiles use the home-relative `PI_CONFIG_DIR` directory name and ignore `PI_CODING_AGENT_DIR`, while the default profile lets `PI_CODING_AGENT_DIR` win) | `omp-models.yaml` | none — loopback placeholder | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | none — loopback placeholder | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml` (default `~/.dsh/settings.yaml`) | `settings.yaml` | none — non-secret loopback bearer placeholder | +| `mcode` | `~/.minimax/config.yaml` (`MINIMAX_DATA_DIR`, then the legacy `MAVIS_DATA_DIR`, win when set; a relative value is refused) | `mcode-config.yaml` | none — loopback placeholder | +| `zcode` | `~/.zcode/v2/config.json` (`ZCODE_DATA_DIR` wins when set; a relative value is refused) | `config.json` | none — loopback placeholder | +| `prime` | `~/.prime/agent/models.json` (`PRIME_AGENT_CODING_AGENT_DIR` wins when set; a relative value is refused) | `prime-models.json` | none — loopback placeholder | The managed DSH export requires DSH 0.1.0-rc.6 or newer and owns only `llm-pi-ai.providers.opencodex`. DSH hot reloads that provider; the user's default model and @@ -218,6 +237,13 @@ hide the whole provider when an existing config contains an unset env reference. checks the generated placeholder on loopback. OMP supports provider-level headers, but this initial integration deliberately remains loopback-only; remote `x-opencodex-api-key` wiring is deferred. +The MCode, ZCode and Prime exports are loopback-only for the same reason and likewise carry the +`opencodex-loopback` placeholder rather than a real credential. Prime Agent reads the same +`models.json` contract Pi does, so the two exports produce the same document; only the destination +differs. A relative path in any of those three environment overrides is refused, because the proxy +and the client can have different working directories and would otherwise disagree about which +file is meant. + :::caution[Merge, never replace] `ocx export` never writes your real client config. The destination is printed for you to merge by hand, and `--out` refuses to overwrite an existing file without `--force`, because replacing a diff --git a/docs-site/src/content/docs/reference/configuration/providers.md b/docs-site/src/content/docs/reference/configuration/providers.md index a12ed68f3b..135f8f9632 100644 --- a/docs-site/src/content/docs/reference/configuration/providers.md +++ b/docs-site/src/content/docs/reference/configuration/providers.md @@ -99,6 +99,7 @@ differing backup and rewrites known legacy namespaced selected ids to bare ids. | `modelSupportsReasoningSummaries?` | `Record` | Set a model to `false` to stop advertising summaries and strip summary-delivery fields. | | `modelReasoningSummaryDelivery?` | `Record` | Per-model Responses delivery enum; rewrites an existing delivery field. | | `modelAdapters?` | `Record` | Per-model `openai-chat` or `openai-responses` wire override for mixed-wire gateways. Explicit entries beat registry defaults. The OpenCode Go preset selects Responses for `gpt-5.6-luna` while leaving sibling models on their documented wires; DeepSeek can select native Responses for `deepseek-v4-flash`; and GitHub Copilot declares Responses-only defaults for its GPT-5 family (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) because those models reject `/chat/completions` for agent traffic. Models without a built-in default (for example `gpt-5.4-nano`) can be opted in here. Single-wire upstream pins and canonical ChatGPT forward reject overrides. | +| xAI Responses opt-in (dashboard) | switch | For `xai` only, atomically sets or clears the `grok-4.5` and `grok-4.6` `modelAdapters` entries. A hand-edited single entry appears as mixed until the next switch write normalizes both. Other overrides and tier behavior are unchanged. | | `modelPreferHostedTools?` | `Record` | Exact-model opt-in for non-forward Responses gateways that reserve a hosted-tool namespace. Currently accepts only `["image_generation"]`; a matching model must use the `openai-responses` wire and support that hosted tool. It removes colliding client `image_gen` declarations and rewrites their selectors to preserve caller tool choice. For OpenAI API virtual `-pro` models, the selected public ID is matched first and the resolved base wire-model ID is a fallback. `modelAdapters` resolves the public ID first, then the base ID; the second resolution determines the final wire. Other models retain normal alias behavior. | | `reasoningEffortMap?` | `Record` | Provider-wide wire aliases for reasoning labels. | | `modelReasoningEffortMap?` | `Record>` | Per-model wire aliases for reasoning labels. | diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index e36975cd62..5ddf5588bc 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -205,8 +205,10 @@ Images API paths and response shape expected by Codex. | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Master switch. | -| `backend?` | `"openai" \| "anthropic"` | auto | Explicit wins; otherwise usable stored Anthropic OAuth selects `anthropic`, then `openai`. | -| `model?` | `string` | backend-dependent | `gpt-5.6-luna` for OpenAI or `claude-sonnet-5` for Anthropic. Legacy explicit `gpt-5.4-mini` migrates on start. | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | Explicit wins; unset always resolves to `openai`. `anthropic` and `xai` run only when explicitly configured; `gemini` and `exa` remain reserved until their executors ship. | +| `model?` | `string` | backend-dependent | `gpt-5.6-luna` for OpenAI, `claude-sonnet-5` for Anthropic, or `grok-4.6` for xAI. Legacy explicit `gpt-5.4-mini` migrates on start. | +| `exaApiKey?` | `string` | none | Operator key for the `exa` backend. Write-only: management reads never return the stored value. | +| `xSearch?` | `object` | omitted | xAI-only opt-in for hosted `x_search`: `enabled`, mutually exclusive `allowedXHandles` / `excludedXHandles` arrays (maximum 20), and ISO `fromDate` / `toDate` (`YYYY-MM-DD`). | | `reasoning?` | `string` | `low` | Sidecar effort. `minimal` is rejected with web search. | | `maxSearchesPerTurn?` | `number` | `3` | Real searches allowed per main-model turn. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Config-file-only routed-model raw-body inactivity deadline. Integer 1–2147483647; every non-empty chunk resets it. | @@ -216,7 +218,11 @@ The OpenAI backend requires a ChatGPT login and enabled ChatGPT `forward` provid routed replays inject main ChatGPT auth into the internal request. The Anthropic backend uses the active stored credential from an enabled Anthropic OAuth provider. An explicitly selected Anthropic backend with no usable account fails closed instead of falling back. The Anthropic executor uses its -native `web_search_20250305` tool. +native `web_search_20250305` tool. The xAI backend requires a usable stored Grok OAuth account, uses +hosted `web_search`, and adds hosted `x_search` when `xSearch.enabled` is true. Malformed `xSearch` +management input returns `400`; a malformed persisted block fails closed during planning. The +`gemini` and `exa` lanes never activate from credential discovery or fallback; the operator must +select them explicitly. `exaApiKey` is accepted on writes but omitted from management responses. Four clocks govern search: base `stallTimeoutSec`, `connectTimeoutMs`, routed-model inactivity, and hosted-search timeout. The effective bridge watchdog is the maximum plus 30 seconds. Routed stall is @@ -227,7 +233,7 @@ an inactivity guard, not a total generation deadline. | Field | Type | Default | Meaning | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Master image-description switch. | -| `backend?` | `"openai" \| "anthropic"` | auto | Same explicit-first, Anthropic-credential-aware selection as web search. | +| `backend?` | `"openai" \| "anthropic"` | auto | Explicit wins; unset prefers a usable stored Anthropic OAuth credential, else `openai`. | | `model?` | `string` | backend-dependent | `gpt-5.4-mini` for OpenAI or `claude-sonnet-5` for Anthropic. | | `maxDescriptionsPerTurn?` | `number` | `8` | New description cache misses admitted per main turn. `0` disables calls; invalid values use default. | | `timeoutMs?` | `number` | `45000` | Sidecar fetch timeout. Integer 1–2147483647. | diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index 46bc060c40..b04612625b 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -155,7 +155,7 @@ smallFastModel`; оно подставляется в обе переменны ## Агенты из ростера (injectAgents) -`ocx claude` (и демон системного окружения) синхронизирует ваш ростер избранных подагентов +Запуск/ensure прокси, `ocx claude` и сохранение связанных настроек в панели синхронизируют ваш ростер избранных подагентов (вкладка Subagents, до 5 моделей) плюс `ocx-self` в `~/.claude/agents/ocx-*.md`. - **`ocx-self`** закрепляет модель по умолчанию из селектора `/model` (с откатом на diff --git a/docs-site/src/content/docs/ru/guides/sidecars.md b/docs-site/src/content/docs/ru/guides/sidecars.md index ae2e2479b2..fed573bd8e 100644 --- a/docs-site/src/content/docs/ru/guides/sidecars.md +++ b/docs-site/src/content/docs/ru/guides/sidecars.md @@ -5,15 +5,16 @@ description: Настоящий веб-поиск для маршрутизир Не все маршрутизируемые модели предоставляют hosted **веб-поиск** или нативный **ввод изображений**. opencodex восполняет эти возможности двумя сайдкарами. Каждый может работать через -провайдера входа ChatGPT (`forward`) или через сохранённого OAuth-провайдера Anthropic. Ошибки +провайдера входа ChatGPT (`forward`) или через сохранённого OAuth-провайдера Anthropic; веб-поиск +также может использовать сохранённый Grok OAuth через явно выбранный бэкенд `xai`. Ошибки сайдкара превращаются в ограниченные по размеру результаты инструментов или маркеры изображений, а не приводят к сбою всего хода. :::note[Автоматический выбор бэкенда] -Явно заданный `backend` имеет приоритет. Если он не задан, opencodex использует `anthropic`, когда -у включённого OAuth-провайдера Anthropic есть активный аккаунт без пометки `needsReauth`; иначе -используется `openai`. Явный `anthropic` без таких учётных данных завершается отказом (fail -closed). Для `openai` нужны одновременно аутентификация через вход ChatGPT и включённый провайдер +Явно заданный `backend` имеет приоритет. Веб-поиск без него всегда использует `openai`; Vision +использует `anthropic` при наличии пригодного OAuth-аккаунта Anthropic, иначе `openai`. Явный +`anthropic` или `xai` без пригодных учётных данных завершается отказом без fallback. Для `openai` +нужны одновременно аутентификация через вход ChatGPT и включённый провайдер `forward`. ::: @@ -28,7 +29,8 @@ opencodex: 2. Запускает маршрутизируемую модель в небольшом **агентном цикле**. Когда она вызывает `web_search`, opencodex использует выбранный бэкенд сайдкара: OpenAI выполняет hosted `web_search` по умолчанию с `gpt-5.6-luna`; Anthropic выполняет `web_search_20250305` по - умолчанию с `claude-sonnet-5`. Потоковый ответ и цитаты становятся результатом инструмента. + умолчанию с `claude-sonnet-5`. xAI выполняет hosted `web_search` по умолчанию с `grok-4.6` и + добавляет `x_search` в тот же запрос, когда `xSearch.enabled` равно true. Потоковый ответ и цитаты становятся результатом инструмента. 3. **Повторяет цикл**, пока модель не ответит или суммарный бюджет реальных запросов не достигнет `maxSearchesPerTurn` (по умолчанию 3), после чего убирает инструмент поиска и принуждает к финальному ответу. Настоящие клиентские инструменты вроде `apply_patch` или shell завершают diff --git a/docs-site/src/content/docs/ru/reference/cli/agents.md b/docs-site/src/content/docs/ru/reference/cli/agents.md index bba29e1f3a..fd32b4db11 100644 --- a/docs-site/src/content/docs/ru/reference/cli/agents.md +++ b/docs-site/src/content/docs/ru/reference/cli/agents.md @@ -152,7 +152,7 @@ override, но файлы на диске никогда не меняются. ## Экспорт client config -### `ocx export --client ` +### `ocx export --client ` Печатает client config, направленный на работающий прокси. Команда сериализует блок провайдера `opencodex` в нативном формате выбранного клиента: base URL, список моделей и, @@ -163,7 +163,7 @@ override, но файлы на диске никогда не меняются. | Флаг | Действие | | --- | --- | -| `--client ` | Обязателен. Выбирает формат конфигурации клиента. | +| `--client ` | Обязателен. Выбирает формат конфигурации клиента. | | `--json` | Печатать только JSON-конфиг в stdout, чтобы redirect сохранял побайтно точный вывод. Вся диагностика, включая заметку о записи через `--out`, идёт в stderr. | | `--out ` | Записать конфиг в ``. Перезаписывать существующий файл не позволит. | | `--force` | Разрешить `--out` заменить существующий файл. | @@ -183,13 +183,16 @@ ocx export --client opencode --out ~/opencodex-opencode.json | Клиент | Канонический путь | Имя скачиваемого файла | Переменная окружения | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` имеет приоритет, если задан) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | нет — блок несёт литерал `opencodex-loopback` | +| `pi` | `~/.pi/agent/models.json` (`PI_CODING_AGENT_DIR` имеет приоритет, если задана; относительное значение отклоняется) | `pi-models.json` | нет — блок несёт литерал `opencodex-loopback` | | `omp` | `~/.omp/agent/models.yml` (по умолчанию; `OMP_PROFILE` имеет приоритет над `PI_PROFILE`, даже если пуст) | `omp-models.yaml` | нет — литерал `opencodex-loopback` | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | нет — loopback placeholder | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml` (по умолчанию `~/.dsh/settings.yaml`) | `settings.yaml` | нет — несекретная loopback bearer-заглушка | +| `mcode` | `~/.minimax/config.yaml` (`MINIMAX_DATA_DIR`, затем устаревшая `MAVIS_DATA_DIR`, имеют приоритет, если заданы; относительное значение отклоняется) | `mcode-config.yaml` | нет — loopback placeholder | +| `zcode` | `~/.zcode/v2/config.json` (`ZCODE_DATA_DIR` имеет приоритет, если задана; относительное значение отклоняется) | `config.json` | нет — loopback placeholder | +| `prime` | `~/.prime/agent/models.json` (`PRIME_AGENT_CODING_AGENT_DIR` имеет приоритет, если задана; относительное значение отклоняется) | `prime-models.json` | нет — loopback placeholder | opencode интерполирует `{env:OPENCODEX_OPENCODE_API_KEY}`. Сгенерированный opencodex экспорт для Pi не требует переменной окружения и несёт литеральную заглушку `opencodex-loopback`. Это значение @@ -204,14 +207,13 @@ Pi не требует переменной окружения и несёт л MCP-записи. ::: -Никакой ключ никогда не сериализуется. Конфиги opencode, Hermes, OpenClaw и Gajae несут только -env-reference, так что секрет остаётся в вашем окружении, а конфиги Pi, OMP, Kimi и DSH несут -loopback-заглушку вместо учётных данных. Loopback-прокси (`127.0.0.1`, по умолчанию) вообще не +Никакой ключ никогда не сериализуется. Сгенерированные конфиги несут либо документированную +env-reference, либо несекретную loopback-заглушку. Loopback-прокси (`127.0.0.1`, по умолчанию) вообще не требует admission key. Если прокси слушает не на loopback, задайте соответствующую переменную `OPENCODEX_OPENCODE_API_KEY`, `OPENCODEX_HERMES_API_KEY` или `OPENCODEX_OPENCLAW_API_KEY`. `OPENCODEX_GAJAE_API_KEY` передаёт provider credential Gajae через окружение, но не позволяет -отправить remote admission header, поэтому сгенерированная интеграция Gajae, как и Pi, OMP, Kimi и -DSH, работает только через loopback. Как выдаются admission key, описано в +отправить remote admission header, поэтому сгенерированная интеграция Gajae +работает только через loopback. Как выдаются admission key, описано в [Удалённом доступе](/reference/configuration/#remote-access). Ключи upstream-провайдеров — это совсем отдельная история и настраиваются в [Провайдерах](/guides/providers/). diff --git a/docs-site/src/content/docs/ru/reference/configuration/providers.md b/docs-site/src/content/docs/ru/reference/configuration/providers.md index 56ad0154bf..21b70bebb5 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/providers.md +++ b/docs-site/src/content/docs/ru/reference/configuration/providers.md @@ -99,6 +99,7 @@ cross-route credential fallback не существует. Строки API GPT- | `modelSupportsReasoningSummaries?` | `Record` | Установите `false` для модели, чтобы перестать рекламировать summary и вырезать поля доставки summary. | | `modelReasoningSummaryDelivery?` | `Record` | Responses delivery enum по моделям; переписывает уже существующее поле delivery. | | `modelAdapters?` | `Record` | Wire-override по модели для `openai-chat` или `openai-responses` в gateway с несколькими wire-форматами. Явные записи имеют приоритет над default'ами registry; preset DeepSeek может выбирать native Responses для `deepseek-v4-flash`, а GitHub Copilot объявляет Responses-only default'ы для семейства GPT-5 (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`), потому что эти модели отклоняют `/chat/completions` для агентного трафика. Модели без встроенного default'а (например, `gpt-5.4-nano`) можно включить здесь. Single-wire upstream pin'ы и canonical ChatGPT forward override не принимают. | +| Opt-in xAI Responses (панель) | переключатель | Только для `xai`: атомарно задаёт или удаляет записи `modelAdapters` для `grok-4.5` и `grok-4.6`. Одна запись отображается как смешанное состояние до следующего переключения. Остальные override и поведение tier не меняются. | | `modelPreferHostedTools?` | `Record` | Opt-in для точного model ID в non-forward Responses gateway, который резервирует namespace hosted tool. Сейчас допускается только `["image_generation"]`; совпавшая модель должна использовать wire `openai-responses` и поддерживать этот hosted tool. Прокси удаляет конфликтующие клиентские объявления `image_gen` и переписывает их selectors, сохраняя caller tool choice. Для виртуальных моделей OpenAI API `-pro` сначала сопоставляется выбранный публичный ID, а затем в качестве fallback используется ID базовой wire-модели. `modelAdapters` сначала разрешается по публичному ID, затем по базовому ID; второй результат определяет итоговый wire. Остальные модели сохраняют обычное alias-поведение. | | `reasoningEffortMap?` | `Record` | Provider-wide wire-alias'ы для reasoning-label'ов. | | `modelReasoningEffortMap?` | `Record>` | Wire-alias'ы для reasoning-label'ов по отдельным моделям. | diff --git a/docs-site/src/content/docs/ru/reference/configuration/server.md b/docs-site/src/content/docs/ru/reference/configuration/server.md index b6816f5e84..64d7ee8e3d 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/server.md +++ b/docs-site/src/content/docs/ru/reference/configuration/server.md @@ -162,8 +162,10 @@ Codex использует маленькие helper-model'и для задач | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Главный переключатель. | -| `backend?` | `"openai" \| "anthropic"` | auto | Явный выбор выигрывает; иначе usable stored Anthropic OAuth выбирает `anthropic`, затем `openai`. | -| `model?` | `string` | backend-dependent | `gpt-5.6-luna` для OpenAI или `claude-sonnet-5` для Anthropic. Старый явный `gpt-5.4-mini` мигрирует при старте. | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | Явный выбор выигрывает; отсутствие значения всегда означает `openai`. `anthropic` и `xai` запускаются только при явной настройке; `gemini` и `exa` зарезервированы до появления executor. | +| `model?` | `string` | backend-dependent | `gpt-5.6-luna` для OpenAI, `claude-sonnet-5` для Anthropic или `grok-4.6` для xAI. Старый явный `gpt-5.4-mini` мигрирует при старте. | +| `exaApiKey?` | `string` | отсутствует | Ключ оператора для backend `exa`. Только для записи: management-read никогда не возвращает сохранённое значение. | +| `xSearch?` | `object` | отсутствует | Опциональный hosted `x_search` только для xAI: `enabled`, взаимоисключающие массивы `allowedXHandles` / `excludedXHandles` (не более 20) и ISO-даты `fromDate` / `toDate` (`YYYY-MM-DD`). | | `reasoning?` | `string` | `low` | Effort sidecar'а. Значение `minimal` с web search отклоняется. | | `maxSearchesPerTurn?` | `number` | `3` | Число реальных поисков, разрешённых за один turn основной модели. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Config-file-only дедлайн бездействия raw-body у routed-model. Целое 1–2147483647; каждый непустой chunk сбрасывает таймер. | @@ -173,7 +175,12 @@ Backend OpenAI требует логина в ChatGPT и включённого с входом от Claude внедряет auth основного ChatGPT во внутренний запрос. Anthropic-backend использует активный stored credential из включённого Anthropic OAuth-провайдера. Явно выбранный Anthropic-backend без рабочего аккаунта закрывается с ошибкой и не откатывается на другой backend. -Исполнитель Anthropic использует нативный tool `web_search_20250305`. +Исполнитель Anthropic использует нативный tool `web_search_20250305`. Backend xAI требует рабочего +сохранённого аккаунта Grok OAuth, использует hosted `web_search` и добавляет hosted `x_search`, когда +`xSearch.enabled` равно true. Некорректный management-input `xSearch` возвращает `400`, а некорректный +сохранённый блок закрывается с ошибкой при планировании. Линии `gemini` и `exa` никогда не активируются +через обнаружение credentials или fallback; оператор должен выбрать их явно. `exaApiKey` принимается +при записи, но не включается в management-response. Поиск ограничивают четыре clock'а: базовый `stallTimeoutSec`, `connectTimeoutMs`, inactivity для routed-model и hosted-search timeout. Эффективный watchdog моста равен максимуму этих значений плюс @@ -184,7 +191,7 @@ routed-model и hosted-search timeout. Эффективный watchdog мост | Поле | Тип | По умолчанию | Значение | | --- | --- | --- | --- | | `enabled?` | `boolean` | on when usable | Главный переключатель описания изображений. | -| `backend?` | `"openai" \| "anthropic"` | auto | Та же логика выбора explicit-first/Anthropic-credential-aware, что и у web search. | +| `backend?` | `"openai" \| "anthropic"` | auto | Явное значение имеет приоритет; если оно не задано, предпочтение отдаётся пригодным сохранённым учётным данным Anthropic OAuth, иначе используется `openai`. | | `model?` | `string` | backend-dependent | `gpt-5.4-mini` для OpenAI или `claude-sonnet-5` для Anthropic. | | `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | Уровень рассуждений OpenAI Responses. Anthropic его игнорирует. | | `maxDescriptionsPerTurn?` | `number` | `8` | Максимум новых промахов description-cache за один main turn. `0` отключает вызовы; некорректные значения возвращают дефолт. | diff --git a/docs-site/src/content/docs/tr/guides/integrations.md b/docs-site/src/content/docs/tr/guides/integrations.md index 4ddd5e0bfd..e0c1df8bb6 100644 --- a/docs-site/src/content/docs/tr/guides/integrations.md +++ b/docs-site/src/content/docs/tr/guides/integrations.md @@ -31,6 +31,9 @@ son olarak `~/.minimax` dizinine geri döner. Yönetilen blok yalnızca `custom_provider.opencodex` alanına sahiptir; `defaultModel` değerini, seçilen MiniMax kimlik bilgisi kaynağını veya kullanıcının MiniMax oturumunu değiştirmez. Bağladıktan sonra MCode içinde bir `custom_provider:opencodex/` girdisi seçin. +Entegrasyon yenilendiğinde model başına doğrulanmış bağlam pencereleri ve akıl yürütme +çabası seçenekleri de yenilenir; bilinmeyen yetenekler atlanır ve MCode oturumunun +yönettiği geçerli çaba seçimi korunur. Yollar, varsa her istemcinin kendi ortam geçersiz kılmalarını dikkate alır. OMP için `OMP_PROFILE`, açıkça boş olduğunda bile varlığıyla `PI_PROFILE`'a üstün @@ -172,6 +175,11 @@ ocx integration client enable --client mcode ocx mcode ``` +Bağlandıktan sonra `ocx sync`, yönetilen MCode bloğunu güncel bağlam pencereleri ve +akıl yürütme çabası seçenekleriyle de yeniler. Eksik, dışarıdan düzenlenmiş, güvenli +olmayan veya hiç sahiplenilmemiş bloklara dokunmaz; yeniden bağlamak istediğinizde +entegrasyonu açıkça yeniden etkinleştirin. + Ayrı MiniMax platform CLI'si (`mmx`) bir dosya anahtarı entegrasyonu değildir. Metin komutları MiniMax'ın Anthropic uyumlu uç noktasını kullandığı için OpenCodex, kimlik bilgilerini yalıtan ve yalnızca geri döngüde çalışan bir başlatıcı sağlar: diff --git a/docs-site/src/content/docs/tr/guides/sidecars.md b/docs-site/src/content/docs/tr/guides/sidecars.md index 4c8fdfe733..1057ab70a7 100644 --- a/docs-site/src/content/docs/tr/guides/sidecars.md +++ b/docs-site/src/content/docs/tr/guides/sidecars.md @@ -6,14 +6,13 @@ description: Yerel ChatGPT sidecar'ları aracılığıyla yönlendirilen modelle Yönlendirilen modellerin tümü barındırılan **web araması** veya yerel **görsel girişi** sunmaz. opencodex bu yetenekleri iki sidecar ile doldurur. Her biri bir ChatGPT girişi (`forward`) sağlayıcısı veya saklanan bir Anthropic OAuth -sağlayıcısı aracılığıyla çalışabilir. Sidecar hataları tüm turu başarısız kılmak +sağlayıcısı aracılığıyla çalışabilir; web araması açık `xai` arka ucuyla saklanan Grok OAuth'ı da kullanabilir. Sidecar hataları tüm turu başarısız kılmak yerine sınırlı araç sonuçları veya görsel işaretçileri haline gelir. :::note[Otomatik arka uç seçimi] -Açık `backend` yapılandırması kazanır. Ayarlanmadığında opencodex, -etkinleştirilmiş bir Anthropic OAuth sağlayıcısının `needsReauth` olarak -işaretlenmemiş etkin bir hesabı varsa `anthropic`'i kullanır; aksi takdirde -`openai`'yi kullanır. Bu kimlik bilgisi olmadan açık `anthropic` kapalı olarak +Açık `backend` yapılandırması kazanır. Web araması ayarlanmadığında her zaman `openai` kullanır; +Vision kullanılabilir bir Anthropic OAuth hesabı varsa `anthropic`, yoksa `openai` kullanır. +Kullanılabilir kimlik bilgisi olmadan açık `anthropic` veya `xai` geri dönüş yapmadan başarısız olur. `openai`, hem ChatGPT girişi kimlik doğrulamasını hem de etkinleştirilmiş bir `forward` sağlayıcısını gerektirir. ::: @@ -30,8 +29,9 @@ Codex, doğrudan geçiş olmayan bir yönlendirilmiş model için barındırıla `web_search`'i çağırdığında opencodex seçilen sidecar arka ucunu kullanır: OpenAI varsayılan olarak `gpt-5.6-luna` ile barındırılan `web_search`'i çalıştırır; Anthropic varsayılan olarak `claude-sonnet-5` ile - `web_search_20250305`'i çalıştırır. Akışlı yanıt ve alıntılar bir araç sonucu - haline gelir. + `web_search_20250305`'i çalıştırır. xAI varsayılan olarak `grok-4.6` ile hosted + `web_search` çalıştırır ve `xSearch.enabled` true olduğunda aynı isteğe `x_search` ekler. + Akışlı yanıt ve alıntılar bir araç sonucu haline gelir. 3. Model yanıt verene veya toplam gerçek sorgu bütçesi `maxSearchesPerTurn`'e (varsayılan 3) ulaşana kadar **döngüye girer**, ardından arama aracını kaldırır ve nihai bir yanıta zorlar. `apply_patch` veya kabuk gibi gerçek @@ -199,4 +199,3 @@ hedeflenen hesap ve iş yükü ile kapsamlı bir şekilde test edilmelidir. Her alan için [Yapılandırma referansı](/tr/reference/configuration/#sidecars) bölümüne bakın. - diff --git a/docs-site/src/content/docs/tr/reference/cli/agents.md b/docs-site/src/content/docs/tr/reference/cli/agents.md index 82949d8f9a..cc87e3bd8e 100644 --- a/docs-site/src/content/docs/tr/reference/cli/agents.md +++ b/docs-site/src/content/docs/tr/reference/cli/agents.md @@ -191,7 +191,7 @@ Grok Build model çitini yönetin ve uygulayın. ## İstemci yapılandırma dışa aktarma -### `ocx export --client ` +### `ocx export --client ` Çalışan proxy'ye bağlı bir istemci yapılandırmasını yazdırın. Komut, `opencodex` sağlayıcı bloğunu — temel URL, model listesi ve istemcinin kimlik bilgisi @@ -203,7 +203,7 @@ yalnızca Codex'in şu anda görebildiği modelleri yayınlar. | Bayrak | Eylem | | --- | --- | -| `--client ` | Gerekli. İstemci yapılandırma lehçesini seçer. | +| `--client ` | Gerekli. İstemci yapılandırma lehçesini seçer. | | `--json` | Betikler için stdout üzerinde oluşturulan belgeyi JSON olarak yazdırın. Bu, seçilen istemcinin yerel formatı YAML, TOML veya JSON5 olsa bile JSON'dur. | | `--out ` | İstemcinin yerel yapılandırma formatını `` konumuna yazın. Mevcut bir dosyanın üzerine yazmayı reddeder. | | `--force` | `--out`'un mevcut bir dosyanın üzerine yazmasına izin verin. | @@ -223,13 +223,16 @@ için kendi varsayılanlarını uygular) gelir. | İstemci | Kurallı hedef | İndirme dosya adı | Ortam değişkeni | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json` (`XDG_CONFIG_HOME` ayarlandığında kazanır) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | yok — blok değişmez `opencodex-loopback` taşır | +| `pi` | `~/.pi/agent/models.json` (ayarlandığında `PI_CODING_AGENT_DIR` öncelikli; göreli değer reddedilir) | `pi-models.json` | yok — blok değişmez `opencodex-loopback` taşır | | `omp` | `~/.omp/agent/models.yml` (boş olduğunda bile `OMP_PROFILE`, `PI_PROFILE`'a üstün gelir; adlandırılmış profiller eve göre `PI_CONFIG_DIR` dizin adını kullanır ve `PI_CODING_AGENT_DIR`'i yok sayar, varsayılan profil ise `PI_CODING_AGENT_DIR`'in kazanmasına izin verir) | `omp-models.yaml` | yok — geri döngü yer tutucusu | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | yok — geri döngü yer tutucusu | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml` (varsayılan `~/.dsh/settings.yaml`) | `settings.yaml` | yok — gizli olmayan geri döngü bearer yer tutucusu | +| `mcode` | `~/.minimax/config.yaml` (ayarlandığında `MINIMAX_DATA_DIR`, ardından eski `MAVIS_DATA_DIR` öncelikli; göreli değer reddedilir) | `mcode-config.yaml` | yok — geri döngü yer tutucusu | +| `zcode` | `~/.zcode/v2/config.json` (ayarlandığında `ZCODE_DATA_DIR` öncelikli; göreli değer reddedilir) | `config.json` | yok — geri döngü yer tutucusu | +| `prime` | `~/.prime/agent/models.json` (ayarlandığında `PRIME_AGENT_CODING_AGENT_DIR` öncelikli; göreli değer reddedilir) | `prime-models.json` | yok — geri döngü yer tutucusu | opencode `{env:OPENCODEX_OPENCODE_API_KEY}` değerini enterpole eder. Üretilen Pi ve OMP dışa aktarımları bir ortam değişkeni gerektirmez: her biri değişmez diff --git a/docs-site/src/content/docs/tr/reference/configuration/providers.md b/docs-site/src/content/docs/tr/reference/configuration/providers.md index c7b13d56c9..d4e414700a 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/providers.md +++ b/docs-site/src/content/docs/tr/reference/configuration/providers.md @@ -105,6 +105,7 @@ alanlı seçilmiş kimlikleri yalın kimliklere yeniden yazar. | `modelSupportsReasoningSummaries?` | `Record` | Özetlerin bildirilmesini durdurmak ve özet teslim alanlarını kaldırmak için bir modeli `false` olarak ayarlayın. | | `modelReasoningSummaryDelivery?` | `Record` | Model başına Responses teslim enum'ı; mevcut bir teslim alanını yeniden yazar. | | `modelAdapters?` | `Record` | Karışık hatlı ağ geçitleri için model başına `openai-chat` veya `openai-responses` hat geçersiz kılma. Açık girdiler kayıt defteri varsayılanlarını yener. OpenCode Go önayarı, kardeş modelleri belgelenmiş hatlarında bırakırken `gpt-5.6-luna` için Responses'ı seçer; DeepSeek, `deepseek-v4-flash` için yerel Responses seçebilir; ve GitHub Copilot, GPT-5 ailesi (`gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`) için yalnızca Responses varsayılanlarını bildirir çünkü bu modeller ajan trafiği için `/chat/completions`'ı reddeder. Yerleşik varsayılanı olmayan modeller (örneğin `gpt-5.4-nano`) burada dahil edilebilir. Tek hatlı yukarı akış pinleri ve kurallı ChatGPT iletme geçersiz kılmaları reddeder. | +| xAI Responses katılımı (panel) | anahtar | Yalnızca `xai` için `grok-4.5` ve `grok-4.6` `modelAdapters` girdilerini atomik olarak ayarlar veya temizler. Tek girdi, sonraki anahtar yazımı ikisini eşitleyene kadar karma durum olarak görünür. Diğer geçersiz kılmalar ve katman davranışı değişmez. | | `modelPreferHostedTools?` | `Record` | Barındırılan bir araç ad alanı ayıran iletme harici Responses ağ geçitleri için tam model dahil etme. Şu anda yalnızca `["image_generation"]` kabul eder; eşleşen bir model `openai-responses` hattını kullanmalı ve bu barındırılan aracı desteklemelidir. Çakışan istemci `image_gen` bildirimlerini kaldırır ve arayan araç seçimini korumak için seçicilerini yeniden yazar. OpenAI API sanal `-pro` modelleri için önce seçilen genel kimlik eşleştirilir ve çözümlenen temel hat model kimliği bir geri dönüştür. `modelAdapters` önce genel kimliği, ardından temel kimliği çözer; ikinci çözümleme son hattı belirler. Diğer modeller normal takma ad davranışını korur. | | `reasoningEffortMap?` | `Record` | Akıl yürütme etiketleri için sağlayıcı genelinde hat takma adları. | | `modelReasoningEffortMap?` | `Record>` | Akıl yürütme etiketleri için model başına hat takma adları. | @@ -479,4 +480,3 @@ bildirir; senkronize edilen katalog `xhigh`'ı ayrı tutarken `max` bildirir. } ``` - diff --git a/docs-site/src/content/docs/tr/reference/configuration/server.md b/docs-site/src/content/docs/tr/reference/configuration/server.md index 3de2b40fa2..25da923a29 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/server.md +++ b/docs-site/src/content/docs/tr/reference/configuration/server.md @@ -232,8 +232,10 @@ Images API yollarını ve yanıt şeklini uygulamalıdır. | Alan | Tip | Varsayılan | Anlamı | | --- | --- | --- | --- | | `enabled?` | `boolean` | kullanılabilir olduğunda açık | Ana anahtar. | -| `backend?` | `"openai" \| "anthropic"` | auto | Açık olan kazanır; aksi takdirde kullanılabilir saklanan Anthropic OAuth `anthropic`'i, ardından `openai`'yi seçer. | -| `model?` | `string` | arka uca bağlı | OpenAI için `gpt-5.6-luna` veya Anthropic için `claude-sonnet-5`. Eski açık `gpt-5.4-mini` başlangıçta geçirilir. | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | Açık değer kazanır; ayarlanmadığında her zaman `openai` seçilir. `anthropic` ve `xai` yalnızca açıkça yapılandırıldığında çalışır; `gemini` ve `exa` executor'ları sunulana kadar ayrılmıştır. | +| `model?` | `string` | arka uca bağlı | OpenAI için `gpt-5.6-luna`, Anthropic için `claude-sonnet-5` veya xAI için `grok-4.6`. Eski açık `gpt-5.4-mini` başlangıçta geçirilir. | +| `exaApiKey?` | `string` | yok | `exa` arka ucu için operatör anahtarı. Yalnızca yazılır; yönetim okumaları saklanan değeri asla döndürmez. | +| `xSearch?` | `object` | atlanmış | Yalnızca xAI için hosted `x_search` opt-in: `enabled`, birbirini dışlayan `allowedXHandles` / `excludedXHandles` dizileri (en fazla 20) ve ISO `fromDate` / `toDate` (`YYYY-MM-DD`). | | `reasoning?` | `string` | `low` | Sidecar çabası. `minimal` web araması ile reddedilir. | | `maxSearchesPerTurn?` | `number` | `3` | Ana model turu başına izin verilen gerçek aramalar. | | `routedModelStallTimeoutMs?` | `number` | `200000` | Yalnızca yapılandırma dosyasındaki yönlendirilen model ham gövde hareketsizlik süresi sınırı. Tamsayı 1–2147483647; boş olmayan her parça onu sıfırlar. | @@ -246,6 +248,11 @@ etkinleştirilmiş bir Anthropic OAuth sağlayıcısından gelen aktif saklanan bilgisini kullanır. Kullanılabilir hesabı olmayan açıkça seçilmiş bir Anthropic arka ucu geri dönmek yerine kapalı olarak başarısız olur. Anthropic yürütücüsü yerel `web_search_20250305` aracını kullanır. +xAI arka ucu kullanılabilir, saklanmış bir Grok OAuth hesabı gerektirir, hosted `web_search` kullanır +ve `xSearch.enabled` true olduğunda hosted `x_search` ekler. Hatalı `xSearch` yönetim girdisi `400` +döndürür; hatalı kalıcı blok planlama sırasında kapalı olarak başarısız olur. `gemini` ve `exa` +hatları kimlik bilgisi keşfi veya fallback ile hiçbir zaman etkinleşmez; operatör bunları açıkça +seçmelidir. `exaApiKey` yazmalarda kabul edilir ancak yönetim yanıtlarından çıkarılır. Aramayı dört saat yönetir: temel `stallTimeoutSec`, `connectTimeoutMs`, yönlendirilen model hareketsizliği ve barındırılan arama zaman aşımı. Geçerli @@ -257,7 +264,7 @@ hareketsizlik korumasıdır, toplam bir üretim süresi sınırı değildir. | Alan | Tip | Varsayılan | Anlamı | | --- | --- | --- | --- | | `enabled?` | `boolean` | kullanılabilir olduğunda açık | Ana görsel açıklama anahtarı. | -| `backend?` | `"openai" \| "anthropic"` | auto | Web araması ile aynı açık öncelikli, Anthropic kimlik bilgisine duyarlı seçim. | +| `backend?` | `"openai" \| "anthropic"` | auto | Açık değer önceliklidir; ayarlanmadığında kullanılabilir kayıtlı bir Anthropic OAuth kimlik bilgisi tercih edilir, aksi halde `openai` kullanılır. | | `model?` | `string` | arka uca bağlı | OpenAI için `gpt-5.4-mini` veya Anthropic için `claude-sonnet-5`. | | `maxDescriptionsPerTurn?` | `number` | `8` | Ana tur başına kabul edilen yeni açıklama önbellek ıskalamaları. `0` çağrıları devre dışı bırakır; geçersiz değerler varsayılanı kullanır. | | `timeoutMs?` | `number` | `45000` | Sidecar getirme zaman aşımı. Tamsayı 1–2147483647. | @@ -273,4 +280,3 @@ sınırı tüketmez. Uzak `https:` görselleri ve başarısız veya boş açıkl Anthropic OAuth sidecar'ları opencodex'in mevcut Claude Code OAuth parmak izini yeniden kullanır. Hedeflenen hesap ve iş yükünü kapsamlı bir şekilde test edin. - diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index 08fb965f27..e5140cb8a7 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -145,7 +145,7 @@ v1 别名按字面解码(历史上 model ID 中包含的两字符序列 `~s` / ## 名册代理(injectAgents) -`ocx claude`(以及系统环境守护进程)会把你的精选子代理名册(Subagents 标签页,最多 5 个模型) +代理启动/ensure、`ocx claude` 和相关的控制面板保存会把你的精选子代理名册(Subagents 标签页,最多 5 个模型) 和 `ocx-self` 同步到 `~/.claude/agents/ocx-*.md`。 - **`ocx-self`** 固定你在 `/model` 选择器中的默认模型(回退到 `claudeCode.model`);两者均 diff --git a/docs-site/src/content/docs/zh-cn/guides/sidecars.md b/docs-site/src/content/docs/zh-cn/guides/sidecars.md index b0da7443b7..522dfdb41c 100644 --- a/docs-site/src/content/docs/zh-cn/guides/sidecars.md +++ b/docs-site/src/content/docs/zh-cn/guides/sidecars.md @@ -5,13 +5,13 @@ description: 通过原生 ChatGPT sidecar,让路由模型获得真实 web sear 不同路由模型对托管 **Web Search** 和原生**图像输入**的支持并不相同。opencodex 通过两个 sidecar 补齐这些能力;它们可以使用 ChatGPT 登录(`forward`)provider,也可以使用已存储的 -Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果或图像提示,不会让整个 turn +Anthropic OAuth provider;web search 还可通过显式 `xai` 后端使用已存储的 Grok OAuth。Sidecar 错误会转换成长度受限的工具结果或图像提示,不会让整个 turn 失败。 :::note[自动选择后端] -显式 `backend` 配置优先。省略时,如果已启用 Anthropic OAuth provider 的活动账户未标记 -`needsReauth`,则使用 `anthropic`;否则使用 `openai`。显式选择 `anthropic` 但没有可用凭据时 -会关闭失败。`openai` 同时需要 ChatGPT 登录和已启用的 `forward` provider。 +显式 `backend` 配置优先。Web search 省略时始终使用 `openai`;Vision 在存在可用 Anthropic +OAuth 账户时使用 `anthropic`,否则使用 `openai`。显式选择 `anthropic` 或 `xai` 但没有可用凭据时 +会关闭失败且不会回退。`openai` 同时需要 ChatGPT 登录和已启用的 `forward` provider。 ::: ## Web-search sidecar @@ -22,7 +22,8 @@ Anthropic OAuth provider。Sidecar 错误会转换成长度受限的工具结果 `web_search(query)` function 工具。原托管工具的选项会保留并用于 sidecar 调用。 2. 让路由模型在一个小型 **agentic 循环**中运行。模型调用 `web_search` 时,opencodex 使用所选 后端:OpenAI 默认以 `gpt-5.6-luna` 运行托管 `web_search`;Anthropic 默认以 - `claude-sonnet-5` 运行 `web_search_20250305`。Streaming 答案及引用会解析为工具结果。 + `claude-sonnet-5` 运行 `web_search_20250305`。xAI 默认以 `grok-4.6` 运行托管 `web_search`, + 并在 `xSearch.enabled` 为 true 时把 `x_search` 加入同一请求。Streaming 答案及引用会解析为工具结果。 3. **循环**直到模型回答,或真实查询总数达到 `maxSearchesPerTurn`(默认 3)。达到上限后会移除 search 工具并强制生成最终答案。如果模型调用 `apply_patch` 或 shell 等真实客户端工具,当前 turn 会结束,以便这些调用到达 Codex。 diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md index db3754ba69..9c49af314e 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/agents.md @@ -132,7 +132,7 @@ ocx claude desktop import [--apply] Validate and import JSON ## Client config export -### `ocx export --client ` +### `ocx export --client ` 输出连接到正在运行代理的客户端配置。此命令会以所选客户端的原生格式序列化 `opencodex` provider 块,其中包含基础 URL、模型列表,以及该客户端适用的凭据引用或 `opencodex-loopback` 占位值。 @@ -140,7 +140,7 @@ ocx claude desktop import [--apply] Validate and import JSON | 标志 | 动作 | | --- | --- | -| `--client ` | 必需。选择客户端配置格式。 | +| `--client ` | 必需。选择客户端配置格式。 | | `--json` | 仅在 stdout 打印配置 JSON,这样重定向即可捕获字节级精确输出。包括 `--out` 写入提示在内的所有诊断信息都会输出到 stderr。 | | `--out ` | 将配置写入 ``。拒绝替换已存在的文件。 | | `--force` | 允许 `--out` 替换已存在的文件。 | @@ -157,13 +157,16 @@ ocx export --client opencode --out ~/opencodex-opencode.json | 客户端 | 规范目标路径 | 下载文件名 | 环境变量 | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json`(设置了 `XDG_CONFIG_HOME` 时以其为准) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | 无 - 块中携带字面值 `opencodex-loopback` | +| `pi` | `~/.pi/agent/models.json` (设置后 `PI_CODING_AGENT_DIR` 优先;相对路径会被拒绝) | `pi-models.json` | 无 - 块中携带字面值 `opencodex-loopback` | | `omp` | `~/.omp/agent/models.yml`(默认路径;即使为空,`OMP_PROFILE` 也优先于 `PI_PROFILE`) | `omp-models.yaml` | 无 - 字面值 `opencodex-loopback` | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | 无 - loopback placeholder | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml`(默认 `~/.dsh/settings.yaml`) | `settings.yaml` | 无 — 非秘密环回 bearer 占位值 | +| `mcode` | `~/.minimax/config.yaml` (设置后 `MINIMAX_DATA_DIR` 优先,其次是旧的 `MAVIS_DATA_DIR`;相对路径会被拒绝) | `mcode-config.yaml` | 无 — loopback placeholder | +| `zcode` | `~/.zcode/v2/config.json` (设置后 `ZCODE_DATA_DIR` 优先;相对路径会被拒绝) | `config.json` | 无 — loopback placeholder | +| `prime` | `~/.prime/agent/models.json` (设置后 `PRIME_AGENT_CODING_AGENT_DIR` 优先;相对路径会被拒绝) | `prime-models.json` | 无 — loopback placeholder | opencode 会插值 `{env:OPENCODEX_OPENCODE_API_KEY}`。opencodex 生成的 Pi 导出不需要环境变量,而是携带字面占位值 `opencodex-loopback`。这个值是必需的:Pi 在构建模型列表时会解析 `apiKey`,如果已有配置包含未设置的环境变量引用,它就会隐藏整个 provider。回环上的代理从不校验生成的占位值。 @@ -171,7 +174,7 @@ opencode 会插值 `{env:OPENCODEX_OPENCODE_API_KEY}`。opencodex 生成的 Pi `ocx export` 从不写入你的真实客户端配置。该命令只会打印目标路径供你手动合并,而 `--out` 在没有 `--force` 的情况下拒绝覆盖已有文件,因为替换配置会破坏其中已有的其他 providers、agents 和 MCP 条目。 ::: -任何密钥都不会被序列化。opencode、Hermes、OpenClaw 和 Gajae 配置里只包含环境引用,因此密钥仍保留在你的环境中;Pi、OMP、Kimi 和 DSH 配置里携带的是环回占位值而不是任何凭据。环回代理(`127.0.0.1`,默认值)根本不需要准入密钥。当代理绑定到环回地址之外时,请设置对应的 `OPENCODEX_OPENCODE_API_KEY`、`OPENCODEX_HERMES_API_KEY` 或 `OPENCODEX_OPENCLAW_API_KEY`。`OPENCODEX_GAJAE_API_KEY` 只会从环境中提供 Gajae provider 凭据,不能发送远程准入 header,因此生成的 Gajae 集成仍与 Pi、OMP、Kimi 和 DSH 一样仅支持环回。关于准入密钥如何签发,请参见 [远程访问](/reference/configuration/#remote-access)。上游 providers 自身的密钥则完全是另一回事,需要按 [Providers](/guides/providers/) 单独配置。 +任何密钥都不会被序列化。生成的配置里携带的要么是有文档记录的环境引用,要么是非机密的环回占位值。环回代理(`127.0.0.1`,默认值)根本不需要准入密钥。当代理绑定到环回地址之外时,请设置对应的 `OPENCODEX_OPENCODE_API_KEY`、`OPENCODEX_HERMES_API_KEY` 或 `OPENCODEX_OPENCLAW_API_KEY`。`OPENCODEX_GAJAE_API_KEY` 只会从环境中提供 Gajae provider 凭据,不能发送远程准入 header,因此生成的 Gajae 集成仍仅支持环回。关于准入密钥如何签发,请参见 [远程访问](/reference/configuration/#remote-access)。上游 providers 自身的密钥则完全是另一回事,需要按 [Providers](/guides/providers/) 单独配置。 同一份负载会通过 `GET /api/client-config` 提供,并在仪表盘的 API 选项卡中渲染,因此 CLI、API 和 GUI 使用的是同一字节内容。 diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md index f37f372cfd..1564842cbb 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/providers.md @@ -86,6 +86,7 @@ selector,而不是分配一个新名称。 | `modelSupportsReasoningSummaries?` | `Record` | 将某个模型设为 `false`,即可停止暴露摘要并移除摘要交付字段。 | | `modelReasoningSummaryDelivery?` | `Record` | 按模型设置的 Responses 交付枚举;会重写现有的 delivery 字段。 | | `modelAdapters?` | `Record` | 按模型设置的 `openai-chat` 或 `openai-responses` 线协议覆盖项,用于混合线协议网关。显式条目优先于注册表默认值;DeepSeek 预设可以为 `deepseek-v4-flash` 选择原生 Responses,GitHub Copilot 则为 GPT-5 系列(`gpt-5.3-codex`、`gpt-5.4`、`gpt-5.4-mini`、`gpt-5.5`、`gpt-5.6-luna`、`gpt-5.6-sol`、`gpt-5.6-terra`)声明了 Responses 专用默认值,因为这些模型在代理流量下会拒绝 `/chat/completions`。没有内置默认值的模型(例如 `gpt-5.4-nano`)可以在此手动启用。单一线协议上游固定项和规范 ChatGPT forward 会拒绝覆盖。 | +| xAI Responses 启用项(仪表板) | 开关 | 仅用于 `xai`,以原子方式设置或清除 `grok-4.5` 和 `grok-4.6` 的 `modelAdapters` 条目。若只存在一个条目,则显示混合状态,直到下次开关写入将两者统一。其他覆盖项和层级行为不变。 | | `modelPreferHostedTools?` | `Record` | 非 forward Responses gateway 的精确模型 ID opt-in,用于上游预留 hosted tool namespace 的情况。目前只支持 `["image_generation"]`;匹配模型必须使用 `openai-responses` wire 且支持该 hosted 工具。它会移除冲突的客户端 `image_gen` 声明,并改写其 selector 以保持调用方的 tool choice。对于 OpenAI API 的虚拟 `-pro` 模型,先匹配所选公开 ID,未命中时才使用解析出的基础 wire-model ID 作为回退。`modelAdapters` 会先按公开 ID、再按基础 ID 解析;后一次结果决定最终 wire。未配置模型保持普通 alias 行为。 | | `reasoningEffortMap?` | `Record` | 提供者级、用于推理标签的线协议别名。 | | `modelReasoningEffortMap?` | `Record>` | 按模型设置的推理标签线协议别名。 | diff --git a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md index 2d1d0773bb..36f467f437 100644 --- a/docs-site/src/content/docs/zh-cn/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-cn/reference/configuration/server.md @@ -145,15 +145,17 @@ Codex 会为标题、提交信息等任务使用较小的辅助模型。启用 | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | | `enabled?` | `boolean` | 在可用时启用 | 总开关。 | -| `backend?` | `"openai" \| "anthropic"` | auto | 显式优先;否则若可用的 Anthropic OAuth 存储凭据存在则选择 `anthropic`,否则选择 `openai`。 | -| `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.6-luna`,Anthropic 使用 `claude-sonnet-5`。旧的显式 `gpt-5.4-mini` 会在启动时迁移。 | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | 显式配置优先;省略时始终使用 `openai`。`anthropic` 和 `xai` 仅在显式配置时运行;`gemini` 和 `exa` 在 executor 发布前仍为保留值。 | +| `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.6-luna`,Anthropic 使用 `claude-sonnet-5`,xAI 使用 `grok-4.6`。旧的显式 `gpt-5.4-mini` 会在启动时迁移。 | +| `exaApiKey?` | `string` | 无 | `exa` 后端的操作员密钥。仅可写入:管理读取绝不会返回已存储的值。 | +| `xSearch?` | `object` | 省略 | xAI 专用的托管 `x_search` opt-in:`enabled`、互斥的 `allowedXHandles` / `excludedXHandles` 数组(最多 20 项),以及 ISO `fromDate` / `toDate`(`YYYY-MM-DD`)。 | | `reasoning?` | `string` | `low` | 侧车努力级别。`minimal` 与 web search 不兼容,会被拒绝。 | | `maxSearchesPerTurn?` | `number` | `3` | 每个主模型轮次允许的实际搜索次数。 | | `routedModelStallTimeoutMs?` | `number` | `200000` | 仅限配置文件的 routed-model 原始正文不活动截止时间。整数范围 1–2147483647;每个非空数据块都会重置它。 | | `timeoutMs?` | `number` | `60000` | 单次托管搜索的截止时间。 | OpenAI 后端要求已登录 ChatGPT,并启用了 ChatGPT `forward` 提供方。来自 Claude 的入站 -routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用的是来自已启用 Anthropic OAuth 提供方的当前保存凭据。如果显式选择了 Anthropic 后端但没有可用账户,则会失败并关闭,而不会回退。Anthropic 执行器使用其原生的 `web_search_20250305` 工具。 +routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用的是来自已启用 Anthropic OAuth 提供方的当前保存凭据。如果显式选择了 Anthropic 后端但没有可用账户,则会失败并关闭,而不会回退。Anthropic 执行器使用其原生的 `web_search_20250305` 工具。xAI 后端要求有可用的已存储 Grok OAuth 账户,使用托管 `web_search`,并在 `xSearch.enabled` 为 true 时添加托管 `x_search`。格式错误的 `xSearch` 管理输入会返回 `400`;格式错误的持久化块会在规划期间失败并关闭。`gemini` 和 `exa` 通道绝不会因凭据发现或回退而激活;操作员必须显式选择它们。`exaApiKey` 可在写入时接受,但会从管理响应中省略。 搜索由四个时钟共同约束:基础 `stallTimeoutSec`、`connectTimeoutMs`、routed-model 不活动超时,以及 托管搜索超时。有效的桥接看门狗是最大值再加 30 秒。routed stall 是不活动保护,而不是总生成截止时间。 @@ -163,7 +165,7 @@ routed 重放会把主 ChatGPT 认证注入内部请求。Anthropic 后端使用 | 字段 | 类型 | 默认值 | 含义 | | --- | --- | --- | --- | | `enabled?` | `boolean` | 在可用时启用 | 图像描述总开关。 | -| `backend?` | `"openai" \| "anthropic"` | auto | 与 web search 相同的显式优先、感知 Anthropic 凭据的选择方式。 | +| `backend?` | `"openai" \| "anthropic"` | auto | 显式值优先;未设置时优先使用可用的已保存 Anthropic OAuth 凭据,否则使用 `openai`。 | | `model?` | `string` | 依后端而定 | OpenAI 使用 `gpt-5.4-mini`,Anthropic 使用 `claude-sonnet-5`。 | | `reasoning?` | `"low" \| "medium" \| "high" \| "xhigh" \| "max"` | `"low"` | OpenAI Responses 推理强度;Anthropic 会忽略该项。 | | `maxDescriptionsPerTurn?` | `number` | `8` | 每个主轮次允许的新增描述缓存未命中次数。`0` 会禁用调用;无效值会使用默认值。 | diff --git a/docs-site/src/content/docs/zh-tw/guides/integrations.md b/docs-site/src/content/docs/zh-tw/guides/integrations.md index 944c6d20fd..8a880fef06 100644 --- a/docs-site/src/content/docs/zh-tw/guides/integrations.md +++ b/docs-site/src/content/docs/zh-tw/guides/integrations.md @@ -26,7 +26,9 @@ loopback,而且絕不會寫入真實憑證。 MiniMax Code 依序遵循 `MINIMAX_DATA_DIR`、`MAVIS_DATA_DIR`,最後才回退到 `~/.minimax`。其受管理區塊只擁有 `custom_provider.opencodex`,不會變更 `defaultModel`、MiniMax 憑證來源或使用者的 MiniMax 登入。連接後請在 MCode -中選擇 `custom_provider:opencodex/`。 +中選擇 `custom_provider:opencodex/`。重新整理整合也會更新有可靠來源的 +逐模型 context window 與 reasoning-effort 選項;未知能力會省略,而 MCode session +目前選取的 effort 不會被覆寫。 路徑遵循客戶端自己的環境覆寫(environment override)。對 OMP 而言,`OMP_PROFILE` 以存在與否優先於 `PI_PROFILE`,即使明確為空也一樣。具名 profile 會把 `PI_CONFIG_DIR` 當作相對於使用者家目錄的目錄名稱,並忽略 `PI_CODING_AGENT_DIR`;沒有具名 profile 時,`PI_CODING_AGENT_DIR` 勝出。OMP 支援 provider 層級的 headers,但這個最初的整合刻意只支援 loopback;遠端 `x-opencodex-api-key` 的連線設定被延後。搬移過的 `HERMES_HOME`、`KIMI_CODE_HOME` 與 `XDG_CONFIG_HOME` 路徑同樣會被遵循,而非猜測。表格列出每個客戶端的預設值。 @@ -85,6 +87,10 @@ ocx integration client enable --client mcode ocx mcode ``` +完成一次連接後,`ocx sync` 也會以目前的 context window 與 reasoning-effort 階梯更新 +OpenCodex 已擁有的 MCode 區塊。若區塊已刪除、遭外部修改、不安全或從未由 OpenCodex +建立,sync 會保持原檔不動;只有在你確定要重新連接時才再次執行 enable。 + 另一個 MiniMax 平台 CLI(`mmx`)不是檔案開關整合。其文字命令使用 MiniMax 的 Anthropic 相容端點,因此 OpenCodex 提供憑證隔離、僅限 loopback 的 launcher: diff --git a/docs-site/src/content/docs/zh-tw/guides/sidecars.md b/docs-site/src/content/docs/zh-tw/guides/sidecars.md index 3db6485291..1ffe807961 100644 --- a/docs-site/src/content/docs/zh-tw/guides/sidecars.md +++ b/docs-site/src/content/docs/zh-tw/guides/sidecars.md @@ -5,13 +5,13 @@ description: 透過原生 ChatGPT sidecar,讓路由模型獲得真實 web sear 不同路由模型對託管 **Web Search** 和原生**圖像輸入**的支援並不相同。opencodex 透過兩個 sidecar 補齊這些能力;它們可以使用 ChatGPT 登入(`forward`)provider,也可以使用已儲存的 -Anthropic OAuth provider。Sidecar 錯誤會轉換成長度受限的工具結果或圖像提示,不會讓整個 turn +Anthropic OAuth provider;web search 還可透過明確的 `xai` backend 使用已儲存的 Grok OAuth。Sidecar 錯誤會轉換成長度受限的工具結果或圖像提示,不會讓整個 turn 失敗。 :::note[自動選擇後端] -顯式 `backend` 設定優先。省略時,如果已啟用 Anthropic OAuth provider 的活動帳號未標記 -`needsReauth`,則使用 `anthropic`;否則使用 `openai`。顯式選擇 `anthropic` 但沒有可用憑證時 -會關閉失敗。`openai` 同時需要 ChatGPT 登入和已啟用的 `forward` provider。 +明確的 `backend` 設定優先。Web search 省略時一律使用 `openai`;Vision 有可用 Anthropic +OAuth 帳號時使用 `anthropic`,否則使用 `openai`。明確選擇 `anthropic` 或 `xai` 但沒有可用憑證時 +會關閉失敗且不回退。`openai` 同時需要 ChatGPT 登入和已啟用的 `forward` provider。 ::: ## Web-search sidecar @@ -22,7 +22,8 @@ Anthropic OAuth provider。Sidecar 錯誤會轉換成長度受限的工具結果 `web_search(query)` function 工具。原託管工具的選項會保留並用於 sidecar 呼叫。 2. 讓路由模型在一個小型 **agentic 迴圈**中執行。模型呼叫 `web_search` 時,opencodex 使用所選 後端:OpenAI 預設以 `gpt-5.6-luna` 執行託管 `web_search`;Anthropic 預設以 - `claude-sonnet-5` 執行 `web_search_20250305`。Streaming 答案及引用會解析為工具結果。 + `claude-sonnet-5` 執行 `web_search_20250305`。xAI 預設以 `grok-4.6` 執行託管 `web_search`, + 並在 `xSearch.enabled` 為 true 時將 `x_search` 加入同一請求。Streaming 答案及引用會解析為工具結果。 3. **迴圈**直到模型回答,或真實查詢總數達到 `maxSearchesPerTurn`(預設 3)。達到上限後會移除 search 工具並強制生成最終答案。如果模型呼叫 `apply_patch` 或 shell 等真實用戶端工具,目前 turn 會結束,以便這些呼叫到達 Codex。 diff --git a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md index ebe59cbcd8..20815d5a08 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli/agents.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli/agents.md @@ -130,7 +130,7 @@ ocx claude desktop import [--apply] 驗證並匯入 JSON ## 客戶端設定匯出 -### `ocx export --client ` +### `ocx export --client ` 印出連接到執行中代理的客戶端設定。此指令會用所選客戶端的原生格式,序列化含有 base URL、模型清單,以及適用的環境變數參考或 loopback 佔位符的 `opencodex` provider 區塊。 @@ -138,7 +138,7 @@ ocx claude desktop import [--apply] 驗證並匯入 JSON | 旗標 | 動作 | | --- | --- | -| `--client ` | 必填。選擇客戶端設定格式。 | +| `--client ` | 必填。選擇客戶端設定格式。 | | `--json` | 僅在 stdout 印出設定 JSON,使重導向能擷取逐位元組輸出。所有診斷訊息(含 `--out` 寫入提示)皆送至 stderr。 | | `--out ` | 將設定寫入 ``。拒絕覆寫既有檔案。 | | `--force` | 允許 `--out` 覆寫既有檔案。 | @@ -155,13 +155,16 @@ ocx export --client opencode --out ~/opencodex-opencode.json | 客戶端 | 標準目的地 | 下載檔名 | 環境變數 | | --- | --- | --- | --- | | `opencode` | `~/.config/opencode/opencode.json`(`XDG_CONFIG_HOME` 設定時優先) | `opencode.json` | `OPENCODEX_OPENCODE_API_KEY` | -| `pi` | `~/.pi/agent/models.json` | `pi-models.json` | 無——區塊帶有字面值 `opencodex-loopback` | +| `pi` | `~/.pi/agent/models.json` (設定後 `PI_CODING_AGENT_DIR` 優先;相對路徑會被拒絕) | `pi-models.json` | 無——區塊帶有字面值 `opencodex-loopback` | | `omp` | `~/.omp/agent/models.yml`(即使是空值,`OMP_PROFILE` 仍優先於 `PI_PROFILE`) | `omp-models.yaml` | 無——loopback 佔位符 | | `hermes` | `~/.hermes/config.yaml` | `hermes-config.yaml` | `OPENCODEX_HERMES_API_KEY` | | `openclaw` | `~/.openclaw/openclaw.json` | `openclaw.json5` | `OPENCODEX_OPENCLAW_API_KEY` | | `kimi` | `~/.kimi-code/config.toml` | `kimi-config.toml` | 無——loopback 佔位符 | | `gajae` | `~/.gjc/agent/models.yml` | `gajae-models.yaml` | `OPENCODEX_GAJAE_API_KEY` | | `dsh` | `$DSH_HOME/settings.yaml`(預設 `~/.dsh/settings.yaml`) | `settings.yaml` | 無——非秘密的 loopback bearer 佔位符 | +| `mcode` | `~/.minimax/config.yaml` (設定後 `MINIMAX_DATA_DIR` 優先,其次為舊的 `MAVIS_DATA_DIR`;相對路徑會被拒絕) | `mcode-config.yaml` | 無——loopback 佔位符 | +| `zcode` | `~/.zcode/v2/config.json` (設定後 `ZCODE_DATA_DIR` 優先;相對路徑會被拒絕) | `config.json` | 無——loopback 佔位符 | +| `prime` | `~/.prime/agent/models.json` (設定後 `PRIME_AGENT_CODING_AGENT_DIR` 優先;相對路徑會被拒絕) | `prime-models.json` | 無——loopback 佔位符 | opencode 會插值 `{env:OPENCODEX_OPENCODE_API_KEY}`。Pi 與 OMP 的匯出不需要環境變數, 而是帶有字面值 `opencodex-loopback`。DSH 匯出需要 DSH 0.1.0-rc.6 或更新版本,且只擁有 diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md index 326aa348d5..f47b5bef05 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/providers.md @@ -67,6 +67,7 @@ description: 供應商項目、認證、端點、模型目錄、配額、context | `modelSupportsReasoningSummaries?` | `Record` | 將模型設為 `false` 以停止廣告摘要並剝離 summary-delivery 欄位。 | | `modelReasoningSummaryDelivery?` | `Record` | Per-model Responses delivery 列舉;重寫既有的 delivery 欄位。 | | `modelAdapters?` | `Record` | 混合 wire 閘道的 Per-model `openai-chat` 或 `openai-responses` wire 覆寫。明確項目勝過 registry 預設;DeepSeek 的預設可為 `deepseek-v4-flash` 選擇原生 Responses。單一 wire 上游 pin 與規範 ChatGPT forward 拒絕覆寫。 | +| xAI Responses 選用(儀表板) | 開關 | 僅用於 `xai`,以原子方式設定或清除 `grok-4.5` 與 `grok-4.6` 的 `modelAdapters` 項目。若只有一個項目,會顯示混合狀態,直到下次開關寫入統一兩者。其他覆寫與層級行為不變。 | | `reasoningEffortMap?` | `Record` | 供應商範圍的 reasoning 標籤 wire 別名。 | | `modelReasoningEffortMap?` | `Record>` | Per-model 的 reasoning 標籤 wire 別名。 | | `noReasoningModels?` | `string[]` | 拒絕 reasoning/thinking 參數的模型。 | diff --git a/docs-site/src/content/docs/zh-tw/reference/configuration/server.md b/docs-site/src/content/docs/zh-tw/reference/configuration/server.md index 8e4f6fd7d9..6df1d0f7be 100644 --- a/docs-site/src/content/docs/zh-tw/reference/configuration/server.md +++ b/docs-site/src/content/docs/zh-tw/reference/configuration/server.md @@ -167,14 +167,16 @@ Codex 使用小型 helper 模型處理如標題與 commit 訊息等任務。啟 | 欄位 | 型別 | 預設值 | 意義 | | --- | --- | --- | --- | | `enabled?` | `boolean` | 可用時開啟 | 主開關。 | -| `backend?` | `"openai" \| "anthropic"` | 自動 | 明確勝出;否則可用的已儲存 Anthropic OAuth 選擇 `anthropic`,然後 `openai`。 | -| `model?` | `string` | 視 backend 而定 | OpenAI 為 `gpt-5.6-luna` 或 Anthropic 為 `claude-sonnet-5`。舊版明確 `gpt-5.4-mini` 在啟動時遷移。 | +| `backend?` | `"openai" \| "anthropic" \| "xai" \| "gemini" \| "exa"` | `openai` | 明確設定優先;省略時一律使用 `openai`。`anthropic` 與 `xai` 僅在明確設定時執行;`gemini` 與 `exa` 在 executor 推出前仍為保留值。 | +| `model?` | `string` | 視 backend 而定 | OpenAI 為 `gpt-5.6-luna`、Anthropic 為 `claude-sonnet-5`、xAI 為 `grok-4.6`。舊版明確 `gpt-5.4-mini` 在啟動時遷移。 | +| `exaApiKey?` | `string` | 無 | `exa` backend 的操作員金鑰。僅可寫入:管理讀取永遠不會傳回已儲存的值。 | +| `xSearch?` | `object` | 省略 | xAI 專用的託管 `x_search` opt-in:`enabled`、互斥的 `allowedXHandles` / `excludedXHandles` 陣列(最多 20 項),以及 ISO `fromDate` / `toDate`(`YYYY-MM-DD`)。 | | `reasoning?` | `string` | `low` | Sidecar effort。`minimal` 在網頁搜尋時被拒絕。 | | `maxSearchesPerTurn?` | `number` | `3` | 每個主模型回合允許的實際搜尋。 | | `routedModelStallTimeoutMs?` | `number` | `200000` | 僅設定檔的路由模型原始 body 不活動截止時間。整數 1–2147483647;每個非空 chunk 重置它。 | | `timeoutMs?` | `number` | `60000` | 一個代管搜尋的截止時間。 | -OpenAI backend 需要 ChatGPT 登入與啟用的 ChatGPT `forward` 供應商。Claude-inbound 路由重播將主 ChatGPT 認證注入內部請求。Anthropic backend 使用來自已啟用 Anthropic OAuth 供應商的現用已儲存憑證。明確選擇的 Anthropic backend 在無可用帳號時 fail closed 而非後退。Anthropic 執行器使用其原生 `web_search_20250305` 工具。 +OpenAI backend 需要 ChatGPT 登入與啟用的 ChatGPT `forward` 供應商。Claude-inbound 路由重播將主 ChatGPT 認證注入內部請求。Anthropic backend 使用來自已啟用 Anthropic OAuth 供應商的現用已儲存憑證。明確選擇的 Anthropic backend 在無可用帳號時 fail closed 而非後退。Anthropic 執行器使用其原生 `web_search_20250305` 工具。xAI backend 需要可用的已儲存 Grok OAuth 帳號,使用託管 `web_search`,並在 `xSearch.enabled` 為 true 時加入託管 `x_search`。格式錯誤的 `xSearch` 管理輸入會傳回 `400`;格式錯誤的持久化區塊會在規劃期間 fail closed。`gemini` 與 `exa` 通道絕不會因憑證探索或 fallback 而啟用;操作員必須明確選擇它們。`exaApiKey` 可在寫入時接受,但會從管理回應中省略。 四個時鐘治理搜尋:基礎 `stallTimeoutSec`、`connectTimeoutMs`、路由模型不活動與代管搜尋逾時。有效的橋接看門狗為最大值加 30 秒。路由停滯是不活動防護,而非總生成截止時間。 @@ -183,7 +185,7 @@ OpenAI backend 需要 ChatGPT 登入與啟用的 ChatGPT `forward` 供應商。C | 欄位 | 型別 | 預設值 | 意義 | | --- | --- | --- | --- | | `enabled?` | `boolean` | 可用時開啟 | 主圖片描述開關。 | -| `backend?` | `"openai" \| "anthropic"` | 自動 | 與網頁搜尋相同的明確優先、Anthropic 憑證感知選擇。 | +| `backend?` | `"openai" \| "anthropic"` | 自動 | 明確值優先;未設定時優先使用可用的已儲存 Anthropic OAuth 憑證,否則使用 `openai`。 | | `model?` | `string` | 視 backend 而定 | OpenAI 為 `gpt-5.4-mini` 或 Anthropic 為 `claude-sonnet-5`。 | | `maxDescriptionsPerTurn?` | `number` | `8` | 每個主回合允許的新描述快取未命中。`0` 停用呼叫;無效值使用預設。 | | `timeoutMs?` | `number` | `45000` | Sidecar 擷取逾時。整數 1–2147483647。 | diff --git a/gui/src/app-routing.ts b/gui/src/app-routing.ts index b58b507a7e..be8fa2a84b 100644 --- a/gui/src/app-routing.ts +++ b/gui/src/app-routing.ts @@ -92,6 +92,7 @@ export const INTEGRATION_TAB_HASHES = [ "integrations/dsh", "integrations/mcode", "integrations/zcode", + "integrations/prime", ] as const; export function hashBelongsToPage(rawHash: string, page: Page): boolean { diff --git a/gui/src/components/apikeys-workspace/client-config-clients.ts b/gui/src/components/apikeys-workspace/client-config-clients.ts index c8007a4584..fc46026971 100644 --- a/gui/src/components/apikeys-workspace/client-config-clients.ts +++ b/gui/src/components/apikeys-workspace/client-config-clients.ts @@ -8,7 +8,7 @@ * with EXPORT_CLIENT_IDS by hand; adding a client server-side renders no row * until this tuple changes. */ -export const CLIENTS = ["opencode", "pi", "omp", "hermes", "openclaw", "kimi", "gajae", "dsh", "mcode", "zcode"] as const; +export const CLIENTS = ["opencode", "pi", "omp", "hermes", "openclaw", "kimi", "gajae", "dsh", "mcode", "zcode", "prime"] as const; export type ExportClientId = (typeof CLIENTS)[number]; export const CLIENT_LABEL_KEYS = { @@ -22,6 +22,7 @@ export const CLIENT_LABEL_KEYS = { dsh: "api.clientConfig.clientDsh", mcode: "api.clientConfig.clientMcode", zcode: "api.clientConfig.clientZcode", + prime: "api.clientConfig.clientPrime", } as const; /** diff --git a/gui/src/components/provider-workspace/ProviderAuthPanel.tsx b/gui/src/components/provider-workspace/ProviderAuthPanel.tsx index 60c15225de..928e15d93c 100644 --- a/gui/src/components/provider-workspace/ProviderAuthPanel.tsx +++ b/gui/src/components/provider-workspace/ProviderAuthPanel.tsx @@ -22,13 +22,80 @@ import { LoginUrlBlock } from "../login-url-block"; import QuotaBars from "../QuotaBars"; import { useCopyFeedback } from "../use-copy-feedback"; import type { CodexAccountPoolController } from "../../hooks/useCodexAccountPool"; -import type { AccountLoadState, OAuthAccountRow, ApiKeyRow, LoginHint, ProviderAuthHandlers } from "./types"; +import { Switch } from "../../ui"; +import type { + AccountLoadState, + OAuthAccountRow, + ApiKeyRow, + LoginHint, + ProviderAuthHandlers, + ProviderUpdatePatch, + ProviderUpdateResult, +} from "./types"; const QUOTA_ENRICH_RESERVE_MS = 4_000; const COCKPIT_IMPORT_MAX_BYTES = 256 * 1024; const EMPTY_OAUTH_ACCOUNTS: OAuthAccountRow[] = []; const EMPTY_API_KEYS: ApiKeyRow[] = []; +function XaiResponsesOptInControl({ + initialState, + onUpdateProvider, +}: { + initialState: NonNullable; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; +}) { + const t = useT(); + const [state, setState] = useState(initialState); + const [seenInitialState, setSeenInitialState] = useState(initialState); + const [saving, setSaving] = useState(false); + const [error, setError] = useState(""); + if (initialState !== seenInitialState) { + setSeenInitialState(initialState); + setState(initialState); + } + const mixed = state === "mixed"; + + const toggle = async () => { + if (!onUpdateProvider || saving) return; + const next = state !== true; + setSaving(true); + setError(""); + try { + const result = await onUpdateProvider("xai", { xaiResponsesOptIn: next }); + if (!result.ok) { + setError(result.error ?? t("prov.updateFail")); + return; + } + setState(result.xaiResponsesOptInState ?? next); + } catch { + setError(t("prov.networkError")); + } finally { + setSaving(false); + } + }; + + return ( +
+
+ {t("pws.xaiResponsesOptIn")} + + {t("pws.xaiResponsesOptInDesc")} + {mixed && {t("pws.xaiResponsesOptInMixed")}} + + {error && {error}} +
+ { void toggle(); }} + disabled={!onUpdateProvider || saving} + label={t("pws.xaiResponsesOptIn")} + /> +
+ ); +} + type CockpitImportResult = { importedCount: number; updatedCount: number; @@ -99,7 +166,7 @@ function safeCockpitImportResult(value: unknown): CockpitImportResult | null { export default function ProviderAuthPanel({ item, apiBase, oauth, accounts = EMPTY_OAUTH_ACCOUNTS, keys = EMPTY_API_KEYS, accountLoadState = "ready", switchingAccountId = null, busy = false, loginHint, authHandlers, onCodexActiveNeedsReauthChange, - codexController, + codexController, onUpdateProvider, }: { item: WorkspaceItem; apiBase: string; @@ -112,6 +179,7 @@ export default function ProviderAuthPanel({ loginHint?: LoginHint | null; authHandlers?: ProviderAuthHandlers; onCodexActiveNeedsReauthChange?: (needs: boolean) => void; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; /** Shared Codex account state owned by Providers (WP3). */ codexController?: CodexAccountPoolController; }) { @@ -248,6 +316,12 @@ export default function ProviderAuthPanel({

{isOauth ? t("pws.availableAccounts") : t("pws.apiKeys")}

+ {item.name === "xai" && ( + + )} {isOauth && ( <> {item.name === "anthropic" && ( diff --git a/gui/src/components/provider-workspace/ProviderDetails.tsx b/gui/src/components/provider-workspace/ProviderDetails.tsx index 62cf94cad8..1b02517835 100644 --- a/gui/src/components/provider-workspace/ProviderDetails.tsx +++ b/gui/src/components/provider-workspace/ProviderDetails.tsx @@ -20,7 +20,7 @@ import type { CodexAccountPoolController } from "../../hooks/useCodexAccountPool import ProviderSettings from "./ProviderSettings"; import { UnsavedLeaveDialog } from "./ProviderDialogs"; import type { ProviderQuotaReportView } from "../../provider-workspace/report"; -import type { AccountLoadState, ProviderModelUsageRow, ProviderUsageTotals, OAuthAccountRow, ApiKeyRow, LoginHint, ProviderAuthHandlers, ProviderUpdatePatch } from "./types"; +import type { AccountLoadState, ProviderModelUsageRow, ProviderUsageTotals, OAuthAccountRow, ApiKeyRow, LoginHint, ProviderAuthHandlers, ProviderUpdatePatch, ProviderUpdateResult } from "./types"; type Tab = "overview" | "models" | "usage" | "accounts" | "settings"; @@ -85,7 +85,7 @@ export default function ProviderDetails({ onCodexActiveNeedsReauthChange?: (needs: boolean) => void; /** Shared Codex account state owned by Providers (WP3). */ codexController?: CodexAccountPoolController; - onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise<{ ok: boolean; error?: string }>; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; isDefault?: boolean; onRemoveProvider?: (name: string) => void; onSetDisabled?: (name: string, disabled: boolean) => void; @@ -310,6 +310,7 @@ export default function ProviderDetails({ busy={busyProvider === item.name} loginHint={loginHint} authHandlers={authHandlers} + onUpdateProvider={onUpdateProvider} onCodexActiveNeedsReauthChange={onCodexActiveNeedsReauthChange} codexController={codexController} /> diff --git a/gui/src/components/provider-workspace/ProviderOverview.tsx b/gui/src/components/provider-workspace/ProviderOverview.tsx index d4b7f3619d..5c5e7468cf 100644 --- a/gui/src/components/provider-workspace/ProviderOverview.tsx +++ b/gui/src/components/provider-workspace/ProviderOverview.tsx @@ -11,7 +11,7 @@ import { formatRelativeTime, relativeTimeLabelsFromT, formatRequestCount, format import { accountQuotaFromReport, formatQuotaSourceLabel, type ProviderQuotaReportView } from "../../provider-workspace/report"; import type { ProviderUsageTotals } from "./types"; import { authModeLabel } from "./ProviderRail"; -import type { ProviderUpdatePatch } from "./types"; +import type { ProviderUpdatePatch, ProviderUpdateResult } from "./types"; import { ProviderCapacityQuota } from "./ProviderCapacityQuota"; type ConnectionTestResult = { @@ -46,7 +46,7 @@ export default function ProviderOverview({ connectionIdentity?: string; onEditSettings?: () => void; onViewUsage?: () => void; - onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise<{ ok: boolean; error?: string }>; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; onReauthenticate?: () => void; onCancelLogin?: () => void; reauthBusy?: boolean; @@ -306,7 +306,7 @@ export default function ProviderOverview({ function NotesSection({ item, onUpdateProvider }: { item: WorkspaceItem; - onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise<{ ok: boolean; error?: string }>; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; }) { const t = useT(); const [editing, setEditing] = useState(false); diff --git a/gui/src/components/provider-workspace/ProviderSettings.tsx b/gui/src/components/provider-workspace/ProviderSettings.tsx index 1509e13a14..847fe7e712 100644 --- a/gui/src/components/provider-workspace/ProviderSettings.tsx +++ b/gui/src/components/provider-workspace/ProviderSettings.tsx @@ -19,7 +19,7 @@ import { openAiAccountProviderState } from "../../provider-payload"; import { providerSupportsLiveModelDiscovery } from "../../provider-workspace/catalog"; import type { CatalogPreset } from "../provider-catalog/provider-presets"; import { authModeLabel } from "./ProviderRail"; -import type { WorkspaceItem, ProviderUpdatePatch } from "./types"; +import type { WorkspaceItem, ProviderUpdatePatch, ProviderUpdateResult } from "./types"; const ADAPTERS = ["openai-responses", "openai-chat", "anthropic", "google", "azure-openai", "cursor"] as const; const EMPTY_MODELS: string[] = []; @@ -63,7 +63,7 @@ export default function ProviderSettings({ availableModels?: string[]; /** When set, load endpoint choices for catalog providers that expose baseUrlChoices. */ apiBase?: string; - onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise<{ ok: boolean; error?: string }>; + onUpdateProvider?: (name: string, patch: ProviderUpdatePatch) => Promise; onDirtyChange?: (dirty: boolean) => void; /** Lets parent dialogs trigger the same save path as the sticky bar. */ onRegisterSave?: (save: (() => Promise) | null) => void; diff --git a/gui/src/components/provider-workspace/types.ts b/gui/src/components/provider-workspace/types.ts index 24dd218f3b..d23464500e 100644 --- a/gui/src/components/provider-workspace/types.ts +++ b/gui/src/components/provider-workspace/types.ts @@ -102,4 +102,12 @@ export type ProviderUpdatePatch = { requestPacing?: WorkspaceItem["requestPacing"] | null; /** Dedicated field: the API PATCHes it alone for the canonical `openai` provider. */ codexAccountMode?: "direct" | "pool"; + /** Management-only write that atomically owns the two supported xAI Grok adapter rows. */ + xaiResponsesOptIn?: boolean; +}; + +export type ProviderUpdateResult = { + ok: boolean; + error?: string; + xaiResponsesOptInState?: WorkspaceItem["xaiResponsesOptInState"]; }; diff --git a/gui/src/i18n/de.ts b/gui/src/i18n/de.ts index d6c503134a..8e64e29b97 100644 --- a/gui/src/i18n/de.ts +++ b/gui/src/i18n/de.ts @@ -855,6 +855,7 @@ export const de: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Die Codex-Anbindung wird vom Proxy-Dienst verwaltet. Beim Start von opencodex wird sie angewendet; beim Stoppen des Dienstes wird das native Routing wiederhergestellt.", "integrations.codex.openService": "Dienststeuerung öffnen", @@ -872,6 +873,7 @@ export const de: Record = { "integrations.detail.desktopNotServed": "Das Profil ist da, Desktop nutzt aber ein anderes", "integrations.detail.desktopAbsent": "Kein Profil angewendet", "integrations.detail.desktopDesiredOff": "Die Claude-Desktop-Integration ist deaktiviert", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop verwendet das Gateway noch; die Bereinigung steht aus", "integrations.detail.desktopDesiredOnNotApplied": "Die Integration ist aktiviert, aber Desktop verwendet nicht das Gateway-Profil", "integrations.detail.desktopSelectedElsewhere": "Desktop verwendet ein anderes Profil", "integrations.detail.desktopProfileDrift": "Das ausgewählte Desktop-Profil wurde geändert", @@ -968,6 +970,7 @@ export const de: Record = { "integrations.semantics.dsh": "OpenCodex verwaltet nur llm-pi-ai.providers.opencodex in $DSH_HOME/settings.yaml. DSH lädt diesen Anbieter im laufenden Betrieb neu; Ihr Standardmodell und deepseek-official bleiben unverändert. Derzeit nur über Loopback; es werden keine echten Zugangsdaten geschrieben.", "integrations.semantics.mcode": "Verwaltet nur custom_provider.opencodex. Standardmodell und MiniMax-Anmeldung bleiben unverändert.", "integrations.semantics.zcode": "Verwaltet nur provider.opencodex in ~/.zcode/v2/config.json. Z.ai-Anmeldung und andere Provider bleiben unverändert. ZCode nach Änderungen neu starten.", + "integrations.semantics.prime": "Verwaltet nur providers.opencodex in der models.json von Prime Agent — ~/.prime/agent, sofern PRIME_AGENT_CODING_AGENT_DIR sie nicht umleitet. Andere Provider und Modell-Overrides bleiben unverändert. Gilt für neue Sitzungen.", "codexAuth.mainAccount": "Hauptkonto", "codexAuth.logLabel": "Log-Kennung", "codexAuth.codexApp": "Codex App", @@ -1252,6 +1255,7 @@ export const de: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "Konfiguration kopieren", "api.clientConfig.download": "Herunterladen", "api.clientConfig.loading": "Client-Konfiguration wird erstellt…", @@ -1691,6 +1695,9 @@ export const de: Record = { "pws.allowPrivateNetwork": "Lokales/privates Netzwerk erlauben", "pws.liveModels": "Modelle beim Anbieter erkennen", "pws.liveModelsDesc": "Lädt den Live-Modellkatalog des Anbieters. Ausschalten, um nur konfigurierte statische Modelle zu verwenden.", + "pws.xaiResponsesOptIn": "Responses API für Grok 4.5 und 4.6 verwenden", + "pws.xaiResponsesOptInDesc": "Leitet beide Modelle über openai-responses. Andere Grok-Modelle und das Tier-Verhalten bleiben unverändert.", + "pws.xaiResponsesOptInMixed": "Teilweise aktiviert.", "pws.cursorTransport": "Cursor-Transport", "pws.cursorTransportHttp2": "HTTP/2 (Standard)", "pws.cursorTransportHttp1": "HTTP/1.1 (Proxy-Kompatibilität)", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 87892599ce..262e913162 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -1193,6 +1193,9 @@ export const en = { "pws.allowPrivateNetwork": "Allow local/private network", "pws.liveModels": "Discover models from provider", "pws.liveModelsDesc": "Fetch the provider's live model catalog. Turn this off to use only configured/static models.", + "pws.xaiResponsesOptIn": "Use Responses API for Grok 4.5 and 4.6", + "pws.xaiResponsesOptInDesc": "Routes both models through openai-responses. Other Grok models and tier behavior are unchanged.", + "pws.xaiResponsesOptInMixed": "Partially enabled.", "pws.cursorTransport": "Cursor transport", "pws.cursorTransportHttp2": "HTTP/2 (default)", "pws.cursorTransportHttp1": "HTTP/1.1 (proxy compatibility)", @@ -1344,6 +1347,7 @@ export const en = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex wiring is owned by the proxy service. Starting opencodex applies it; stopping the service restores native routing.", "integrations.codex.openService": "Open service controls", @@ -1361,6 +1365,7 @@ export const en = { "integrations.detail.desktopNotServed": "The profile exists, but Desktop serves another one", "integrations.detail.desktopAbsent": "No profile applied", "integrations.detail.desktopDesiredOff": "Claude Desktop integration is off", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop is still using the gateway; cleanup is pending", "integrations.detail.desktopDesiredOnNotApplied": "Integration is on, but Desktop is not using the gateway profile", "integrations.detail.desktopSelectedElsewhere": "Desktop is using another profile", "integrations.detail.desktopProfileDrift": "The selected Desktop profile changed", @@ -1457,6 +1462,7 @@ export const en = { "integrations.semantics.dsh": "OpenCodex manages only llm-pi-ai.providers.opencodex in $DSH_HOME/settings.yaml. DSH hot reloads this provider; your default model and deepseek-official stay unchanged. Currently loopback-only; no real credential is written.", "integrations.semantics.mcode": "Manages only custom_provider.opencodex. Your default model and MiniMax login stay unchanged.", "integrations.semantics.zcode": "Manages only provider.opencodex in ~/.zcode/v2/config.json. Your Z.ai login and other providers stay unchanged. Restart ZCode after changes.", + "integrations.semantics.prime": "Manages only providers.opencodex in Prime Agent's models.json — ~/.prime/agent unless PRIME_AGENT_CODING_AGENT_DIR redirects it. Your other providers and model overrides stay unchanged. Applies to new sessions.", "codexAuth.mainAccount": "Main Account", "codexAuth.logLabel": "Log label", "codexAuth.codexApp": "Codex App", @@ -1749,6 +1755,7 @@ export const en = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "Copy config", "api.clientConfig.download": "Download", "api.clientConfig.loading": "Building client config…", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index 4da3bc33f1..147773fd93 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -1166,6 +1166,9 @@ export const fr: Record = { "pws.allowPrivateNetwork": "Autoriser le réseau local/privé", "pws.liveModels": "Détecter les modèles auprès du fournisseur", "pws.liveModelsDesc": "Récupérez le catalogue de modèles en direct du fournisseur. Désactivez cette option pour utiliser uniquement les modèles configurés/statiques.", + "pws.xaiResponsesOptIn": "Utiliser l’API Responses pour Grok 4.5 et 4.6", + "pws.xaiResponsesOptInDesc": "Achemine les deux modèles via openai-responses. Les autres modèles Grok et le comportement des tiers restent inchangés.", + "pws.xaiResponsesOptInMixed": "Activation partielle.", "pws.cursorTransport": "Transport Cursor", "pws.cursorTransportHttp2": "HTTP/2 (par défaut)", "pws.cursorTransportHttp1": "HTTP/1.1 (compatibilité proxy)", @@ -1317,6 +1320,7 @@ export const fr: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Le câblage de Codex est géré par le service proxy. Le démarrage d’opencodex l’applique ; l’arrêt du service rétablit le routage natif.", "integrations.codex.openService": "Ouvrir les commandes du service", @@ -1334,6 +1338,7 @@ export const fr: Record = { "integrations.detail.desktopNotServed": "Le profil existe, mais Desktop en utilise un autre", "integrations.detail.desktopAbsent": "Aucun profil appliqué", "integrations.detail.desktopDesiredOff": "L’intégration Claude Desktop est désactivée", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop utilise encore la passerelle ; le nettoyage est en attente", "integrations.detail.desktopDesiredOnNotApplied": "L’intégration est activée, mais Desktop n’utilise pas le profil de passerelle", "integrations.detail.desktopSelectedElsewhere": "Desktop utilise un autre profil", "integrations.detail.desktopProfileDrift": "Le profil Desktop sélectionné a changé", @@ -1430,6 +1435,7 @@ export const fr: Record = { "integrations.semantics.dsh": "OpenCodex gère uniquement llm-pi-ai.providers.opencodex dans $DSH_HOME/settings.yaml. DSH recharge ce fournisseur à chaud ; votre modèle par défaut et deepseek-official restent inchangés. Seule l’adresse de bouclage est actuellement prise en charge ; aucun identifiant réel n’est écrit.", "integrations.semantics.mcode": "Gère uniquement custom_provider.opencodex. Votre modèle par défaut et votre connexion MiniMax restent inchangés.", "integrations.semantics.zcode": "Gère uniquement provider.opencodex dans ~/.zcode/v2/config.json. Votre connexion Z.ai et les autres fournisseurs restent inchangés. Redémarrez ZCode après toute modification.", + "integrations.semantics.prime": "Gère uniquement providers.opencodex dans le models.json de Prime Agent — ~/.prime/agent, sauf si PRIME_AGENT_CODING_AGENT_DIR le redirige. Vos autres fournisseurs et surcharges de modèles restent inchangés. S'applique aux nouvelles sessions.", "codexAuth.mainAccount": "Compte principal", "codexAuth.logLabel": "Libellé du journal", "codexAuth.codexApp": "Application Codex", @@ -1713,6 +1719,7 @@ export const fr: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "Copier la configuration", "api.clientConfig.download": "Télécharger", "api.clientConfig.loading": "Génération de la configuration du client…", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index a65cc76d6b..11a85127ea 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -1126,6 +1126,9 @@ export const ja: Record = { "pws.allowPrivateNetwork": "ローカル/プライベートネットワークを許可", "pws.liveModels": "プロバイダーからモデルを検出", "pws.liveModelsDesc": "プロバイダーのライブモデルカタログを取得します。オフにすると設定済みの静的モデルのみを使用します。", + "pws.xaiResponsesOptIn": "Grok 4.5 と 4.6 で Responses API を使用", + "pws.xaiResponsesOptInDesc": "両モデルを openai-responses 経由でルーティングします。他の Grok モデルと tier 動作は変わりません。", + "pws.xaiResponsesOptInMixed": "一部のみ有効です。", "pws.cursorTransport": "Cursor トランスポート", "pws.cursorTransportHttp2": "HTTP/2(デフォルト)", "pws.cursorTransportHttp1": "HTTP/1.1(プロキシ互換)", @@ -1277,6 +1280,7 @@ export const ja: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex の接続はプロキシサービスが管理します。opencodex を起動すると適用され、サービスを停止するとネイティブのルーティングに戻ります。", "integrations.codex.openService": "サービス制御を開く", @@ -1294,6 +1298,7 @@ export const ja: Record = { "integrations.detail.desktopNotServed": "プロファイルはありますが Desktop は別のものを使用中です", "integrations.detail.desktopAbsent": "適用されたプロファイルはありません", "integrations.detail.desktopDesiredOff": "Claude Desktop 連携はオフです", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop はまだゲートウェイを使用しています。クリーンアップ待ちです", "integrations.detail.desktopDesiredOnNotApplied": "連携はオンですが、Desktop はゲートウェイプロファイルを使用していません", "integrations.detail.desktopSelectedElsewhere": "Desktop は別のプロファイルを使用しています", "integrations.detail.desktopProfileDrift": "選択された Desktop プロファイルが変更されました", @@ -1390,6 +1395,7 @@ export const ja: Record = { "integrations.semantics.dsh": "OpenCodex が管理するのは $DSH_HOME/settings.yaml 内の llm-pi-ai.providers.opencodex だけです。DSH はこのプロバイダーをホットリロードし、既定のモデルと deepseek-official は変更しません。現在はループバック専用で、実際の認証情報は書き込みません。", "integrations.semantics.mcode": "custom_provider.opencodex のみを管理します。既定モデルと MiniMax ログインは変更しません。", "integrations.semantics.zcode": "~/.zcode/v2/config.json の provider.opencodex のみを管理します。Z.ai ログインと他のプロバイダーは変更しません。変更後は ZCode を再起動してください。", + "integrations.semantics.prime": "Prime Agent の models.json 内の providers.opencodex のみを管理します。場所は ~/.prime/agent ですが、PRIME_AGENT_CODING_AGENT_DIR が設定されている場合はそちらが優先されます。他のプロバイダーとモデルオーバーライドは変更しません。新しいセッションから適用されます。", "codexAuth.mainAccount": "メインアカウント", "codexAuth.logLabel": "ログラベル", "codexAuth.codexApp": "Codex App", @@ -1679,6 +1685,7 @@ export const ja: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "設定をコピー", "api.clientConfig.download": "ダウンロード", "api.clientConfig.loading": "クライアント設定を生成中…", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index ba19d179e8..5bbc14ae7d 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -879,6 +879,7 @@ export const ko: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex 연결은 프록시 서비스가 관리합니다. opencodex를 시작하면 적용되고 서비스를 중지하면 기본 라우팅으로 복원됩니다.", "integrations.codex.openService": "서비스 제어 열기", @@ -896,6 +897,7 @@ export const ko: Record = { "integrations.detail.desktopNotServed": "프로필은 있지만 Desktop이 다른 것을 씁니다", "integrations.detail.desktopAbsent": "적용된 프로필이 없습니다", "integrations.detail.desktopDesiredOff": "Claude Desktop 통합이 꺼져 있습니다", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop이 여전히 게이트웨이를 사용 중입니다. 정리 대기 중", "integrations.detail.desktopDesiredOnNotApplied": "통합은 켜져 있지만 Desktop이 게이트웨이 프로필을 사용하지 않습니다", "integrations.detail.desktopSelectedElsewhere": "Desktop이 다른 프로필을 사용 중입니다", "integrations.detail.desktopProfileDrift": "선택된 Desktop 프로필이 변경되었습니다", @@ -992,6 +994,7 @@ export const ko: Record = { "integrations.semantics.dsh": "OpenCodex는 $DSH_HOME/settings.yaml의 llm-pi-ai.providers.opencodex만 관리합니다. DSH는 이 provider를 hot reload하며 기본 model과 deepseek-official은 변경하지 않습니다. 현재 loopback 전용이며 실제 credential을 기록하지 않습니다.", "integrations.semantics.mcode": "custom_provider.opencodex만 관리하며 기본 모델과 MiniMax 로그인은 변경하지 않습니다.", "integrations.semantics.zcode": "~/.zcode/v2/config.json의 provider.opencodex만 관리하며 Z.ai 로그인과 다른 프로바이더는 변경하지 않습니다. 변경 후 ZCode를 재시작하세요.", + "integrations.semantics.prime": "Prime Agent의 models.json에서 providers.opencodex만 관리합니다. 위치는 ~/.prime/agent이며 PRIME_AGENT_CODING_AGENT_DIR가 설정되면 그쪽이 우선합니다. 다른 프로바이더와 모델 오버라이드는 변경하지 않습니다. 새 세션부터 적용됩니다.", "codexAuth.mainAccount": "메인 계정", "codexAuth.logLabel": "로그 라벨", "codexAuth.codexApp": "Codex App", @@ -1279,6 +1282,7 @@ export const ko: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "설정 복사", "api.clientConfig.download": "다운로드", "api.clientConfig.loading": "클라이언트 설정 생성 중…", @@ -1718,6 +1722,9 @@ export const ko: Record = { "pws.allowPrivateNetwork": "로컬/사설 네트워크 허용", "pws.liveModels": "프로바이더에서 모델 검색", "pws.liveModelsDesc": "프로바이더의 실시간 모델 카탈로그를 가져옵니다. 끄면 설정된 정적 모델만 사용합니다.", + "pws.xaiResponsesOptIn": "Grok 4.5와 4.6에 Responses API 사용", + "pws.xaiResponsesOptInDesc": "두 모델을 openai-responses로 라우팅합니다. 다른 Grok 모델과 티어 동작은 바뀌지 않습니다.", + "pws.xaiResponsesOptInMixed": "일부만 활성화됨.", "pws.cursorTransport": "Cursor 전송", "pws.cursorTransportHttp2": "HTTP/2 (기본값)", "pws.cursorTransportHttp1": "HTTP/1.1 (프록시 호환)", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index f41af16d00..396ccf3ed0 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -1177,6 +1177,9 @@ export const ru: Record = { "pws.allowPrivateNetwork": "Разрешить локальную/частную сеть", "pws.liveModels": "Обнаруживать модели провайдера", "pws.liveModelsDesc": "Загружать актуальный каталог моделей провайдера. Выключите, чтобы использовать только настроенные статические модели.", + "pws.xaiResponsesOptIn": "Использовать Responses API для Grok 4.5 и 4.6", + "pws.xaiResponsesOptInDesc": "Направляет обе модели через openai-responses. Другие модели Grok и поведение tier не меняются.", + "pws.xaiResponsesOptInMixed": "Включено частично.", "pws.cursorTransport": "Транспорт Cursor", "pws.cursorTransportHttp2": "HTTP/2 (по умолчанию)", "pws.cursorTransportHttp1": "HTTP/1.1 (совместимость с прокси)", @@ -1328,6 +1331,7 @@ export const ru: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Подключением Codex управляет прокси-сервис. При запуске opencodex оно применяется, а при остановке сервиса восстанавливается нативная маршрутизация.", "integrations.codex.openService": "Открыть управление сервисом", @@ -1345,6 +1349,7 @@ export const ru: Record = { "integrations.detail.desktopNotServed": "Профиль есть, но Desktop использует другой", "integrations.detail.desktopAbsent": "Профиль не применён", "integrations.detail.desktopDesiredOff": "Интеграция Claude Desktop отключена", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop всё ещё использует шлюз; очистка не завершена", "integrations.detail.desktopDesiredOnNotApplied": "Интеграция включена, но Desktop не использует профиль шлюза", "integrations.detail.desktopSelectedElsewhere": "Desktop использует другой профиль", "integrations.detail.desktopProfileDrift": "Выбранный профиль Desktop был изменён", @@ -1441,6 +1446,7 @@ export const ru: Record = { "integrations.semantics.dsh": "OpenCodex управляет только llm-pi-ai.providers.opencodex в $DSH_HOME/settings.yaml. DSH применяет этот провайдер горячей перезагрузкой; модель по умолчанию и deepseek-official остаются без изменений. Сейчас поддерживается только loopback; реальные учётные данные не записываются.", "integrations.semantics.mcode": "Управляет только custom_provider.opencodex. Модель по умолчанию и вход MiniMax не меняются.", "integrations.semantics.zcode": "Управляет только provider.opencodex в ~/.zcode/v2/config.json. Вход Z.ai и другие провайдеры не меняются. Перезапустите ZCode после изменений.", + "integrations.semantics.prime": "Управляет только providers.opencodex в models.json Prime Agent — ~/.prime/agent, если PRIME_AGENT_CODING_AGENT_DIR не переопределяет путь. Другие провайдеры и переопределения моделей не меняются. Применяется к новым сессиям.", "codexAuth.mainAccount": "Основной аккаунт", "codexAuth.logLabel": "Метка журнала", "codexAuth.codexApp": "Codex App", @@ -1730,6 +1736,7 @@ export const ru: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "Копировать конфигурацию", "api.clientConfig.download": "Скачать", "api.clientConfig.loading": "Формируется конфигурация клиента…", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index 101dc684c4..f460bbeb36 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -1184,6 +1184,9 @@ export const tr: Record = { "pws.allowPrivateNetwork": "Yerel/özel ağa izin ver", "pws.liveModels": "Sağlayıcıdan canlı model keşfet", "pws.liveModelsDesc": "Sağlayıcının canlı model kataloğunu çekin.", + "pws.xaiResponsesOptIn": "Grok 4.5 ve 4.6 için Responses API kullan", + "pws.xaiResponsesOptInDesc": "İki modeli de openai-responses üzerinden yönlendirir. Diğer Grok modelleri ve katman davranışı değişmez.", + "pws.xaiResponsesOptInMixed": "Kısmen etkin.", "pws.cursorTransport": "Cursor aktarımı", "pws.cursorTransportHttp2": "HTTP/2 (varsayılan)", "pws.cursorTransportHttp1": "HTTP/1.1 (proxy uyumluluğu)", @@ -1335,6 +1338,7 @@ export const tr: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex bağlantısı proxy servisine aittir.", "integrations.codex.openService": "Servis kontrollerini aç", @@ -1352,6 +1356,7 @@ export const tr: Record = { "integrations.detail.desktopNotServed": "Profil mevcut ancak Desktop başkasını kullanıyor", "integrations.detail.desktopAbsent": "Uygulanan profil yok", "integrations.detail.desktopDesiredOff": "Claude Desktop entegrasyonu kapalı", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop hâlâ ağ geçidini kullanıyor; temizlik bekleniyor", "integrations.detail.desktopDesiredOnNotApplied": "Entegrasyon açık ancak Desktop kullanmıyor", "integrations.detail.desktopSelectedElsewhere": "Desktop başka bir profil kullanıyor", "integrations.detail.desktopProfileDrift": "Seçilen Desktop profili değişti", @@ -1447,6 +1452,7 @@ export const tr: Record = { "integrations.semantics.dsh": "OpenCodex yalnızca $DSH_HOME/settings.yaml içindeki llm-pi-ai.providers.opencodex bölümünü yönetir. DSH bu sağlayıcıyı çalışırken yeniden yükler; varsayılan modeliniz ve deepseek-official değişmez. Şimdilik yalnızca geri döngü desteklenir; gerçek kimlik bilgisi yazılmaz.", "integrations.semantics.mcode": "Yalnızca custom_provider.opencodex bölümünü yönetir. Varsayılan model ve MiniMax oturumu değişmez.", "integrations.semantics.zcode": "Yalnızca ~/.zcode/v2/config.json içindeki provider.opencodex bölümünü yönetir. Z.ai oturumu ve diğer sağlayıcılar değişmez. Değişikliklerden sonra ZCode'u yeniden başlatın.", + "integrations.semantics.prime": "Yalnızca Prime Agent'ın models.json dosyasındaki providers.opencodex bölümünü yönetir — PRIME_AGENT_CODING_AGENT_DIR ayarlı değilse ~/.prime/agent. Diğer sağlayıcılar ve model geçersiz kılmaları değişmez. Yeni oturumlarda geçerli olur.", "integrations.semantics.omp": "Kataloğu yüklemek için OMP'yi yeniden başlatın.", "codexAuth.mainAccount": "Ana Hesap", "codexAuth.logLabel": "Günlük etiketi", @@ -1737,6 +1743,7 @@ export const tr: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "JSON Kopyala", "api.clientConfig.download": "İndir", "api.clientConfig.loading": "İstemci konfigürasyonu oluşturuluyor…", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index 89b891d603..942e21e61f 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -972,6 +972,9 @@ export const zhTW: Record = { "pws.allowPrivateNetwork": "允許本地/私有網路", "pws.liveModels": "從供應商發現模型", "pws.liveModelsDesc": "取得供應商的即時模型目錄。關閉後僅使用已配置的靜態模型。", + "pws.xaiResponsesOptIn": "讓 Grok 4.5 與 4.6 使用 Responses API", + "pws.xaiResponsesOptInDesc": "透過 openai-responses 路由這兩個模型。其他 Grok 模型與層級行為不變。", + "pws.xaiResponsesOptInMixed": "已部分啟用。", "pws.cursorTransport": "Cursor 傳輸協定", "pws.cursorTransportHttp2": "HTTP/2(預設)", "pws.cursorTransportHttp1": "HTTP/1.1(代理相容)", @@ -1853,6 +1856,7 @@ export const zhTW: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex 連線由代理服務管理。啟動 opencodex 時套用;停止服務時還原原生路由。", "integrations.codex.openService": "開啟服務控制", @@ -1870,6 +1874,7 @@ export const zhTW: Record = { "integrations.detail.desktopNotServed": "設定檔存在,但 Desktop 使用的是另一個", "integrations.detail.desktopAbsent": "未套用任何設定檔", "integrations.detail.desktopDesiredOff": "Claude Desktop 整合已關閉", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop 仍在使用閘道,清理尚未完成", "integrations.detail.desktopDesiredOnNotApplied": "整合已開啟,但 Desktop 未使用閘道設定檔", "integrations.detail.desktopSelectedElsewhere": "Desktop 正在使用其他設定檔", "integrations.detail.desktopProfileDrift": "選取的 Desktop 設定檔已變更", @@ -1966,6 +1971,7 @@ export const zhTW: Record = { "integrations.semantics.dsh": "OpenCodex 只管理 $DSH_HOME/settings.yaml 中的 llm-pi-ai.providers.opencodex。DSH 會熱重載該 provider;你的預設模型與 deepseek-official 維持不變。目前僅支援 loopback,且不會寫入真實憑證。", "integrations.semantics.mcode": "僅管理 custom_provider.opencodex,不會變更預設模型或 MiniMax 登入狀態。", "integrations.semantics.zcode": "僅管理 ~/.zcode/v2/config.json 中的 provider.opencodex,不會變更 Z.ai 登入狀態或其他供應商。變更後請重新啟動 ZCode。", + "integrations.semantics.prime": "僅管理 Prime Agent 的 models.json 中的 providers.opencodex;預設位於 ~/.prime/agent,若設定 PRIME_AGENT_CODING_AGENT_DIR 則以其為準。不會變更其他供應商或模型覆寫設定。對新工作階段生效。", "codexAuth.pinned": "已固定", "codexAuth.pinnedHint": "你手動選取了此帳號,因此較高的選擇順序不會越過它。此固定會持續到該帳號用盡、你改選其他帳號,或你變更任一選擇順序為止。", "codexAuth.requestUserInput": "在 Default 模式中要求輸入", @@ -2005,6 +2011,7 @@ export const zhTW: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "cws.tabsLabel": "Combo 詳細區段", "cws.field.nativeAlias": "原生 OpenAI 別名", "cws.field.nativeAliasHint": "讓此 combo 擁有受支援的未限定原生 OpenAI 模型 ID。帶有帳號或供應商限定的 OpenAI 路由仍保持獨立。", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index c5d588efa0..b9cd4a3573 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -872,6 +872,7 @@ export const zh: Record = { "integrations.tab.dsh": "DeepSeek Harness (DSH)", "integrations.tab.mcode": "MiniMax Code", "integrations.tab.zcode": "ZCode", + "integrations.tab.prime": "Prime Agent", "integrations.codex.title": "Codex CLI", "integrations.codex.body": "Codex 连接由代理服务管理。启动 opencodex 时应用该连接;停止服务时恢复原生路由。", "integrations.codex.openService": "打开服务控制", @@ -889,6 +890,7 @@ export const zh: Record = { "integrations.detail.desktopNotServed": "配置存在,但 Desktop 使用的是另一个", "integrations.detail.desktopAbsent": "未应用任何配置", "integrations.detail.desktopDesiredOff": "Claude Desktop 集成已关闭", + "integrations.detail.desktopDesiredOffCleanupPending": "Claude Desktop 仍在使用网关,清理尚未完成", "integrations.detail.desktopDesiredOnNotApplied": "集成已开启,但 Desktop 未使用网关配置", "integrations.detail.desktopSelectedElsewhere": "Desktop 正在使用其他配置", "integrations.detail.desktopProfileDrift": "选中的 Desktop 配置已更改", @@ -985,6 +987,7 @@ export const zh: Record = { "integrations.semantics.dsh": "OpenCodex 只管理 $DSH_HOME/settings.yaml 中的 llm-pi-ai.providers.opencodex。DSH 会热重载该 provider;你的默认模型和 deepseek-official 保持不变。目前仅支持环回地址,且不会写入真实凭据。", "integrations.semantics.mcode": "仅管理 custom_provider.opencodex,不会更改默认模型或 MiniMax 登录状态。", "integrations.semantics.zcode": "仅管理 ~/.zcode/v2/config.json 中的 provider.opencodex,不会更改 Z.ai 登录状态或其他提供商。更改后请重启 ZCode。", + "integrations.semantics.prime": "仅管理 Prime Agent 的 models.json 中的 providers.opencodex;默认位于 ~/.prime/agent,若设置 PRIME_AGENT_CODING_AGENT_DIR 则以其为准。不会更改其他提供商或模型覆盖设置。对新会话生效。", "codexAuth.mainAccount": "主账号", "codexAuth.logLabel": "日志标签", "codexAuth.codexApp": "Codex App", @@ -1272,6 +1275,7 @@ export const zh: Record = { "api.clientConfig.clientDsh": "DeepSeek Harness (DSH)", "api.clientConfig.clientMcode": "MiniMax Code", "api.clientConfig.clientZcode": "ZCode", + "api.clientConfig.clientPrime": "Prime Agent", "api.clientConfig.copy": "复制配置", "api.clientConfig.download": "下载", "api.clientConfig.loading": "正在生成客户端配置…", @@ -1711,6 +1715,9 @@ export const zh: Record = { "pws.allowPrivateNetwork": "允许本地/私有网络", "pws.liveModels": "从提供方发现模型", "pws.liveModelsDesc": "获取提供方的实时模型目录。关闭后仅使用已配置的静态模型。", + "pws.xaiResponsesOptIn": "为 Grok 4.5 和 4.6 使用 Responses API", + "pws.xaiResponsesOptInDesc": "通过 openai-responses 路由这两个模型。其他 Grok 模型和层级行为不变。", + "pws.xaiResponsesOptInMixed": "已部分启用。", "pws.cursorTransport": "Cursor 传输协议", "pws.cursorTransportHttp2": "HTTP/2(默认)", "pws.cursorTransportHttp1": "HTTP/1.1(代理兼容)", diff --git a/gui/src/pages/Integrations.tsx b/gui/src/pages/Integrations.tsx index 2505589b2a..70018037b9 100644 --- a/gui/src/pages/Integrations.tsx +++ b/gui/src/pages/Integrations.tsx @@ -39,6 +39,7 @@ const TABS: readonly TabDefinition[] = [ { id: "dsh", hash: "integrations/dsh", labelKey: "integrations.tab.dsh" }, { id: "mcode", hash: "integrations/mcode", labelKey: "integrations.tab.mcode" }, { id: "zcode", hash: "integrations/zcode", labelKey: "integrations.tab.zcode" }, + { id: "prime", hash: "integrations/prime", labelKey: "integrations.tab.prime" }, ] as const; const FILE_CLIENTS = new Set([ @@ -52,6 +53,7 @@ const FILE_CLIENTS = new Set([ "dsh", "mcode", "zcode", + "prime", ]); function readIntegrationTab(hash = window.location.hash): IntegrationTab { diff --git a/gui/src/pages/dashboard-overview-sections.tsx b/gui/src/pages/dashboard-overview-sections.tsx index 7834743d0b..6b944ed5eb 100644 --- a/gui/src/pages/dashboard-overview-sections.tsx +++ b/gui/src/pages/dashboard-overview-sections.tsx @@ -15,7 +15,7 @@ import { requireJson, type SidecarPatch, shadowCallModelOptions, - sidecarBackendForModel, + webSearchSidecarSelectionForModel, updateJobLabel, visionEnabledPatch, visionMaxDescriptionsPatch, @@ -515,7 +515,9 @@ export function DashboardSidecarPanels({ d }: { d: Dash }) {