python-codex 0.2.7__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_codex-0.2.7 → python_codex-0.3.0}/.github/workflows/publish.yml +1 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/.github/workflows/test.yml +1 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/AGENTS.md +14 -6
- python_codex-0.3.0/PKG-INFO +704 -0
- python_codex-0.3.0/README.md +681 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/README_ZH.md +65 -15
- {python_codex-0.2.7 → python_codex-0.3.0}/docs/ALIGNMENT.md +102 -49
- python_codex-0.3.0/docs/CONTEXT.md +187 -0
- python_codex-0.3.0/docs/RELEASE_0.3.0.md +74 -0
- python_codex-0.3.0/docs/RUNTIME.md +622 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/docs/responses_server/README.md +4 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/packages/pycodex-ws/pyproject.toml +2 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/__init__.py +14 -14
- python_codex-0.3.0/pycodex/agent.py +599 -0
- python_codex-0.3.0/pycodex/bootstrap.py +417 -0
- python_codex-0.3.0/pycodex/cli.py +396 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/compat.py +19 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/context.py +222 -212
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/doctor.py +52 -48
- python_codex-0.3.0/pycodex/events.py +857 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/feishu_card.py +217 -163
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/feishu_link.py +43 -83
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/model.py +324 -253
- python_codex-0.3.0/pycodex/model_metadata.py +43 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/portable.py +76 -45
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/portable_server.py +32 -24
- python_codex-0.3.0/pycodex/prompts/models.json +714 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/protocol.py +177 -137
- python_codex-0.3.0/pycodex/runtime.py +628 -0
- python_codex-0.3.0/pycodex/runtime_services.py +481 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/apply_patch_tool.py +69 -48
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/base_tool.py +89 -42
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/clock_tool.py +58 -25
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/close_agent_tool.py +2 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/code_mode_manager.py +77 -64
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/exec_command_tool.py +26 -11
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/exec_tool.py +4 -4
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/grep_files_tool.py +12 -10
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/ipython_tool.py +10 -13
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/list_dir_tool.py +13 -9
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/read_file_tool.py +29 -17
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/request_permissions_tool.py +15 -5
- python_codex-0.3.0/pycodex/tools/request_user_input_tool.py +102 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/resume_agent_tool.py +2 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/send_input_tool.py +11 -8
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/shell_command_tool.py +7 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/shell_tool.py +7 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/spawn_agent_tool.py +7 -4
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/unified_exec_manager.py +102 -69
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/update_plan_tool.py +8 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/view_image_tool.py +7 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/wait_agent_tool.py +27 -4
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/wait_tool.py +5 -4
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/web_search_tool.py +4 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/write_stdin_tool.py +12 -11
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/__init__.py +2 -17
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/compactor.py +41 -72
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/debug.py +2 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/dotenv.py +6 -7
- python_codex-0.3.0/pycodex/utils/event_helpers.py +190 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/get_env.py +27 -70
- {python_codex-0.2.7/pycodex → python_codex-0.3.0/pycodex/utils}/image_utils.py +8 -11
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/random_ids.py +1 -2
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/session_persist.py +217 -163
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/truncation.py +21 -45
- {python_codex-0.2.7 → python_codex-0.3.0}/pyproject.toml +4 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/__init__.py +1 -5
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/__main__.py +0 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/app.py +36 -31
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/config.py +23 -23
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/messages_api.py +51 -53
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/payload_processors.py +25 -20
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/server.py +11 -11
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/session_store.py +14 -11
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/stream_router.py +101 -98
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/tools/custom_adapter.py +17 -16
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/tools/web_search.py +39 -36
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/trajectory_dump.py +36 -14
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/TESTS.md +138 -27
- python_codex-0.3.0/tests/compare_context_requests.py +485 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/compare_steer_request_bodies.py +138 -82
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/compare_tool_schemas.py +68 -54
- python_codex-0.3.0/tests/conftest.py +6 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/fake_responses_server.py +62 -50
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/fakes.py +17 -26
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/responses_server/fake_chat_completions_server.py +70 -63
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/responses_server/test_server.py +131 -56
- python_codex-0.3.0/tests/responses_server/test_trajectory_dump.py +127 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_agent.py +588 -211
- python_codex-0.3.0/tests/test_agent_state.py +1718 -0
- python_codex-0.3.0/tests/test_async_bridge.py +142 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_builtin_tools.py +215 -252
- python_codex-0.3.0/tests/test_cli.py +744 -0
- python_codex-0.3.0/tests/test_compactor.py +111 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_context.py +198 -86
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_doctor.py +12 -11
- python_codex-0.3.0/tests/test_events.py +792 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_fake_responses_server.py +93 -11
- python_codex-0.3.0/tests/test_feishu_card.py +732 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_feishu_link.py +35 -3
- python_codex-0.3.0/tests/test_feishu_oauth.py +61 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_ipython_tool.py +18 -39
- python_codex-0.3.0/tests/test_model.py +1889 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_packaging.py +17 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_portable.py +33 -20
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/test_py36_syntax.py +3 -1
- python_codex-0.3.0/tests/test_runtime_state.py +860 -0
- python_codex-0.3.0/tests/test_session_backend.py +726 -0
- python_codex-0.3.0/tests/test_workspace_server.py +1209 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tools/feishu_oauth.py +40 -57
- python_codex-0.3.0/tools/sync_model_prompts.py +39 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/__main__.py +0 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/app.py +461 -375
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/workspace.html +852 -228
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/workspaces.html +94 -95
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/workspaces.py +137 -79
- python_codex-0.2.7/PKG-INFO +0 -455
- python_codex-0.2.7/README.md +0 -433
- python_codex-0.2.7/docs/CONTEXT.md +0 -470
- python_codex-0.2.7/pycodex/agent.py +0 -633
- python_codex-0.2.7/pycodex/cli.py +0 -670
- python_codex-0.2.7/pycodex/collaboration.py +0 -20
- python_codex-0.2.7/pycodex/interactive_session.py +0 -415
- python_codex-0.2.7/pycodex/model_metadata.py +0 -31
- python_codex-0.2.7/pycodex/prompts/collaboration_default.md +0 -11
- python_codex-0.2.7/pycodex/prompts/collaboration_plan.md +0 -128
- python_codex-0.2.7/pycodex/prompts/models.json +0 -1452
- python_codex-0.2.7/pycodex/runtime.py +0 -225
- python_codex-0.2.7/pycodex/runtime_services.py +0 -434
- python_codex-0.2.7/pycodex/tools/request_user_input_tool.py +0 -193
- python_codex-0.2.7/pycodex/utils/toolcall_visualize.py +0 -713
- python_codex-0.2.7/pycodex/utils/visualize.py +0 -560
- python_codex-0.2.7/tests/compare_request_user_input_roundtrip.py +0 -693
- python_codex-0.2.7/tests/test_async_bridge.py +0 -38
- python_codex-0.2.7/tests/test_cli.py +0 -4535
- python_codex-0.2.7/tests/test_compactor.py +0 -111
- python_codex-0.2.7/tests/test_feishu_card.py +0 -382
- python_codex-0.2.7/tests/test_model.py +0 -1566
- python_codex-0.2.7/tests/test_visualize.py +0 -37
- python_codex-0.2.7/tests/test_workspace_server.py +0 -2155
- {python_codex-0.2.7 → python_codex-0.3.0}/.gitignore +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/LICENSE +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/packages/pycodex-ws/README.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/packages/pycodex-ws/pycodex_ws_meta/__init__.py +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/default_base_instructions.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/__init__.py +1 -1
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/agent_tool_schemas.py +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/tools/exec_runtime.js +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/pycodex/utils/async_bridge.py +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/responses_server/tools/__init__.py +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/tests/__init__.py +0 -0
- {python_codex-0.2.7 → python_codex-0.3.0}/workspace_server/__init__.py +0 -0
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
- Rust 到 Python 的主映射:`submission_loop` -> `pycodex/runtime.py`,`run_turn` / `run_sampling_request` -> `pycodex/agent.py`,`ToolRouter` -> `pycodex/tools/base_tool.py` + `pycodex/tools/`.
|
|
11
11
|
- 会话协议先收敛到 4 类 item:`UserMessage`、`AssistantMessage`、`ToolCall`、`ToolResult`;只有这层稳定后再扩 richer event model。
|
|
12
12
|
- 优先保持主循环可测试、可替换:模型侧通过 `ModelClient` 协议接入;测试专用的 `ScriptedModelClient` 放在 `tests/fakes.py`,不要放进运行时包。
|
|
13
|
+
- `ModelClient` 的基础契约包括只读 `model: str` 和 async `complete`;`Agent.model_name` 直接读取 client.model,不用 getattr 为缺字段兜底,测试 client 也要提供模型标识。
|
|
14
|
+
- `Agent(model_client, tool_registry, context_config)` 三项必传;上下文构造选项统一放在 `ContextConfig`,由 Agent 按 client.model 创建独占的 `ContextManager`,不保留 manager 注入/缺省构造双路径。依赖引用与事件回调用普通属性,不恢复机械 getter/setter;runtime services 直接从 `agent.tool_registry.runtime_environment` 访问,外层 `AgentRuntime` 继续可选。
|
|
15
|
+
- Rollout recorder 由 Agent 内部创建和维护,不接受外部对象注入。`session_file_path=None`(默认值)表示仅在内存中保存历史,不创建 recorder 或 rollout;传入路径才启用记录。CLI/Web/飞书的 `build_agent` 显式分配默认路径及对应 uuidv7 session id;托管子 Agent 只传其 id、保持路径为 None。不要新增独立记录开关,也不要依赖 client 的 `_openai_subagent` 标记决定是否记录。session id 与记录开关独立,未传时仍分配 uuidv7。记录会话的构造仅准备路径和 metadata,首次非空 history append 或成功 compact 才创建文件及父目录,先写 metadata 和 Agent 当时的 history,再写新记录;recorder 不另存 initial_history 副本,Agent 不提供 replace_history 接口。fork 保留原来的记录状态;子 Agent 的 turn、compact、fork 和无参 resume 仅更新内存,不能靠列表过滤代替禁止落盘。构造、fork 和有参 resume 复用一个私有 recorder 装配方法,显式选择 create/resume,装配完成后再同步 Agent/provider identity;history、usage 和接纳状态仍由各操作维护。显式构造路径只用于新建,已有文件必须报错;首次写仍以 exclusive create 防止竞争覆盖,写失败不能静默恢复。CLI/Web 经 `runtime.resume(path)` 调用 `agent.resume(path)` 加载历史、接上指定文件的 recorder、同步 session id、清空 usage 并恢复接纳;默认不记录的 Agent 也可通过有参 resume 开始记录到现有文件。无参 `agent.resume()` 仅重开原内存会话并重绑工具回调,不读写文件、不改变 history/identity/recorder/usage,供子 Agent 服务使用,返回 None。Agent 只检查自身 active,Runtime 负责拒绝 active/queued/closing 下的恢复与会话变更;显式路径读失败保持原状态,不按文件存在性兜底;不保留 reopen 方法。测试通过隔离 CODEX_HOME 避免写真实会话。
|
|
16
|
+
- Agent 按用户明确约定串行执行:`run_turn` 是普通 async def,`ask` 是同步桥接;不创建或持有 turn Task,不提供 `cancel` / `cancel_current`,不恢复 Task 监听器。`maybe_invoke` 仅在 idle 时直接 await 同一条 run_turn 路径,异常正常传播。关闭仅停止接纳新输入,并等待当前 turn、已接收队列及子 Agent 自然结束;不要用超时强制取消来“修复”关闭等待。这一取消策略刻意不同于 upstream;计时器、I/O 清理和显式并行工具的 asyncio 实现不属于 turn 生命周期管理。
|
|
17
|
+
- 后端只保留 `AgentRuntime -> Agent` 两层,不增加 Session 包装或保留 SubmissionQueue 别名。Agent 不持有 Runtime/Queue 引用,不通过 input-source 回调取输入或结算回执。steer 由 Runtime 调用 `agent.stop_asap()`,Agent 完成当前请求与已发出的工具并记录结果,在安全边界发 `TurnInterruptedEvent`、抛 `TurnInterrupted`;Runtime 自己捕获、结算旧提交并启动下一批 `run_turn`。这不是 Task 取消;Runtime 内部沿用 steer 的逻辑 turn id,但新的执行重新计数。裸 Agent 不消费外部队列,Runtime 没有 worker 时 pending 输入保持等待。
|
|
13
18
|
- `ResponsesModelClient` 直接复用 `~/.codex/config.toml` 的 provider 配置;当前已验证这里的 responses provider 需要 `stream = true`,否则会返回 `400` 和 `Stream must be set to true`。
|
|
14
19
|
- 现在 `ResponsesModelClient` 默认会对流式断连做 provider 级自动重试(`stream_max_retries` 默认 5);写 CLI/REPL 测试时如果断言“先向用户报错,再靠下一句 `go on` 继续”,必须在测试 provider 配置里显式设 `stream_max_retries = 0`,否则测试可能一直等不到预期错误而卡住。
|
|
15
20
|
- `responses_server` compat 层应透传请求里的 `model`;不要再做 “取 downstream /models 第一个 id 并强制覆盖请求模型” 这种兜底兼容。
|
|
@@ -20,7 +25,10 @@
|
|
|
20
25
|
- 真实 vLLM `0.19.0` 的 `/v1/messages` 会对缺失 `max_tokens` 直接返回 `400`;messages 适配层必须总是补这个字段。当前约定是优先透传请求里的 `max_output_tokens`/`max_tokens`,否则回退到默认 `32000`。
|
|
21
26
|
- 对 vLLM chat-completions 打开 `return_token_ids=true` 时,streaming `prompt_token_ids` 只出现在首个 chunk,后续每个 chunk 的 `choices[*].token_ids` 都是 decode delta;要在 `responses_server` 侧导出 trajectory 时,按“首个 `prompt_token_ids` + 按序拼接所有 chunk 的 `token_ids`”重建即可。
|
|
22
27
|
- `pycodex` 默认是最小交互 CLI;无 prompt 时进入 REPL,并通过 `AgentRuntime` 跑外层提交循环。当前会显示最小事件流、assistant 流式输出、简单 title/history(`/title`, `/history`),并默认注册上游对齐工具子集和明确标记的本地扩展。
|
|
23
|
-
- Web
|
|
28
|
+
- CLI/Web/飞书必须通过统一的 `AgentRuntime.submit_input` 接入 Agent:会话命令、steer/queue、状态广播、交互问答/权限、worker 和关闭语义属于后端;前端只做输入/展示/连接适配。`pycodex.bootstrap.build_runtime` 负责公共装配并注入 `/link`、`/unlink` 和连接清理,不让 runtime 依赖飞书 SDK。Web 独立包 `workspace_server/` 使用 `pycodex-ws` 启动,不导入/运行 CLI shell,也不保留第二条 prompt queue。IPython 是明确例外,继续返回裸 Agent。`attach/detach` 是独立订阅,detach 不关闭后端;模型/恢复/标题变更必须广播给所有前端。
|
|
29
|
+
- 保持文件结构简洁:会话命令放在 `runtime.py`,CLI 启动、终端 I/O 和输入循环统一放在 `cli.py`;事件、纯文本 `visualize()`、有状态 `render(display)` 及展示状态/提示规则放在 `events.py`,通用无状态文本/颜色/摘要 helpers 放在 `utils/event_helpers.py`,helpers 不反向依赖事件或前端,不维护展示 handler mapping。每个前端实例独占 `EventDisplay`,事件本身保持冻结且不持有展示状态;CLI 只执行 log/status/prompt 回调,飞书卡片复用同一套无色 render,仅保留会话快照和卡片布局适配。飞书灰框按排队/开始/完成边界保留最近完成的回复,新一轮标记 `(*last turn)`、完成后替换;临时活动/问题单独展示,不把事件日志累积进回复正文,不恢复工具/流式/重试等逐事件展示分支。Web/飞书不接收 ANSI 文本。测试按行为归属维护,展示规则在事件层验证,前端只留必要的输入/展示/传输集成回归。
|
|
30
|
+
- Runtime 统一通过 `start()` / `close()` 启停,不恢复公开 `shutdown()` / `run_forever()` 双入口或独立关闭 Future。`Agent.accepts_input` 是本地接纳开关,`runtime.accepts_input` 只读取它;Runtime 关闭时把该开关置为 false,后台唤醒因此停止,已接收请求继续排空。关闭不入队特殊请求,不引入 `begin_shutdown` / `draining`。worker 排空后在命令锁内清理子 Agent 和连接,最后由 `Agent.shutdown()` 一次性清理工具。取消关闭调用方不能取消 worker/turn,Web 线程清理异常也必须 stop/join,不重复关闭底层会话。
|
|
31
|
+
- 交互 CLI 的 Ctrl+C 在 prompt_toolkit 输入边界通过 `c-c` / `<sigint>` 按键绑定以 `EOFError` 正常退出,兼容不支持 `interrupt_exception` 构造参数的 3.0.36,和 `/exit` 共用 `runtime.close()`;不要让输入子 Task 抛出的 `KeyboardInterrupt` 逃到 asyncio runner 后触发全体 Task 清理。单次 Ctrl+C 发起正常退出,接纳关闭事件展示 `[closing]` 等待提示,已有模型/工具/队列继续自然结束,不借此恢复 turn cancellation。关闭等待期间再次 Ctrl+C 是显式强退:CLI 的进程级 SIGINT handler 以状态 130 立即退出,不再进入 asyncio 清理等待;这不改变 Runtime 的正常排空语义,也不保证外部工具进程停止。旧版 prompt_toolkit 会在输入结束时重置 SIGINT,因此关闭边界要重新安装 handler;正常结束或清理报错后恢复原 SIGINT handler。
|
|
24
32
|
- Relative images in board HTML resolve to HTTP siblings such as `/w/<workspace-id>/<image>` (or `/<image>` in single-workspace mode), not to `/board/...`. Keep the image fallback routes after concrete workspace/API routes, resolve files from the board's directory, and reject non-`image/*` files or paths that escape that directory.
|
|
25
33
|
- 交互 CLI 的事件流展示优先表达用户可感知的阶段(例如工具开始/完成、模型回看工具结果),不要直接把内部 `iteration` 计数暴露成主要状态文案;`iterations` 应继续保留在 `TurnResult` 等程序化结果里。
|
|
26
34
|
- 在交互 CLI 里,`stream_error` 表示当前 Responses stream attempt 失败且模型客户端可能马上自动重试;不要在这个事件上 `finish_stream()` 输出当前 assistant delta buffer,否则第一次失败 attempt 的文本和重试成功后的最终回复会重复显示。真正 fatal 的失败仍由 `turn_failed` 走通用 flush,保留 partial 输出。
|
|
@@ -37,9 +45,9 @@
|
|
|
37
45
|
- `exec_command` / `write_stdin` 的 unified-exec 对齐要注意两层默认截断语义:省略 `max_output_tokens` 时也要按 upstream 默认 `10_000` token 预算裁剪 tool response;同时长时间未轮询的未读输出缓冲不能无限累积,需保留 upstream 同款 `1 MiB` head/tail。
|
|
38
46
|
- 当前协议层已经支持两类原版工具载荷:普通 function tools,以及 `apply_patch` 这类 freeform/custom tools;工具结果也支持结构化 `input_image` content items,用于 `view_image` 这类会把图片喂回模型的工具。
|
|
39
47
|
- 当前本地 runtime 已支持一个最小的 in-process sub-agent 管理层:`spawn_agent` / `send_input` / `resume_agent` / `wait_agent` / `close_agent` 通过共享的 `SubAgentManager` 驱动新的 `AgentRuntime` 实例,不依赖 CLI harness 自带的多 agent 基础设施。
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
48
|
+
- `request_user_input` / `request_permissions` handler 由 `AgentRuntime` 绑定,通过 `input_requested/input_resolved` 事件收集各前端输入;不要让工具直接抢终端 stdin,也不要由前端覆盖 manager handler。有请求时普通输入回答当前问题,slash 输入仍执行命令;支持多题、Other、取消、超时和结构化 `answer_input`。没有前端或正在关闭时返回取消,最后一个前端 detach 会解除等待。
|
|
49
|
+
- Collaboration mode 已按用户要求彻底移除:不保留模式枚举、ContextConfig/ToolContext 模式字段、协作提示模板、`build_agent` 的 `session_mode` 参数或模式门控;不要为了 upstream 对齐重新引入。移除模式不代表启用 `request_user_input`,它的默认不可用返回单独保留。普通 CLI/Web 交互、`update_plan` 和 subagent 与该模式无关,继续保留。
|
|
50
|
+
- `request_user_input` 保留默认工具注册及参数声明,但调用固定返回 `request_user_input is unavailable in Default mode`,不收集答案、不触发 `input_requested`,有交互 handler 也不启用。工具本身无状态,不注入 request manager,不为此恢复模式系统或增加启用开关。通用 runtime 问答/权限服务继续保留。`ToolResult.success` 仅是本地执行状态,不能序列化到 Responses input;恢复旧 rollout 读到 `success` 时也不得重新发送该字段。
|
|
43
51
|
- 当前 `exec` / `wait` 已有一个最小 code-mode 实现:底层通过 Node 子进程运行 JavaScript,自带 `text` / `image` / `store` / `load` / `exit` / `notify` / `yield_control` helper,并允许通过 `tools.<name>(...)` 调回本地已注册工具;`web_search` 当前作为 Responses API provider-native tool declaration 暴露给模型,不经过本地 ToolRegistry 执行。
|
|
44
52
|
- 除明确记录的 pycodex 扩展(当前为 `clock`)外,我们支持的 tools 必须和原版 Codex 内置 tools 一一对应:名称、定位、参数形状、交互模型、输出语义都应尽量对齐;不要混合多个原版工具的语义做一个“折中工具”。
|
|
45
53
|
- 代码风格上不要使用 `*` 定义 keyword-only 参数;接口默认允许位置参数。
|
|
@@ -60,7 +68,7 @@
|
|
|
60
68
|
- `--put` 现在会先做 `/healthz` preflight,再开始扫描/压缩目录;如果用户报“卡死”,先看目标 `host:port` 是否真有 storage server 在监听。默认打包策略也已经切到白名单:只带 `config.toml`、`.env`、`AGENTS.md`、`AGENTS.override.md`、`skills/**`,以及 config 里相对引用的 `model_instructions_file`,所以像 `sessions/` 这类运行态目录不会再靠黑名单排除。
|
|
61
69
|
- `--call` / portable storage paths must not rely on the process default text encoding. Always pass `encoding="utf-8"` when reading config, prompts, AGENTS files, skills, dotenv, and session history; for user-authored instructions/history, prefer `errors="replace"` so a Windows GBK locale cannot crash on UTF-8 punctuation such as U+2264 or em dash.
|
|
62
70
|
- 对接真实 `~/.codex/sessions/.../rollout-*.jsonl` 时,不要假设它一定是严格的一行一个 JSON object:本机样本可能包含 pretty-printed 多行对象,且文件尾部偶尔带未完成记录。恢复历史时用 concatenated-JSON 方式读取,并容忍尾部残缺。
|
|
63
|
-
- `pycodex`
|
|
71
|
+
- `pycodex` 前端装配的普通 session 保存按上游思路走:新 session 一开始就分配稳定的 uuidv7 thread/session id,并把历史增量追加到 `CODEX_HOME/sessions/.../rollout-*.jsonl`;裸 Agent 默认和子 Agent 都仅保存在内存中。`/resume` 列表应只展示至少有真实 user message 的 rollout,避免空白新 session 污染恢复列表。
|
|
64
72
|
- auto-compact 对齐上游配置名 `model_auto_compact_token_limit`;为空时关闭,触发依据是最近一次模型上报的 `usage.total_tokens`,pre-turn 压缩上一轮历史,mid-turn 压缩工具 follow-up 前的当前历史,并继续复用现有 compacted rollout 记录。
|
|
65
73
|
- Local compact templates intentionally diverge from upstream: the prompt explicitly preserves the latest real user request/language, and the summary prefix tells the next model to continue instead of merely acknowledging the handoff. Do not mechanically replace these additions with `codex-rs/core/templates/compact/{prompt.md,summary_prefix.md}`. Real `compacted` rollout entries remain append-only checkpoints whose `replacement_history` can be summary-only; the old transcript stays on disk for audit but is not part of the next active prompt.
|
|
66
74
|
- Responses streaming 里的 `response.incomplete` 不是连接断开:不要让 `ResponsesModelClient` 把它当 retryable incomplete stream 反复重连。普通 turn 应明确报 `response.incomplete`;compact 请求如果已经收到 assistant partial summary,可以用这个 partial summary 完成 replacement history,避免 midturn auto-compact 卡在 5 次 retry。
|
|
@@ -69,6 +77,6 @@
|
|
|
69
77
|
- 普通 turn 遇到 `ResponsesIncompleteError(reason="max_output_tokens")` 时,上游语义是保留异常前已经收到的 `response.output_item.done`;pycodex 因为模型客户端按整轮返回,需要在异常路径把这些 done assistant/reasoning items 写入 history 和 rollout,才能让用户下一句 `continue` 接上。不要把纯 `response.output_text.delta` 合成 history,也不要持久化没有 tool result 的 tool call。
|
|
70
78
|
- Feishu card tests read `~/.codex/.feishu_refresh_token` through production code; when running `tests/test_feishu_card.py` locally, isolate HOME (for example `HOME=/tmp/pycodex-empty-home env -u VIRTUAL_ENV uv run pytest tests/test_feishu_card.py tests/test_feishu_link.py`) unless the test itself controls `HOME`.
|
|
71
79
|
- `lark_oapi.ws.client` creates a module-level asyncio `loop` at import time and `Client.start()` always uses that global. For `/link` long-connection listeners, bind that SDK global to a listener-thread-owned loop before constructing the client, and stop it through private `_disconnect()` plus `loop.stop()` on `/unlink`; otherwise unlink/link can reuse a still-running SDK loop and fail with `RuntimeError: This event loop is already running`.
|
|
72
|
-
- `exec_command` background completion auto-resume is intentionally Agent-idle-only: when a session exits, it may call `Agent.maybe_invoke(...)` and start a synthetic `<exec_command_completed>` turn only if that Agent is not already running a turn. Do not enqueue/cache these events in `
|
|
80
|
+
- `exec_command` background completion auto-resume is intentionally Agent-idle-only: when a session exits, it may call `Agent.maybe_invoke(...)` and start a synthetic `<exec_command_completed>` turn only if that Agent is not already running a turn. Do not enqueue/cache these events in `AgentRuntime`; direct Agent/IPython use should share the same Agent-level hook.
|
|
73
81
|
- `clock` is a per-Agent/session pycodex extension with one global period value. Reuse `Agent.maybe_invoke(...)` for `<clock_tick>` wake-ups and include the timezone-aware ISO 8601 `current_time` captured when the timer expires: cancel the pending countdown when any turn starts, restart it only after a successful reply, and cancel it on `clock(null)` or runtime shutdown. Terminal events expose only aggregate `background_work_count`, which includes running exec sessions and an enabled clock after a successful reply; CLI/workspace idle status should use that single field. Do not add a second submission queue or shell-based sleep loop.
|
|
74
82
|
- The tool description JSON fallbacks (`pycodex/prompts/exec_tools.json` and `pycodex/prompts/subagent_tools.json`) were deleted after moving schemas into class-level `BaseTool` specs. `ToolSpec.serialize()` intentionally skips function-tool `output_schema`, matching upstream `ResponsesApiTool.output_schema #[serde(skip)]`; keep output schemas as local metadata only unless upstream wire format changes.
|