中文 README。English version: README.md
PyPI distributions:
- 主包:
python-codex - Workspace 安装别名:
pycodex-ws
Import 路径仍保持 pycodex;CLI 命令为 pycodex 和 pycodex-ws。
pycodex-ws 是一个薄 metapackage,精确依赖同版本的 python-codex。
实际代码和 console script 继续由 python-codex 提供,两个 distribution
不会重复安装同名模块。
这个仓库把上游 Codex(https://github.com/openai/codex)里最核心的 agent
闭环先抽成一个尽量小的 Python 版本,重点保留两层结构:
submission_loop:顺序消费提交的操作。run_turn:在单个 turn 内持续执行模型采样 -> 工具调用 -> 把工具结果喂回模型,直到拿到最终回答。
对应的 Rust 参考点:
codex-rs/core/src/codex.rs里的submission_loopcodex-rs/core/src/codex.rs里的run_turncodex-rs/core/src/codex.rs里的run_sampling_requestcodex-rs/core/src/tools/router.rs里的ToolRoutercodex-rs/core/src/stream_events_utils.rs里的handle_output_item_done
安装完整包或 workspace 安装别名:
pip install python-codex
pip install pycodex-ws先安装开发依赖:
uv sync试一下真实入口:
uv run pycodex "Reply with exactly OK."
uv run pycodex这里不是对 Rust 版本做 1:1 移植,而是先收敛到一个最小可复用内核:
- 用一个很薄的
ModelClient协议抽象模型侧。 - 用
ToolRegistry管理工具规格和执行器。 - 用
AgentLoop实现核心闭环。 - 用
AgentRuntime保留外层提交队列,方便以后继续对齐 Rust 的submission_loop。
暂时刻意不包含:
- TUI / 流式增量渲染
- MCP / connectors / sandbox / approvals
- memory / compact / review mode
- 真实 OpenAI 适配器
这些都可以后续继续往上叠,但当前项目先把最核心的“工具增强推理主循环”钉住。
pycodex/protocol.py:最小的会话 item / prompt / event 协议pycodex/model.py:模型客户端协议和 Responses API 适配器pycodex/cli.py:pycodex单轮命令行入口pycodex/tools/base_tool.py:BaseTool、ToolRegistry、ToolContextpycodex/tools/:具体工具实现pycodex/agent.py:主循环pycodex/runtime.py:外层提交队列tests/test_agent.py:核心行为测试
当前进度可以分成两层看:
- prompt/context 对齐:
- 非交互
exec路径下,instructions和input已经对齐到上游 Codex; - 这一层现在主要由
pycodex/context.py和 vendored prompt data 负责。
- 非交互
- turn-loop 语义对齐:
AgentLoop默认不再使用固定 12 轮上限;- 现在和上游一样,按 “还有没有 follow-up / tool handoff” 自然收敛;
- 本地不再保留额外的 iteration-limit 参数。
- request-level 对齐:
- 非交互
exec路径的 request body 已基本对齐; - 默认 CLI 的 non-exec 首轮请求现在也已切到
codex-tui+<collaboration_mode>这条上游路径; - 默认 CLI 的两轮主线程对话 request/header 也已补抓并对齐,包括后续 turn 不再携带
workspaces; - 当前剩余重点主要转向更外围的行为分支,而不是这条已比较路径上的 request/header。
- 非交互
- tool round-trip 对齐:
request_user_input的 Default-mode unavailable 路径已按真实 upstream capture 对齐;- Plan-mode happy path 现在也已按 upstream 源码补齐到工具/协议层:会强制
isOther=true、要求非空options,并以 JSON 字符串 +success=true回传结构化答案; - 新增了一个基于
tests/fake_responses_server.pyproxy 模式的 deterministic round-trip compare 脚本tests/compare_request_user_input_roundtrip.py;它在本机已安装的codex-cli 0.115.0上确认:Plan-mode live capture 里唯一剩余的function_call_outputschema 差异是pycodex多带了success=true。
更细的对齐说明见 docs/ALIGNMENT.md。
如果本机已经有 Codex CLI 配置,可直接复用 ~/.codex/config.toml 里的
model、model_provider、base_url、env_key:
from pycodex import ResponsesModelClient
client = ResponsesModelClient.from_codex_config()当前实现走 OpenAI-compatible Responses API 的流式 /responses 接口。这个点
已经用本机 ~/.codex/config.toml 做过联调验证。
通过 CLI 启动时,pycodex 还会在读取配置前加载同目录下的 .env
(通常是 ~/.codex/.env),方便把 provider key 之类的环境变量放在那里。
为对齐上游 Codex,.env 中以 CODEX_ 开头的变量不会被导入。
pycodex 现在默认是一个最小交互式入口,内部通过 AgentRuntime 驱动 turn
提交循环,默认直接复用 ~/.codex/config.toml:
pycodex
pycodex "Summarize this repo in one sentence."
printf 'Reply with exactly OK.' | pycodex
pycodex --json "Reply with exactly OK."
pycodex --profile model_proxy "Reply with exactly OK."
pycodex --vllm-endpoint http://127.0.0.1:18000 "Reply with exactly OK."
pycodex --put @127.0.0.1:5577
pycodex --put /data/.codex/@127.0.0.1:5577
pycodex --call SECRET-CALLID@127.0.0.1:5577 "只回复 OK。"
pycodex doctor当前行为:
- 没有 argv prompt 且 stdin 是 TTY 时,进入交互模式
- 有 argv prompt 或 stdin 管道输入时,执行单轮请求
- 交互模式下支持
/exit和/quit - 交互模式下会显示简洁阶段事件流,例如工具执行状态和模型回看工具结果
- assistant 文本会按流式 delta 直接打印
- 交互模式下支持
/history、/title、/model和/resume /model <name>会切换当前交互会话后续请求使用的模型;/model会显示当前模型和可选模型/resume不带参数时会按首条用户消息预览列出当前可恢复的 session;/resume 1会恢复列表里的第 1 个 session/resume <数字>会从CODEX_HOME/sessions读取选中的已记录 Codex rollout, 并直接替换当前内存里的会话 history- 新 session 现在会自动保存到
CODEX_HOME/sessions/.../rollout-*.jsonl, 使用稳定的 session/thread id,并按 item 级别 append + flush,和/resume读取的 rollout 格式保持一致 - 如果 workspace 根目录存在非空的
TURN_HOOK.md,每个已完成 turn 之后都会把 刚结束的 history fork 成一个不落盘的临时 follow-up 会话,并把文件内容作为下一条 user 指令提交;适合做 Feishu 通知这类副作用收尾动作 - 交互模式默认支持 steer:普通输入会走 runtime 的 steer 路径,当前请求会在下一个安全边界尽快停下,后续 steer 文本会按顺序并入下一次模型请求的
input;如需明确排队可用/queue <message>,会打印[steer] queued: ...,随后等该 turn 真正开始时再打印[steer] inserted: ... - 当前默认工具集由上游对齐子集和 pycodex 的
clock扩展组成:shell、shell_command、exec_command、write_stdin、clock、exec、wait、web_search、update_plan、request_user_input、request_permissions、spawn_agent、send_input、resume_agent、wait_agent、close_agent、apply_patch、grep_files、read_file、list_dir、view_image clock(period_m)为当前 Agent session 设置一个周期计时器,传null取消;每次回复后重新计时,到期后用包含当前时区时间的<clock_tick>消息唤醒 Agent- 后台命令或 clock 正在等待时,空闲状态统一显示为
idle: sleeping - workspace 只在当前活动 tab 上显示关闭按钮
--vllm-endpoint http://host:port会自动拉起一个本地responses_servercompat 层;当 path 为空时会内部补/v1,继续把/responses请求转到下游/v1/chat/completions。这条本地 compat 路径始终使用标准 Responses request shape,即使所选模型的 metadata 打开了responses_lite也不会切换成 lite wire format;启动时还会读取下游/v1/models,自动使用返回列表中的最后一个 model id。当前对model_provider = "vllm"已补上 reasoning 兼容:会把 chat chunk 里的reasoning/reasoning_content翻回 Responsesreasoningitem,并把历史里的reasoningitem 回放成下游 assistant message 的reasoning字段;同时会向 vLLM 请求 streaming usage,并在最终response.completed.response.usage中回传pycodex doctor会检查配置、.env、API key、DNS、TCP/TLS,以及可选的 live Responses API 请求
它目前主要用于:
- 验证 provider / model / auth 配置是否可用
- 调试
ResponsesModelClient - 做最小单轮 / 多轮 smoke test
doctor 示例:
pycodex doctor
pycodex doctor --skip-live
pycodex doctor --jsonPortable Mode 适合在新机器、新容器或新的调试镜像里,快速带起你平时使用的
pycodex 配置。
常见用法:
pycodex --put @127.0.0.1:5577
pycodex --put /data/.codex/@127.0.0.1:5577
uv run pycodex --call SECRET-CALLID@127.0.0.1:5577
uv run pycodex --call SECRET-CALLID@127.0.0.1:5577 "检查当前工作区并解释为什么启动失败。"--put会打印一个可复用的SECRET-CALLID@host:port,以及最终可直接执行的pycodex --call ...命令- 到新环境后,直接执行那条
--call命令即可开始使用 - 这个模式适合快速恢复
config.toml、.env、AGENTS.md和skills/ --put /path/.codex/@host:port可以发布另一套 Codex home
import asyncio
from pycodex import (
AgentLoop,
BaseTool,
ContextManager,
ResponsesModelClient,
ToolRegistry,
)
class EchoTool(BaseTool):
name = "echo"
description = "Echo the provided text."
input_schema = {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"],
}
async def run(self, context, args):
del context
return args["text"]
async def main() -> None:
model = ResponsesModelClient.from_codex_config()
context_manager = ContextManager.from_codex_config()
tools = ToolRegistry()
tools.register(EchoTool())
agent = AgentLoop(model, tools, context_manager)
result = await agent.run_turn("Call the echo tool with text=hello, then tell me what it returned.")
print(result.output_text)
asyncio.run(main())更细的说明见 docs/ALIGNMENT.md。这里保留一个高层 checklist,方便直接看当前进度。
上游官方工具:
-
shell— 执行 argv 形式的 shell 命令。 -
shell_command— 执行字符串形式的 shell script。 -
exec_command— 启动带 session 的长命令执行。 -
write_stdin— 向已有执行 session 写入 stdin 或轮询输出。 -
web_search— 暴露 provider-native 的网页搜索能力。 -
update_plan— 更新任务计划并维护步骤状态。 -
request_user_input— 向用户发起结构化问题并等待回答。 -
request_permissions— 请求额外权限再继续执行。 -
spawn_agent— 创建并启动子 agent。 -
send_input— 给已有子 agent 继续发送输入。 -
resume_agent— 恢复已关闭的子 agent。 -
wait_agent— 等待子 agent 进入终态。 -
close_agent— 关闭不再需要的子 agent。 -
apply_patch— 用 freeform patch 精确修改文件。 -
grep_files— 按模式搜索文件内容。 -
read_file— 读取文件片段并保留行号语义。 -
list_dir— 列出目录树片段。 -
view_image— 把本地图片转成模型可见输入。
尚未单独建模的上游官方低频 / 特殊模式工具:
-
wait_infinite— 长时间阻塞等待外部事件或后续输入。 -
spawn_agents_on_csv— 按 CSV 批量创建子 agent 任务。 -
report_agent_job_result— 上报批处理 agent job 的结果。 -
js_repl— JavaScript REPL / code-mode 主入口。 -
js_repl_reset— 重置js_repl的运行状态。 -
artifacts— 生成或管理结构化工件输出。 -
list_mcp_resources— 列出 MCP 资源。 -
list_mcp_resource_templates— 列出 MCP 资源模板。 -
read_mcp_resource— 读取 MCP 资源内容。 -
multi_tool_use.parallel— 并行包装多个 developer tools 调用。
本仓库额外兼容层 / 过渡工具:
-
clock— pycodex 的周期性 Agent 唤醒扩展。 -
exec— 当前对 code-mode 的本地近似实现。 -
wait— 当前对 code-mode 等待行为的本地近似实现。
-
AgentLoop/AgentRuntime主循环骨架 — turn 闭环和提交队列已成立。 - 非交互
exec路径的instructions对齐 — base instructions 已对齐上游。 - 非交互
exec路径的input对齐 — prompt input 已对齐上游。 - developer/contextual-user message 的 shape 对齐 — message/content 结构已对齐。
-
AGENTS.md+<environment_context>注入逻辑对齐 — 上下文拼接顺序已对齐。 - 非交互
exec路径的上游工具子集对齐 — 对齐子集已收敛;pycodex 额外暴露clock。 -
include = ["reasoning.encrypted_content"]— reasoning include 字段已对齐。 -
prompt_cache_key— 请求级 prompt cache key 已补齐。 -
x-client-request-id— 请求 id header 已补齐。 -
x-codex-turn-metadata— turn id / sandbox header 已补齐。 -
originator— mode-aware originator header 已补齐。 -
user-agent精确字符串对齐 — 非交互exec路径已对齐上游字符串。 - 上游 exec-mode tool schema 的逐字段对齐 — 对齐工具使用类内 spec;
clock作为扩展单独记录。 - 交互模式与非
exec路径的完整行为对齐 — non-exec 首轮 context 已切到codex-tui路径,但 REPL 连续多轮行为还未完全验证。 - sandbox / approvals / compact / memory 等外围行为对齐 — 外围系统仍在后续范围。