[codex] 修复 Coding Agents 的 Codex 启动和代理隔离 (#1123)
* feat: add coding agent install status * chore: add latest claude opus model preset * feat: add coding agent config editing * Add scoped coding agent launch proxy * Add Codex proxy plan * fix coding agents codex launch proxy * fix codex catalog context test --------- Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# Codex Config And Proxy Plan
|
||||
|
||||
## Goals
|
||||
|
||||
- Launch Codex from Hermes without mutating the user's real `~/.codex`.
|
||||
- Keep model/provider config isolated by Hermes profile and provider.
|
||||
- Support OpenAI Responses providers directly.
|
||||
- Add a local adapter for providers that only expose OpenAI Chat Completions.
|
||||
- Keep Codex resume/history stable by using a consistent model provider id.
|
||||
|
||||
## Directory Layout
|
||||
|
||||
All generated Codex state should live under the Web UI home:
|
||||
|
||||
```text
|
||||
~/.hermes-web-ui/coding-agent/
|
||||
model/{profile}/{provider}/codex/
|
||||
config.toml
|
||||
auth.json
|
||||
AGENTS.md
|
||||
workspace/{profile}/{provider}/
|
||||
```
|
||||
|
||||
Launch command shape:
|
||||
|
||||
```bash
|
||||
cd ~/.hermes-web-ui/coding-agent/workspace/{profile}/{provider} \
|
||||
&& CODEX_HOME=~/.hermes-web-ui/coding-agent/model/{profile}/{provider}/codex \
|
||||
codex --model {model}
|
||||
```
|
||||
|
||||
## Current MVP Config
|
||||
|
||||
For Responses-compatible providers, generate:
|
||||
|
||||
```toml
|
||||
model_provider = "custom"
|
||||
model = "provider-model-id"
|
||||
disable_response_storage = true
|
||||
|
||||
[model_providers.custom]
|
||||
name = "provider-id"
|
||||
base_url = "https://provider.example/v1"
|
||||
wire_api = "responses"
|
||||
requires_openai_auth = false
|
||||
experimental_bearer_token = "provider-api-key"
|
||||
```
|
||||
|
||||
Keep `auth.json` empty for third-party providers:
|
||||
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
Reason: avoid overwriting the user's official Codex / ChatGPT login cache.
|
||||
|
||||
## Stable Provider Id
|
||||
|
||||
Use `model_provider = "custom"` for third-party providers.
|
||||
|
||||
Codex history and resume behavior can depend on provider identity. Keeping a stable provider id avoids making history appear to move between provider-specific ids.
|
||||
|
||||
Provider identity remains visible in:
|
||||
|
||||
- `[model_providers.custom].name`
|
||||
- the generated directory path
|
||||
- the UI launch result
|
||||
|
||||
## Local Proxy Plan
|
||||
|
||||
Some providers expose only OpenAI Chat Completions:
|
||||
|
||||
```text
|
||||
/v1/chat/completions
|
||||
```
|
||||
|
||||
Codex prefers Responses:
|
||||
|
||||
```text
|
||||
/v1/responses
|
||||
```
|
||||
|
||||
Add a local proxy endpoint:
|
||||
|
||||
```text
|
||||
/api/codex-proxy/{routeKey}/v1/responses
|
||||
```
|
||||
|
||||
The `routeKey` should encode:
|
||||
|
||||
```text
|
||||
profile + "\0" + provider + "\0" + model
|
||||
```
|
||||
|
||||
Authentication should use a generated `hwui_...` token, not the upstream provider key.
|
||||
|
||||
## Responses To Chat Mapping
|
||||
|
||||
When the upstream provider is Chat Completions only:
|
||||
|
||||
- Convert Responses `input` items to Chat `messages`.
|
||||
- Convert Responses `tools` to Chat `tools`.
|
||||
- Convert `max_output_tokens` to `max_tokens`.
|
||||
- Preserve `stream: true`.
|
||||
- Map function calls and function outputs both ways.
|
||||
|
||||
Response event mapping for streaming:
|
||||
|
||||
```text
|
||||
chat delta.content -> response.output_text.delta
|
||||
chat delta.tool_calls -> response.function_call_arguments.delta
|
||||
finish -> response.completed
|
||||
```
|
||||
|
||||
Non-streaming mapping:
|
||||
|
||||
```text
|
||||
chat.choices[0].message.content -> output message/content
|
||||
chat.choices[0].message.tool_calls -> output function_call items
|
||||
chat.usage -> response.usage
|
||||
```
|
||||
|
||||
## Config Generation With Proxy
|
||||
|
||||
For Chat-only providers, generated Codex config should point at Hermes:
|
||||
|
||||
```toml
|
||||
model_provider = "custom"
|
||||
model = "provider-model-id"
|
||||
disable_response_storage = true
|
||||
|
||||
[model_providers.custom]
|
||||
name = "provider-id"
|
||||
base_url = "http://127.0.0.1:{serverPort}/api/codex-proxy/{routeKey}/v1"
|
||||
wire_api = "responses"
|
||||
requires_openai_auth = false
|
||||
experimental_bearer_token = "hwui_generated_route_token"
|
||||
```
|
||||
|
||||
The proxy then forwards to the real provider with the real provider key.
|
||||
|
||||
## Implementation Tasks
|
||||
|
||||
1. Add a Codex proxy service parallel to the Claude Code proxy service.
|
||||
2. Register route targets in memory for launch-time provider/model selection.
|
||||
3. Add `/api/codex-proxy/:key/v1/responses`.
|
||||
4. Implement Responses to Chat conversion.
|
||||
5. Implement Chat to Responses conversion for streaming and non-streaming.
|
||||
6. Add launch-time api mode selection for Codex providers.
|
||||
7. Generate Codex `base_url` against the local proxy when api mode is Chat Completions.
|
||||
8. Add server tests for config generation, auth rejection, streaming conversion, tool call conversion, and error passthrough.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Whether to expose Codex protocol selection in the UI immediately or infer it from provider preset metadata.
|
||||
- Whether to persist proxy targets or require relaunch after server restart.
|
||||
- Whether model catalog generation is needed for the first Codex MVP.
|
||||
- Whether MCP and `AGENTS.md` should be copied from a template or edited only through the advanced config editor.
|
||||
Reference in New Issue
Block a user