Skip to content

feat(codex): add Codex translation service via local Codex CLI#1168

Open
long2ice wants to merge 12 commits into
tisfeng:devfrom
long2ice:feat/codex-service
Open

feat(codex): add Codex translation service via local Codex CLI#1168
long2ice wants to merge 12 commits into
tisfeng:devfrom
long2ice:feat/codex-service

Conversation

@long2ice
Copy link
Copy Markdown

@long2ice long2ice commented May 7, 2026

Summary

Add a translation service that delegates to the locally installed
codex exec --json subprocess, mirroring the existing ClaudeCode service
pattern. Each query spawns a fresh Codex process — no cross-query state.

Scope

  • New CodexCLIService slots into the StreamService pipeline; assembles
    the prompt and hands it to a per-invocation runner.
  • CodexCLIRunner detects the codex binary via login shell, spawns
    codex exec --json --skip-git-repo-check --ephemeral --sandbox read-only -C <tmpdir>,
    and yields assistant text.
  • CodexCLIEventParser decodes Codex 0.128.x JSONL events:
    item.completed (agent_message) → assistant text; turn.completed.usage
    → token usage; turn.failed / error → typed errors.
  • CodexCLIError distinguishes notInstalled / notLoggedIn /
    quotaExceeded / cliError with localized messages.
  • CodexCLILogger + CodexCLIDebugWindow write per-request logs to
    Application Support/<bundle>/logs/codex-cli/ and expose them in a
    floating panel under AGENT_CLI_DEBUG.
  • CodexCLIServiceConfigurationView shows install status + risk warning;
    service-tab risk-alert flow gates first-time enabling.
  • Wired into QueryServiceFactory, EZServiceType, Localizable.xcstrings
    (en / sk / zh-Hans / zh-Hant), and a service-icon imageset.

Non-goals

  • No incremental token streaming. Codex 0.128.x emits the full message in
    one item.completed event; the runner yields it once per turn.
  • No OAuth / proxy workarounds — uses the user's local codex login /
    OPENAI_API_KEY exactly as the official CLI does.

Test plan

  • CodexCLIRunnerTests — argument construction, error parsing
    (stdout JSONL + stderr fallbacks), token-usage extraction, login-shell
    resolution.
  • CodexCLIServiceTests — service type, API key requirement,
    factory registration.
  • Manual: enable service, accept risk alert, translate
    "曾经沧海难为水" → returns English translation.
  • Manual: with codex uninstalled, settings status row shows
    "not installed" red icon.
  • Build and run on macOS 13+.

Mirror the ClaudeCode service pattern to delegate translation requests
to the locally installed `codex exec --json` subprocess. Parse Codex's
JSONL events (`item.completed` / `turn.completed`) for assistant text
and token usage; surface dedicated errors for missing binary, signed-out
state, and quota exhaustion. Wire the service into the factory, settings
tab risk-alert flow, EZServiceType enum, and service-icon assets, and
add unit tests covering argument construction, error parsing, and token
usage extraction.
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello long2ice, Thank you for your first PR contribution 🎉 long2ice

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3423c1f78d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIEventParser.swift Outdated
Codex emits failure events such as turn.failed with `error` either as a
plain string or as a structured object like `{"message":"...","code":"..."}`.
The strict `String?` decoder dropped the object form on the floor, so users
saw a generic fallback instead of proper auth / quota classification or the
real CLI message. Introduce a `CodexCLIErrorField` wrapper that handles
both shapes and falls back to `nil` for unsupported types.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acc77a10f9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/README.md Outdated
Comment thread EasydictTests/Service/CodexCLI/README.md Outdated
long2ice added 2 commits May 7, 2026 11:17
Replace the placeholder READMEs with the AGENTS.md-mandated layout:
each Codex directory now ships a Chinese `<dir>-overview.md` plus a
matching `<dir>-architecture.svg` rendered via fireworks-tech-graph.
The service diagram traces request flow Service → Runner → codex
subprocess → EventParser → text/usage/error outputs (with Logger as
side branch); the tests diagram maps both @suite types to their
covered test groups and pins out-of-scope concerns. Update
project.pbxproj to expose the new files in Xcode's navigator.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f4c7b339df

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIEventParser.swift
Previously parseCodexError ran auth/quota keyword matching against any
decoded stdout line that exposed a message, which would mis-classify
runs whose agent_message or reasoning text legitimately mentioned
"401", "unauthorized", or "rate limit". Gate the classification behind
isFailureEvent so only turn.failed / thread.failed / error events
(and item.completed errors) feed the auth/quota detectors. Add two
regression tests covering noise-only stdout and noise-then-failure
ordering.
@tisfeng
Copy link
Copy Markdown
Owner

tisfeng commented May 9, 2026

Thanks your PR, we will review it soon

@MoonMao42
Copy link
Copy Markdown
Collaborator

一个小小的建议,因为翻译工作一般来说比较轻松,而且要求速度,而我们编码一般用最先进的model,速度较慢.所以如果能加个模型选择以及思考程度在模型设置页而不是沿用主进程的模型会更好.给用户选择可以切xxx模型.具体实现exec -m就可以解决

@Issues-translate-bot
Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


A small suggestion, because translation work is generally easy and requires speed, and our coding generally uses the most advanced models, which are slower. Therefore, it would be better if you can add model selection and thinking level to the model settings page instead of using the model of the main process. Give users the option to switch to xxx model. It can be solved by implementing exec -m

Address @MoonMao42's review feedback by letting users pick a translation-
specific model and reasoning effort instead of inheriting the heavyweight
defaults from ~/.codex/config.toml. Empty model and `.default` effort
both fall through to codex's existing config so the change is opt-in.
The runner now adds `-m <model>` and `-c model_reasoning_effort=<value>`
only when the user supplies a non-empty value, and the settings panel
exposes a free-form model input plus a localized picker covering all
seven values codex accepts (default / none / minimal / low / medium /
high / xhigh).
@long2ice
Copy link
Copy Markdown
Author

done

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2b4788b737

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIEventParser.swift Outdated
parseCodexError previously stored only the first failure event's message,
so transient `type:"error"` progress notices (e.g. reconnect hints) emitted
before the terminal `turn.failed` would mask the actual failure reason.
Switch the generic message to last-wins so the cliError fallback always
surfaces the most recent failure text. Auth and quota detection keep
first-match: the earliest keyword hit is more reliable as the root signal
than later cascade messages.
@tisfeng
Copy link
Copy Markdown
Owner

tisfeng commented May 12, 2026

请解决一下冲突

@Issues-translate-bot
Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


Please resolve the conflict

# Conflicts:
#	Easydict.xcodeproj/project.pbxproj
#	Easydict/objc/Service/Model/EZEnumTypes.h
#	Easydict/objc/Service/Model/EZEnumTypes.m
@long2ice
Copy link
Copy Markdown
Author

done

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7173fe94df

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIRunner.swift Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 87dc2962d9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIEventParser.swift Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2417ecc148

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread Easydict/Swift/Service/CodexCLI/CodexCLIRunner.swift Outdated
@tisfeng
Copy link
Copy Markdown
Owner

tisfeng commented May 17, 2026

这两天一直在弄自动打包脚本,没来得及看这个 PR,请大家先帮忙 review 一下。

@Issues-translate-bot
Copy link
Copy Markdown

Bot detected this issue is not in English and translated it automatically.


I have been working on the automatic packaging script for the past two days and have not had time to look at this PR. Please help review it first.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f057496817

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,61 @@
# CodexCLI 目录概览
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Replace Markdown overview with required HTML overview

The new Swift/Service/CodexCLI source directory is documented as codex-cli-overview.md, but /workspace/Easydict/AGENTS.md requires non-exempt project source directories to provide a Chinese HTML overview named <directory-kebab>-overview.html plus a same-prefix SVG. Keeping this as Markdown breaks the repository’s documented discovery/maintenance workflow for this module because tooling and contributors expecting the mandated HTML artifact will not find it.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants