Skip to content

Commit e8625c8

Browse files
committed
Merge dev (sol/terra/luna rollout + search hardening) into main
# Conflicts: # package.json
2 parents bbb630e + 3ec9020 commit e8625c8

293 files changed

Lines changed: 13253 additions & 4243 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
run: cd gui && bun install --frozen-lockfile && bun run build
7878

7979
- name: CLI help smoke
80-
run: bun run src/cli.ts help
80+
run: bun run src/cli/index.ts help
8181

8282
npm-global-smoke:
8383
name: npm-global ${{ matrix.os }}

.github/workflows/release.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,15 @@ jobs:
286286
git push origin "refs/tags/${release_tag}"
287287
fi
288288
289+
# Preview builds must be marked prerelease so GitHub "latest" keeps pointing at the
290+
# stable channel (matching npm dist-tags); see issue #64.
291+
prerelease_flag=""
292+
if [[ "$RELEASE_VERSION" == *-preview.* ]]; then
293+
prerelease_flag="--prerelease"
294+
fi
295+
289296
if gh release view "$release_tag" >/dev/null 2>&1; then
290-
gh release edit "$release_tag" --title "$release_tag" --notes-file "$notes_file"
297+
gh release edit "$release_tag" --title "$release_tag" --notes-file "$notes_file" ${prerelease_flag:+$prerelease_flag}
291298
else
292-
gh release create "$release_tag" --target "$GITHUB_SHA" --title "$release_tag" --notes-file "$notes_file"
299+
gh release create "$release_tag" --target "$GITHUB_SHA" --title "$release_tag" --notes-file "$notes_file" ${prerelease_flag:+$prerelease_flag}
293300
fi

.github/workflows/service-lifecycle.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ on:
55
branches: [main, dev]
66
paths:
77
- "src/service.ts"
8-
- "src/cli.ts"
9-
- "src/bun-runtime.ts"
8+
- "src/cli/index.ts"
9+
- "src/lib/bun-runtime.ts"
1010
- "package.json"
1111
- "bun.lock"
1212
- ".github/workflows/service-lifecycle.yml"
1313
push:
1414
paths:
1515
- "src/service.ts"
16-
- "src/cli.ts"
17-
- "src/bun-runtime.ts"
16+
- "src/cli/index.ts"
17+
- "src/lib/bun-runtime.ts"
1818
- "package.json"
1919
- "bun.lock"
2020
- ".github/workflows/service-lifecycle.yml"
@@ -46,7 +46,7 @@ jobs:
4646
4747
- name: Install service
4848
run: |
49-
bun run src/cli.ts service install
49+
bun run src/cli/index.ts service install
5050
sleep 2
5151
5252
- name: Verify service is running
@@ -56,7 +56,7 @@ jobs:
5656
5757
- name: ocx stop should stop the service too
5858
run: |
59-
bun run src/cli.ts stop
59+
bun run src/cli/index.ts stop
6060
sleep 1
6161
# Service should NOT be active after ocx stop
6262
if systemctl --user is-active opencodex-proxy 2>/dev/null; then
@@ -67,7 +67,7 @@ jobs:
6767
6868
- name: Restart service and verify crash-restart
6969
run: |
70-
bun run src/cli.ts service start
70+
bun run src/cli/index.ts service start
7171
sleep 2
7272
PID=$(cat ~/.opencodex/ocx.pid 2>/dev/null || echo "")
7373
if [ -n "$PID" ]; then
@@ -84,7 +84,7 @@ jobs:
8484
8585
- name: Uninstall service
8686
run: |
87-
bun run src/cli.ts service uninstall
87+
bun run src/cli/index.ts service uninstall
8888
sleep 1
8989
if systemctl --user is-active opencodex-proxy 2>/dev/null; then
9090
echo "❌ FAIL: service still active after uninstall"
@@ -109,7 +109,7 @@ jobs:
109109
110110
- name: Install service
111111
run: |
112-
bun run src/cli.ts service install
112+
bun run src/cli/index.ts service install
113113
sleep 3
114114
115115
- name: Verify launchd agent loaded
@@ -123,13 +123,13 @@ jobs:
123123
124124
- name: ocx stop should unload the agent
125125
run: |
126-
bun run src/cli.ts stop
126+
bun run src/cli/index.ts stop
127127
sleep 2
128128
echo "✅ ocx stop completed"
129129
130130
- name: Uninstall service
131131
run: |
132-
bun run src/cli.ts service uninstall
132+
bun run src/cli/index.ts service uninstall
133133
sleep 1
134134
if launchctl list | grep -q com.opencodex.proxy; then
135135
echo "❌ LaunchAgent still loaded after uninstall"
@@ -156,7 +156,7 @@ jobs:
156156
- name: Install service
157157
shell: pwsh
158158
run: |
159-
bun run src/cli.ts service install
159+
bun run src/cli/index.ts service install
160160
Start-Sleep -Seconds 3
161161
162162
- name: Verify scheduled task exists
@@ -173,14 +173,14 @@ jobs:
173173
- name: ocx stop should end the task
174174
shell: pwsh
175175
run: |
176-
bun run src/cli.ts stop
176+
bun run src/cli/index.ts stop
177177
Start-Sleep -Seconds 2
178178
Write-Host "✅ ocx stop completed"
179179
180180
- name: Uninstall service
181181
shell: pwsh
182182
run: |
183-
bun run src/cli.ts service uninstall
183+
bun run src/cli/index.ts service uninstall
184184
Start-Sleep -Seconds 1
185185
$found = $true
186186
try { $task = schtasks /query /tn opencodex-proxy 2>&1 } catch { $found = $false }

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ devlog/
1010
# Local agent/session artifacts
1111
.codexclaw/
1212
.omo/
13+
14+
# Test-generated artifacts
15+
tests/.tmp-*/

README.ko.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ codex -m "ollama/llama3" "이 함수를 리팩터링해 줘"
139139

140140
라우팅된 모델은 **Codex App** 모델 선택기에도 모델별 reasoning effort 컨트롤과 함께 나타납니다:
141141

142+
현재 Codex 빌드는 모델이 광고하는 경우 `low`, `medium`, `high`, `xhigh`, `max` reasoning 컨트롤을
143+
노출할 수 있습니다. opencodex는 프로바이더 config가 명시적으로 alias를 지정하지 않는 한 `xhigh`
144+
`max`를 서로 다른 단계로 유지합니다.
145+
146+
GPT-5.6 Sol/Terra/Luna는 OpenAI API key 및 OpenRouter preset에서 rollout-ready catalog 항목으로
147+
seed됩니다(`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`; OpenRouter는 `openai/...` 사용). 실제
148+
사용 가능 여부는 upstream preview gate를 따르며, opencodex는 계정/프로바이더가 제공할 때 쓸
149+
routing/catalog metadata를 준비해 둡니다.
150+
142151
<p align="center">
143152
<img src="assets/codex-app-picker.png" alt="opencodex 라우팅 모델을 reasoning effort 선택기와 함께 보여주는 Codex App" width="480">
144153
</p>
@@ -164,8 +173,9 @@ opencodex는 두 가지 동작을 분리해서 유지합니다:
164173
- **한 번 로그인하면 API 키는 생략.** xAI, Anthropic, Kimi는 OAuth를 지원하므로 기존 계정으로 인증할 수 있고 토큰은 자동 갱신됩니다. 또는 `codex login`을 forward 하거나, API 키를 붙여넣거나, `${ENV_VAR}` 참조를 쓸 수 있습니다 — 선택은 자유입니다.
165174
- **Codex가 동작하는 모든 곳에서.** Codex CLI, TUI, App, SDK에 자동으로 주입됩니다. 라우팅된 모델이 네이티브 모델처럼 Codex 모델 선택기에 나타납니다.
166175
- **알맞은 모델에 위임.** 대시보드나 config에서 최대 5개의 라우팅/네이티브 모델을 Codex 서브에이전트 선택기에 노출해, 복잡한 작업은 reasoning 모델로, 빠른 작업은 저렴한 모델로 보낼 수 있습니다.
176+
- **프리뷰 게이트된 OpenAI rollout에 대비.** GPT-5.6 Sol/Terra/Luna fallback 항목은 OpenAI API key와 OpenRouter route용으로 준비되어 있으며, upstream access가 있을 때 `max` reasoning과 372k usable-context metadata를 사용합니다.
167177
- **어떤 모델에도 초능력을.** OpenAI가 아닌 모델도 ChatGPT 로그인 위에서 도는 `gpt-5.4-mini` sidecar로 실제 웹 검색과 이미지 이해를 사용합니다.
168-
- **무슨 일이 일어나는지 보이게.** 웹 대시보드가 프로바이더, OAuth 상태, 모델 선택, 실시간 요청 로그를 보여줍니다 — 왜 요청이 실패했는지 더는 추측하지 않아도 됩니다.
178+
- **무슨 일이 일어나는지 보이게.** 웹 대시보드가 프로바이더, OAuth 상태, 모델 선택, upstream이 보고한 cached/cache-write 토큰 수를 포함한 실시간 요청 로그를 보여줍니다 — 왜 요청이 실패했는지 더는 추측하지 않아도 됩니다.
169179
- **백그라운드 실행.** 시스템 서비스(launchd / systemd / Task Scheduler)로 설치하면 부팅 시 자동 시작되어 신경 쓸 필요가 없습니다.
170180
- **깔끔한 종료, 잔여물 제로.** `ocx stop`(또는 대시보드의 Stop 버튼)은 프록시를 종료하고, 설치된 백그라운드 서비스를 멈추며, Codex를 원래 설정으로 복원합니다. 이후 `codex`는 잔여 설정이나 좀비 프로세스 없이 이전과 똑같이 동작합니다.
171181

@@ -266,8 +276,10 @@ opencodex는 `config.json.invalid-<timestamp>`로 백업하고 경고를 출력
266276
프로바이더 항목은 라우팅 카탈로그 메타데이터도 함께 지정할 수 있습니다. `contextWindow`는 프로바이더
267277
전체에 적용되는 Codex 노출용 컨텍스트 상한, `modelContextWindows`는 모델별 상한,
268278
`modelInputModalities``["text"]``["text", "image"]` 같은 모델별 입력 힌트입니다. 이 값들은 라이브
269-
`/models` 메타데이터를 상한으로 제한할 뿐, 더 작은 라이브 컨텍스트를 늘리지는 않습니다. 전체 필드는
270-
설정 레퍼런스를 참고하세요.
279+
`/models` 메타데이터를 상한으로 제한할 뿐, 더 작은 라이브 컨텍스트를 늘리지는 않습니다. 번들된 GPT-5.6
280+
Sol/Terra/Luna fallback metadata는 OpenAI API key와 OpenRouter catalog 항목에 372,000 토큰 usable
281+
context window를 사용하며, upstream preview access를 우회하지 않습니다. 전체 필드는 설정 레퍼런스를
282+
참고하세요.
271283

272284
> **Z.AI 경유 GLM-5.2 1M 컨텍스트:** `openai-chat` adapter에서는 `glm-5.2``glm-5.2[1m]`이 모두
273285
> 동작합니다 — opencodex가 요청 전에 끝의 `[1m]` 접미사를 제거하기 때문입니다(OpenAI 호환 엔드포인트는

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ When you omit the `provider/` prefix, opencodex routes to the default provider
141141

142142
Routed models also appear in the **Codex App** model picker with per-model reasoning effort controls:
143143

144+
Current Codex builds can expose `low`, `medium`, `high`, `xhigh`, and `max` reasoning controls when a
145+
model advertises them. opencodex keeps `xhigh` and `max` distinct unless a provider config explicitly
146+
maps one to the other.
147+
148+
GPT-5.6 Sol/Terra/Luna are seeded as rollout-ready catalog entries for the OpenAI API key and
149+
OpenRouter presets (`gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`; OpenRouter uses
150+
`openai/...`). They remain preview-gated by upstream availability; opencodex only prepares the
151+
routing and catalog metadata for accounts and providers that can serve them.
152+
144153
<p align="center">
145154
<img src="assets/codex-app-picker.png" alt="Codex App showing opencodex routed models with reasoning effort picker" width="480">
146155
</p>
@@ -168,9 +177,11 @@ next Codex session. opencodex keeps two separate behaviors:
168177
can auto-pick a lower-usage account from the pool, with quota refresh and non-PII request labels.
169178
- **Log in once, skip the API key.** OAuth support for xAI, Anthropic, and Kimi means you can authenticate with your existing account. Tokens auto-refresh. Or forward your `codex login`, paste an API key, or use `${ENV_VAR}` references — your call.
170179
- **Works everywhere Codex does.** Injects into Codex CLI, TUI, App, and SDK automatically. Routed models show up in Codex's model picker just like native ones.
180+
- **History-safe injection.** On local installs the proxy points Codex's own built-in `openai` provider at itself via a single `openai_base_url` line — new threads keep their native provider tag, so ongoing chat history is never remapped and an unclean shutdown can't hide it. (Threads re-tagged by older versions are migrated back once on the first start; remote/LAN binds use a dedicated provider entry instead, since they need an API-key header.)
171181
- **Delegate to the right model.** Feature up to five routed or native models in Codex's subagent picker from the dashboard or config — route complex tasks to a reasoning model, fast tasks to a cheap one.
182+
- **Prepare for preview-gated OpenAI rollouts.** GPT-5.6 Sol/Terra/Luna fallback entries are ready for OpenAI API key and OpenRouter routes, with `max` reasoning and 372k usable-context metadata when upstream access is available.
172183
- **Give any model superpowers.** Non-OpenAI models get real web search and image understanding via a `gpt-5.4-mini` sidecar over your ChatGPT login.
173-
- **See what's happening.** The web dashboard shows providers, OAuth status, model selection, and a live request log — no more guessing why a request failed.
184+
- **See what's happening.** The web dashboard shows providers, OAuth status, model selection, and a live request log, including cached/cache-write token counts when upstream reports them — no more guessing why a request failed.
174185
- **Runs in the background.** Install as a system service (launchd / systemd / Task Scheduler) and forget about it. The proxy starts on boot and stays out of your way.
175186
- **Clean exit, zero residue.** `ocx stop` (or the dashboard's Stop button) shuts down the proxy, stops the background service if one is installed, and restores Codex to its original configuration. Plain `codex` works exactly as it did before — no leftover config, no orphaned processes.
176187

@@ -285,7 +296,9 @@ Provider entries can also annotate routed catalog metadata. Use `contextWindow`
285296
Codex-visible context cap, `modelContextWindows` for model-specific caps, and
286297
`modelInputModalities` for model-specific catalog input hints such as `["text"]` or
287298
`["text", "image"]`. Context values cap live `/models` metadata; they never raise a smaller live
288-
context window. See the configuration reference for the full field list.
299+
context window. The bundled GPT-5.6 Sol/Terra/Luna fallback metadata uses a 372,000-token usable
300+
context window for OpenAI API key and OpenRouter catalog entries; it does not bypass upstream preview
301+
access. See the configuration reference for the full field list.
289302

290303
> **GLM-5.2 1M context via Z.AI:** through the `openai-chat` adapter, both `glm-5.2`
291304
> and `glm-5.2[1m]` work — opencodex strips the trailing `[1m]` suffix before

README.zh-CN.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ npm install -g @bitkyc08/opencodex # 不要加 --ignore-scripts、--omit=optio
100100
- **登录一次,免填 API key。** xAI、Anthropic、Kimi 支持 OAuth,可用现有账户认证,token 自动刷新。也可以转发 `codex login`、粘贴 API key,或使用 `${ENV_VAR}` 引用 —— 随你选择。
101101
- **Codex 在哪里能用,它就在哪里能用。** 自动注入 Codex CLI、TUI、App 和 SDK。路由模型像原生模型一样出现在 Codex 的模型选择器里。
102102
- **委派给合适的模型。** 在仪表盘或 config 中把最多 5 个路由/原生模型放进 Codex 的 subagent 选择器 —— 复杂任务交给 reasoning 模型,快速任务交给便宜模型。
103+
- **为 preview-gated OpenAI rollout 做好准备。** GPT-5.6 Sol/Terra/Luna fallback 条目已可用于 OpenAI API key 和 OpenRouter 路由;当上游访问可用时,会带有 `max` reasoning 和 372k usable-context 元数据。
103104
- **给任意模型超能力。** 非 OpenAI 模型也能通过你的 ChatGPT 登录上运行的 `gpt-5.4-mini` sidecar 获得真正的网页搜索和图片理解。
104-
- **看清正在发生什么。** Web 仪表盘展示 provider、OAuth 状态、模型选择和实时请求日志 —— 不必再猜测请求为何失败。
105+
- **看清正在发生什么。** Web 仪表盘展示 provider、OAuth 状态、模型选择和实时请求日志;当上游返回时,也会包含 cached/cache-write token 计数 —— 不必再猜测请求为何失败。
105106
- **后台运行。** 安装为系统服务(launchd / systemd / Task Scheduler)后开机自启,无需操心。
106107
- **干净退出,零残留。** `ocx stop`(或仪表盘的 Stop 按钮)会关闭代理、停止已安装的后台服务,并将 Codex 恢复为原始配置。之后 `codex` 就像从未安装过 opencodex 一样工作 —— 无残留配置,无僵尸进程。
107108

@@ -147,6 +148,13 @@ codex -m "ollama/llama3" "重构这个函数"
147148

148149
路由模型也会出现在 **Codex App** 模型选择器中,并带有按模型的 reasoning effort 控制:
149150

151+
当前 Codex 构建在模型声明支持时可显示 `low``medium``high``xhigh``max` reasoning 控制。
152+
除非 provider config 明确设置 alias,opencodex 会把 `xhigh``max` 保持为不同档位。
153+
154+
GPT-5.6 Sol/Terra/Luna 已在 OpenAI API key 和 OpenRouter 预设中作为 rollout-ready 目录条目预置
155+
`gpt-5.6-sol``gpt-5.6-terra``gpt-5.6-luna`;OpenRouter 使用 `openai/...`)。可用性仍受上游
156+
preview gate 限制;opencodex 只是准备好你的账户/provider 可访问时所需的路由和目录元数据。
157+
150158
<p align="center">
151159
<img src="assets/codex-app-picker.png" alt="Codex App 展示 opencodex 路由模型及 reasoning effort 选择器" width="480">
152160
</p>
@@ -256,8 +264,9 @@ npm uninstall -g @bitkyc08/opencodex
256264

257265
provider 条目还可以标注路由目录元数据。`contextWindow` 设置 provider 级别、对 Codex 可见的上下文上限,
258266
`modelContextWindows` 设置按模型的上限,`modelInputModalities` 设置按模型的目录输入提示,例如 `["text"]`
259-
`["text", "image"]`。这些值只会对实时 `/models` 元数据设上限,绝不会抬高更小的实时上下文窗口。完整字段
260-
参阅配置参考。
267+
`["text", "image"]`。这些值只会对实时 `/models` 元数据设上限,绝不会抬高更小的实时上下文窗口。内置
268+
GPT-5.6 Sol/Terra/Luna fallback 元数据会为 OpenAI API key 和 OpenRouter 目录条目使用 372,000 token 的
269+
usable context window;它不会绕过上游 preview access。完整字段参阅配置参考。
261270

262271
> **通过 Z.AI 使用 GLM-5.2 1M 上下文:**`openai-chat` adapter 下,`glm-5.2``glm-5.2[1m]` 都可用 ——
263272
> opencodex 会在发送请求前剥离末尾的 `[1m]` 后缀,因为 OpenAI 兼容端点会拒绝带方括号的 id(Z.AI 400 code

bin/ocx.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
* The package source is TypeScript that runs on the Bun runtime. To let
66
* `npm install -g @bitkyc08/opencodex` work without a separately-installed Bun,
77
* we bundle the runtime via the `bun` npm dependency and exec it from this
8-
* Node shim. (Dev still runs `bun run src/cli.ts` directly via the shebang on
9-
* src/cli.ts — only the published npm `bin` routes through here.)
8+
* Node shim. (Dev still runs `bun run src/cli/index.ts` directly via the shebang on
9+
* src/cli/index.ts — only the published npm `bin` routes through here.)
1010
*/
1111
import { spawn, spawnSync } from "node:child_process";
1212
import { createRequire } from "node:module";
@@ -18,7 +18,7 @@ import { fileURLToPath } from "node:url";
1818
const PKG = "@bitkyc08/opencodex";
1919
const require = createRequire(import.meta.url);
2020
const here = dirname(fileURLToPath(import.meta.url));
21-
const cliPath = join(here, "..", "src", "cli.ts");
21+
const cliPath = join(here, "..", "src", "cli", "index.ts");
2222

2323
function isNodeModulesInstall() {
2424
return here.split(/[\\/]/).includes("node_modules");
@@ -67,7 +67,7 @@ function shouldRepairCodexShim() {
6767
}
6868

6969
function historyRestoreIncomplete() {
70-
// Mirror src/update.ts historyRestoreIncomplete — a codex-history-backup-*.json surviving
70+
// Mirror src/update/index.ts historyRestoreIncomplete — a codex-history-backup-*.json surviving
7171
// a stop means the native-history restore was skipped (locked state DB).
7272
try {
7373
return readdirSync(configDir()).some(

0 commit comments

Comments
 (0)