diff --git a/.agents/skills/testing-opencodex-management-api/SKILL.md b/.agents/skills/testing-opencodex-management-api/SKILL.md new file mode 100644 index 00000000000..60f5453a2b6 --- /dev/null +++ b/.agents/skills/testing-opencodex-management-api/SKILL.md @@ -0,0 +1,120 @@ +--- +name: testing-opencodex-management-api +description: Exercise the OpenCodex management API in a disposable, isolated development environment without touching personal client state. +--- + +# Testing the OpenCodex management API + +## Isolation is a prerequisite + +Use a disposable OS account, container, or VM with a disposable OS home. Do not run this +recipe in your normal desktop account merely by changing `OPENCODEX_HOME`. +That variable relocates OpenCodex state, not every client or shell integration. +On macOS, even disabling `claudeCode.systemEnv` can remove an existing managed block +from the OS home's `.zshrc`; `CLAUDE_CONFIG_DIR` does not redirect that file. +Raycast integration can also update existing OpenCodex-owned entries under the OS home. +A temporary client directory alone is therefore not a complete isolation boundary. + +Within the disposable environment, allocate a unique scratch directory and set `HOME` +to a fresh directory inside it before startup. A `HOME` override in a normal desktop +account is not a substitute for the disposable account, container, or VM. Set all of +`OPENCODEX_HOME`, `CODEX_HOME`, `CODEX_SQLITE_HOME`, `GROK_HOME`, `CLAUDE_CONFIG_DIR`, and +`OPENCODEX_CLAUDE_DESKTOP_CONFIG_DIR` to distinct directories inside it before startup. +Confirm the effective OS home belongs to the disposable account. Do not copy personal +tokens, client configuration, shell profiles, or keychain contents into this environment. +Start from a clean environment or inspect inherited path overrides before launching. +Codex SQLite state resolves in this order: a root `sqlite_home` key in +`CODEX_HOME/config.toml`, then `CODEX_SQLITE_HOME`, then `CODEX_HOME` itself. Keep the +scratch `CODEX_HOME/config.toml` free of an outside `sqlite_home`, resolve the effective +SQLite home with that precedence, and abort unless it is inside the scratch directory. + +Save a scratch `config.json` under `OPENCODEX_HOME` with an unused loopback port: + +```json +{ + "port": 19100, + "hostname": "127.0.0.1", + "codexAutoStart": false, + "syncResumeHistory": false, + "clientIntegrations": {"codex": false, "grok": false, "claude-desktop": false}, + "claudeCode": {"enabled": false, "injectAgents": false, "systemEnv": false} +} +``` + +Use both redirected client homes and integration disables. Disabled integrations may +still remove owned artifacts. `codexAutoStart` alone does not disable startup sync: +desired-state checks also consider integration settings and the hub/loopback-listener +role. Do not depend on any one flag as an isolation boundary. + +## Start and authenticate + +Install the repository's locked development dependencies and use the Bun version named +by `package.json`. Check that the selected Bun executable is available in this shell; +do not assume a particular developer's PATH layout. Start one foreground instance: + +```sh +bun run src/cli/index.ts start --port 19100 +``` + +Avoid `ensure`, tray, and service installation paths for this exercise: they can spawn +detached processes or alter persistent service state. Do not enable live providers or +submit billable traffic unless that separate test is explicitly authorized. + +Prefer reading the scratch instance's generated `admin-api-token` locally. Alternatively, +provision a randomly generated `OPENCODEX_ADMIN_AUTH_TOKEN` used only for this test. +It must differ from every data-plane API key; a collision makes management authentication +unavailable. Never paste the token into a PR, screenshot, log, or tracked fixture. + +Management requests accept `x-opencodex-api-key: ` or +`Authorization: Bearer `. Missing authorization is refused. A valid token +does not bypass route-specific origin, session, or policy requirements. Keep requests +loopback-only and do not follow redirects with credentials. + +## Focused Lab automation exercise + +Read `GET /api/lab/automation` for policy and live scheduler state; inspect recorded runs +with `GET /api/lab/automation/runs`. Enabling automation is an explicit state change, +not a requirement for a basic management-authentication test. + +A policy write uses `PUT /api/lab/automation`, for example: + +```json +{"policy":{"enabled":true,"layers":{"protocolConformance":true}}} +``` + +Serialize policy writes. The read/merge and save do not share one lock, so concurrent +writers can overwrite each other's changes even though publication itself is atomic. +Re-read the policy after changing it. + +A fixture-only manual run uses `POST /api/lab/automation/run` with this request body: + +```json +{"evidenceLayer":"protocol_conformance","scenarioId":"responses-core.protocol.request-shape"} +``` + +For `live_route_compatibility`, include `providerName` and `modelId` in the POST request +body, not as substitute top-level configuration fields. The named provider must already +exist in `config.providers`, and live calls require authorization and suitable test +credentials. Lab must also be active at proxy startup: a later policy PUT alone does +not register the live route executor. Enable automation in the disposable home, stop +the foreground proxy, and start it again before a separately authorized live run. +The fixture-only protocol exercise above does not need this restart. Consult +`planManualLabRun` in `src/lab/automation/planner.ts` for accepted +combinations instead of guessing a scenario or provider. + +The manual endpoint awaits dispatch and returns a run/trigger result. Inspect the returned +status rather than assuming success or a terminal run. Scheduler work is separate and +may not appear immediately; read the configured scheduler limits instead of sleeping for +a hard-coded interval. + +## Stop and inspect + +Send one interrupt to the foreground process and let its bounded cleanup/drain finish. +A clean shutdown exits with zero; cleanup or drain failures may exit nonzero. A second +signal requests forced termination and is not proof of successful cleanup. +Check that the test listener and any test-owned children have stopped before removing +the exact scratch tree. Do not clean directories based on a name pattern or age. +Capture only redacted status, exit code, exact test commands, and observed results. + +This is a development testing recipe. It does not replace the operating reference in +`skills/ocx/` or the consent rules in `AGENTS_INSTALL.md`. diff --git a/AGENTS.md b/AGENTS.md index 64c6c3106fc..c91d1491740 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,8 +14,9 @@ Bun-native TypeScript with no separate server compile step. - `src/` — proxy runtime: routing, provider adapters, config, management API. - `tests/` — Bun tests in domain directories that mirror `src/` (`tests//*.test.ts`; `providers/` and `adapters/` have one more - level for the larger vendors). The map is `scripts/test-layout/layout.json` - and `tests/test-layout.test.ts` enforces it: every file resolves to a + level for the larger vendors). The explicit map is + `scripts/test-layout/layout.json`, with regex seeds and migration state in + `scripts/test-layout/seeds.json`; `tests/test-layout.test.ts` enforces that every file resolves to a domain and sits in it, and only the two layout guards live at the root. Shared helpers in `tests/helpers/`, fixtures in `tests/fixtures/`, broader scenarios in `tests/e2e-style/`. Source-oracle tests resolve the repository @@ -24,7 +25,7 @@ Bun-native TypeScript with no separate server compile step. test file lands in its domain directory and needs an entry in both `layout.json` `explicit` and `tests/fixtures/test-layout-expected.json` (`tests/test-layout-tooling.test.ts` names the missing one); the regex - seeds in `layout.json` place a conventionally named file until then. + seeds in `seeds.json` place a conventionally named file until then. History: `devlog/_fin/260905_test_modularization_and_windows/`. - `gui/` — React + Vite dashboard; packaged output is served from `gui/dist`. - `app/` — native macOS WidgetKit extension bundled into the Tauri desktop app; @@ -213,6 +214,9 @@ bun run skill:surface # regenerate after adding a capability bun run skill:surface:check # what CI asserts ``` +For development tests of the management API, use the isolated +[management API test recipe](./.agents/skills/testing-opencodex-management-api/SKILL.md). + `tests/ci-workflows/skill-ocx.test.ts` fails if the committed map drifts from `src/cli/capabilities.ts`, and also if the hand-written pages name a command the registry does not have. That second check is not hypothetical: it caught a documented `ocx request-history` that never existed. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/000_plan.md b/devlog/_plan/260927_release_train_4/clients-proxy/000_plan.md new file mode 100644 index 00000000000..773ba393739 --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/000_plan.md @@ -0,0 +1,123 @@ +# Release train 4: clients and proxy lane + +At `origin/dev` `24b2f39b77` on 2026-09-27, this lane has a mix of useful client +integrations, routing changes, and proposals whose current diffs are not safe to +land. Carry the bounded changes through ordinary PRs to `dev`, correct the observed +regressions, and leave concrete reasons on proposals that need a new contract. + +## Loop specification + +- Archetype: satisfy the release-train acceptance contract, one dependency-ordered + work phase per PABCD cycle. +- Trigger: the release train 4 `clients-proxy` lane assignment. +- Goal: land verified client/proxy changes that help the next release and record a + disposition for every assigned PR and issue. +- Non-goals: `main`, `preview`, releases, version changes, other lanes, writes to + contributor forks, automatic third-party installer execution, and eager client + activation on the three core request paths. +- Verifier: the focused commands in the decade docs, `bun run test:changed`, + `bun run typecheck`, `bun run structure:check`, `bun run privacy:scan`, + `bun run skill:surface:check` when CLI capabilities change, exact-head PR CI, + and a successful post-merge `dev` CI run. Conditional branches have explicit + activation cases in their phase documents. +- Stop condition: every row below has a supported merge or hold decision, each + landed PR passed its actual required jobs, source PRs/issues received the + appropriate links and disposition, and the final `dev` run succeeded. +- Memory artifact: this numbered unit, its phase evidence, and the lane's + session-bound goalplan/ledger. +- Terminal outcomes: DONE means that stop condition holds; NOOP means no + candidate survived review; NEEDS_HUMAN means an external contract or approval + blocks a specific candidate; BLOCKED means repeated external failure prevents + all meaningful progress; UNSAFE means validation found an unresolved release + blocker. There is no user-specified token or wall-clock bound. +- Escalation: a new scope, an unresolvable security boundary, or a required + external account decision goes to the coordinator. PR push/merge and issue/PR + disposition within this lane are already authorized. + +All source edits, Git operations, and tests use this lane's dedicated +worktree checkout. The native +session directory is used only for ignored FSM and goalplan state. Local full +suite may be omitted due to seven concurrent lane worktrees; focused regressions +remain mandatory, and each PR's Verification section will state the exact +commands, results, and coverage left to CI. + +## Source ownership and selection + +`structure/clients/integrations.md:27-55` assigns pure client builders to +`src/clients/config-export.ts`, detection paths to +`src/integrations/registry.ts`, and snapshot/classification/writes to the shared +integration modules. New clients stay explicit and use those seams. The three +core request files (`src/router.ts`, `src/server/lifecycle.ts`, +`src/server/responses/core.ts`) must retain the Lab import boundary enforced by +`tests/lab/core-lab-boundary.test.ts`. `src/config/proxy-env.ts` owns process +proxy activation (`structure/config-proxy.md:1-20`). + +| Item | Current head/state | Decision and evidence | Work phase | +| --- | --- | --- | --- | +| #6051 | `987b8097`, open | Carry the disposable-home management-API recipe with a discoverable contributor link; `.agents/skills/` has no existing entry point. | [010](010_recipe.md) | +| #5893 / #5853 | `3743320a`, draft | Carry only when every macOS exception maps faithfully onto the bypass variables the active transports read, or discovery refuses before any environment write; an inherited SOCKS proxy keeps its existing path. | [020](020_macos_proxy.md) | +| #5950 / #5660 | `ef03f5ab`, open | HOLD Qoder: opt-in config writes, restore, and path handling still need current-base revalidation (`src/clients/config-export/qoder.ts`, PR test). | [030](030_qoder.md) | +| #5272 | `7dd796d7`, open | Carry Kilo after checking all merged config candidates; first-file-only selection can be overridden by a later legacy file (`src/clients/config-export/kilo.ts:57-63` in PR). | [040](040_kilo.md) | +| #5193 | `91090f80`, open/conflicting | Reimplement a focused Droid slice on current `dev` only if its client contract and export provenance can be proven. The PR's broad rewrite changes shared loopback export behavior. | [050](050_droid.md) | +| #5871 | `ba2d2600`, open/conflicting | Carry after conflict repair and an outbound decision-payload regression (`src/combos/jev.ts:588-595` in PR). | [060](060_jev.md) | +| #5983 / #5982 | `cd45810f`, open | Carry with explicit non-memory metadata taking precedence over the subagent header fallback (`src/server/responses/memory-models.ts:65` in PR). | [070](070_memory.md) | +| #5905 / #5679 | `19948a38`, draft | Hold: opening regular Cursor integration status can automatically fetch an external installer manifest. Decide explicit opt-in and cover timeout/status before carry. | [080](080_held_items.md) | +| #3833 | `d47e376b`, draft | Hold: Command Code rejects the exported literal `apiKey` placeholder; the PR test only checks presence. Needs supported client credential form and live client proof. | [080](080_held_items.md) | +| #4854 | open | Hold OpenScience until its actual config schema and ownership paths are established. Manual OpenAI-compatible endpoint is available. | [080](080_held_items.md) | +| #3494 | open | Hold VS Code extension integration until one named extension's supported settings and reload lifecycle are verified. | [080](080_held_items.md) | +| #1416 | open | Hold Orca launch manifest until the stopped-proxy, secret-free consumer contract is pinned; live-catalog config export is the wrong bootstrap path. | [080](080_held_items.md) | +| #2811 | open | Design only: #5016 was closed because `plan` required `managed: true` that the production inspector never reports. A reachable provenance proof precedes apply. | [080](080_held_items.md) | + +## Dependency order and merge method + +`010` establishes the verification recipe, `020` owns outbound proxy activation, +`030` proves the existing client path on current `dev`, and `040`/`050` reuse that +verified roster with one client at a time. `060` precedes `070` because both touch +`src/types/config.ts`; that is a merge-conflict dependency, not a runtime one. +`080` records held items after each applicable outcome. [090](090_final_ci.md) +checks the latest integrated tree. Each carried source PR becomes a new ordinary +`dev` PR from this lane, with a `Co-authored-by` trailer in the PR description +or branch commit. Git authorship alone does not satisfy the carry policy. A +large or conflicted source diff is reduced before +landing; the source PR is thanked, linked, and closed only once its replacement +is merged. No GitHub native stack or tip-only CI exception is selected. + +For every batch, fetch `origin/dev` again, inspect the source PR's current head +and diff, check the file-size ratchet and merged union/locale/count consumers, +run focused tests and typecheck, perform explicit security review for any +credential, proxy, installer, or authentication boundary, then inspect +required CI at the exact new PR +head before merging. GUI changes need a screenshot in the PR description from +the separate `pr-assets` branch, never committed to the PR branch. Merge only +when the new PR head contains the latest `origin/dev`; dispatch `ci.yml` on +`dev` manually as specified in [090](090_final_ci.md) and inspect its exact +head before the next batch. + +## Consultation and uncertainty + +The architect proposal: D1 existing +integration ownership and D2 proxy ownership accepted; D3 Cursor discovery +amended to hold pending opt-in; D4 managed clients accepted with #3833 held; +D5 new client proposals held pending primary client contracts; D6 JEV then +memory accepted; D7 Codex updater remains design-only. Four independent source +PR reviewers examined the candidates. The architect's first reflection +found three gaps: attribution trailer, explicit security review, and the +recipe's OS-home isolation condition. All three were folded into this revision +before independent audit. Their findings are proposals; each carry is +rechecked on the actual integrated diff and current `dev`. + +Baseline verifier preflight on `24b2f39b77`: `bun run typecheck`, +`bun run structure:check`, `bun run privacy:scan`, +`bun run skill:surface:check`, and `bun test +tests/lab/core-lab-boundary.test.ts` each exited 0; the Lab guard ran 25 +tests. These check the baseline and this planning tree only. New PR behavior +still requires the phase-specific commands after the relevant diff is present. +`bun run test:changed` on this docs-only staged diff selected zero tests and +exited 1; it is not evidence of test passage. Docs checks and semantic audit +cover the roadmap, and implementation batches rerun changed tests. + +The same architect rechecked the D2 safety amendment and returned ALIGNED. +The independent A reviewer first +reported six blockers, then one remaining test-layout blocker; every finding +was folded into the relevant decade document and its final verdict was PASS. +This closes the roadmap design review, not any proposed code change. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/010_recipe.md b/devlog/_plan/260927_release_train_4/clients-proxy/010_recipe.md new file mode 100644 index 00000000000..4af0bdb796b --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/010_recipe.md @@ -0,0 +1,95 @@ +# Phase 1: management API test recipe (#6051) + +The preceding D concluded that the reviewed roadmap is locked at `ce5a406862`; +the next action is this bounded recipe carry. Depends on `000_plan.md`; +docs-only carry, then one ordinary PR. The source PR +adds `.agents/skills/testing-opencodex-management-api/SKILL.md` with a +disposable-home setup and correct Lab requests. It needs a repository entry +point before another agent can reliably discover it. + +## Exact change map + +- NEW `.agents/skills/testing-opencodex-management-api/SKILL.md`: carry the + 108-line source recipe from #6051 head `987b8097624e50e6c39b00aca145fe4755043c4b` + with source-verified isolation and activation corrections after checking every command and path against current + management routes. Preserve its disposable OS account/home, container, or + VM prerequisite; redirect client homes and disable integrations before a + smoke. `OPENCODEX_HOME` alone does not isolate client writes. Keep explicit + token read, bounded process cleanup, and authorization before live-provider + requests. No secret values or real account identifiers enter examples. +- MODIFY `AGENTS.md` near the Commands and `skills/ocx/` guidance: add one + contributor-facing link to the test recipe. Before: only the runtime-control + `skills/ocx/` reference is discoverable (`AGENTS.md:207-209`). After: one + sentence identifies `.agents/skills/testing-opencodex-management-api/SKILL.md` + as the development test recipe, while `skills/ocx/` remains the operating + reference and `AGENTS_INSTALL.md` retains consent guidance. Do not change + runtime imports, CLI capabilities, or the generated operating-surface map. +- MODIFY `010_recipe.md` with a short outcome addendum after validation, + naming the carried source SHA, attribution, and exact command results. The + carry commit or PR body + must contain `Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>`. + +## Acceptance and proof + +Read the recipe's executable examples against +`src/server/management/lab-automation-routes.ts:119-180` and +`src/lab/automation/planner.ts:278-340`; POST fields are body fields and PUT +policy fields are supported there. `bun test +tests/lab/lab-automation-management-http.test.ts` ran at the base and passed +2 tests; it checks route cancel/pagination, not the prose or POST example. +Run a smoke only in a disposable OS account/home, +container, or VM with redirected client homes and integrations disabled; +the current desktop account does not meet this precondition, so record the +smoke as unrun. Confirm the carried file against the pinned PR head, its +frontmatter and link target. Stage every changed and new file before running +`git diff --cached --check` and `bun run privacy:scan`; the scan uses +`git ls-files`, so an untracked skill would be invisible. After commit run +`git diff origin/dev...HEAD --check`. Also run `bun run structure:check` and +`bun run typecheck`. These commands protect +the tree and paths; semantic correctness of the recipe needs source review. +`bun run test:changed` can select zero tests for a docs-only diff and is then +not passing evidence. A docs-only CI skip is recorded as skipped, not +as a passing suite. PR template Summary/Verification/Checklist, source author +credit, exact-head required checks, and post-merge `dev` CI still apply. + +The architect proposed D1-R (carry the +isolation and route examples), D1-L (one AGENTS discovery link), and D1-V +(attribution and exact gates). All three are accepted. Putting the recipe in +`skills/ocx/` would confuse development tests with operating guidance; a +PR-only link would not be durable. + +## Local carry outcome + +Imported the recipe from #6051 head +`987b8097624e50e6c39b00aca145fe4755043c4b`; the initial `cmp` +against that Git object exited 0 at 108 lines. C-phase implementation review +then required two source-grounded corrections to the final copy: redirecting +Codex's SQLite home and disabling resume-history sync in the disposable +configuration, and activating Lab at startup before a separately authorized +live-route run. The isolation instructions also require `HOME` to point into +the disposable scratch root. The final recipe therefore intentionally differs from the +source PR. `AGENTS.md:212` links it beside +the operating reference. The same independent A reviewer first found that +an unstaged whitespace check would miss a staged change and the privacy scan +would miss an untracked skill; the plan now stages all files before both gates, +and the reviewer returned PASS. + +After staging, `git diff --cached --check`, `bun run privacy:scan`, +`bun run structure:check`, and `bun run typecheck` exited 0. `bun test +tests/lab/lab-automation-management-http.test.ts +tests/lab/lab-automation.test.ts` passed 24 tests with 0 failures. These tests +cover the route and planner baseline, not the prose; route and planner source +were read against the example fields. `bun run test:changed` exited 1 because +the docs-only diff selected 0 tests. The live smoke was not run in this +desktop account: it lacks the disposable OS-home prerequisite. Full local +suite is omitted due to concurrent lane worktrees; CI remains the broader +gate. PR-head and post-merge `dev` CI evidence are recorded after publication. + +After the C-phase corrections, the scratch `config.json` example parsed as +JSON with `syncResumeHistory: false`; `git diff --cached --check` and +`bun run privacy:scan` exited 0 on the staged revision. The independent +implementation reviewer rechecked the SQLite and Lab startup paths and +returned PASS. A separate token/isolation security reviewer also returned +PASS on the amended recipe. Neither reviewer ran the live smoke, and the +24-test route/planner run and typecheck predate only these documentation edits; +no runtime source changed between those checks and this revision. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/020_macos_proxy.md b/devlog/_plan/260927_release_train_4/clients-proxy/020_macos_proxy.md new file mode 100644 index 00000000000..79b2cce96df --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/020_macos_proxy.md @@ -0,0 +1,62 @@ +# Phase 2: macOS system proxy discovery (#5893) + +Depends on `010_recipe.md` for lane order. Carry the small proxy change after +rebasing its draft head onto current `dev`; do not change Windows discovery or +explicit proxy precedence. `structure/config-proxy.md:1-20` owns the contract. + +## Exact change map + +- NEW `src/config/macos-system-proxy.ts`: observe and parse macOS system + proxy settings only on Darwin; return no discovery for disabled, malformed, + or unavailable settings. No caller imports this module on every request. +- MODIFY `src/config/proxy-env.ts`: before, `proxy: "auto"` considers the + existing Windows path and merges loopback bypasses. After, Darwin discovery + is considered only for that explicit setting and when no inherited scheme + proxy wins. Translate macOS exceptions only when their matching semantics + are proven equivalent to Bun's `no_proxy` semantics. A bare name such as + `localhost` must not enter either effective proxy-bypass variable as a + suffix. If any system exception is not faithfully representable, refuse + macOS auto-discovery and leave process proxy variables unchanged with a + privacy-safe diagnostic. Preserve the address-only loopback bypass. Add + proven-safe entries to the bypass variable the selected HTTP(S) transport + actually reads. If inherited `ALL_PROXY`/`all_proxy` selects SOCKS, + macOS discovery must not add scheme proxies or discovered exceptions. + Preserve the inherited proxy path and assert both transports' + effective routes when the two bypass variables disagree. Redact + credential-bearing proxy URLs. +- MODIFY `tests/server/proxy-env.test.ts`: retain source tests and add a case + with lowercase `no_proxy` distinct from uppercase `NO_PROXY`; assert the + effective bypass after activation. Drive a request to `localhost` and + `app.localhost` (or the proxy matcher used by that request) and prove that + the exception does not widen direct egress. An unrepresentable exception + must refuse discovery before the normal `mergeNoProxyEntries` tail; assert + a full byte-identical snapshot of `HTTP_PROXY`, `HTTPS_PROXY`, lowercase + equivalents, `ALL_PROXY`, `all_proxy`, `NO_PROXY`, and `no_proxy`. Cover + safe wildcard/IP entries, malformed/disabled `scutil` output, explicit + environment precedence, `proxy` unset, inherited SOCKS `ALL_PROXY` with + conflicting uppercase/lowercase bypass lists, and unchanged Windows + behavior. Tests use + a mocked system command; they do not claim a real macOS Settings session. +- MODIFY `structure/config-proxy.md` and the English plus affected translated + `docs-site/src/content/docs/*/reference/configuration/server.md` pages to + state the actual opt-in/automatic precedence after code is verified. + +## Acceptance and proof + +Activation scenario: Darwin with `config.proxy: "auto"`, no inherited HTTP(S) +or SOCKS proxy (`ALL_PROXY`/`all_proxy` included), and valid system settings +sets the proxy and safely representable bypass list. Bypass precedence is +asserted per transport: Bun's native HTTP(S) fetch reads a non-empty lowercase +`no_proxy` before `NO_PROXY`, while `resolveProxyRoute` honors an explicitly +defined uppercase `NO_PROXY`, including an empty value. Tests keep route +assertions for both transports when the two variables disagree. +Negative scenarios: unset `config.proxy` never reads macOS system settings or applies +discovered routes, while the existing inherited-proxy loopback bypass remains; +inherited HTTP(S) or SOCKS proxy wins without mixed bypass semantics, +unrepresentable exceptions refuse before any environment write, disabled or +bad system settings leave egress unchanged, and Windows keeps its prior route. Run +`bun test tests/server/proxy-env.test.ts`, `bun run test:changed`, `bun run +typecheck`, `bun run structure:check`, and `bun run privacy:scan`. Build +`docs-site/` if docs change. `tests/lab/core-lab-boundary.test.ts` checks the +core import rule. Perform explicit security review of credential-bearing +proxy URL handling. Recheck exact-head CI and live `dev` CI before the next batch. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/030_qoder.md b/devlog/_plan/260927_release_train_4/clients-proxy/030_qoder.md new file mode 100644 index 00000000000..b80d8c1ba45 --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/030_qoder.md @@ -0,0 +1,46 @@ +# Phase 3: opt-in Qoder client (#5950) + +Depends on the preceding lane batch's `dev` result; Qoder reuses the existing +pure export, registry and journaled writer seams rather than adding request +path code. The source PR touches 36 files, including GUI and translations; +carry one coherent client slice and remove unrelated drift. + +## Exact change map + +- NEW `src/clients/config-export/qoder.ts`: build the documented provider + contribution and exact managed fragment paths. Loopback may use a + non-secret placeholder; remote bind must have a supported admission header + or refuse. +- MODIFY `src/clients/config-export/contracts.ts` and + `src/clients/config-export.ts`: before, Qoder is absent from the export ID + union/registry. After, `qoder` is a named opt-in export with a derived + roster count, not a hand-written total. +- MODIFY `src/integrations/registry.ts` and `mutation-plan.ts`: resolve a + Qoder-supported user path, validate file/directory safety, and use the + common status/preview/apply/disable/restore classifier. No automatic + detection write or core request-path import. +- MODIFY `src/cli/help.ts`, `src/cli/registry.ts`, the GUI integration lists, + routing, marks, API IDs, and affected locales to expose the same client ID. + Update `docs-site/src/content/docs/guides/integrations.md`, + `structure/clients/integrations.md`, and + `structure/dashboard-and-usage.md` in the same change. +- MODIFY/NEW tests under `tests/clients/`, `tests/config/`, `tests/gui/`, and + `gui/tests/` for exact generated shape, absent client, foreign keys, + symlink/unsafe path refusal, drift, snapshot-before-write, disable, and + byte-exact restore. Register new test names in both test-layout manifests. + +## Acceptance and proof + +Activation: an operator explicitly enables Qoder against a disposable config; +the generated provider is present and a later disable/restore recovers prior +bytes. A hostile or changed file refuses without overwrite. Windows path +tests use a Windows-shaped home/env and confirm no POSIX-only assumption. +Run `bun test tests/clients/qoder-client.test.ts +tests/clients/integrations-state.test.ts +tests/config/client-config-export-new-clients.test.ts`, relevant `gui/tests/`, +`bun run test:changed`, `bun run typecheck`, `bun run lint:gui`, +`bun run build:gui`, `bun run structure:check`, `bun run privacy:scan`, +and `bun run skill:surface:check` if the capability registry changes. +Perform explicit security review of admission and config serialization. Check +the file-size ratchet, test-layout manifests, locale union, screenshot, +exact-head required CI, and merged `dev` run. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/040_kilo.md b/devlog/_plan/260927_release_train_4/clients-proxy/040_kilo.md new file mode 100644 index 00000000000..06279c30c5e --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/040_kilo.md @@ -0,0 +1,43 @@ +# Phase 4: Kilo managed config (#5272) + +`030_qoder.md` remains held; this phase reconciles the shared export-client +union and GUI roster against current `dev`. The PR's 57-file slice includes a JSONC +writer extension; preserve unrelated parsed client state during apply and disable, +and restore original comment-bearing bytes from the snapshot on undo. + +## Exact change map + +- NEW `src/clients/config-export/kilo.ts`: generate the documented Kilo + provider block and resolve the active global config path. Before, no Kilo + export exists. After, a config is selected only when later legacy files + cannot override its managed `provider.opencodex` block. If two candidate + files can supply that block, status and apply refuse with a clear conflict; + no first-file-wins write that appears successful but is ineffective. +- MODIFY `src/clients/config-export.ts`, `contracts.ts`, + `src/integrations/registry.ts`, `target.ts`, `state.ts`, `writer.ts`, + `mutation-plan.ts`, `config-io.ts`, and `src/lib/jsonc.ts` only as required + for JSONC parsing and the common ownership contract. The parser must reject + non-roundtrippable syntax before mutation; the snapshot keeps original + comment-bearing bytes recoverable for undo. +- MODIFY the CLI export/help/registry entries, GUI integration registry and + affected locale keys, public integration documentation, and + `structure/clients/integrations.md` for the actual Kilo path. +- NEW/MODIFY `tests/clients/kilo-client.test.ts` and adjacent config/GUI + tests: add a two-file precedence conflict fixture with distinct provider + values, byte-exact restore of an initial comment-bearing file, unsafe path + refusal, and Windows-shaped home/path resolution. Register test files in + both test-layout manifests. + +## Acceptance and proof + +Activation: explicit apply to an unambiguous Kilo install writes only owned +fields; disabling preserves unrelated parsed values; restoring returns the original bytes. +Conflict activation: a later candidate file contains the same provider key; +status and mutation both refuse before snapshot/write. Run +`bun test tests/clients/kilo-client.test.ts +tests/config/client-config-export.test.ts`, the relevant `gui/tests`, +`bun run test:changed`, `bun run typecheck`, `bun run lint:gui`, +`bun run build:gui`, `bun run structure:check`, `bun run privacy:scan`, +and `bun run skill:surface:check` if capabilities change. Check screenshot, +merged file-size cap, union/locale counts, explicit credential/path security +review, exact-head CI, and post-merge `dev`. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/050_droid.md b/devlog/_plan/260927_release_train_4/clients-proxy/050_droid.md new file mode 100644 index 00000000000..c33d2aa7b26 --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/050_droid.md @@ -0,0 +1,42 @@ +# Phase 5: focused Factory Droid integration (#5193) + +Depends on `040_kilo.md` for shared roster reconciliation. The source PR +conflicts with current `dev` and changes 83 files, including broad export +behavior and unrelated test harnesses. Reimplement the narrow client thesis; +if the installed Droid contract cannot be verified, record a hold and leave +the source PR open with a reason. + +## Exact change map if verified + +- NEW `src/clients/config-export/droid.ts`: build only Droid's documented + settings and per-model rows using the documented user settings path. Do not + add an automatic startup/config write or copy provider credentials. +- MODIFY `src/clients/config-export.ts`, `contracts.ts`, + `src/integrations/registry.ts`, and `mutation-plan.ts` to add the typed ID + and exact managed fragments. Before, Droid is absent. After, explicit + export/enable uses the shared journal and restore path. +- MODIFY `src/cli/export-command.ts` only if Droid needs a distinct + loopback catalog source. Preserve the existing catalog provenance for every + other loopback-only client; the source PR's all-client redirect is not + accepted without a separate proof. Update CLI help, GUI roster/locales, + `docs-site/src/content/docs/guides/integrations.md`, and + `structure/clients/integrations.md` for the verified client slice. +- NEW `tests/clients/droid-client.test.ts`: assert exact client-consumed + settings, foreign model preservation, symlink/unsafe path refusal, Windows + path, drift, disable and exact-byte restore. MODIFY + `tests/cli/cli-export-command.test.ts` to prove existing clients retain + their old catalog/selection source. Register the new test in both manifests. + +## Acceptance and proof + +Activation: a disposable Droid config is explicitly enabled and subsequently +restored. Negative: a changed user model or unsafe target refuses before +overwrite, and a non-Droid loopback client exports the same catalog as before. +Run `bun test tests/clients/droid-client.test.ts +tests/cli/cli-export-command.test.ts`, relevant integration and GUI tests, +`bun run test:changed`, `bun run typecheck`, `bun run lint:gui`, +`bun run build:gui`, `bun run structure:check`, `bun run privacy:scan`, and +surface check if needed. Do not claim live Droid behavior from a synthetic +fixture alone; verify the documented client schema before committing the +implementation. Explicit credential/path security review, a GUI screenshot, +and exact-head CI precede merge. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/060_jev.md b/devlog/_plan/260927_release_train_4/clients-proxy/060_jev.md new file mode 100644 index 00000000000..1970ba9786e --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/060_jev.md @@ -0,0 +1,40 @@ +# Phase 6: operator JEV model profiles (#5871) + +Depends on the shared type/roster reconciliation from prior batches; the PR +currently conflicts with `dev`. Keep profile settings optional and off the +single-provider/no-profile request path. + +## Exact change map + +- MODIFY `src/types/config.ts` and `src/combos/types.ts`: add an optional + target-keyed profile shape. Trace creation in management input, persistence + through config serialization/deserialization, and consumption by JEV; a + missing profile retains the old request shape. +- MODIFY `src/combos/jev.ts`: insert an operator-authored per-target note into + the outbound decision payload while retaining existing candidate bounds + and built-in profile behavior. Validate and bound that freeform text at the + input boundary, document that it is sent to the decision provider, and + review privacy/security implications explicitly. Do not widen the target + model set or create a new unsolicited model request. +- MODIFY `src/server/management/combo-routes.ts`, + `src/server/responses/core-combo.ts`, GUI combo workspace controls/data, + relevant locales, `docs-site/src/content/docs/guides/combos.md`, and + `structure/providers-and-adapters.md` to expose and describe that same + optional shape. Keep locale keys exhaustive. +- MODIFY `tests/routing/jev-decision.test.ts` to capture the actual outbound + request and assert the selected target note appears. Also test absent + profile, wrong target, and bound candidates; update management and GUI tests. + +## Acceptance and proof + +Activation: configure a note for target A, invoke JEV with A, and observe it in +the outbound decision payload; invoke B/absent profile and observe the prior +payload. Run `bun test tests/routing/jev-decision.test.ts +tests/routing/combo-management-api.test.ts`, relevant `gui/tests`, +`bun run test:changed`, `bun run typecheck`, `bun run lint:gui`, +`bun run build:gui`, `bun run structure:check`, `bun run privacy:scan`, +and `bun test tests/lab/core-lab-boundary.test.ts`. Recheck the current-base +union/locale and file-size ratchet; inspect the actual transmitted note, +its bounds, privacy handling, and user-facing disclosure in a security review. +GUI screenshot and exact-head CI are +required before merge. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/070_memory.md b/devlog/_plan/260927_release_train_4/clients-proxy/070_memory.md new file mode 100644 index 00000000000..ae1384f1629 --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/070_memory.md @@ -0,0 +1,58 @@ +# Phase 7: selected models for Codex memory (#5983) + +Depends on `060_jev.md` for serial changes to `src/types/config.ts`. The source +PR spans 51 files. The carried classifier treats explicit turn metadata as +authoritative and consults the `x-openai-subagent` header only when that +metadata is absent. + +## Exact change map + +- NEW `src/server/responses/memory-models.ts`: classify memory phases from + validated turn metadata. Before: no memory-specific target. After: an + explicit `none`/non-memory metadata result returns no memory route, and the + legacy subagent header is consulted only when metadata is absent. Reject + malformed target settings without silently selecting a different model. +- MODIFY `src/server/responses/request-prepare.ts` and the related normalize, + options, availability, and config modules only to thread the selected + memory target through both HTTP and WebSocket admission. Do not import Lab + from `src/server/responses/core.ts`, `src/router.ts`, or + `src/server/lifecycle.ts`; do not add a timer for no-memory users. +- MODIFY `src/types/config.ts`, `src/types/request.ts`, config schema/leaf + validation, CLI/config docs, management config route, and GUI Memory panel + and locale keys so input, persisted value, reload and consumers agree. No + hand-counted preset/capability totals. +- REVIEW and MODIFY the relevant mapped source-of-truth documents: + `structure/config.md` for the persisted setting, + `structure/transports/responses.md` and + `structure/transports/responses-failover.md` for routing behavior, + `structure/gui-and-management-api.md` for settings exposure, and + `structure/providers-and-adapters.md` for `src/types/` ownership. + Check the other documents mapped to `src/server/` in + `structure/INDEX.md`; update any whose described contract changes. +- NEW `tests/responses/responses-memory-models.test.ts`: send explicit + non-memory metadata plus a subagent header and assert the normal model + serves the request. Cover real memory metadata, absent metadata fallback, + unavailable selected target, HTTP and WebSocket entry, and no-memory + baseline. The WebSocket case must enter through actual WebSocket admission, + not merely call the classifier with `transport: "websocket"`. +- NEW `tests/config/settings-memory-models.test.ts`: cover accepted and + rejected persisted memory targets, load degradation, and management-save + behavior without dropping unrelated config. +- MODIFY relevant `gui/tests` for model selection and disabled/unknown + targets. Register both new test files in `scripts/test-layout/layout.json` + and `tests/fixtures/test-layout-expected.json`. + +## Acceptance and proof + +Activation: a memory-phase request with configured target routes there; +explicit non-memory metadata never routes there even with the fallback header; +no setting retains current behavior. Run `bun test +tests/responses/responses-memory-models.test.ts +tests/responses/responses-shadow-intercept.test.ts +tests/config/settings-memory-models.test.ts`, a WebSocket entry-path +regression, and the relevant `gui/tests`, +`bun run test:changed`, `bun run typecheck`, `bun run lint:gui`, +`bun run build:gui`, `bun run structure:check`, `bun run privacy:scan`, +and `bun test tests/lab/core-lab-boundary.test.ts`. Inspect user-facing +English/translated docs, current merged type unions and file-size caps. +Require GUI screenshot and exact-head CI before merge. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/080_held_items.md b/devlog/_plan/260927_release_train_4/clients-proxy/080_held_items.md new file mode 100644 index 00000000000..dccbef8c54a --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/080_held_items.md @@ -0,0 +1,40 @@ +# Phase 8: source PR and issue disposition + +Depends on outcomes from `010`-`070`. This is a GitHub triage phase, not a +product-code batch. It is complete only when each row has a current link and +the correct open/closed state. Comments are in English and name the specific +missing proof or replaced PR. Do not close a source PR until its replacement +has merged into `dev`; leave a genuine enhancement open when held. + +## Exact external change map + +- COMMENT, then CLOSE replaced source PRs #6051, #5893, #5272, + #5193, #5871, #5983 only if the corresponding carried behavior actually + landed. Include the lane PR and merge SHA and thank the original author. +- COMMENT, KEEP OPEN #5950 and linked #5660: Qoder is held because its opt-in + config-write, restore and path contracts have not been revalidated on this train. +- COMMENT, KEEP OPEN #5905: opening Cursor status currently fetches a remote + installer manifest without a user action. Ask for an explicit discovery + policy and timeout/status regression. Keep draft and no installer launch. +- COMMENT, KEEP OPEN #3833: the literal `apiKey` placeholder in its export is + rejected by Command Code; require a documented supported keyless/reference + form and client-side proof, then refresh against `dev` and security review. +- COMMENT, KEEP OPEN #4854: require OpenScience config path/schema and + override/restore ownership evidence; the manual endpoint remains usable. +- COMMENT, KEEP OPEN #3494: require one named VS Code extension's officially + supported settings, reload behavior, and per-scope ownership contract. +- COMMENT, KEEP OPEN #1416: require a versioned, secret-free Orca launch + manifest that can be generated while the proxy is stopped; do not insert + it into live model export before the consumer schema is agreed. +- COMMENT, KEEP OPEN #2811: record the design-only judgment. #5016 was + closed unmerged because `managed: true` was unreachable from the production + inspector. Establish a real provenance predicate and read-only plan before + considering an apply mutation. +- CLOSE linked #5853 and #5982 only when the exact behavior is on + `dev`, with the lane merge link. #5679 remains open while #5905 is held. + +## Acceptance and proof + +Fetch each PR/issue after each comment/close and verify state and URL. Do not +count a `gh` command's exit alone as proof. The issue-close list is conditional +on actual merged outcomes. Re-read source authors for attribution trailers. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/090_final_ci.md b/devlog/_plan/260927_release_train_4/clients-proxy/090_final_ci.md new file mode 100644 index 00000000000..c80f76faf0d --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/090_final_ci.md @@ -0,0 +1,32 @@ +# Phase 9: final integration and CI + +Depends on all selected carries and triage. This phase writes no product code +unless the last `dev` run exposes a lane-owned regression; any repair gets its +own new PABCD work phase and ordinary PR. + +## Exact evidence map + +- MODIFY `devlog/_plan/260927_release_train_4/clients-proxy/000_plan.md` + disposition rows when outcomes change. Before: candidate judgments at + `origin/dev` `24b2f39b77`; after: each row names actual lane PR, merge SHA, + source PR/issue state, and any residual hold. +- NEW a numbered outcome file under this unit, recording each PR head and + merge SHA, focused commands and their exits, required CI run IDs/URLs, + final `dev` run URL, and remaining cross-lane file overlaps. + +## Acceptance and proof + +Fetch latest `origin/dev`; for every lane PR, retain the exact pre-merge PR +head SHA and required-job run IDs that passed before merge. `ci.yml` does +not run on a push to `dev`, so after the merge resolve the integrated `dev` +commit and explicitly dispatch `gh workflow run ci.yml -R +lidge-jun/opencodex --ref dev -f lane=all`. Identify the resulting run by +`workflow_dispatch` event and exact `headSha`, then record its run ID, URL, +attempt, requested jobs and final conclusions. If `dev` moves before dispatch, +refresh the head and verify the run covers that newer integrated tree instead +of claiming evidence for an older SHA. Missing, skipped, cancelled, pending, +failed, and wrong-head results do not count as passing for requested jobs. +Compare changed paths +against other lane overlap in the final report. `git status --short` must +contain no unaccounted files, and each source PR/issue closure must point to +the actual integrated SHA. diff --git a/devlog/_plan/260927_release_train_4/clients-proxy/100_outcome.md b/devlog/_plan/260927_release_train_4/clients-proxy/100_outcome.md new file mode 100644 index 00000000000..35f106ceb69 --- /dev/null +++ b/devlog/_plan/260927_release_train_4/clients-proxy/100_outcome.md @@ -0,0 +1,28 @@ +# Phase 10: lane outcome + +The clients/proxy lane lands through one integration PR, [#6124](https://github.com/lidge-jun/opencodex/pull/6124). It stacks the six reviewed lane PRs linearly, each with its commits and `Co-authored-by` trailers intact, plus two union commits. Batching replaced six sequential rebase-and-CI cycles on a congested Actions queue. Each lane PR passed its own exact-head `Cross-platform CI` run before batching: + +| Carry | Lane PR, reviewed head | PR CI run | Source PR | Review outcome | +| --- | --- | --- | --- | --- | +| Management API test recipe, roadmap | #6095 `fc6c06050e` | [36333525807](https://github.com/lidge-jun/opencodex/actions/runs/36333525807) | #6051 | PASS after folding pre-disclosure wording and agent ids | +| JEV per-target notes | #6107 `186ed34fee` | [36333529243](https://github.com/lidge-jun/opencodex/actions/runs/36333529243) | #5871 | NEAR-PASS; control-character rule and error text folded | +| Memory-phase model routing | #6109 `fd4087e9c6` | [36336008534](https://github.com/lidge-jun/opencodex/actions/runs/36336008534) | #5983 (#5982) | NEAR-PASS; malformed/null metadata folded; debug-log finding withdrawn | +| macOS system proxy discovery | #6111 `001b83317b` | [36333558812](https://github.com/lidge-jun/opencodex/actions/runs/36333558812) | #5893 (#5853) | PASS after four rounds (defaults, noProxy, localhost) | +| Kilo Code integration | #6114 `e54be87916` | [36336759783](https://github.com/lidge-jun/opencodex/actions/runs/36336759783) | #5272 | PASS; conflict naming and disable-under-conflict folded | +| Factory Droid integration | #6115 `adbd3927b7` | [36338469971](https://github.com/lidge-jun/opencodex/actions/runs/36338469971) | #5193 | PASS after four rounds (legacy collisions, selectors, IPv6) | + +## Decisions that changed the roadmap + +- **Qoder (#5950, #5660): HOLD.** Qoder's own CLI documentation says not to configure BYOK manually in `settings.json` and documents no `providers`/`modelConfigs` schema. A writer could therefore target a file the client does not honour. Comments on #5950 and #5660 ask for a supported import path or official schema. +- **macOS default exceptions (020 amendment).** The strict "refuse any unrepresentable exception" rule would never activate on a default macOS configuration (`*.local`, `169.254/16`). A Bun 1.4.0 probe showed `.local` matching `local` and its subdomains on label boundaries, while `*.local` and CIDR entries are ignored. So `*.` maps to `.`, and only the exact link-local ranges are dropped, with a notice. Any other CIDR, glob, or simple-host rule still refuses before an environment write. +- **Kilo and Droid landed together** because Qoder was held. That made the client count seventeen, which needed one reconciliation commit. +- **Test layout seeds moved.** The union of new test registrations brought `scripts/test-layout/layout.json` to exactly 2,000 lines, which is `NEW_OVERSIZED`. `keepAtRoot`, `domains`, and `migrated` moved into `seeds.json` beside it, and `explicit` stayed in `layout.json`. No cap or exemption changed. + +## Held items and triage comments + +The following stay open. Each has an English comment naming the missing proof: #5950 and #5660 (Qoder contract), #5905 and #5679 (remote installer lookup must follow an explicit user action), #3833 (literal `apiKey` is refused by Command Code; needs a documented key reference or `false`), #4854 (OpenScience schema and ownership), #3494 (a named VS Code extension's supported settings and reload lifecycle), #1416 (a versioned, secret-free Orca launch manifest), and #2811 (design only; needs a reachable provenance predicate before any apply). + +## Verification boundaries + +Local full root suites were not run. Seven lane worktrees share one Bun test lock and one machine, so hosted CI shards are the broad gate. Each lane PR's and the batch's Verification sections list the focused and GUI runs. Not exercised: a real macOS Settings session (`scutil` is mocked), live Kilo or Droid clients (schemas are checked against vendor documentation), and native Windows (Windows-shaped path tests only). The merge SHA and the post-merge `dev` CI run are recorded in the lane's final report and on #6124. + diff --git a/docs-site/src/content/docs/fr/guides/integrations.md b/docs-site/src/content/docs/fr/guides/integrations.md index d4438e568fb..7588d5526fe 100644 --- a/docs-site/src/content/docs/fr/guides/integrations.md +++ b/docs-site/src/content/docs/fr/guides/integrations.md @@ -1,10 +1,10 @@ --- title: Intégrations -description: Connectez opencodex à OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast et omo depuis le tableau de bord — un commutateur par client, avec une sauvegarde avant chaque écriture. +description: Connectez opencodex à OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo et Factory Droid depuis le tableau de bord — un commutateur par client, avec une sauvegarde avant chaque écriture. --- L'onglet **Intégrations** écrit le bloc fournisseur d'opencodex dans le fichier de configuration du client, -puis peut le retirer. Quinze clients fonctionnent ainsi, chacun avec son propre commutateur : +puis peut le retirer. Dix-sept clients fonctionnent ainsi, chacun avec son propre commutateur : | Client | Fichier de configuration | Format | Prise d'effet de la modification | Identifiant | |---|---|---|---|---| @@ -23,6 +23,8 @@ puis peut le retirer. Quinze clients fonctionnent ainsi, chacun avec son propre | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | immédiatement à l'enregistrement — Raycast surveille le fichier | aucun — bouclage uniquement | | omo | `~/.omo/agent/models.json` | JSON | nouvelles sessions | espace réservé de bouclage | | Cline CLI | `~/.cline/data/settings/providers.json` + `models.json` | JSON | après arrêt et redémarrage | bouclage uniquement | +| Kilo | premier fichier existant parmi `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` ou `config.json` sous `~/.config/kilo` (`XDG_CONFIG_HOME` déplace ce répertoire ; `kilo.jsonc` est créé si aucun n'existe) | JSONC | nouvelles sessions | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` sous Windows) | JSON | dès la détection du fichier | boucle locale sans clé | Les modèles GJC dotés d'une échelle d'effort de raisonnement prise en charge exportent `reasoning: true`, `thinking.levels` et `compat.supportsReasoningEffort`, afin que GJC propose le choix de l'effort. Les modèles Codex natifs reçoivent leur échelle standard même si le catalogue l'omet. Ces champs sont absents sans échelle connue ; `none` n'envoie pas d'effort et `ultra` devient `max` sur le réseau. Actualisez l'intégration pour mettre à jour ces options. @@ -299,3 +301,17 @@ ocx integration client restore --op ``` [CLI / rollback / CLINE_PROVIDER_SETTINGS_PATH](/guides/integrations/#cline-cli). + +## Kilo + +Kilo n’écrit que `provider.opencodex` dans le premier fichier global existant sous `~/.config/kilo` (`XDG_CONFIG_HOME` déplace ce répertoire ; `kilo.jsonc` est créé si aucun candidat n’existe). Si un autre fichier candidat définit aussi `provider.opencodex`, l’état signale un conflit et Appliquer refuse. Les autres clés restent inchangées. Appliquer réécrit tout le fichier ; commentaires et virgules finales ne sont pas conservés. Sélectionnez `opencodex/` dans Kilo. + +Désactiver peut retirer le bloc appartenant à OpenCodex du fichier enregistré même si un autre candidat est en conflit ou ne peut pas être analysé ; cet autre fichier reste intact. + +```bash +ocx integration client enable --client kilo +``` + +## Factory Droid + +Factory Droid utilise `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` sous Windows). Activez explicitement l’intégration avec `ocx integration client enable --client droid`, puis choisissez un modèle personnalisé dans `/model`. Les entrées gérées n’utilisent pas de clé et fonctionnent uniquement en boucle locale. La désactivation supprime ces entrées ; l’annulation restaure les octets sauvegardés. Si l’ancien `config.json` contient des entrées OpenCodex ou si `settings.local.json` remplace `customModels`, résolvez ce conflit avant l’activation. Consultez la [documentation Factory BYOK](https://docs.factory.ai/model-independence/byok). 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 b63eb62f9c3..f9db378b53d 100644 --- a/docs-site/src/content/docs/fr/reference/cli/agents.md +++ b/docs-site/src/content/docs/fr/reference/cli/agents.md @@ -176,7 +176,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 @@ -187,7 +187,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. | @@ -220,6 +220,8 @@ propres valeurs par défaut à ces lignes. | `aside` | `~/.aside/u//models.json` pour le compte que le fichier `accounts.json` d'Aside désigne comme courant ; un manifeste illisible est refusé plutôt que de retomber sur un compte | `aside-models.json` | aucun — espace réservé de bouclage | | `raycast` | `~/.config/raycast/ai/providers.yaml`, sur macOS comme sur Windows (Raycast n'honore pas `XDG_CONFIG_HOME`) | `raycast-providers.yaml` | aucun — bouclage uniquement, aucune entrée `api_keys` n'est écrite | | `omo` | `~/.omo/agent/models.json` (`OMO_CODING_AGENT_DIR`, puis `SENPI_CODING_AGENT_DIR`, puis `PI_CODING_AGENT_DIR` l'emportent dans cet ordre une fois définis ; une valeur relative est refusée) | `omo-models.json` | aucun — espace réservé de bouclage | +| `kilo` | premier fichier existant parmi `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` ou `config.json` sous `~/.config/kilo` (`XDG_CONFIG_HOME` déplace ce répertoire) ; utilise `kilo.jsonc` si aucun n'existe | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | boucle locale uniquement ; aucune variable d’environnement | L'exportation Raycast est un document `providers.yaml` autonome contenant un seul élément `id: opencodex` dans la séquence `providers` : `name: OpenCodex`, l'URL de base `/v1` du proxy et chaque modèle routé avec 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 3a9ca385079..6fe894b567f 100644 --- a/docs-site/src/content/docs/fr/reference/configuration/server.md +++ b/docs-site/src/content/docs/fr/reference/configuration/server.md @@ -273,4 +273,4 @@ compte et la charge de travail prévus. ## Diagnostic réseau des quotas Codex -Le champ `quotaRefresh` de la ligne du compte Codex principal décrit la récupération du quota, pas le quota restant ni les droits d’accès au modèle. Il peut être absent lorsque les données sont en cache ou qu’aucune récupération n’a eu lieu. La requête utilise l’environnement du service proxy en cours d’exécution, pas celui du terminal interactif. Sans `proxy`, l’environnement existant est conservé ; `"auto"` lit uniquement le proxy statique Windows au démarrage. PAC/WPAD, les paramètres SOCKS seuls et les changements à chaud ne sont pas pris en compte automatiquement. Un succès avec TUN ne valide pas à lui seul le chemin du proxy HTTP. Consultez [les commandes et les états en anglais](/reference/configuration/server/#codex-quota-network-diagnostics). +Le champ `quotaRefresh` de la ligne du compte Codex principal décrit la récupération du quota, pas le quota restant ni les droits d’accès au modèle. Il peut être absent lorsque les données sont en cache ou qu’aucune récupération n’a eu lieu. La requête utilise l’environnement du service proxy en cours d’exécution, pas celui du terminal interactif. Sans `proxy`, l’environnement existant est conservé ; `"auto"` lit les paramètres HTTP/HTTPS statiques de Windows ou macOS au démarrage. Sur macOS, un proxy hérité empêche cette lecture. Sur macOS, un motif valide `*.` devient `.` : `foo.local` contourne le proxy pour `*.local`, `xlocal` non, et le nom racine `local` le contourne aussi. Les plages exactes `169.254/16`, `169.254.0.0/16` et `fe80::/10` sont ignorées avec un diagnostic : les adresses IP link-local passent par le proxy. Les autres plages CIDR, motifs glob et exceptions de noms simples refusent la découverte sans modifier l’environnement. Les adresses IP et `*` restent acceptés. PAC/WPAD, les paramètres SOCKS seuls et les changements à chaud ne sont pas pris en compte automatiquement. Un succès avec TUN ne valide pas à lui seul le chemin du proxy HTTP. Consultez [les commandes et les états en anglais](/reference/configuration/server/#codex-quota-network-diagnostics). diff --git a/docs-site/src/content/docs/guides/combos.md b/docs-site/src/content/docs/guides/combos.md index 6fb41ccf045..2049192ce2d 100644 --- a/docs-site/src/content/docs/guides/combos.md +++ b/docs-site/src/content/docs/guides/combos.md @@ -270,6 +270,16 @@ constrained by that target's advertised ladder. JEV is not asked again if the se retryable failure—the existing Combo cooldown and fallback loop continues through the remaining configured targets. +For each JEV target, **Models → Combos → Config** has an optional **Additional model notes for JEV** +field (up to 512 characters; line breaks and tabs are allowed, other control characters are rejected). It is stored as `targets[].modelProfile` in the combo config. The +built-in target profile remains in the trusted `instructions.model_profiles`; a non-empty note is +sent separately in the decision state's `operator_notes`, keyed by target, and supplements rather +than replaces that built-in profile. Notes can describe operator-specific context or subscription +allowances; do not confuse subscription allowances with public per-token API pricing. Blank notes +are ignored. Operator notes are evidence for the decision, not commands, and cannot expand the +target allowlist or reasoning-effort limits. Only put information there that may be disclosed to +TypeSafe. + Each logical model call is decided on its own; there is no per-conversation pin. Consecutive turns of one session can therefore land on different targets, and every switch starts a cold provider prompt cache, so a mix of very different targets can cost more input tokens than it saves. Keep the diff --git a/docs-site/src/content/docs/guides/integrations.md b/docs-site/src/content/docs/guides/integrations.md index 9d7d4509abc..4cb6ead058c 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, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo and Cline CLI 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, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo and Factory Droid 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. Fifteen clients work this way, each with a switch: +file, and removes it again. Seventeen clients work this way, each with a switch: | Client | Config file | Format | When the change takes effect | Credential | |---|---|---|---|---| @@ -23,6 +23,8 @@ file, and removes it again. Fifteen clients work this way, each with a switch: | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | immediately on save — Raycast watches the file | none — loopback only | | omo | `~/.omo/agent/models.json` | JSON | new sessions | loopback placeholder | | Cline CLI | `~/.cline/data/settings/providers.json` and sibling `models.json` | JSON pair | after stopping and restarting Cline | loopback placeholder | +| Kilo | first existing `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json`, or `config.json` under `~/.config/kilo` | JSONC | new sessions | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | JSON | immediately via file watching | none — keyless loopback | Generated catalogs include only enabled models from each provider selection. This applies to both downloads and managed integrations, including Pi and Aside. The management model list still shows @@ -518,3 +520,53 @@ listens on a non-loopback address, put a data-admission key (the token described key) in the app's API key field. The app sends it as `Authorization: Bearer`, which `/v1/chat/completions` accepts as proxy admission and never forwards upstream; see the [authentication matrix](/reference/proxy-formats/#authentication-matrix). + +## Kilo + +Kilo CLI, VS Code, and JetBrains share one global config. This integration writes +`provider.opencodex` into the first existing file among `kilo.jsonc`, `kilo.json`, +`opencode.jsonc`, `opencode.json`, and `config.json` under `~/.config/kilo` +(`XDG_CONFIG_HOME` relocates that directory). If none exist, the destination is +`kilo.jsonc`. Project configs are never written. +Kilo merges all of these global files. If another candidate also defines +`provider.opencodex`, status names every competing file and Apply and Replace refuse; +remove `provider.opencodex` from those files before enabling the integration. An unreadable or unsafe +candidate also blocks the write. Disable can still remove a block owned in the recorded file +while another candidate conflicts or cannot be parsed; the other candidate is left untouched. + +The owned fragment is only `provider.opencodex` (OpenCode V1 shape: `npm`, `options`, +`models`). Kilo's published schema has no OpenCode V2 `providers` key, so that block is +not emitted. `$schema`, `model`, `enabled_providers`, MCP, and other keys stay +user-owned. Select `opencodex/` in Kilo after applying. + +Loopback uses `{env:OPENCODEX_KILO_API_KEY}` as `options.apiKey`. A non-loopback bind +moves admission to `options.headers["x-opencodex-api-key"]` and never serializes a real +key. Apply rewrites the whole global file as pretty JSON, so comments and trailing +commas in other keys are not preserved. Kilo is not on the implicit catalog fan-out; +refresh it explicitly after changing the routed model selection. + +```bash +ocx integration client enable --client kilo +ocx export --client kilo --out ./kilo.jsonc +``` + +## Factory Droid + +Run Droid once to create `~/.factory`, then explicitly enable this integration with +`ocx integration client enable --client droid`. OpenCodex adds only documented +`customModels` entries to your personal `settings.json`, using a keyless local +Chat Completions endpoint. Choose a row from Droid's `/model` picker. Disable +removes the managed rows; Undo restores the exact saved file. Other settings and +custom models remain yours. + +Models whose IDs or display names contain `,` or `]` are skipped because the +managed selector cannot address them safely; export and managed settings show +the same rows. A nonempty catalog with no addressable models is refused. + +Droid also reads legacy `config.json` and local `settings.local.json`. Resolve +legacy rows that use the OpenCodex endpoint, a generated model ID, or an +`OpenCodex:` display name, and any local `customModels` override, before enabling; +OpenCodex refuses those ambiguous settings. It also refuses an +unsafe target or a row edited since apply. The integration is loopback only and +never copies provider credentials. Factory documents the [BYOK schema](https://docs.factory.ai/model-independence/byok) +and [personal settings path](https://docs.factory.ai/droid-cli/settings). diff --git a/docs-site/src/content/docs/ja/guides/integrations.md b/docs-site/src/content/docs/ja/guides/integrations.md index 5f1b21e521f..15e2f8ba560 100644 --- a/docs-site/src/content/docs/ja/guides/integrations.md +++ b/docs-site/src/content/docs/ja/guides/integrations.md @@ -1,9 +1,9 @@ --- title: クライアント統合 -description: ダッシュボードから opencodex を OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast、omo、Cline CLI に接続します。クライアントごとにスイッチがあり、書き込み前には必ずバックアップを取ります。 +description: ダッシュボードから opencodex を OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast、omo、Cline CLI、Kilo、Factory Droid に接続します。クライアントごとにスイッチがあり、書き込み前には必ずバックアップを取ります。 --- -**Integrations** タブは、各クライアントの設定ファイルに opencodex のプロバイダーブロックを書き込み、必要に応じて削除します。次の 15 クライアントは、それぞれのスイッチで管理できます。 +**Integrations** タブは、各クライアントの設定ファイルに opencodex のプロバイダーブロックを書き込み、必要に応じて削除します。次の 17 クライアントは、それぞれのスイッチで管理できます。 | クライアント | 設定ファイル | 形式 | 変更が反映される時点 | 認証情報 | |---|---|---|---|---| @@ -22,6 +22,8 @@ description: ダッシュボードから opencodex を OpenCode、Pi、OMP、Her | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | 保存後すぐ。Raycast がファイルを監視 | なし。ループバックのみ | | omo | `~/.omo/agent/models.json` | JSON | 新しいセッション | ループバック用プレースホルダー | | Cline CLI | `~/.cline/data/settings/providers.json` と同階層の `models.json` | JSON のペア | Cline の停止と再起動後 | ループバック用プレースホルダー | +| Kilo | `~/.config/kilo` 内で最初に存在する `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json`、`config.json`(`XDG_CONFIG_HOME` でディレクトリを変更可能。どれもなければ `kilo.jsonc` を作成) | JSONC | 新しいセッション | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` Windows の場合) | JSON | ファイル変更を即時反映 | キー不要のループバック | 生成されるカタログには、各プロバイダーの選択で有効なモデルのみが含まれます。これはダウンロードと管理対象の統合の両方に適用され、Pi と Aside も対象です。管理画面のモデル一覧にはすべてのモデルが表示されるため、追加のモデルを有効にできます。 @@ -216,6 +218,21 @@ Undo は、もともと存在しなかったファイルも含め、**元の両 ダウンロードされる `cline-config-bundle.json` には、`providers.json` 用の `settings` と `models.json` 用の `catalog` という 2 つのネイティブ文書要素が含まれます。それ自体は Cline の設定ファイルではありません。ジャーナル付きのマージとロールバックには統合コマンドを使ってください。生成された統合はリモートの受け入れ認証に対応せず、認証不要のループバックアクセスが必要です。 +## Kilo + +Kilo CLI、VS Code、JetBrains は同じグローバル設定を共有します。この統合は `~/.config/kilo` 内の `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json`、`config.json` のうち最初に存在するファイルに `provider.opencodex` を書き込みます。`XDG_CONFIG_HOME` でこのディレクトリを変更できます。候補がなければ `kilo.jsonc` を作成します。プロジェクト設定には書き込みません。 + +Kilo はこれらのグローバルファイルをすべてマージします。別の候補も `provider.opencodex` を定義する場合、状態に競合ファイルが表示され、適用と置換は拒否されます。有効化する前に、そのファイルから `provider.opencodex` を削除してください。所有済みファイルの無効化は競合があっても実行できます。読み取れない候補や安全に扱えない候補も書き込みを妨げます。 + +管理対象は OpenCode V1 形式の `provider.opencodex`(`npm`、`options`、`models`)だけです。OpenCode V2 の `providers` は出力しません。`$schema`、`model`、`enabled_providers`、MCP などのキーはユーザーが管理します。適用後、Kilo で `opencodex/` を選択してください。 + +ループバックでは `options.apiKey` に `{env:OPENCODEX_KILO_API_KEY}` を使います。ループバック以外へのバインドでは認証を `options.headers["x-opencodex-api-key"]` に移し、実際のキーは保存しません。適用時はグローバルファイル全体を整形済み JSON として書き直すため、他のキーのコメントと末尾カンマは保持されません。Kilo は自動カタログ更新の対象外です。ルーティング対象のモデル選択を変更したら、明示的に更新してください。 + +```bash +ocx integration client enable --client kilo +ocx export --client kilo --out ./kilo.jsonc +``` + ## GitHub Copilot アプリ GitHub Copilot デスクトップアプリでは、opencodex を OpenAI 互換のモデルプロバイダーとして利用できます。これは手動で設定するクライアントで、Integrations タブのスイッチはありません。また、opencodex がバックエンドとして Copilot サブスクリプションを使う上流の `github-copilot` プロバイダーとは別のものです。 @@ -240,3 +257,7 @@ GitHub Copilot デスクトップアプリでは、opencodex を OpenAI 互換 アプリはモデルの検出に `GET /v1/models`、リクエストの処理に `POST /v1/chat/completions` を使います。リクエストは opencodex の通常のモデルルーティングを通るため、他のクライアントと同じように、プロバイダーの認証情報、OAuth アカウント、コンボが適用されます。受け付けるリクエストフィールドは[プロキシ形式のリファレンス](/reference/proxy-formats/)を参照してください。 モデルが見つからないと表示される場合は、Base URL が `/v1/chat/completions` ではなく `/v1` で終わっていることと、`/v1/models` が空でない `data` 配列を返すことを確認してください。opencodex がループバック以外のアドレスで待ち受けている場合は、アプリの API key 欄にデータ受け入れキー([リモートアクセス](/reference/configuration/server/#remote-access)に記載されたトークン、またはダッシュボードで生成した `ocx_…` キー)を入力します。アプリはこれを `Authorization: Bearer` として送信します。`/v1/chat/completions` はこれをプロキシの受け入れ認証にだけ使い、上流には転送しません。詳しくは[認証マトリクス](/reference/proxy-formats/#authentication-matrix)を参照してください。 + +## Factory Droid + +Factory Droid は `~/.factory/settings.json`(Windows では `%USERPROFILE%\.factory\settings.json`)を使用します。`ocx integration client enable --client droid` で明示的に有効化し、`/model` でカスタムモデルを選択します。管理対象の行はキーを使わず、ループバックでのみ動作します。無効化すると管理対象の行が削除され、Undo で保存済みのバイト列が復元されます。従来の `config.json` に OpenCodex の行がある場合や、`settings.local.json` が `customModels` を上書きする場合は、有効化する前に競合を解消してください。[Factory BYOK のドキュメント](https://docs.factory.ai/model-independence/byok)も参照してください。 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 20d62ca3eca..bf7b59fc1b3 100644 --- a/docs-site/src/content/docs/ja/reference/cli/agents.md +++ b/docs-site/src/content/docs/ja/reference/cli/agents.md @@ -136,7 +136,7 @@ Grok Build モデル フェンスを管理および適用します。 ## クライアント設定のエクスポート -### `ocx export --client ` +### `ocx export --client ` 実行中のプロキシに接続するクライアント設定を出力します。このコマンドは、ベース URL、モデル一覧、およびクライアントに応じた認証情報参照または `opencodex-loopback` プレースホルダーを含む `opencodex` プロバイダーブロックを、選択したクライアントのネイティブ形式でシリアル化します。 @@ -144,7 +144,7 @@ Grok Build モデル フェンスを管理および適用します。 |旗 |アクション | | --- | --- | -| `--client ` |必須。クライアントの設定形式を選択します。 | +| `--client ` |必須。クライアントの設定形式を選択します。 | | `--json` |構成 JSON のみを標準出力に出力するため、リダイレクトはバイト正確な出力をキャプチャします。 `--out` 書き込みメモを含むすべての診断は stderr に送られます。 | | `--out ` |設定を `` に書き込みます。既存のファイルの置き換えを拒否します。 | | `--force` | `--out` が既存のファイルを置き換えることを許可します。 | @@ -174,6 +174,8 @@ ocx export --client opencode --out ~/opencodex-opencode.json | `aside` | `~/.aside/u//models.json`。Aside 自身の `accounts.json` が現在のアカウントとして指す account を使います。マニフェストが読めない場合は、既定のアカウントに落とさず拒否します | `aside-models.json` | なし — loopback placeholder | | `raycast` | `~/.config/raycast/ai/providers.yaml` (macOS と Windows で同じ。Raycast は `XDG_CONFIG_HOME` を尊重しません) | `raycast-providers.yaml` | なし — loopback のみ。`api_keys` エントリは書き込まれません | | `omo` | `~/.omo/agent/models.json` (`OMO_CODING_AGENT_DIR`、次に `SENPI_CODING_AGENT_DIR`、次に `PI_CODING_AGENT_DIR` の順で設定時に優先。相対値は拒否されます) | `omo-models.json` | なし — loopback placeholder | +| `kilo` | `~/.config/kilo` 配下で最初に存在する `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json`、`config.json`(`XDG_CONFIG_HOME` が設定されていればその配下)。候補がなければ `kilo.jsonc` | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | ループバックのみ・環境変数不要 | Raycast のエクスポートは、`providers` シーケンスに `id: opencodex` 要素を 1 つだけ持つ独立した `providers.yaml` 文書です。内容は `name: OpenCodex`、プロキシの `/v1` ベース URL、および `abilities` 付きのルーティング済み全モデルです (`tools` と `system_message` は常にサポート、`vision` はカタログの入力モダリティから、`reasoning_effort` はモデルに effort ラダーがある場合、`temperature` は推論モデルではオフ)。Custom Providers は Raycast Pro の機能で、Raycast はこのファイルを監視しているため、保存した変更は再起動なしで反映されます。形式は [manual.raycast.com/ai/custom-providers](https://manual.raycast.com/ai/custom-providers) に記載されています。`api_keys` エントリは書き込まれないため、このエクスポートは loopback 専用で、loopback 以外のバインドは拒否されます。 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 27dbf08b986..7eeac7e4776 100644 --- a/docs-site/src/content/docs/ja/reference/configuration/server.md +++ b/docs-site/src/content/docs/ja/reference/configuration/server.md @@ -184,6 +184,6 @@ Anthropic OAuth サイドカーは、opencodex の既存のクロード コー ## Codex クォータのネットワーク診断 -メイン Codex アカウント行の `quotaRefresh` はクォータ取得の診断情報であり、残量やモデルへのアクセス権を示すものではありません。キャッシュ利用時や取得を行わない場合は省略されることがあります。取得には操作中のシェルではなく、実行中のプロキシサービスの環境が使われます。`proxy` 未設定では既存の環境を維持し、`"auto"` は起動時に Windows の静的プロキシ設定だけを読みます。PAC/WPAD、SOCKS のみの設定、実行中の変更は自動反映されません。TUN での成功だけでは HTTP プロキシ経路の正常性は確認できません。[コマンドと状態の説明(英語)](/reference/configuration/server/#codex-quota-network-diagnostics)を参照してください。 +メイン Codex アカウント行の `quotaRefresh` はクォータ取得の診断情報であり、残量やモデルへのアクセス権を示すものではありません。キャッシュ利用時や取得を行わない場合は省略されることがあります。取得には操作中のシェルではなく、実行中のプロキシサービスの環境が使われます。`proxy` 未設定では既存の環境を維持し、`"auto"` は起動時の Windows または macOS の静的 HTTP/HTTPS 設定を読みます。macOS では継承したプロキシがある場合、読み取りを行いません。macOS では有効な `*.` を `.` に変換します。`*.local` は `foo.local` と基底名 `local` を直接接続にしますが、`xlocal` は対象外です。`169.254/16`、`169.254.0.0/16`、`fe80::/10` は診断を出して省略し、リンクローカル IP アドレスはプロキシを使います。IP アドレスと `*` は受け入れますが、その他の CIDR、glob、単純ホスト名の例外では環境を変更せず検出を中止します。PAC/WPAD、SOCKS のみの設定、実行中の変更は自動反映されません。TUN での成功だけでは HTTP プロキシ経路の正常性は確認できません。[コマンドと状態の説明(英語)](/reference/configuration/server/#codex-quota-network-diagnostics)を参照してください。 `dropCodexSafetyBuffering`: プロバイダーの安全性の適用と拒否応答は変更しません。native `codex.response.metadata.headers` WebSocket メタデータと `/responses/compact` は対象外です。 diff --git a/docs-site/src/content/docs/ko/guides/integrations.md b/docs-site/src/content/docs/ko/guides/integrations.md index b1d4b990de0..e39df9ea9da 100644 --- a/docs-site/src/content/docs/ko/guides/integrations.md +++ b/docs-site/src/content/docs/ko/guides/integrations.md @@ -1,9 +1,9 @@ --- title: 연동 -description: 대시보드에서 OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI를 opencodex에 연결합니다. 클라이언트마다 스위치가 하나씩 있으며 기록 전마다 백업합니다. +description: 대시보드에서 OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo와 Factory Droid를 opencodex에 연결합니다. 클라이언트마다 스위치가 하나씩 있으며 기록 전마다 백업합니다. --- -**Integrations** 탭은 클라이언트의 설정 파일에 opencodex 프로바이더 블록을 쓰고 다시 제거합니다. 다음 15개 클라이언트는 각각 스위치로 관리합니다. +**Integrations** 탭은 클라이언트의 설정 파일에 opencodex 프로바이더 블록을 쓰고 다시 제거합니다. 다음 17개 클라이언트는 각각 스위치로 관리합니다. | 클라이언트 | 설정 파일 | 형식 | 변경 적용 시점 | 자격 증명 | |---|---|---|---|---| @@ -22,6 +22,8 @@ description: 대시보드에서 OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | 저장 즉시 — Raycast가 파일을 감시함 | 없음 — 루프백 전용 | | omo | `~/.omo/agent/models.json` | JSON | 새 세션에서 | 루프백 자리표시자 | | Cline CLI | `~/.cline/data/settings/providers.json` 및 같은 위치의 `models.json` | JSON 파일 쌍 | Cline을 중지하고 다시 시작한 뒤 | 루프백 자리표시자 | +| Kilo | `~/.config/kilo`에서 먼저 존재하는 `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json`, `config.json` (`XDG_CONFIG_HOME`로 디렉터리 변경 가능, 모두 없으면 `kilo.jsonc` 생성) | JSONC | 새 세션에서 | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` Windows에서) | JSON | 파일 변경 시 즉시 | 키 없는 루프백 | 생성된 카탈로그에는 각 프로바이더 선택에서 활성화된 모델만 들어갑니다. Pi와 Aside를 포함한 다운로드와 관리형 연동 모두에 적용됩니다. 관리 모델 목록에는 전체 모델이 계속 표시되어 추가 모델을 활성화할 수 있습니다. @@ -214,6 +216,21 @@ Undo는 원래 없던 파일까지 포함해 **두 원본 바이트 문자열 다운로드되는 `cline-config-bundle.json`에는 두 네이티브 문서 구성 요소가 있습니다. `providers.json`용 `settings`와 `models.json`용 `catalog`입니다. 번들 자체가 Cline 설정 파일은 아닙니다. 저널을 남기는 병합과 롤백에는 연동 명령을 권장합니다. 생성된 연동은 원격 수용 연결을 지원하지 않으며 인증이 없는 루프백 접근이 필요합니다. +## Kilo + +Kilo CLI, VS Code, JetBrains는 전역 설정을 공유합니다. 이 연동은 `~/.config/kilo` 아래의 `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json`, `config.json` 중 먼저 존재하는 파일에 `provider.opencodex`를 씁니다. `XDG_CONFIG_HOME`로 이 디렉터리를 옮길 수 있습니다. 후보 파일이 없으면 `kilo.jsonc`를 만듭니다. 프로젝트 설정은 수정하지 않습니다. + +Kilo는 이 전역 파일을 모두 병합합니다. 다른 후보 파일에도 `provider.opencodex`가 있으면 상태에 충돌 파일을 표시하고 적용과 교체를 거부합니다. 연동을 켜기 전에 해당 파일에서 `provider.opencodex`를 제거하세요. 이미 소유한 파일의 블록은 충돌 중에도 비활성화할 수 있습니다. 읽을 수 없거나 안전하지 않은 후보 파일도 쓰기를 막습니다. + +관리하는 부분은 OpenCode V1 형식의 `provider.opencodex`(`npm`, `options`, `models`)뿐입니다. OpenCode V2의 `providers` 키는 내보내지 않습니다. `$schema`, `model`, `enabled_providers`, MCP 등의 키는 사용자가 관리합니다. 적용한 뒤 Kilo에서 `opencodex/`을 선택하세요. + +루프백에서는 `options.apiKey`로 `{env:OPENCODEX_KILO_API_KEY}`를 사용합니다. 루프백이 아닌 바인드에서는 인증을 `options.headers["x-opencodex-api-key"]`로 옮기며 실제 키를 저장하지 않습니다. 적용 시 전역 파일 전체를 보기 좋은 JSON으로 다시 쓰므로 다른 키의 주석과 후행 쉼표는 보존되지 않습니다. Kilo는 자동 카탈로그 갱신 대상이 아닙니다. 라우팅 모델 선택을 바꾼 뒤에는 명시적으로 갱신하세요. + +```bash +ocx integration client enable --client kilo +ocx export --client kilo --out ./kilo.jsonc +``` + ## GitHub Copilot 앱 GitHub Copilot 데스크톱 앱에서 opencodex를 OpenAI 호환 모델 프로바이더로 사용할 수 있습니다. Integrations 탭의 스위치가 없는 수동 클라이언트 설정이며, opencodex의 백엔드로 Copilot 구독을 사용하는 upstream `github-copilot` 프로바이더와는 별개입니다. @@ -238,3 +255,7 @@ GitHub Copilot 데스크톱 앱에서 opencodex를 OpenAI 호환 모델 프로 앱은 모델 검색에 `GET /v1/models`, 요청 처리에 `POST /v1/chat/completions`를 사용합니다. 요청은 opencodex의 일반 모델 라우팅을 거치므로 다른 클라이언트와 마찬가지로 프로바이더 자격 증명, OAuth 계정, 콤보가 적용됩니다. 허용되는 요청 필드는 [프록시 형식 레퍼런스](/reference/proxy-formats/)를 확인하세요. 모델이 없다고 표시되면 Base URL이 `/v1/chat/completions`가 아니라 `/v1`로 끝나는지, `/v1/models`가 비어 있지 않은 `data` 배열을 반환하는지 확인하세요. opencodex가 루프백이 아닌 주소에서 수신 대기한다면 앱의 API key 입력란에 데이터 수용 키([원격 액세스](/reference/configuration/server/#remote-access)에 설명된 토큰 또는 대시보드에서 생성한 `ocx_…` 키)를 입력하세요. 앱은 이를 `Authorization: Bearer`로 전송하며, `/v1/chat/completions`는 프록시 수용 인증에만 사용하고 upstream으로 전달하지 않습니다. 자세한 내용은 [인증 매트릭스](/reference/proxy-formats/#authentication-matrix)를 확인하세요. + +## Factory Droid + +Factory Droid는 `~/.factory/settings.json`(Windows에서는 `%USERPROFILE%\.factory\settings.json`)을 사용합니다. `ocx integration client enable --client droid`로 명시적으로 활성화한 다음 `/model`에서 사용자 지정 모델을 선택하세요. 관리되는 항목에는 키가 없으며 루프백에서만 동작합니다. 비활성화하면 관리되는 항목이 제거되고, Undo는 저장된 원본 바이트를 복원합니다. 기존 `config.json`에 OpenCodex 항목이 있거나 `settings.local.json`이 `customModels`를 덮어쓰면 활성화 전에 충돌을 해결하세요. [Factory BYOK 문서](https://docs.factory.ai/model-independence/byok)를 참고하세요. 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 8dec1675fc8..1a26b811bf9 100644 --- a/docs-site/src/content/docs/ko/reference/cli/agents.md +++ b/docs-site/src/content/docs/ko/reference/cli/agents.md @@ -163,7 +163,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의 네이티브 형식으로 직렬화합니다. @@ -171,7 +171,7 @@ Grok Build model fence를 관리하고 적용합니다. | 플래그 | 동작 | | --- | --- | -| `--client ` | 필수입니다. 클라이언트 설정 형식을 선택합니다. | +| `--client ` | 필수입니다. 클라이언트 설정 형식을 선택합니다. | | `--json` | config JSON만 stdout에 출력하므로, redirect가 byte-exact 출력을 캡처합니다. `--out` write note를 포함한 모든 진단 메시지는 stderr로 갑니다. | | `--out ` | config를 ``에 씁니다. 기존 파일이 있으면 덮어쓰지 않습니다. | | `--force` | `--out`이 기존 파일을 덮어쓰도록 허용합니다. | @@ -201,6 +201,8 @@ ocx export --client opencode --out ~/opencodex-opencode.json | `aside` | `~/.aside/u//models.json`. Aside의 `accounts.json`이 현재 계정으로 지정한 account를 사용합니다. 매니페스트를 읽을 수 없으면 임의의 계정으로 넘어가지 않고 거부합니다 | `aside-models.json` | 없음 — loopback placeholder | | `raycast` | `~/.config/raycast/ai/providers.yaml` (macOS와 Windows 모두 동일. Raycast는 `XDG_CONFIG_HOME`을 따르지 않습니다) | `raycast-providers.yaml` | 없음 — loopback 전용. `api_keys` 항목은 쓰지 않습니다 | | `omo` | `~/.omo/agent/models.json` (`OMO_CODING_AGENT_DIR`, `SENPI_CODING_AGENT_DIR`, `PI_CODING_AGENT_DIR` 순서로 설정된 값이 우선. 상대 경로는 거부됩니다) | `omo-models.json` | 없음 — loopback placeholder | +| `kilo` | `~/.config/kilo`에서 먼저 존재하는 `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` 또는 `config.json` (`XDG_CONFIG_HOME`이 설정되면 해당 디렉터리 사용); 후보가 없으면 `kilo.jsonc` | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | 루프백 전용, 환경 변수 불필요 | Raycast 내보내기는 `providers` 시퀀스에 `id: opencodex` 요소 하나만 담은 독립 `providers.yaml` 문서입니다. 내용은 `name: OpenCodex`, proxy의 `/v1` base URL, 그리고 `abilities`가 붙은 라우팅된 모든 모델입니다(`tools`와 `system_message`는 항상 지원, `vision`은 카탈로그의 입력 모달리티를 따름, `reasoning_effort`는 모델에 effort 사다리가 있을 때, `temperature`는 추론 모델에서 꺼짐). Custom Providers는 Raycast Pro 기능이며, Raycast가 이 파일을 감시하므로 저장한 변경은 재시작 없이 적용됩니다. 형식은 [manual.raycast.com/ai/custom-providers](https://manual.raycast.com/ai/custom-providers)에 문서화되어 있습니다. `api_keys` 항목은 쓰지 않으므로 이 내보내기는 loopback 전용이며, loopback이 아닌 bind는 거부됩니다. 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 b2a71843a4e..e166d1e50ba 100644 --- a/docs-site/src/content/docs/ko/reference/configuration/server.md +++ b/docs-site/src/content/docs/ko/reference/configuration/server.md @@ -243,4 +243,4 @@ Anthropic OAuth 사이드카는 opencodex의 기존 Claude Code OAuth fingerprin ## Codex 할당량 네트워크 진단 -메인 Codex 계정 행의 `quotaRefresh`는 할당량 조회 결과를 분류하는 진단값입니다. 남은 할당량이나 모델 접근 권한을 뜻하지 않으며, 캐시를 쓰거나 조회하지 않았다면 생략될 수 있습니다. 요청은 명령을 입력한 터미널이 아니라 실행 중인 프록시 서비스의 환경을 따릅니다. `proxy`를 지정하지 않으면 기존 환경을 유지하고, `"auto"`는 시작할 때 Windows의 정적 프록시 설정만 읽습니다. PAC/WPAD, SOCKS 전용 설정과 실행 중 변경은 자동으로 반영하지 않습니다. TUN에서 성공했다고 HTTP 프록시 경로도 정상이라는 뜻은 아닙니다. 명령과 상태값은 [네트워크 진단(영문)](/reference/configuration/server/#codex-quota-network-diagnostics)에서 확인하세요. +메인 Codex 계정 행의 `quotaRefresh`는 할당량 조회 결과를 분류하는 진단값입니다. 남은 할당량이나 모델 접근 권한을 뜻하지 않으며, 캐시를 쓰거나 조회하지 않았다면 생략될 수 있습니다. 요청은 명령을 입력한 터미널이 아니라 실행 중인 프록시 서비스의 환경을 따릅니다. `proxy`를 지정하지 않으면 기존 환경을 유지하고, `"auto"`는 시작 시 Windows 또는 macOS의 정적 HTTP/HTTPS 설정을 읽습니다. macOS에서는 상속된 프록시가 있으면 읽지 않습니다. macOS에서는 유효한 `*.`을 `.`으로 바꿉니다. `*.local`은 `foo.local`과 최상위 이름 `local`을 직접 연결하지만 `xlocal`은 제외합니다. `169.254/16`, `169.254.0.0/16`, `fe80::/10`은 진단 메시지와 함께 생략하므로 링크 로컬 IP 주소는 프록시를 사용합니다. IP 주소와 `*`는 허용하지만 다른 CIDR, glob, 단순 호스트명 예외는 환경 변경 전에 탐색을 거부합니다. PAC/WPAD, SOCKS 전용 설정과 실행 중 변경은 자동으로 반영하지 않습니다. TUN에서 성공했다고 HTTP 프록시 경로도 정상이라는 뜻은 아닙니다. 명령과 상태값은 [네트워크 진단(영문)](/reference/configuration/server/#codex-quota-network-diagnostics)에서 확인하세요. diff --git a/docs-site/src/content/docs/reference/cli/agents.md b/docs-site/src/content/docs/reference/cli/agents.md index 3d2e1a57aa1..933e2fc6baa 100644 --- a/docs-site/src/content/docs/reference/cli/agents.md +++ b/docs-site/src/content/docs/reference/cli/agents.md @@ -283,7 +283,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 @@ -294,7 +294,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. | @@ -326,6 +326,8 @@ client applies its own defaults for those). | `aside` | `~/.aside/u//models.json` for the account Aside's own `accounts.json` names as current; an unreadable manifest is refused rather than defaulting to an account | `aside-models.json` | none — loopback placeholder | | `raycast` | `~/.config/raycast/ai/providers.yaml` on macOS and Windows alike (Raycast does not honor `XDG_CONFIG_HOME`) | `raycast-providers.yaml` | none — loopback only, no `api_keys` entry is written | | `omo` | `~/.omo/agent/models.json` (`OMO_CODING_AGENT_DIR`, then `SENPI_CODING_AGENT_DIR`, then `PI_CODING_AGENT_DIR` win in that order when set; a relative value is refused) | `omo-models.json` | none — loopback placeholder | +| `kilo` | first existing `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json`, or `config.json` under `~/.config/kilo` (`XDG_CONFIG_HOME` relocates that directory); uses `kilo.jsonc` when none exists | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | loopback only; no environment variable | 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 diff --git a/docs-site/src/content/docs/reference/configuration.md b/docs-site/src/content/docs/reference/configuration.md index 3a299fa7f98..909edc30e26 100644 --- a/docs-site/src/content/docs/reference/configuration.md +++ b/docs-site/src/content/docs/reference/configuration.md @@ -61,7 +61,7 @@ a known configured model id. Cursor may require a model-list refresh or restart `fastRows` is an optional boolean and defaults to `true`. The raw OpenAI-style `/v1/models` list, Claude Code discovery, and client config exports (including pi, OpenCode, -OMP, Hermes, OpenClaw, Kimi, gjc, DSH, MCode, ZCode, Prime, Aside, Raycast, and omo) add a `--fast` selector for every model whose +OMP, Hermes, OpenClaw, Kimi, gjc, DSH, MCode, ZCode, Prime, Aside, Raycast, omo, Cline, and Kilo) add a `--fast` selector for every model whose resolved Fast policy is eligible. Selecting one routes the base model and requests the `priority` service tier — the same Fast the Codex app exposes through its picker toggle. The base row stays listed, so the row is an addition rather than a replacement. diff --git a/docs-site/src/content/docs/reference/configuration/server.md b/docs-site/src/content/docs/reference/configuration/server.md index c8e9f967ffb..f0d92698dbf 100644 --- a/docs-site/src/content/docs/reference/configuration/server.md +++ b/docs-site/src/content/docs/reference/configuration/server.md @@ -12,7 +12,7 @@ runs helper features around provider requests. | --- | --- | --- | --- | | `port` | `number` | `10100` | Proxy listen port. | | `hostname?` | `string` | `"127.0.0.1"` | Bind address. A non-loopback bind requires a data-admission token, resolved from `OPENCODEX_API_AUTH_TOKEN`, then `OCX_API_TOKEN_FILE`, then the installed owner-only `service-api-token` — nothing has to be exported by hand. See [Remote access](#remote-access). | -| `proxy?` | `string` | — | Outbound HTTP(S) or SOCKS5 proxy URL (`socks5://host:port`), `${ENV_VAR}`, or `"auto"`. HTTP URLs apply to `HTTP_PROXY` / `HTTPS_PROXY` when those are unset. SOCKS5 URLs use OpenCodex's real SOCKS5 transport and are also exposed through `ALL_PROXY` (`ocx start --socks5`); inherited `HTTP(S)_PROXY` is cleared in this process. Loopback stays in `NO_PROXY`. `"auto"` reads the Windows system proxy (WinINET `ProxyEnable`/`ProxyServer`) once at process start, preserves distinct `http=` and `https=` entries, and logs the hosts it chose. A bare `ProxyServer` value applies to both schemes. On other platforms, or when the system proxy is off, SOCKS-only, or unreadable, it uses direct egress and says so. PAC/WPAD and live proxy changes are not followed; restart the service after changing the system proxy. | +| `proxy?` | `string` | — | Outbound HTTP(S) or SOCKS5 proxy URL (`socks5://host:port`), `${ENV_VAR}`, or `"auto"`. HTTP URLs apply to `HTTP_PROXY` / `HTTPS_PROXY` when those are unset. SOCKS5 URLs use OpenCodex's real SOCKS5 transport and are also exposed through `ALL_PROXY` (`ocx start --socks5`); inherited `HTTP(S)_PROXY` is cleared in this process. Loopback stays in `NO_PROXY`. `"auto"` reads Windows WinINET or macOS static HTTP/HTTPS settings once at startup. Inherited HTTP(S) proxy variables skip discovery; on macOS, inherited `ALL_PROXY`/`all_proxy` also skips it. Windows keeps separate `http=` and `https=` entries; a bare `ProxyServer` applies to both. macOS translates IP literals, `*`, and a valid `*.` glob to Bun's `.` bypass. That glob also bypasses the bare apex ``. The exact link-local ranges `169.254/16`, `169.254.0.0/16`, and `fe80::/10` are omitted with a diagnostic: link-local IP literals use the proxy. Other CIDRs, globs, and simple-host exceptions refuse discovery without changing the proxy environment. Disabled, malformed, PAC/WPAD, SOCKS-only, and live changes are not followed. Restart after changing system settings. | | `noProxy?` | `string \| string[]` | — | Hosts that bypass `proxy`, merged with inherited `NO_PROXY` and loopback entries. A string may use comma-separated `NO_PROXY` syntax or `${ENV_VAR}`. | | `emptyCompletionRetry?` | `boolean` | `false` | Opt in to one identical Responses retry when a turn has no text or tool call, including a stream that ends before a terminal event. The retry may be billable. `OCX_EMPTY_COMPLETION_RETRY=0` disables it without changing config; combo and routed-compaction turns remain excluded. | | `dropCodexSafetyBuffering?` | `boolean` | `false` | Remove optional client-facing hints from canonical Codex Responses passthrough: the two `x-codex-safety-buffering-enabled` / `x-codex-safety-buffering-faster-model` response headers, `response.metadata` events whose metadata type is `safety_buffering`, and top-level `safety_buffering` fields. Other headers, response data, policy refusals and failures are preserved. This does not disable provider safety enforcement or upstream buffering. Native `codex.response.metadata.headers` WebSocket metadata and `/responses/compact` are outside this filter. | @@ -41,6 +41,7 @@ runs helper features around provider requests. | `resetCreditAutoRedeem?` | `{ enabled?: boolean; leadTimeMinutes?: number }` | off | Opt-in: redeem the main Codex account's soonest-expiring reset credit `leadTimeMinutes` (1–60, default 10) before it expires. Every attempt re-reads the upstream credit list first and skips when the credit is gone (for example, redeemed by hand); the `redeem_request_id` is journaled in `$OPENCODEX_HOME/reset-credit-auto-redeem.json` before the call so a crash replays the same idempotent request instead of spending a second credit. Servers sharing this configuration directory coordinate reservations and settlements so one process does not replace another's request record. Logs carry a hashed account key only. | | `syncResumeHistory?` | `boolean` | `true` | Reversible Codex App history compatibility. Original metadata is backed up and restored by `ocx stop` / `ocx restore`. | | `shadowCallIntercept?` | `{ enabled?: boolean; model?: string; sourceModels?: string[] }` | off | Redirect recognized Codex helper/shadow calls to a chosen model while preserving the request's configured reasoning effort. The default source prefixes are `gpt-6-luna` and `gpt-5.6-luna`; older clients through 0.144.x used `gpt-5.4-mini`, which `sourceModels` can restore. | +| `memoryModels?` | `{ extract?: { model: string; reasoningEffort?: string }; consolidation?: { model: string; reasoningEffort?: string } }` | off | Route Codex's two memory phases to a chosen model, with an optional reasoning effort per phase. See [Memory routing](#memory-routing). | | `webSearchSidecar?` | `OcxWebSearchSidecarConfig` | on when usable | Web-search sidecar options. | | `visionSidecar?` | `OcxVisionSidecarConfig` | on when usable | Image-description sidecar options. | | `images?` | `OcxImagesConfig` | automatic OpenAI selection | Standalone Images relay options for Codex `image_gen`. | @@ -164,8 +165,14 @@ terminal does not update an already running service. An unset `proxy` leaves inherited proxy variables unchanged. An explicit HTTP(S) proxy URL fills `HTTP_PROXY` and `HTTPS_PROXY` only where they are unset. -`"proxy": "auto"` reads the Windows static WinINET proxy once at startup; existing -proxy environment variables take precedence. Auto discovery does not resolve +`"proxy": "auto"` reads Windows static WinINET or macOS static HTTP/HTTPS +settings once at startup. Existing proxy environment variables take precedence; +macOS discovery also skips inherited `ALL_PROXY`/`all_proxy`. A macOS `*.` +exception becomes `.`: `foo.local` bypasses for `*.local`, `xlocal` +does not, and the bare `local` apex also bypasses. Exact link-local CIDRs +are dropped with a warning, so link-local IP literals use the proxy. Other +unrepresentable exceptions refuse discovery without changing proxy variables. +Auto discovery does not resolve PAC/WPAD, SOCKS-only settings or live proxy changes. Use a supported static HTTP proxy setting or an explicit HTTP(S) proxy URL when needed. @@ -658,6 +665,55 @@ caller's credential does not cross to the other provider. The selected model mus input size and content. Restart the proxy after editing `config.json` by hand. Dashboard saves apply immediately. +## Memory routing + +In **Dashboard → Overview → Memory routing**, choose a model and an optional reasoning effort for +each of Codex's two memory phases, then click **Save**. Select **Off** and save to +remove the override. Changes apply to the next memory request without restarting the proxy. + +Set `memoryModels` in OpenCodex `config.json` to route those requests. With the block omitted, +both phases keep their existing route. The phases are independent: configuring one leaves the +other alone. + +```json +{ + "memoryModels": { + "extract": { "model": "provider/model-id", "reasoningEffort": "low" }, + "consolidation": { "model": "provider/model-id", "reasoningEffort": "medium" } + } +} +``` + +`extract` is the pass that summarizes one finished session into a raw memory; `consolidation` is the +single agent run that merges those raw memories into the files under `$CODEX_HOME/memories`. +`model` accepts native model IDs, provider-qualified model IDs, and configured combos. +`reasoningEffort` is optional; omit it to keep the effort Codex asked for. Supported declarations are +`none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`, and `ultra`. Codex hard-codes `low` for +extract and `medium` for consolidation, so a configured effort replaces that value. + +OpenCodex recognizes these requests from Codex's own turn metadata: `request_kind: "memory"` in +the `x-codex-turn-metadata` header marks an extract pass, and `thread_source: +"memory_consolidation"` marks the consolidation thread. On HTTP, a request whose +`x-openai-subagent` header names `memory_consolidation` counts as a consolidation pass only when +turn metadata is absent. Explicit non-memory metadata wins over that fallback. The model id is +deliberately not a signal: the extract pass runs on the same helper model +Codex uses for titles and commit messages, so a model-based rule would also capture ordinary +helper calls. Missing, malformed, or conflicting metadata does not activate the override; when +several copies of the metadata are supplied they must name the same phase. WebSocket requests use +each frame's metadata rather than the connection's earlier handshake metadata — the bridge +re-attaches the handshake's `x-openai-subagent` header to every frame, so that header names the +connection, not the current pass, and is not a websocket signal. + +A configured phase wins when `shadowCallIntercept` would match the same request. A phase left off +keeps its current routing, including any existing shadow-call rule that matches its model. The +selected model's provider receives the session text Codex summarizes for memory, including +sessions that normally run on another provider; the dashboard panel states this next to the model +pickers. A phase whose target stopped resolving — the provider is +disabled or deleted, or its combo no longer exists — fails that memory call with `409` and error code +`memory_model_target_unavailable` instead of falling back to the default provider. The request log +names the phase (`memory-extract` or `memory-consolidation`) as the routing reason. Restart the +proxy after editing `config.json` by hand. Dashboard saves apply immediately. + ## Shadow calls Codex uses small helper models for tasks such as titles and commit messages. Enable diff --git a/docs-site/src/content/docs/ru/guides/integrations.md b/docs-site/src/content/docs/ru/guides/integrations.md index 2bbf27ba135..d6ae86fa896 100644 --- a/docs-site/src/content/docs/ru/guides/integrations.md +++ b/docs-site/src/content/docs/ru/guides/integrations.md @@ -1,10 +1,10 @@ --- title: Интеграции -description: Подключайте opencodex к OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo и Cline CLI из дашборда — отдельный переключатель для каждого клиента и резервная копия перед каждой записью. +description: Подключайте opencodex к OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo и Factory Droid из дашборда — отдельный переключатель для каждого клиента и резервная копия перед каждой записью. --- Вкладка **Integrations** записывает блок провайдера opencodex в собственный файл -конфигурации клиента и при необходимости удаляет его. Так работают пятнадцать +конфигурации клиента и при необходимости удаляет его. Так работают семнадцать клиентов, у каждого свой переключатель: | Клиент | Файл конфигурации | Формат | Когда изменение начинает действовать | Учётные данные | @@ -24,6 +24,8 @@ description: Подключайте opencodex к OpenCode, Pi, OMP, Hermes, Open | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | сразу после сохранения — Raycast следит за файлом | нет — только loopback | | omo | `~/.omo/agent/models.json` | JSON | в новых сессиях | заглушка для loopback | | Cline CLI | `~/.cline/data/settings/providers.json` и соседний `models.json` | пара JSON | после остановки и повторного запуска Cline | заглушка для loopback | +| Kilo | первый существующий файл среди `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` и `config.json` в `~/.config/kilo` (`XDG_CONFIG_HOME` переносит каталог; если файлов нет, создаётся `kilo.jsonc`) | JSONC | в новых сессиях | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` в Windows) | JSON | сразу при изменении файла | loopback без ключа | Создаваемые каталоги включают только модели, включённые в настройках каждого провайдера. Это относится и к скачиваемым файлам, и к управляемым интеграциям, @@ -530,6 +532,21 @@ OpenCodex требует явного `--overwrite-conflict`. Отключени поддерживает удалённую настройку допуска и требует loopback-доступа без аутентификации. +## Kilo + +Kilo CLI, VS Code и JetBrains используют общую глобальную конфигурацию. Интеграция записывает `provider.opencodex` в первый существующий файл среди `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` и `config.json` в `~/.config/kilo`. Переменная `XDG_CONFIG_HOME` переносит этот каталог. Если файлов нет, создаётся `kilo.jsonc`. Конфигурация проекта не изменяется. + +Kilo объединяет все эти глобальные файлы. Если другой файл-кандидат тоже определяет `provider.opencodex`, статус перечисляет конфликтующие файлы, а применение и замена отклоняются. Перед включением удалите `provider.opencodex` из этих файлов. Отключение уже принадлежащего OpenCodex блока доступно и при таком конфликте. Нечитаемый или небезопасный файл-кандидат также блокирует запись. + +Интеграции принадлежит только `provider.opencodex` в формате OpenCode V1 (`npm`, `options`, `models`). Поле OpenCode V2 `providers` не создаётся. `$schema`, `model`, `enabled_providers`, MCP и прочие ключи остаются под управлением пользователя. После применения выберите в Kilo `opencodex/`. + +Для loopback значение `options.apiKey` — `{env:OPENCODEX_KILO_API_KEY}`. При привязке не к loopback авторизация переносится в `options.headers["x-opencodex-api-key"]`; настоящий ключ не записывается. Применение переписывает весь глобальный файл как форматированный JSON, поэтому комментарии и завершающие запятые в других ключах не сохраняются. Kilo не участвует в автоматическом обновлении каталога; после изменения выбора маршрутизируемых моделей обновите интеграцию явно. + +```bash +ocx integration client enable --client kilo +ocx export --client kilo --out ./kilo.jsonc +``` + ## Приложение GitHub Copilot Настольное приложение GitHub Copilot может использовать opencodex как совместимого с OpenAI поставщика моделей. Это ручная настройка клиента без переключателя на вкладке Integrations. Она не связана с upstream-провайдером `github-copilot`, который использует подписку Copilot как backend для opencodex. @@ -554,3 +571,7 @@ OpenCodex требует явного `--overwrite-conflict`. Отключени Для получения списка моделей приложение использует `GET /v1/models`, а для запросов — `POST /v1/chat/completions`. Запросы проходят через обычную маршрутизацию моделей opencodex, поэтому применяются учётные данные провайдера, OAuth-аккаунты и комбинации моделей, как и для любого другого клиента. Поддерживаемые поля запроса перечислены в [справочнике форматов прокси](/reference/proxy-formats/). Если приложение сообщает, что моделей нет, проверьте, что Base URL заканчивается на `/v1`, а не на `/v1/chat/completions`, и что `/v1/models` возвращает непустой массив `data`. Если opencodex слушает адрес вне loopback, укажите в поле API key ключ допуска данных (токен из раздела [удалённого доступа](/reference/configuration/server/#remote-access) или созданный в дашборде ключ `ocx_…`). Приложение отправляет его как `Authorization: Bearer`; `/v1/chat/completions` использует его только для допуска к прокси и не пересылает upstream. Подробнее см. [матрицу аутентификации](/reference/proxy-formats/#authentication-matrix). + +## Factory Droid + +Factory Droid использует `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` в Windows). Явно включите интеграцию командой `ocx integration client enable --client droid`, затем выберите пользовательскую модель через `/model`. Управляемые записи не содержат ключа и работают только через loopback. Отключение удаляет управляемые записи, а Undo восстанавливает сохранённые байты. Если в прежнем `config.json` есть записи OpenCodex или `settings.local.json` переопределяет `customModels`, устраните конфликт до включения. См. [документацию Factory BYOK](https://docs.factory.ai/model-independence/byok). 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 e2ad3a31e22..c1835afff88 100644 --- a/docs-site/src/content/docs/ru/reference/cli/agents.md +++ b/docs-site/src/content/docs/ru/reference/cli/agents.md @@ -163,7 +163,7 @@ override, но файлы на диске никогда не меняются. ## Экспорт client config -### `ocx export --client ` +### `ocx export --client ` Печатает client config, направленный на работающий прокси. Команда сериализует блок провайдера `opencodex` в нативном формате выбранного клиента: base URL, список моделей и, @@ -174,7 +174,7 @@ override, но файлы на диске никогда не меняются. | Флаг | Действие | | --- | --- | -| `--client ` | Обязателен. Выбирает формат конфигурации клиента. | +| `--client ` | Обязателен. Выбирает формат конфигурации клиента. | | `--json` | Печатать только JSON-конфиг в stdout, чтобы redirect сохранял побайтно точный вывод. Вся диагностика, включая заметку о записи через `--out`, идёт в stderr. | | `--out ` | Записать конфиг в ``. Перезаписывать существующий файл не позволит. | | `--force` | Разрешить `--out` заменить существующий файл. | @@ -207,6 +207,8 @@ ocx export --client opencode --out ~/opencodex-opencode.json | `aside` | `~/.aside/u//models.json` для аккаунта, который `accounts.json` самого Aside называет текущим; нечитаемый манифест отклоняется, а не подменяется произвольным аккаунтом | `aside-models.json` | нет — loopback placeholder | | `raycast` | `~/.config/raycast/ai/providers.yaml` одинаково на macOS и Windows (Raycast не учитывает `XDG_CONFIG_HOME`) | `raycast-providers.yaml` | нет — только loopback, запись `api_keys` не создаётся | | `omo` | `~/.omo/agent/models.json` (`OMO_CODING_AGENT_DIR`, затем `SENPI_CODING_AGENT_DIR`, затем `PI_CODING_AGENT_DIR` имеют приоритет в этом порядке, если заданы; относительное значение отклоняется) | `omo-models.json` | нет — loopback placeholder | +| `kilo` | первый существующий файл среди `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` или `config.json` в `~/.config/kilo` (`XDG_CONFIG_HOME` переносит каталог); если ни одного нет, используется `kilo.jsonc` | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | только loopback; переменная окружения не нужна | Экспорт для Raycast — это отдельный документ `providers.yaml` с одним элементом `id: opencodex` в последовательности `providers`: `name: OpenCodex`, базовый URL прокси с `/v1` и каждая маршрутизируемая 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 f2a7bc704ab..2a4dcb20c68 100644 --- a/docs-site/src/content/docs/ru/reference/configuration/server.md +++ b/docs-site/src/content/docs/ru/reference/configuration/server.md @@ -232,6 +232,6 @@ opencodex. Перед использованием прогоните soak-test ## Сетевая диагностика квоты Codex -Поле `quotaRefresh` в строке основного аккаунта Codex описывает получение квоты, а не её остаток или право доступа к модели. Оно может отсутствовать при чтении кэша или если запрос не выполнялся. Используется окружение работающего прокси-сервиса, а не текущего терминала. Если `proxy` не задан, существующее окружение сохраняется; `"auto"` читает только статические настройки прокси Windows при запуске. PAC/WPAD, настройки только SOCKS и изменения во время работы автоматически не учитываются. Успех через TUN сам по себе не подтверждает исправность пути HTTP-прокси. См. [команды и состояния на английском](/reference/configuration/server/#codex-quota-network-diagnostics). +Поле `quotaRefresh` в строке основного аккаунта Codex описывает получение квоты, а не её остаток или право доступа к модели. Оно может отсутствовать при чтении кэша или если запрос не выполнялся. Используется окружение работающего прокси-сервиса, а не текущего терминала. Если `proxy` не задан, существующее окружение сохраняется; `"auto"` при запуске читает статические настройки HTTP/HTTPS Windows или macOS. На macOS унаследованный прокси отменяет это чтение. На macOS допустимый шаблон `*.` преобразуется в `.`: для `*.local` прямое соединение получают `foo.local` и само имя `local`, но не `xlocal`. Точные диапазоны `169.254/16`, `169.254.0.0/16` и `fe80::/10` пропускаются с диагностикой: link-local IP-адреса используют прокси. IP-адреса и `*` принимаются; прочие CIDR, glob-шаблоны и исключения простых имён отменяют обнаружение без изменения окружения. PAC/WPAD, настройки только SOCKS и изменения во время работы автоматически не учитываются. Успех через TUN сам по себе не подтверждает исправность пути HTTP-прокси. См. [команды и состояния на английском](/reference/configuration/server/#codex-quota-network-diagnostics). `dropCodexSafetyBuffering`: не меняет проверки безопасности провайдера или отказы. Native WebSocket `codex.response.metadata.headers` и `/responses/compact` не входят в область фильтра. diff --git a/docs-site/src/content/docs/tr/guides/integrations.md b/docs-site/src/content/docs/tr/guides/integrations.md index 71d77a09e5b..7d1731ca433 100644 --- a/docs-site/src/content/docs/tr/guides/integrations.md +++ b/docs-site/src/content/docs/tr/guides/integrations.md @@ -1,10 +1,10 @@ --- title: Entegrasyonlar -description: Kontrol panelinden OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast ve omo'yu opencodex'e bağlayın — istemci başına tek bir anahtar ve her yazmadan önce alınan bir yedek. +description: Kontrol panelinden OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo ve Factory Droid'u opencodex'e bağlayın — istemci başına tek bir anahtar ve her yazmadan önce alınan bir yedek. --- **Entegrasyonlar** sekmesi, opencodex'in sağlayıcı bloğunu istemcinin kendi -yapılandırma dosyasına yazar ve tekrar kaldırır. On beş istemci bu şekilde +yapılandırma dosyasına yazar ve tekrar kaldırır. On yedi istemci bu şekilde çalışır, her biri bir anahtarla: | İstemci | Yapılandırma dosyası | Format | Değişiklik ne zaman geçerli olur? | Kimlik bilgisi | @@ -24,6 +24,8 @@ yapılandırma dosyasına yazar ve tekrar kaldırır. On beş istemci bu şekild | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | kaydedildiği anda — Raycast dosyayı izler | yok — yalnızca geri döngü | | omo | `~/.omo/agent/models.json` | JSON | yeni oturumlarda | geri döngü yer tutucusu | | Cline CLI | `~/.cline/data/settings/providers.json` + `models.json` | JSON | kapatıp yeniden başlattıktan sonra | yalnızca loopback | +| Kilo | `~/.config/kilo` altında ilk bulunan `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` veya `config.json` (`XDG_CONFIG_HOME` bu dizini taşır; hiçbiri yoksa `kilo.jsonc` oluşturulur) | JSONC | yeni oturumlarda | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` Windows'ta) | JSON | dosya değişince hemen | anahtarsız geri döngü | Desteklenen akıl yürütme düzeylerine sahip GJC modelleri, GJC'nin düzey seçimi sunabilmesi için `reasoning: true`, `thinking.levels` ve `compat.supportsReasoningEffort` alanlarını dışa aktarır. Yerel Codex modelleri, katalogda belirtilmese bile standart düzeylerini alır. Bilinen düzeyi olmayan modellerde bu alanlar bulunmaz. `none` düzey göndermez ve `ultra` gönderimde `max` düzeyine dönüşür; bu yüzden seçeneklerde yer almazlar. Model seçeneklerini güncellemek için entegrasyonu yenileyin. @@ -324,3 +326,17 @@ ocx integration client restore --op ``` [CLI / rollback / CLINE_PROVIDER_SETTINGS_PATH](/guides/integrations/#cline-cli). + +## Kilo + +Kilo yalnızca `~/.config/kilo` altındaki ilk mevcut genel dosyada `provider.opencodex` yazar (`XDG_CONFIG_HOME` bu dizini taşır; hiçbir aday yoksa `kilo.jsonc` oluşturulur). Başka bir aday dosya da `provider.opencodex` tanımlıyorsa durum çakışma bildirir ve Uygula işlemi reddedilir. Diğer anahtarlar değişmez. Uygula dosyanın tamamını yeniden yazar; yorumlar ve sondaki virgüller korunmaz. Kilo’da `opencodex/` seçin. + +Başka bir aday çakışsa veya ayrıştırılamasa bile Devre Dışı Bırak, kaydedilen dosyadaki OpenCodex'e ait bloğu kaldırabilir; diğer aday dosya değişmez. + +```bash +ocx integration client enable --client kilo +``` + +## Factory Droid + +Factory Droid, `~/.factory/settings.json` dosyasını (Windows'ta `%USERPROFILE%\.factory\settings.json`) kullanır. `ocx integration client enable --client droid` komutuyla açıkça etkinleştirin, ardından `/model` içinde özel bir model seçin. Yönetilen satırlar anahtarsızdır ve yalnızca geri döngü bağlantısında çalışır. Devre dışı bırakma yönetilen satırları kaldırır; Undo kaydedilen baytları geri yükler. Eski `config.json` dosyasında OpenCodex satırları varsa veya `settings.local.json`, `customModels` değerini geçersiz kılıyorsa etkinleştirmeden önce çakışmayı giderin. [Factory BYOK belgelerine](https://docs.factory.ai/model-independence/byok) 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 c1fb9849612..5a610d045d3 100644 --- a/docs-site/src/content/docs/tr/reference/cli/agents.md +++ b/docs-site/src/content/docs/tr/reference/cli/agents.md @@ -202,7 +202,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 @@ -214,7 +214,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. | @@ -247,6 +247,8 @@ için kendi varsayılanlarını uygular) gelir. | `aside` | Aside'ın kendi `accounts.json` dosyasının güncel olarak gösterdiği hesap için `~/.aside/u//models.json`; okunamayan bir manifest, gelişigüzel bir hesaba düşmek yerine reddedilir | `aside-models.json` | yok — geri döngü yer tutucusu | | `raycast` | `~/.config/raycast/ai/providers.yaml`, macOS ve Windows'ta aynı (Raycast `XDG_CONFIG_HOME` değerini dikkate almaz) | `raycast-providers.yaml` | yok — yalnızca geri döngü, `api_keys` girdisi yazılmaz | | `omo` | `~/.omo/agent/models.json` (ayarlandığında sırasıyla `OMO_CODING_AGENT_DIR`, `SENPI_CODING_AGENT_DIR`, `PI_CODING_AGENT_DIR` öncelikli; göreli değer reddedilir) | `omo-models.json` | yok — geri döngü yer tutucusu | +| `kilo` | `~/.config/kilo` altında ilk bulunan `kilo.jsonc`, `kilo.json`, `opencode.jsonc`, `opencode.json` veya `config.json` (`XDG_CONFIG_HOME` bu dizini taşır); hiçbiri yoksa `kilo.jsonc` kullanılır | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | yalnızca loopback; ortam değişkeni gerekmez | Raycast dışa aktarımı, `providers` dizisinde tek bir `id: opencodex` öğesi içeren bağımsız bir `providers.yaml` belgesidir: `name: OpenCodex`, proxy'nin `/v1` temel URL'si ve 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 71524df464a..a4d69c1f4a0 100644 --- a/docs-site/src/content/docs/tr/reference/configuration/server.md +++ b/docs-site/src/content/docs/tr/reference/configuration/server.md @@ -304,4 +304,4 @@ yeniden kullanır. Hedeflenen hesap ve iş yükünü kapsamlı bir şekilde test ## Codex kota ağı tanılaması -Ana Codex hesabının satırındaki `quotaRefresh`, kalan kotayı veya model erişim yetkisini değil, kota sorgusunun sonucunu açıklar. Önbellek kullanıldığında ya da sorgu yapılmadığında alan bulunmayabilir. Sorgu, etkileşimli terminalin değil çalışan proxy servisinin ortamını kullanır. `proxy` ayarlanmazsa mevcut ortam korunur; `"auto"` yalnızca başlangıçta Windows’un statik proxy ayarlarını okur. PAC/WPAD, yalnızca SOCKS ayarları ve çalışma sırasındaki değişiklikler otomatik uygulanmaz. TUN ile başarı, HTTP proxy yolunun da çalıştığını tek başına göstermez. [Komutlar ve durumlar için İngilizce bölüme](/reference/configuration/server/#codex-quota-network-diagnostics) bakın. +Ana Codex hesabının satırındaki `quotaRefresh`, kalan kotayı veya model erişim yetkisini değil, kota sorgusunun sonucunu açıklar. Önbellek kullanıldığında ya da sorgu yapılmadığında alan bulunmayabilir. Sorgu, etkileşimli terminalin değil çalışan proxy servisinin ortamını kullanır. `proxy` ayarlanmazsa mevcut ortam korunur; `"auto"` başlangıçta Windows veya macOS statik HTTP/HTTPS ayarlarını okur. macOS üzerinde devralınmış proxy varsa bu ayarlar okunmaz. macOS üzerinde geçerli `*.` kalıbı `.` olur: `*.local` için `foo.local` ve yalın `local` doğrudan gider, `xlocal` gitmez. Tam `169.254/16`, `169.254.0.0/16` ve `fe80::/10` aralıkları bir tanıyla atlanır; link-local IP adresleri proxy kullanır. IP adresleri ve `*` kabul edilir; diğer CIDR, glob ve yalın ana makine istisnaları ortam değiştirilmeden keşfi reddeder. PAC/WPAD, yalnızca SOCKS ayarları ve çalışma sırasındaki değişiklikler otomatik uygulanmaz. TUN ile başarı, HTTP proxy yolunun da çalıştığını tek başına göstermez. [Komutlar ve durumlar için İngilizce bölüme](/reference/configuration/server/#codex-quota-network-diagnostics) bakın. diff --git a/docs-site/src/content/docs/zh-cn/guides/integrations.md b/docs-site/src/content/docs/zh-cn/guides/integrations.md index 96b973d31fe..90018e3100a 100644 --- a/docs-site/src/content/docs/zh-cn/guides/integrations.md +++ b/docs-site/src/content/docs/zh-cn/guides/integrations.md @@ -1,9 +1,9 @@ --- title: 集成 -description: 从仪表盘将 opencodex 连接到 OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast、omo 和 Cline CLI;每个客户端都有独立开关,且每次写入前都会备份。 +description: 从仪表盘将 opencodex 连接到 OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast、omo、Cline CLI、Kilo 和 Factory Droid;每个客户端都有独立开关,且每次写入前都会备份。 --- -**Integrations** 标签页可将 opencodex 的提供商配置块写入客户端自己的配置文件,也可再次移除。以下 15 个客户端都采用这种方式,各有独立开关: +**Integrations** 标签页可将 opencodex 的提供商配置块写入客户端自己的配置文件,也可再次移除。以下 17 个客户端都采用这种方式,各有独立开关: | 客户端 | 配置文件 | 格式 | 变更生效时间 | 凭据 | |---|---|---|---|---| @@ -22,6 +22,8 @@ description: 从仪表盘将 opencodex 连接到 OpenCode、Pi、OMP、Hermes、 | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | 保存后立即生效——Raycast 监视该文件 | 无——仅回环 | | omo | `~/.omo/agent/models.json` | JSON | 新会话 | 回环占位符 | | Cline CLI | `~/.cline/data/settings/providers.json` 及同目录下的 `models.json` | JSON 文件对 | 停止并重启 Cline 后 | 回环占位符 | +| Kilo | `~/.config/kilo` 下最先存在的 `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json` 或 `config.json`(`XDG_CONFIG_HOME` 可迁移目录;均不存在时创建 `kilo.jsonc`) | JSONC | 新会话 | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` Windows 上) | JSON | 文件变更时立即生效 | 无密钥回环 | 生成的目录只包含各提供商选择中已启用的模型。下载文件和托管集成都遵循这一规则,Pi 和 Aside 也不例外。管理模型列表仍显示完整阵容,以便启用更多模型。 @@ -214,6 +216,21 @@ Undo 会恢复**两个原始字节串**,包括原本不存在的文件。操 下载文件 `cline-config-bundle.json` 包含两个原生文档成员:对应 `providers.json` 的 `settings`,以及对应 `models.json` 的 `catalog`。它本身不是 Cline 设置文件。建议使用集成命令,以获得带日志的合并和回滚。此生成集成不支持远程准入接线,需要免认证的回环访问。 +## Kilo + +Kilo CLI、VS Code 和 JetBrains 共用一份全局配置。此集成只在 `~/.config/kilo` 下最先存在的 `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json` 或 `config.json` 中写入 `provider.opencodex`。`XDG_CONFIG_HOME` 可以迁移该目录;如果候选文件均不存在,则创建 `kilo.jsonc`。不会修改项目配置。 + +Kilo 会合并所有这些全局文件。如果另一个候选文件也定义了 `provider.opencodex`,状态会列出冲突文件,应用和替换都会被拒绝。启用集成前,请从那些文件中移除 `provider.opencodex`。即使发生这种冲突,仍可禁用已归 OpenCodex 所有的配置块。无法读取或不安全的候选文件也会阻止写入。 + +仅 `provider.opencodex` 属于此集成,采用 OpenCode V1 结构(`npm`、`options`、`models`);不会输出 OpenCode V2 的 `providers` 键。`$schema`、`model`、`enabled_providers`、MCP 等键仍由用户管理。应用后,在 Kilo 中选择 `opencodex/`。 + +回环连接使用 `{env:OPENCODEX_KILO_API_KEY}` 作为 `options.apiKey`。非回环绑定将认证移到 `options.headers["x-opencodex-api-key"]`,且不会写入真实密钥。应用时会将整个全局文件重写为格式化 JSON,因此其他键中的注释和尾随逗号不会保留。Kilo 不参与自动目录刷新;更改路由模型选择后,请明确刷新此集成。 + +```bash +ocx integration client enable --client kilo +ocx export --client kilo --out ./kilo.jsonc +``` + ## GitHub Copilot 应用 GitHub Copilot 桌面应用可以将 opencodex 用作兼容 OpenAI 的模型提供方。这需要手动配置客户端,Integrations 标签页没有对应的开关;它也不同于上游 `github-copilot` 提供方,后者使用 Copilot 订阅作为 opencodex 的后端。 @@ -238,3 +255,7 @@ GitHub Copilot 桌面应用可以将 opencodex 用作兼容 OpenAI 的模型提 应用通过 `GET /v1/models` 发现模型,并通过 `POST /v1/chat/completions` 发送请求。这些请求经过 opencodex 的常规模型路由,因此与其他客户端一样会应用提供方凭据、OAuth 账户和组合路由。支持的请求字段见[代理格式参考](/reference/proxy-formats/)。 如果应用提示没有模型,请确认 Base URL 以 `/v1` 结尾,而不是 `/v1/chat/completions`,并确认 `/v1/models` 返回非空的 `data` 数组。如果 opencodex 监听的不是回环地址,请在应用的 API key 字段中填写数据准入密钥([远程访问](/reference/configuration/server/#remote-access)中说明的令牌,或由仪表盘生成的 `ocx_…` 密钥)。应用会将其作为 `Authorization: Bearer` 发送;`/v1/chat/completions` 仅将其用于代理准入,不会转发到上游。详见[认证矩阵](/reference/proxy-formats/#authentication-matrix)。 + +## Factory Droid + +Factory Droid 使用 `~/.factory/settings.json`(Windows 上为 `%USERPROFILE%\.factory\settings.json`)。使用 `ocx integration client enable --client droid` 明确启用,然后在 `/model` 中选择自定义模型。托管条目不含密钥,且仅支持回环连接。禁用会移除托管条目;Undo 会恢复保存的原始字节。如果旧版 `config.json` 含有 OpenCodex 条目,或 `settings.local.json` 覆盖了 `customModels`,请先解决冲突再启用。参见 [Factory BYOK 文档](https://docs.factory.ai/model-independence/byok)。 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 b1a0d4306ce..4c1795216d2 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 @@ -141,7 +141,7 @@ ocx claude desktop import [--apply] Validate and import JSON ## Client config export -### `ocx export --client ` +### `ocx export --client ` 输出连接到正在运行代理的客户端配置。此命令会以所选客户端的原生格式序列化 `opencodex` provider 块,其中包含基础 URL、模型列表,以及该客户端适用的凭据引用或 `opencodex-loopback` 占位值。 @@ -149,7 +149,7 @@ ocx claude desktop import [--apply] Validate and import JSON | 标志 | 动作 | | --- | --- | -| `--client ` | 必需。选择客户端配置格式。 | +| `--client ` | 必需。选择客户端配置格式。 | | `--json` | 仅在 stdout 打印配置 JSON,这样重定向即可捕获字节级精确输出。包括 `--out` 写入提示在内的所有诊断信息都会输出到 stderr。 | | `--out ` | 将配置写入 ``。拒绝替换已存在的文件。 | | `--force` | 允许 `--out` 替换已存在的文件。 | @@ -179,6 +179,8 @@ ocx export --client opencode --out ~/opencodex-opencode.json | `aside` | `~/.aside/u//models.json`,对应 Aside 自己的 `accounts.json` 指明的当前账户;清单不可读时会被拒绝,而不是退回到某个账户 | `aside-models.json` | 无 — loopback placeholder | | `raycast` | `~/.config/raycast/ai/providers.yaml`(macOS 与 Windows 相同;Raycast 不遵循 `XDG_CONFIG_HOME`) | `raycast-providers.yaml` | 无 — 仅限回环,不会写入 `api_keys` 条目 | | `omo` | `~/.omo/agent/models.json`(设置后依次由 `OMO_CODING_AGENT_DIR`、`SENPI_CODING_AGENT_DIR`、`PI_CODING_AGENT_DIR` 优先;相对路径会被拒绝) | `omo-models.json` | 无 — loopback placeholder | +| `kilo` | `~/.config/kilo` 下最先存在的 `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json` 或 `config.json`(`XDG_CONFIG_HOME` 可更改该目录);均不存在时使用 `kilo.jsonc` | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | 仅限回环;无需环境变量 | Raycast 导出是一份独立的 `providers.yaml` 文档,在 `providers` 序列中只有一个 `id: opencodex` 元素:`name: OpenCodex`、代理的 `/v1` 基础 URL,以及每个已路由模型及其 `abilities`(`tools` 与 `system_message` 始终支持,`vision` 取自目录的输入模态,`reasoning_effort` 在模型有 effort 阶梯时设置,`temperature` 对推理模型关闭)。Custom Providers 是 Raycast Pro 功能,且 Raycast 会监视该文件,因此保存后的更改无需重启即可生效。格式见 [manual.raycast.com/ai/custom-providers](https://manual.raycast.com/ai/custom-providers)。不会写入任何 `api_keys` 条目,所以该导出仅限回环,非回环绑定会被拒绝。 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 76efbe5738e..1fc4ee8ccc7 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 @@ -198,6 +198,6 @@ Anthropic OAuth 侧车会复用 opencodex 现有的 Claude Code OAuth 指纹。 ## Codex 额度网络诊断 -主 Codex 账户行中的 `quotaRefresh` 描述额度查询结果,并不代表剩余额度或模型访问权限。读取缓存或未执行查询时,该字段可能省略。查询使用正在运行的代理服务的环境,而不是当前终端的环境。未设置 `proxy` 时保留现有环境;`"auto"` 只在启动时读取 Windows 静态代理设置,不自动处理 PAC/WPAD、仅 SOCKS 的设置或运行中的更改。TUN 测试成功并不能单独证明 HTTP 代理路径正常。命令和状态说明见[英文网络诊断章节](/reference/configuration/server/#codex-quota-network-diagnostics)。 +主 Codex 账户行中的 `quotaRefresh` 描述额度查询结果,并不代表剩余额度或模型访问权限。读取缓存或未执行查询时,该字段可能省略。查询使用正在运行的代理服务的环境,而不是当前终端的环境。未设置 `proxy` 时保留现有环境;`"auto"` 在启动时读取 Windows 或 macOS 静态 HTTP/HTTPS 设置;macOS 上若有继承代理则跳过读取。macOS 将有效的 `*.` 转为 `.`:`*.local` 使 `foo.local` 和裸域名 `local` 直连,但不匹配 `xlocal`。精确的 `169.254/16`、`169.254.0.0/16`、`fe80::/10` 网段会跳过并给出诊断,因此链路本地 IP 地址使用代理。IP 地址和 `*` 仍可用;其他 CIDR、通配形式和简单主机名例外会在修改环境前拒绝自动发现。不自动处理 PAC/WPAD、仅 SOCKS 的设置或运行中的更改。TUN 测试成功并不能单独证明 HTTP 代理路径正常。命令和状态说明见[英文网络诊断章节](/reference/configuration/server/#codex-quota-network-diagnostics)。 `dropCodexSafetyBuffering`: 不会改变供应商安全策略或拒绝响应。原生 WebSocket `codex.response.metadata.headers` 和 `/responses/compact` 不在过滤范围内。 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 9aa5f572483..20a31542115 100644 --- a/docs-site/src/content/docs/zh-tw/guides/integrations.md +++ b/docs-site/src/content/docs/zh-tw/guides/integrations.md @@ -1,9 +1,9 @@ --- title: 整合 -description: 從儀表板把 opencodex 連接到 OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast 與 omo——每個客戶端一個開關,每次寫入前都會先備份。 +description: 從儀表板把 opencodex 連接到 OpenCode、Pi、OMP、Hermes、OpenClaw、Kimi Code、gjc、DeepSeek Harness、MiniMax Code、ZCode、Prime Agent、Aside、Raycast、omo、Cline CLI、Kilo 與 Factory Droid——每個客戶端一個開關,每次寫入前都會先備份。 --- -**整合(Integrations)** 分頁會把 opencodex 的 provider 區塊寫入客戶端自己的設定檔,也會把它移除。共有十五個客戶端以這種方式運作,每個都有一個開關: +**整合(Integrations)** 分頁會把 opencodex 的 provider 區塊寫入客戶端自己的設定檔,也會把它移除。共有十七個客戶端以這種方式運作,每個都有一個開關: | 客戶端 | 設定檔 | 格式 | 變更生效時機 | 憑證 | |---|---|---|---|---| @@ -22,6 +22,8 @@ description: 從儀表板把 opencodex 連接到 OpenCode、Pi、OMP、Hermes、 | Raycast | `~/.config/raycast/ai/providers.yaml` | YAML | 儲存後立即生效——Raycast 會監看該檔案 | 無——僅限 loopback | | omo | `~/.omo/agent/models.json` | JSON | 新工作階段 | loopback 佔位符 | | Cline CLI | `~/.cline/data/settings/providers.json` + `models.json` | JSON | 結束並重新啟動後 | 僅限 loopback | +| Kilo | `~/.config/kilo` 下最先存在的 `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json` 或 `config.json`(`XDG_CONFIG_HOME` 會移動該目錄;若都不存在則建立 `kilo.jsonc`) | JSONC | 新工作階段 | `OPENCODEX_KILO_API_KEY` | +| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` Windows 上) | JSON | 檔案變更時立即生效 | 無金鑰迴環 | 具有受支援推理強度階梯的 GJC 模型會匯出 `reasoning: true`、`thinking.levels` 與 `compat.supportsReasoningEffort`,讓 GJC 提供強度選擇。原生 Codex 模型即使未在目錄中列出階梯,也會取得標準階梯。沒有已知階梯的模型會省略這些欄位;`none` 不傳送強度,`ultra` 在傳輸時會折疊成 `max`,因此不會列為選項。重新整理整合即可更新模型選項。 @@ -201,3 +203,17 @@ ocx integration client restore --op ``` [CLI / rollback / CLINE_PROVIDER_SETTINGS_PATH](/guides/integrations/#cline-cli). + +## Kilo + +Kilo 只會把 `provider.opencodex` 寫入 `~/.config/kilo` 下最先存在的全域檔(`XDG_CONFIG_HOME` 會移動該目錄;若沒有任何候選檔則建立 `kilo.jsonc`)。若另一個候選檔也定義 `provider.opencodex`,狀態會回報衝突且套用會拒絕。其他鍵保持不變。套用會重寫整個檔案,因此不會保留註解與尾隨逗號。請在 Kilo 中選擇 `opencodex/<模型>`。 + +即使其他候選檔發生衝突或無法剖析,停用仍可移除已記錄檔案中由 OpenCodex 管理的區塊;其他候選檔不會變動。 + +```bash +ocx integration client enable --client kilo +``` + +## Factory Droid + +Factory Droid 使用 `~/.factory/settings.json`(Windows 上為 `%USERPROFILE%\.factory\settings.json`)。使用 `ocx integration client enable --client droid` 明確啟用,然後在 `/model` 中選擇自訂模型。受管理的項目不含金鑰,且僅支援迴環連線。停用會移除受管理的項目;Undo 會還原儲存的原始位元組。如果舊版 `config.json` 含有 OpenCodex 項目,或 `settings.local.json` 覆寫了 `customModels`,請先解決衝突再啟用。請參閱 [Factory BYOK 文件](https://docs.factory.ai/model-independence/byok)。 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 9b06950e1a3..f8d3b04c87a 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 @@ -139,7 +139,7 @@ ocx claude desktop import [--apply] 驗證並匯入 JSON ## 客戶端設定匯出 -### `ocx export --client ` +### `ocx export --client ` 印出連接到執行中代理的客戶端設定。此指令會用所選客戶端的原生格式,序列化含有 base URL、模型清單,以及適用的環境變數參考或 loopback 佔位符的 `opencodex` provider 區塊。 @@ -147,7 +147,7 @@ ocx claude desktop import [--apply] 驗證並匯入 JSON | 旗標 | 動作 | | --- | --- | -| `--client ` | 必填。選擇客戶端設定格式。 | +| `--client ` | 必填。選擇客戶端設定格式。 | | `--json` | 僅在 stdout 印出設定 JSON,使重導向能擷取逐位元組輸出。所有診斷訊息(含 `--out` 寫入提示)皆送至 stderr。 | | `--out ` | 將設定寫入 ``。拒絕覆寫既有檔案。 | | `--force` | 允許 `--out` 覆寫既有檔案。 | @@ -177,6 +177,8 @@ ocx export --client opencode --out ~/opencodex-opencode.json | `aside` | `~/.aside/u//models.json`,對應 Aside 自己的 `accounts.json` 指定的目前帳戶;資訊清單無法讀取時會被拒絕,而不是退回任一帳戶 | `aside-models.json` | 無——loopback 佔位符 | | `raycast` | `~/.config/raycast/ai/providers.yaml`(macOS 與 Windows 相同;Raycast 不遵循 `XDG_CONFIG_HOME`) | `raycast-providers.yaml` | 無——僅限 loopback,不會寫入 `api_keys` 項目 | | `omo` | `~/.omo/agent/models.json`(設定後依序由 `OMO_CODING_AGENT_DIR`、`SENPI_CODING_AGENT_DIR`、`PI_CODING_AGENT_DIR` 優先;相對路徑會被拒絕) | `omo-models.json` | 無——loopback 佔位符 | +| `kilo` | `~/.config/kilo` 下最先存在的 `kilo.jsonc`、`kilo.json`、`opencode.jsonc`、`opencode.json` 或 `config.json`(`XDG_CONFIG_HOME` 可變更該目錄);皆不存在時使用 `kilo.jsonc` | `kilo.jsonc` | `OPENCODEX_KILO_API_KEY` | +| `droid` | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | `factory-settings.json` | 僅限迴環;不需環境變數 | Raycast 匯出是一份獨立的 `providers.yaml` 文件,在 `providers` 序列中只有一個 `id: opencodex` 元素:`name: OpenCodex`、proxy 的 `/v1` base URL,以及每個路由模型及其 `abilities`(`tools` 與 `system_message` 一律支援,`vision` 依目錄的輸入模態而定,`reasoning_effort` 在模型有 effort 階梯時設定,`temperature` 對推理模型關閉)。Custom Providers 是 Raycast Pro 功能,且 Raycast 會監看該檔案,因此儲存後的變更不需重新啟動即可生效。格式說明見 [manual.raycast.com/ai/custom-providers](https://manual.raycast.com/ai/custom-providers)。不會寫入任何 `api_keys` 項目,所以此匯出僅限 loopback,非 loopback 的 bind 會被拒絕。 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 ec8ffe6e41f..ee1b7e72c77 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 @@ -217,4 +217,4 @@ Anthropic OAuth sidecar 重用 opencodex 既有的 Claude Code OAuth 指紋。 ## Codex 配額網路診斷 -主 Codex 帳戶列中的 `quotaRefresh` 描述配額查詢結果,並不代表剩餘配額或模型存取權限。讀取快取或未執行查詢時,這個欄位可能省略。查詢使用執行中代理服務的環境,而不是目前終端機的環境。未設定 `proxy` 時保留既有環境;`"auto"` 只在啟動時讀取 Windows 靜態代理設定,不會自動處理 PAC/WPAD、僅 SOCKS 的設定或執行中的變更。TUN 測試成功本身不能證明 HTTP 代理路徑正常。命令與狀態說明請見[英文網路診斷章節](/reference/configuration/server/#codex-quota-network-diagnostics)。 +主 Codex 帳戶列中的 `quotaRefresh` 描述配額查詢結果,並不代表剩餘配額或模型存取權限。讀取快取或未執行查詢時,這個欄位可能省略。查詢使用執行中代理服務的環境,而不是目前終端機的環境。未設定 `proxy` 時保留既有環境;`"auto"` 在啟動時讀取 Windows 或 macOS 靜態 HTTP/HTTPS 設定;macOS 上若有繼承代理則略過讀取。macOS 會將有效的 `*.` 轉成 `.`:`*.local` 讓 `foo.local` 與裸網域 `local` 直連,但不比對 `xlocal`。精確的 `169.254/16`、`169.254.0.0/16`、`fe80::/10` 網段會略過並顯示診斷,因此鏈路本機 IP 位址使用代理。IP 位址與 `*` 仍可使用;其他 CIDR、萬用字元形式及簡單主機名稱例外會在修改環境前拒絕自動探索。不會自動處理 PAC/WPAD、僅 SOCKS 的設定或執行中的變更。TUN 測試成功本身不能證明 HTTP 代理路徑正常。命令與狀態說明請見[英文網路診斷章節](/reference/configuration/server/#codex-quota-network-diagnostics)。 diff --git a/gui/public/provider-icons/README.md b/gui/public/provider-icons/README.md index 3f0878f924e..7efbbbac919 100644 --- a/gui/public/provider-icons/README.md +++ b/gui/public/provider-icons/README.md @@ -380,3 +380,5 @@ committing it. `b60df52303ba7170772b256c20c04940`), gradient id and all. The contributor works at Crusoe and confirms this is the company mark. Painted as an image: the gradient is the brand, so it must never be masked. + +- `factory-droid.svg` — Factory Docs favicon, fetched 2026-09-28 from `https://docs.factory.ai/favicon.svg`; unmodified first-party asset for Factory Droid. diff --git a/gui/public/provider-icons/factory-droid.svg b/gui/public/provider-icons/factory-droid.svg new file mode 100644 index 00000000000..38aad643a75 --- /dev/null +++ b/gui/public/provider-icons/factory-droid.svg @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/gui/src/app-routing.ts b/gui/src/app-routing.ts index 3f7f107b8c1..ee5be633727 100644 --- a/gui/src/app-routing.ts +++ b/gui/src/app-routing.ts @@ -109,6 +109,8 @@ export const INTEGRATION_TAB_HASHES = [ "integrations/raycast", "integrations/omo", "integrations/cline", + "integrations/kilo", + "integrations/droid", ] as const; /** diff --git a/gui/src/combo-workspace-data.ts b/gui/src/combo-workspace-data.ts index 0695cd5eada..28750c0ef87 100644 --- a/gui/src/combo-workspace-data.ts +++ b/gui/src/combo-workspace-data.ts @@ -91,6 +91,8 @@ export interface ComboTarget { weight?: number; /** Exact efforts JEV may choose; omitted means every currently advertised effort. */ reasoningEfforts?: ComboEffort[]; + /** Optional operator note that supplements the built-in JEV profile. */ + modelProfile?: string; /** UI-only stable key for React lists; never sent to the API. */ clientKey?: string; } @@ -111,6 +113,7 @@ export function newComboTarget(partial: Partial = {}): ComboTarget ...(partial.reasoningEfforts !== undefined ? { reasoningEfforts: [...partial.reasoningEfforts] } : {}), + ...(partial.modelProfile !== undefined ? { modelProfile: partial.modelProfile } : {}), clientKey: partial.clientKey ?? `ct-${++comboTargetKeySeq}`, }; } @@ -257,6 +260,7 @@ export function parseComboList(payload: unknown): ComboItem[] { model, ...(weight !== undefined ? { weight } : {}), ...(reasoningEfforts !== undefined ? { reasoningEfforts } : {}), + ...(typeof tr.modelProfile === "string" ? { modelProfile: tr.modelProfile } : {}), })); } out.push({ @@ -448,7 +452,8 @@ export function draftEquals(a: ComboItem, b: ComboItem): boolean { return t.provider === o.provider && t.model === o.model && (t.weight ?? 1) === (o.weight ?? 1) - && targetReasoningEffortsEqual(t, o); + && targetReasoningEffortsEqual(t, o) + && (t.modelProfile ?? "") === (o.modelProfile ?? ""); }); } @@ -479,6 +484,9 @@ export function toPutBody(item: ComboItem, options: { renameFrom?: string } = {} ...(target.reasoningEfforts !== undefined ? { reasoningEfforts: [...target.reasoningEfforts] } : {}), + ...(target.modelProfile?.trim() + ? { modelProfile: target.modelProfile.trim() } + : {}), })), strategy: item.strategy, defaultEffort: item.defaultEffort, @@ -515,6 +523,7 @@ export type ComboDraftError = | "invalidStickyLimit" | "invalidWeight" | "invalidReasoningEfforts" + | "invalidModelProfile" | "noEnabledTarget"; export function validateComboDraft( @@ -565,6 +574,13 @@ export function validateComboDraft( || new Set(t.reasoningEfforts).size !== t.reasoningEfforts.length)) { return "invalidReasoningEfforts"; } + if (t.modelProfile !== undefined + && (t.modelProfile.length > 512 || [...t.modelProfile].some(char => { + const code = char.charCodeAt(0); + return (code < 32 && code !== 9 && code !== 10 && code !== 13) || code === 127; + }))) { + return "invalidModelProfile"; + } } const targets = new Set(); diff --git a/gui/src/components/MemoryModelsPanel.tsx b/gui/src/components/MemoryModelsPanel.tsx new file mode 100644 index 00000000000..595f166843f --- /dev/null +++ b/gui/src/components/MemoryModelsPanel.tsx @@ -0,0 +1,226 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import { useT, type TKey } from "../i18n/shared"; +import { IconAlert, IconInfo, IconX } from "../icons"; +import { Select } from "../ui"; +import { createBoundedFetch } from "../bounded-fetch"; +import { requireJson, useModalDialog, type ModelInfo } from "../pages/dashboard-shared"; +import { formatNamespacedModelId } from "../provider-icons"; + +type Phase = "extract" | "consolidation"; +interface PhaseSetting { model?: string; reasoningEffort?: string } +type Settings = { extract?: PhaseSetting; consolidation?: PhaseSetting }; + +const EFFORTS = ["none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"]; + +/** + * Read the persisted phases. A phase without a model is "Off", so it is dropped rather than kept + * as an empty row: that is also the shape the PUT sends back for it. + */ +function readSettings(payload: { memoryModels?: unknown }): Settings { + const value = payload.memoryModels; + if (value == null) return {}; + if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("invalid settings"); + const out: Settings = {}; + for (const phase of ["extract", "consolidation"] as const) { + const raw = (value as Record)[phase]; + if (raw === undefined) continue; + if (!raw || typeof raw !== "object" || Array.isArray(raw)) throw new Error("invalid phase"); + const model = "model" in raw && typeof raw.model === "string" ? raw.model.trim() : ""; + if (!model) throw new Error("invalid model"); + const effort = "reasoningEffort" in raw ? raw.reasoningEffort : undefined; + if (effort !== undefined && (typeof effort !== "string" || !EFFORTS.includes(effort))) throw new Error("invalid effort"); + out[phase] = { model, ...(effort ? { reasoningEffort: effort } : {}) }; + } + return out; +} + +/** + * One phase's PUT payload. A phase with no model is "Off", which the route reads as an absent + * key, so it must stay out of the object rather than travel as an empty string. + */ +function phasePayload(model: string, effort: string): PhaseSetting | undefined { + return model ? { model, ...(effort ? { reasoningEffort: effort } : {}) } : undefined; +} + +export default function MemoryModelsPanel(props: { apiBase: string; models: ModelInfo[] }) { + return ; +} + +function MemoryModelsControls({ apiBase, models }: { apiBase: string; models: ModelInfo[] }) { + const t = useT(); + const [saved, setSaved] = useState(undefined); + const [infoOpen, setInfoOpen] = useState(false); + const [extractModel, setExtractModel] = useState(""); + const [extractEffort, setExtractEffort] = useState(""); + const [consolidationModel, setConsolidationModel] = useState(""); + const [consolidationEffort, setConsolidationEffort] = useState(""); + const [busy, setBusy] = useState(false); + const [loadError, setLoadError] = useState(false); + const [feedback, setFeedback] = useState<"saved" | "failed" | null>(null); + const active = useRef(false); + const pending = useRef | null>(null); + const infoTriggerRef = useRef(null); + const infoDialogRef = useModalDialog(infoOpen, infoTriggerRef); + + const accept = useCallback((value: Settings) => { + setSaved(value); + setExtractModel(value.extract?.model ?? ""); + setExtractEffort(value.extract?.reasoningEffort ?? ""); + setConsolidationModel(value.consolidation?.model ?? ""); + setConsolidationEffort(value.consolidation?.reasoningEffort ?? ""); + }, []); + + const load = useCallback(async () => { + if (pending.current) return; + const request = createBoundedFetch(15_000); + pending.current = request; + setLoadError(false); + try { + const response = await fetch(`${apiBase}/api/settings`, { signal: request.signal }); + const value = readSettings(await requireJson(response)); + if (active.current && pending.current === request) accept(value); + } catch { + if (active.current && pending.current === request) setLoadError(true); + } finally { + request.clear(); + if (pending.current === request) pending.current = null; + } + }, [apiBase, accept]); + + useEffect(() => { + active.current = true; + const timer = window.setTimeout(() => { void load(); }, 0); + return () => { + window.clearTimeout(timer); + active.current = false; + pending.current?.controller.abort(); + pending.current?.clear(); + pending.current = null; + }; + }, [load]); + + const save = async () => { + if (pending.current || saved === undefined) return; + const request = createBoundedFetch(15_000); + pending.current = request; + setBusy(true); + setFeedback(null); + const extract = phasePayload(extractModel, extractEffort); + const consolidation = phasePayload(consolidationModel, consolidationEffort); + try { + const response = await fetch(`${apiBase}/api/settings`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + // Null clears the whole block; a phase left at "Off" is simply absent. + memoryModels: extract || consolidation + ? { ...(extract ? { extract } : {}), ...(consolidation ? { consolidation } : {}) } + : null, + }), + signal: request.signal, + }); + const value = readSettings(await requireJson(response)); + if (active.current && pending.current === request) { + accept(value); + setFeedback("saved"); + } + } catch { + if (active.current && pending.current === request) setFeedback("failed"); + } finally { + request.clear(); + if (active.current && pending.current === request) setBusy(false); + if (pending.current === request) pending.current = null; + } + }; + + const options = [{ value: "", label: t("memoryModels.off") }, + ...[...new Set([...models.map(item => item.namespaced), + ...[extractModel, consolidationModel].filter(Boolean)])] + .map(value => ({ value, label: formatNamespacedModelId(value, t) }))]; + const effortOptions = [{ value: "", label: t("memoryModels.defaultEffort") }, + ...EFFORTS.map(value => ({ value, label: t(`models.reasoningEffort.${value}` as TKey) }))]; + const disabled = busy || saved === undefined || loadError; + const dirty = extractModel !== (saved?.extract?.model ?? "") + || extractEffort !== (saved?.extract?.reasoningEffort ?? "") + || consolidationModel !== (saved?.consolidation?.model ?? "") + || consolidationEffort !== (saved?.consolidation?.reasoningEffort ?? ""); + // The account notice is about the phase that stays on Codex's own model, so it is both + // true and useful only while exactly one of the two phases is routed. + const partiallyRouted = Boolean(extractModel) !== Boolean(consolidationModel); + const info = t("memoryModels.info"); + + const row = (phase: Phase, model: string, effort: string, setModel: (value: string) => void, setEffort: (value: string) => void) => ( +
+
+
{t(`memoryModels.${phase}` as TKey)}
+
{t(`memoryModels.${phase}Hint` as TKey)}
+
+
+ { setEffort(value); setFeedback(null); }} /> +
+
+ ); + + return ( +
+
+ {t("memoryModels.title")} + +
+
{t("memoryModels.description")}
+ {row("extract", extractModel, extractEffort, setExtractModel, setExtractEffort)} + {row("consolidation", consolidationModel, consolidationEffort, setConsolidationModel, setConsolidationEffort)} +
+
{t("memoryModels.dataNotice")}
+ +
+ {partiallyRouted &&
+ {t("memoryModels.accountNotice")} +
} + {loadError &&
{t("memoryModels.loadFailed")}
} + {feedback === "failed" &&
{t("memoryModels.saveFailed")}
} + {feedback === "saved" &&
{t("memoryModels.saved")}
} + { event.preventDefault(); setInfoOpen(false); }} + > + + +
+ {info} +
+
+ +
+ +
+
+ ); +} diff --git a/gui/src/components/apikeys-workspace/client-config-clients.ts b/gui/src/components/apikeys-workspace/client-config-clients.ts index e164810fbb7..e4ac4a62e1a 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", "prime", "aside", "raycast", "omo", "cline"] as const; +export const CLIENTS = ["opencode", "pi", "omp", "hermes", "openclaw", "kimi", "gajae", "dsh", "mcode", "zcode", "prime", "aside", "raycast", "omo", "cline", "kilo", "droid"] as const; export type ExportClientId = (typeof CLIENTS)[number]; export const CLIENT_LABEL_KEYS = { @@ -27,6 +27,8 @@ export const CLIENT_LABEL_KEYS = { raycast: "api.clientConfig.clientRaycast", omo: "api.clientConfig.clientOmo", cline: "api.clientConfig.clientCline", + kilo: "api.clientConfig.clientKilo", + droid: "api.clientConfig.clientDroid", } as const; /** @@ -79,6 +81,8 @@ export const CLIENT_MARKS: Partial> = { // so it would paint the plate and throw the face away — see the README. omo: "/provider-icons/omo.svg", cline: "/provider-icons/cline-color.svg", + kilo: "/provider-icons/kilo.svg", + droid: "/provider-icons/factory-droid.svg", }; /** diff --git a/gui/src/components/combo-workspace-controls.tsx b/gui/src/components/combo-workspace-controls.tsx index 7096fac936f..8f4f3a9d81d 100644 --- a/gui/src/components/combo-workspace-controls.tsx +++ b/gui/src/components/combo-workspace-controls.tsx @@ -179,7 +179,7 @@ export function TargetEditor({ const replaceModel = (index: number, patch: Pick) => { onChange(targets.map((row, i) => { if (i !== index) return row; - const { reasoningEfforts: _reasoningEfforts, ...rest } = row; + const { reasoningEfforts: _reasoningEfforts, modelProfile: _modelProfile, ...rest } = row; return { ...rest, ...patch }; })); }; @@ -381,6 +381,18 @@ export function TargetEditor({ })} )} +