Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
eb36faf
chore(release): open dev at 2.80.0 before releasing 2.79.0 (#6676)
github-actions[bot] Oct 6, 2026
36fa092
fix(messages): accumulate temporary tool declarations linearly (#6656)
luvs01 Oct 6, 2026
544f1c5
fix(jev): exclude Claude Code reminders from decision state (#6662)
geunwoojun99 Oct 6, 2026
aed4f1c
fix(claude): retain ToolSearch references in translated results (#6660)
Ingwannu Oct 6, 2026
3eff7d9
fix(devin): accumulate consecutive tool results without prefix copies…
luvs01 Oct 6, 2026
3db71c6
fix(openai-chat): apply the Qwen3.8-27B template rule to gateway-name…
lidge-jun Oct 6, 2026
4e25303
fix(cursor): preserve bare client tool names for Claude Code sessions…
yeongjunyoo Oct 6, 2026
0033ede
fix(codex-shim): name the path and chmod fix when a private shim arti…
sungyongcho Oct 6, 2026
66a5c9f
fix(service): credit Linux desktop Start at Login as restart protecti…
sungyongcho Oct 6, 2026
7f3f368
fix(lifecycle): retryable restart-drain code and quiet journal no-op …
lidge-jun Oct 6, 2026
4146c58
fix(deps): bump proxy-addr, fast-uri, ip-address and source-map-js fo…
lidge-jun Oct 6, 2026
0cd680a
fix(jev): preserve applied effort transitions in combo logs (#6663)
geunwoojun99 Oct 6, 2026
9099e4b
fix(cursor): use factual tool redirects for Claude-family models (#6664)
geunwoojun99 Oct 6, 2026
5b65e8e
test(cli): shorten recover-history temp prefixes to stay under Window…
ismell0992-afk Oct 7, 2026
c30b522
fix(web-search): keep local pacing waits out of the header deadline (…
lidge-jun Oct 7, 2026
5257b9f
Merge main into 2.80.0 promotion
lidge-jun Oct 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion desktop/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "opencodex-desktop"
version = "2.79.0"
version = "2.80.0"
description = "OpenCodex desktop shell"
authors = ["OpenCodex contributors"]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "OpenCodex",
"version": "2.79.0",
"version": "2.80.0",
"identifier": "com.opencodex.desktop",
"build": {
"frontendDist": "../ui",
Expand Down
16 changes: 16 additions & 0 deletions devlog/_plan/261006_lane_c_provider_compat/000_roadmap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 000 — Lane C (provider compat) roadmap

Lane session 01a11129 (fork of coordinator 01a11110). Worktree /Users/jun/Developer/new/700_projects/opencodex/.tmp/lanes/sweep-c-providers,
branch codex/sweep-c-providers at origin/dev f494403fba. This unit rides the lane's own PR; the coordinator owns devlog/_plan/261006_compat_hardening_sweep.

| wp | Item | Plan | Exit |
|---|---|---|---|
| wp1 | roadmap | this file | audited, locked |
| wp2 | PR #6657 (luvs01, Devin) | worktree sweep-c-providers-6657 on the PR head; merge origin/dev (no force push); gpt-6.1-sol adversarial review of src/adapters/devin.ts change against tests/providers/devin-chat-wire-fixes.test.ts; fold real defects as commits on the PR branch; bun test focused file, typecheck, structure:check; push; gh pr ready; exact-head CI | READY or NEEDS_HUMAN |
| wp3 | PR #6654 (Ollama, branch on origin) | same shape in sweep-c-providers-6654 with focused commands: bun test tests/providers/ollama/ollama-native-tool-continuations.test.ts tests/providers/ollama/ollama-native-v4.test.ts tests/adapters/abort-race.test.ts; verify initial and rebuild 413, ordinary build error 400, cancellation precedence and zero upstream sends on refusal; also confirm the 413 mapping keeps ordinary build errors at 400 and that docs-site/structure text matches code; shared files structure/transports/responses.md and docs-site reference/adapters.md are B/C shared (second lander reconciles) | READY or NEEDS_HUMAN |
| wp4 | issue #6674 | in the lane worktree: widen qwen38LeadingSystemTemplate in src/adapters/openai-chat/messages.ts from ^(?:Qwen/)? to ^(?:[^/]+/)* so provider-namespaced served ids (openai/Qwen3.8-27B, hosted_vllm/Qwen/Qwen3.8-27B) match while Qwen3.8-27B-FP8 and api.openai.com stay excluded; add positive cases openai/Qwen3.8-27B and hosted_vllm/Qwen/Qwen3.8-27B plus namespaced negative (openai/Qwen3.8-27B-FP8) and native OpenAI control (openai/Qwen3.8-27B on api.openai.com) to tests/adapters/openai/openai-chat-qwen38-leading-system.test.ts; update the owning structure doc if it states the matcher; one PR, Closes #6674 | READY |
| wp4 | issue #6502 | no code change: the report is 2.76.0 and Antigravity effort families were regrouped in 2.77.0 (#6501). resolveAntigravityWireModelId resolves discovery mappings first, aliases second, identity last, so the 404 alone does not tell an endpoint, mapping or account cause apart. Comment asking for a current-version repro with a redacted discovered model list and the resolved wire id; record NEEDS_HUMAN for insufficient evidence | NEEDS_HUMAN |

Verification per PR: focused bun test, bun run typecheck, bun run structure:check, no full local suite (four lanes share this Mac; coverage left to hosted CI), exact-head CI with only path/event-filtered skips.
Bounds: tools gh/git/bun; writes only in the lane write scope plus own registry/structure/docs entries. Branch synchronization (git merge origin/dev into a PR head branch, then push) is lane-owned and granted by the packet; PR integration into dev (gh pr merge) is coordinator-only and never done here.

14 changes: 14 additions & 0 deletions docs-site/src/content/docs/guides/claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,19 @@ depend on them for long unattended runs.

<!-- TODO(WP5 GUI): Add the sidecar settings-screen walkthrough after the GUI controls ship. -->

## Client tools on Cursor routes

When Claude Code uses a Cursor-backed model, OpenCodex preserves recognized client tool names
such as `Bash`, `Read`, `Write`, `Edit`, `Grep`, `Glob`, and `Task` in the Cursor catalog, tool
guidance, and replayed calls. This keeps the names consistent with Claude Code's instructions.
Denied Cursor-native execution frames direct the model to the client tools available that turn.

A mixed catalog containing a bare Codex `exec_command` or `shell_command` bridge uses wire
aliases such as `ocx_client_Read` to avoid Cursor tool collisions; calls returned to Claude Code
still use its original tool names. Namespaced MCP tools keep their namespaced identities.
OpenCodex includes these aliases in Cursor's transport byte budget, so a tool whose definition
would exceed the limit is omitted for that turn.

## Reasoning effort

Claude Code's `/effort` setting is preserved across the adapter:
Expand All @@ -818,6 +831,7 @@ The proxy translates every Anthropic Messages API request into the Codex Respons
| Assistant text | `output_text` |
| Assistant `tool_use` | `function_call` (`input` → JSON-stringified `arguments`) |
| User `tool_result` | `function_call_output` (`is_error` → `[tool error]` prefix) |
| `tool_reference` in a tool result | Text `Tool loaded: <tool_name>` in the paired result; preserves loaded-tool names without adding declarations or enabling translated server-side deferral |
| `thinking` / `redacted_thinking` replay | `reasoning` items with bounded `ocxr1` envelopes for signatures and redacted payloads |
| Function tools | `{type: "function"}` (`web_search*` → `{type: "web_search"}`) |
| `tool_choice` | `auto`→`auto`, `none`→`none`, `any`→`required`, named function→`{type:"function",name}`, hosted WebSearch/web_search→`{type:"web_search"}` |
Expand Down
15 changes: 12 additions & 3 deletions docs-site/src/content/docs/guides/combos.md
Original file line number Diff line number Diff line change
Expand Up @@ -474,9 +474,11 @@ The decision state is deliberately bounded: up to 500 characters of the current
240-character previous-assistant tail, a 520-character latest-tool-output tail, the tool name, and
boolean image/tool signals may be sent to the selected decision backend. It excludes credentials,
request headers, raw image bytes, tool arguments, encrypted reasoning, and full conversation history.
Use a decision method only for content you are willing to send to that backend. Recognized OpenCodex machine-context
envelopes are removed from all three text samples, but ordinary assistant and tool-output text is
not a secret scanner and may still contain sensitive content. TypeSafe states that Jev is not
Use a decision method only for content you are willing to send to that backend. Recognized Codex machine-context
envelopes and Claude Code `<system-reminder>` blocks are removed from all three text samples before
clipping, so injected reminders do not displace the actual task. The original model request is
unchanged. This is not a secret scanner: ordinary assistant and tool-output text may still contain
sensitive content. TypeSafe states that Jev is not
trained on customer requests, but its terms set no fixed retention period for submitted state and
offer zero data retention only on enterprise plans
([models](https://docs.typesafe.ai/models), [legal](https://docs.typesafe.ai/legal)). TypeSafe
Expand All @@ -486,6 +488,13 @@ target/effort, a coarse decision gate, latency, optional confidence/probability,
Automated tests use mocked TypeSafe responses plus a no-key fail-open smoke; a live TypeSafe decision
requires an operator-supplied key and is not run implicitly.

When JEV's selected effort is applied to the Responses child, request and attempt logs show a
differing effort as `high->xhigh` or `high->low`. Later effort adjustments remain in the chain,
such as `high->xhigh->medium`. An unchanged effort or a target without effort control keeps the
existing label; fallback attempts do not inherit the initial JEV effort. With the opt-in
`protocols.rollout.nativeChatCombos` path, native Chat children currently do not apply JEV's
selected effort; their labels retain the caller's effort and any native child adjustments instead.

After the Combo has served requests, open **Models → Combos → jev-auto → Stats** to inspect JEV's
picks without replacing the normal model picker or Usage page. The tab separates backend-reported decision
tokens from tokens reported by physical model sends, and shows decision gates, fail-open picks,
Expand Down
18 changes: 17 additions & 1 deletion docs-site/src/content/docs/guides/desktop-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,26 @@ registration, including installations under `Program Files`. Previously enabled
registrations are updated once on launch. Startup entries you disabled in the tray
or Task Manager remain disabled.

## Startup safety on macOS
## Startup safety on macOS and Linux

Startup safety reports **Desktop app** protection when OpenCodex's recorded ownership,
**Start at Login** registration, and live supervision of its bundled proxy all match.
On Linux, the pinned autostart backend writes the login entry to
`~/.config/autostart/OpenCodex.desktop`, even when `$XDG_CONFIG_HOME` is set. Startup
safety reads that entry and the desktop install-id under `~/.config`. When
`$XDG_CONFIG_HOME` points elsewhere, the login session searches a different autostart
directory, so startup safety stays **At risk** instead of crediting the entry.
The entry counts only while it is not marked `Hidden=true` or
`X-GNOME-Autostart-enabled=false`, and has no `OnlyShowIn`, `NotShowIn`, or `TryExec`
condition. Its `Exec` must be an unquoted absolute path to `opencodex-desktop`, without
spaces, escapes, or field codes, followed by exactly `--autostart`. The resolved
executable must still be named `opencodex-desktop`, with its bundled `ocx` beside it.
Startup safety reads the full evidence chain twice and grants protection only when
both reads agree.

AppImage installations remain **At risk**: the autostart backend registers the outer
AppImage path, while the live desktop process runs inside its mount. Startup safety
cannot verify that relationship and does not credit AppImage protection.
A missing or stale check remains **At risk**. If the desktop app owns the proxy but
protection cannot be verified, reopen OpenCodex and check **Start at Login**. Service
and launcher installation or repair stays disabled while that ownership remains;
Expand Down
1 change: 1 addition & 0 deletions docs-site/src/content/docs/ko/guides/claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,7 @@ Claude Code의 `/effort` 설정은 어댑터에서도 유지돼요.
| Assistant 텍스트 | `output_text` |
| Assistant `tool_use` | `function_call`(`input` → JSON 문자열로 변환한 `arguments`) |
| 사용자 `tool_result` | `function_call_output`(`is_error` → `[tool error]` 접두사) |
| 도구 결과의 `tool_reference` | 짝지어진 결과에 `Tool loaded: <tool_name>` 텍스트로 보존합니다. 도구 선언을 추가하거나 번역 경로의 서버 측 지연 로딩을 활성화하지는 않습니다. |
| `thinking` / `redacted_thinking` 재생 | 서명과 비공개 페이로드를 제한된 `ocxr1` 봉투에 담은 `reasoning` 항목 |
| Function 도구 | `{type: "function"}`(`web_search*` → `{type: "web_search"}`) |
| `tool_choice` | `auto`→`auto`, `none`→`none`, `any`→`required`, 이름 지정 함수→`{type:"function",name}`, 호스팅 WebSearch/web_search→`{type:"web_search"}` |
Expand Down
11 changes: 9 additions & 2 deletions docs-site/src/content/docs/reference/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ transport; it does not infer subscription attribution from the inbound protocol.
tool message as the anchor.
- **Rewrites Codex's GPT-5 identity prompt** to a model-agnostic intro so routed models don't claim to
be OpenAI.
- For translated `Qwen3.8-27B` requests, a text-only developer reminder after the leading system
- For translated `Qwen3.8-27B` requests (including gateway-namespaced ids such as
`openai/Qwen3.8-27B`), a text-only developer reminder after the leading system
message stays in its conversation slot but is sent as `user`. The model's
[chat template](https://huggingface.co/Qwen/Qwen3.8-27B/blob/1d4bf0f2ff6012fd82039f2fa52739d0dd7c60c0/chat_template.jinja)
rejects later `system` messages and does not accept `developer`, while later `user` messages
Expand Down Expand Up @@ -543,7 +544,13 @@ compatibility pair: `agent.v1.AgentService/RunSSE` for server output and
Foreground `shellArgs` and `shellStreamArgs` are an exception: both are rejected before spawn
on every platform until kernel-backed descendant ownership is available. Use client shell tools;
background-shell execution and other native operations retain their existing policy.
- The denial reply is a silent redirect whose wording follows the request catalog.
- The denial reply follows the request catalog. Explicit Claude-family Cursor models receive
factual wording that names the available tools without instructions to hide or avoid discussing
the redirect. Factual routing commentary can precede the next tool call without ending the turn.
When no client or configured MCP tools are available, Claude models are asked to answer without
tools or report the limitation instead of calling nonexistent shell/edit tools.
Other models, including Auto/default, retain the existing silent-redirect wording and commentary
guard. Tool availability, execution policy, and approval/sandbox behavior are unchanged.
In code mode — a freeform unified `exec` and no bare shell bridge — the redirect points inside `exec`, where
shell, file, search, and fetch are nested `tools.<name>(...)` helpers of the JavaScript cell,
and never recommends the top-level shell bridge code mode does not expose. A flat catalog that
Expand Down
5 changes: 3 additions & 2 deletions docs-site/src/content/docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ full owner inventory for the Responses surface.
`server/index/serve-options.ts` owns the HTTP boundary and delegates the Responses data plane to
the `server/responses.ts` facade and its `server/responses/*.ts` modules:

1. `server/index/serve-options.ts` applies CORS and API authentication, rejects new work while draining, and
records request lifecycle metadata. It serves `GET /v1/models`, `POST /v1/responses`,
1. `server/index/serve-options.ts` applies CORS and API authentication, rejects new work while draining
with HTTP 503, JSON `error.code: "server_restarting"`, and `Retry-After: 5`, and
records request lifecycle metadata. Drain responses use the receiving listener's CORS policy. It serves `GET /v1/models`, `POST /v1/responses`,
`POST /v1/responses/compact`, `POST /v1/images/generations` / `POST /v1/images/edits`
(relayed to an OpenAI-family upstream by `server/images.ts` for codex's built-in `image_gen`
tool), `POST /v1/live` / `POST /v1/realtime/calls` (ChatGPT / Codex App voice and OpenAI
Expand Down
5 changes: 5 additions & 0 deletions docs-site/src/content/docs/reference/cli/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,11 @@ Migration restores the recorded native launcher without replacing a newer launch
then installs the private wrapper. If private installation fails after native restoration, the native
launcher stays restored and the operation can be retried. Missing or unusable native launchers require
package-manager repair; OpenCodex does not guess another installation or rewrap the manager's path.
Migration also refuses when the recorded `codex-shim.json` is not a regular file owned by you or is
group- or world-writable. Older releases wrote that file with the process umask, so a umask of `002`
left it at mode `0664`. The refusal names the file and the `chmod 600` that clears only the
group- or world-writable refusal. Symlink and foreign-owner refusals remain; OpenCodex does not
change the permissions itself.

Launcher installation alone does not prove that Codex requests will use OpenCodex. After a runnable
install, the command checks the current Codex routing and reports a warning instead of a green result
Expand Down
6 changes: 6 additions & 0 deletions docs-site/src/content/docs/reference/management-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,12 @@ whether to star the repository.

### System lifecycle

During a restart drain, new data-plane requests receive HTTP 503 with JSON
`error.type: "server_error"`, `error.code: "server_restarting"`, and the message
"OpenCodex is restarting; retry this request." Responses retain `Retry-After: 5`
and the receiving listener's CORS policy. This code lets every Codex version retry
the 503 without reporting model capacity; provider overload errors retain their separate mapping.

| Method and path | Purpose | Notable errors |
| --- | --- | --- |
| `GET /api/system/memory` | Return scalar process, heap, stream, response-state, watchdog, and active-turn metrics. Response-state diagnostics include spill-write status, consecutive failures, fixed privacy-safe failure class, and last failure/success timestamps. `spillLastWriteFailureOrigin` is `retry_returned_timeout`, `timeout_memo_refusal`, or null; cumulative `spillAclRetryReturnedTimeouts` and `spillAclTimeoutMemoRefusals` count terminal failed publications. See [Windows spill diagnostics](/troubleshooting/windows-memory/) for process-local semantics. Raw errors and paths are never returned. | — |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ runtime the leak itself remains an upstream problem:
continuation-size fields from this endpoint and offers a confirm-gated
**Drain & restart** action: it shows
the current active-turn count, waits up to 60s for active turns (reusing
the existing 503 + `Retry-After` drain), then aborts any remaining turns.
the existing HTTP 503 JSON `server_restarting` + `Retry-After: 5` drain),
then aborts any remaining turns.
The running proxy owns restart authorization and drain coordination, then
exits; an installed service manager launches the replacement when applicable.
The action reports success only after a different, identity-verified process
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bitkyc08/opencodex",
"version": "2.79.0",
"version": "2.80.0",
"description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code",
"type": "module",
"main": "./bin/package-main.mjs",
Expand Down
Loading
Loading