Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions ACKNOWLEDGEMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@

- **Link**: https://github.com/openai/codex
- **License**: Apache-2.0
- **借鉴形式**: Prompt 蓝本(精简移植)+ 协议反查(数据模式参照)
- **首次借鉴 PR / 时间**: v2.0.x 起协议结构反查;fix/219 起 prompt 结构借鉴
- **借鉴形式**: Prompt 蓝本(精简移植)+ 协议反查(数据模式参照)+ V4A apply_patch system guidance(verbatim 引用)
- **首次借鉴 PR / 时间**: v2.0.x 起协议结构反查;fix/219 起 compact prompt 结构借鉴;PR #235 后续(post-#236)起 apply_patch V4A chat-path guidance verbatim 引用
- **借鉴清单**:
- `COMPACT_SUMMARIZATION_PROMPT` 基础骨架 → `crates/adapters/src/responses/compact.rs:82-92`
(源文件:`codex-rs/core/templates/compact/prompt.md`,~460 chars)
Expand All @@ -137,6 +137,12 @@
- `CompactHistoryResponse { output: Vec<ResponseItem> }` + `ResponseItem::Compaction { encrypted_content }` 响应结构
→ `compact.rs` 序列化路径
(源文件:`codex-rs/codex-api/src/endpoint/compact.rs` + `codex-rs/protocol/src/models.rs:882`)
- apply_patch V4A chat-path system guidance(verbatim 引用)→
`crates/adapters/src/responses/apply_patch_v4a_reference.md`(verbatim 镜像,头部加 adapter note 显式 override "shell command" 字眼为 "function-call tool",其余原文未改动)
由 `crates/adapters/src/responses/request.rs::APPLY_PATCH_CHAT_PATH_SYSTEM_GUIDANCE`(`include_str!`)拼装注入
源文件:`codex-rs/core/prompt_with_apply_patch_instructions.md` 的 L277-L351 @ commit `0b4f86095c8005d8f74e9c62b971d72c1670aa88`
动机:issue #235 真机 capture 28-turn / 26MB DeepSeek+Kimi 数据,模型生成 V4A patch 在 chat-path 失败率 6 / 7 个 turn,需要在 prompt 注入完整 V4A 教学(envelope / hunks / `@@` 锚点 / 3-line context / EBNF / 多操作 example)。chat-path 无 lark grammar 兜底,只能靠 prompt 引导。
上游 SHA 升级时:同步更新本文件 + `apply_patch_v4a_reference.md` 头部 + `request.rs::APPLY_PATCH_CHAT_PATH_SYSTEM_GUIDANCE` doc comment + `README.md` / `README.en.md` 致谢段 + `NOTICE` 文件共 6 处 commit SHA,再 fresh slice 覆盖 reference 正文。
- **本项目差异 / 扩展**:
- prompt 补两条 Claude Code 关键 bullet("All user messages verbatim" + "Next Step verbatim quote"),
借鉴自 Piebald-AI/claude-code-system-prompts 反编译公开版本第 6 / 9 段(见下方同名 entry)
Expand Down
60 changes: 60 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Codex App Transfer
Copyright (c) 2026 Codex App Transfer

This project is licensed under the MIT License (see LICENSE.txt).

=============================================================================
Third-party attribution
=============================================================================

This project includes prose / prompt content derived from upstream open-source
projects. The following attributions are required by the upstream licenses.

-----------------------------------------------------------------------------
openai/codex — Apache License 2.0
-----------------------------------------------------------------------------

Copyright 2025 OpenAI

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at:

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.

Derived content in this repository:

* crates/adapters/src/responses/apply_patch_v4a_reference.md
Verbatim mirror of the V4A apply_patch walkthrough section
(envelope grammar / `@@` anchors / 3-line context / EBNF / multi-op
example) from upstream:
Source repo: https://github.com/openai/codex
Source commit: 0b4f86095c8005d8f74e9c62b971d72c1670aa88
Source file: codex-rs/core/prompt_with_apply_patch_instructions.md
Source lines: L277-L351 (75 lines)
The mirror file adds a one-line "Adapter note" preamble (authored by
codex-app-transfer maintainers) clarifying that in this chat-completions
environment apply_patch is a function-call tool, not a shell command.
The borrowed prose itself is otherwise unmodified.

The mirror file is embedded into the system prompt at runtime via
`include_str!` from
`crates/adapters/src/responses/request.rs::APPLY_PATCH_CHAT_PATH_SYSTEM_GUIDANCE`.

* crates/adapters/src/responses/compact.rs (prior borrowing, retained)
`COMPACT_SUMMARIZATION_PROMPT` skeleton and `COMPACT_SUMMARY_PREFIX`
derived from
`codex-rs/core/templates/compact/{prompt.md,summary_prefix.md}`.
See ACKNOWLEDGEMENTS.md for full borrowing list and file:line mapping.

-----------------------------------------------------------------------------

For the complete list of upstream projects this repository borrows from
(including non-Apache projects), see ACKNOWLEDGEMENTS.md and the credits
section of README.md / README.en.md.
3 changes: 2 additions & 1 deletion README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ With any provider enabled, Codex CLI's model picker shows `<provider> / <real-mo
- Manage multiple providers; map OpenAI model names (`gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` / `gpt-5.3-codex` / `gpt-5.2`) to the provider's real model IDs
- Translate Codex CLI's Responses API streaming / non-streaming requests into upstream protocols: Chat Completions, Gemini Native (`:streamGenerateContent`), Gemini CLI OAuth (Cloud Code Assist), Anthropic Messages (`/v1/messages`), Grok Web (`/rest/app-chat/conversations/new`), Responses passthrough, etc.
- Multi-turn tool conversation context + `previous_response_id` history replay + autocompact expansion + thinking / reasoning_content injection — all aligned with the OpenAI Responses API protocol
- Codex CLI's freeform `apply_patch` tool (edit-file +/- diff UI) works on DeepSeek / Kimi / MiMo and other chat-completions providers: the adapter bridges Responses `custom_tool_call` ↔ chat `function_call` wire forms, the model emits V4A-format patches, Codex CLI renders the diff (issue #235)
- **Two-layer session history persistence**: L1 in-memory LRU + L2 sqlite with 30-day TTL (`~/.codex-app-transfer/sessions.db`), preserving history across `.app` restarts
- Codex CLI config guardrails: snapshots `~/.codex/{config.toml,auth.json}` before apply; restores via per-key smart merge on exit / next start
- Real-time logs panel auto-refreshing every 2s; unified `tracing::warn!(error_id, detail)` with stable tokens — operators can grep / aggregate
Expand Down Expand Up @@ -224,7 +225,7 @@ Some experimental providers (Grok Web / Gemini CLI OAuth / Antigravity OAuth) in
- [`lonr-6/cc-desktop-switch`](https://github.com/lonr-6/cc-desktop-switch) — v1.x desktop shell skeleton + README structure reference
- [`BerriAI/litellm`](https://github.com/BerriAI/litellm) — bidirectional protocol translation patterns
- [`tauri-apps/tauri`](https://tauri.app/) — v2 + `cas://` architecture base
- [`openai/codex`](https://github.com/openai/codex) — autocompact prompt base structure + compact protocol reverse-reference (Apache-2.0)
- [`openai/codex`](https://github.com/openai/codex) — autocompact prompt base structure + compact protocol reverse-reference + verbatim apply_patch V4A chat-path system guidance (`codex-rs/core/prompt_with_apply_patch_instructions.md` L277-L351 @ commit `0b4f86095c8005d8f74e9c62b971d72c1670aa88`, Apache-2.0)
- [`Piebald-AI/claude-code-system-prompts`](https://github.com/Piebald-AI/claude-code-system-prompts) — autocompact anchor bullets (All user messages verbatim + Next Step verbatim)
- [`7as0nch/mimo2codex`](https://github.com/7as0nch/mimo2codex) — MiMo protocol reference
- [`router-for-me/CLIProxyAPI`](https://github.com/router-for-me/CLIProxyAPI) — Gemini OAuth wire-level reference
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Codex App Transfer 是一个面向 **OpenAI Codex CLI** 的轻量桌面配置 +
- 管理多套供应商,按 OpenAI 模型名(`gpt-5.5` / `gpt-5.4` / `gpt-5.4-mini` / `gpt-5.3-codex` / `gpt-5.2`)映射到供应商真实模型 ID
- 把 Codex CLI 的 Responses API 流式 / 非流式请求转换为上游协议:Chat Completions、Gemini Native(`:streamGenerateContent`)、Gemini CLI OAuth(Cloud Code Assist)、Anthropic Messages(`/v1/messages`)、Grok Web(`/rest/app-chat/conversations/new`)、Responses 透传等
- 多轮工具对话上下文 + `previous_response_id` 历史回放 + autocompact 展开 + thinking / reasoning_content 注入全部对齐 OpenAI Responses API 协议
- Codex CLI 的 freeform `apply_patch` 工具(编辑文件 +/- diff UI)在 DeepSeek / Kimi / MiMo 等 chat-completions provider 上正常工作:adapter 双向桥接 Responses `custom_tool_call` ↔ chat `function_call` 形态,模型按 V4A 格式生成 patch,Codex CLI 渲染为 diff(issue #235)
- 会话历史**两层持久化**:L1 内存 LRU + L2 sqlite 30 天 TTL(`~/.codex-app-transfer/sessions.db`),`.app` 重启不丢历史
- Codex CLI 原配置守护:apply 前自动快照 `~/.codex/{config.toml,auth.json}`,退出 / 下次启动按 key 智能合并还原
- 实时日志面板,2 秒自动刷新;统一 `tracing::warn!(error_id, detail)` + 稳定 token,operator 可 grep / 聚合
Expand Down Expand Up @@ -232,7 +233,7 @@ v2.1.12+ 的客户端 **强制** RSA-3072 PKCS#1-v1.5-SHA256 验签 `latest.json
- [`lonr-6/cc-desktop-switch`](https://github.com/lonr-6/cc-desktop-switch) — v1.x 桌面壳骨架 + README 结构参考
- [`BerriAI/litellm`](https://github.com/BerriAI/litellm) — 协议双向转换思路
- [`tauri-apps/tauri`](https://tauri.app/) — v2 + `cas://` 架构基座
- [`openai/codex`](https://github.com/openai/codex) — autocompact prompt 骨架 + compact 协议结构反查(Apache-2.0)
- [`openai/codex`](https://github.com/openai/codex) — autocompact prompt 骨架 + compact 协议结构反查 + apply_patch V4A chat-path system guidance verbatim 引用(`codex-rs/core/prompt_with_apply_patch_instructions.md` L277-L351 @ commit `0b4f86095c8005d8f74e9c62b971d72c1670aa88`,Apache-2.0)
- [`Piebald-AI/claude-code-system-prompts`](https://github.com/Piebald-AI/claude-code-system-prompts) — autocompact prompt 锚定 bullet(All user messages verbatim + Next Step verbatim)
- [`7as0nch/mimo2codex`](https://github.com/7as0nch/mimo2codex) — MiMo 协议借鉴
- [`router-for-me/CLIProxyAPI`](https://github.com/router-for-me/CLIProxyAPI) — Gemini OAuth wire 参考
Expand Down
79 changes: 79 additions & 0 deletions crates/adapters/src/responses/apply_patch_v4a_reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
> Adapter note (codex-app-transfer): in this chat-completions environment `apply_patch` is exposed as a function-call tool, NOT a shell command. Read every "`apply_patch` shell command" / "invoke apply_patch like `shell {"command":[...]}`" reference in the prose below as "the `apply_patch` function-call tool" — the patch envelope, hunk format, and V4A grammar are identical; only the invocation surface differs. Specifically: call the `apply_patch` function with a single `input` string containing the V4A patch (no `shell` wrapper, no JSON-quoting tricks); the trailing shell-style invocation example at the very end is for the upstream Codex CLI's shell-tool path and does not apply here.
>
> Source: verbatim mirror of openai/codex @ commit `0b4f86095c8005d8f74e9c62b971d72c1670aa88`, file `codex-rs/core/prompt_with_apply_patch_instructions.md`, lines L277-L351. Apache-2.0, Copyright 2025 OpenAI. Stored at `crates/adapters/src/responses/apply_patch_v4a_reference.md` in this repository. See `NOTICE` + `ACKNOWLEDGEMENTS.md` for full attribution.

## `apply_patch`

Use the `apply_patch` shell command to edit files.
Your patch language is a stripped‑down, file‑oriented diff format designed to be easy to parse and safe to apply. You can think of it as a high‑level envelope:

*** Begin Patch
[ one or more file sections ]
*** End Patch

Within that envelope, you get a sequence of file operations.
You MUST include a header to specify the action you are taking.
Each operation starts with one of three headers:

*** Add File: <path> - create a new file. Every following line is a + line (the initial contents).
*** Delete File: <path> - remove an existing file. Nothing follows.
*** Update File: <path> - patch an existing file in place (optionally with a rename).

May be immediately followed by *** Move to: <new path> if you want to rename the file.
Then one or more “hunks”, each introduced by @@ (optionally followed by a hunk header).
Within a hunk each line starts with:

For instructions on [context_before] and [context_after]:
- By default, show 3 lines of code immediately above and 3 lines immediately below each change. If a change is within 3 lines of a previous change, do NOT duplicate the first change’s [context_after] lines in the second change’s [context_before] lines.
- If 3 lines of context is insufficient to uniquely identify the snippet of code within the file, use the @@ operator to indicate the class or function to which the snippet belongs. For instance, we might have:
@@ class BaseClass
[3 lines of pre-context]
- [old_code]
+ [new_code]
[3 lines of post-context]

- If a code block is repeated so many times in a class or function such that even a single `@@` statement and 3 lines of context cannot uniquely identify the snippet of code, you can use multiple `@@` statements to jump to the right context. For instance:

@@ class BaseClass
@@ def method():
[3 lines of pre-context]
- [old_code]
+ [new_code]
[3 lines of post-context]

The full grammar definition is below:
Patch := Begin { FileOp } End
Begin := "*** Begin Patch" NEWLINE
End := "*** End Patch" NEWLINE
FileOp := AddFile | DeleteFile | UpdateFile
AddFile := "*** Add File: " path NEWLINE { "+" line NEWLINE }
DeleteFile := "*** Delete File: " path NEWLINE
UpdateFile := "*** Update File: " path NEWLINE [ MoveTo ] { Hunk }
MoveTo := "*** Move to: " newPath NEWLINE
Hunk := "@@" [ header ] NEWLINE { HunkLine } [ "*** End of File" NEWLINE ]
HunkLine := (" " | "-" | "+") text NEWLINE

A full patch can combine several operations:

*** Begin Patch
*** Add File: hello.txt
+Hello world
*** Update File: src/app.py
*** Move to: src/main.py
@@ def greet():
-print("Hi")
+print("Hello, world!")
*** Delete File: obsolete.txt
*** End Patch

It is important to remember:

- You must include a header with your intended action (Add/Delete/Update)
- You must prefix new lines with `+` even when creating a new file
- File references can only be relative, NEVER ABSOLUTE.

You can invoke apply_patch like:

```
shell {"command":["apply_patch","*** Begin Patch\n*** Add File: hello.txt\n+Hello, world!\n*** End Patch\n"]}
```
Loading