python-codex 0.3.1__tar.gz → 0.3.3__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.3.3/.gitattributes +2 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/.github/workflows/publish.yml +11 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/AGENTS.md +5 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/PKG-INFO +77 -5
- {python_codex-0.3.1 → python_codex-0.3.3}/README.md +76 -4
- {python_codex-0.3.1 → python_codex-0.3.3}/README_ZH.md +55 -4
- {python_codex-0.3.1 → python_codex-0.3.3}/docs/ALIGNMENT.md +23 -0
- python_codex-0.3.3/docs/RELEASE_0.3.2.md +36 -0
- python_codex-0.3.3/docs/RELEASE_0.3.3.md +43 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/docs/RUNTIME.md +291 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/docs/responses_server/README.md +21 -3
- {python_codex-0.3.1 → python_codex-0.3.3}/packages/pycodex-ws/README.md +9 -1
- {python_codex-0.3.1 → python_codex-0.3.3}/packages/pycodex-ws/pyproject.toml +2 -2
- python_codex-0.3.3/pycodex/__main__.py +4 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/model.py +11 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/pyproject.toml +8 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/stream_router.py +17 -13
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/TESTS.md +52 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/responses_server/fake_chat_completions_server.py +14 -1
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/responses_server/test_server.py +39 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_doctor.py +16 -4
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_model.py +209 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_packaging.py +28 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_workspace_server.py +2 -2
- python_codex-0.3.3/tests/test_workspace_views.py +948 -0
- python_codex-0.3.3/tests/workspace_content_views.mjs +919 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/app.py +203 -10
- python_codex-0.3.3/workspace_server/content_views.LICENSE.txt +470 -0
- python_codex-0.3.3/workspace_server/content_views.css +1 -0
- python_codex-0.3.3/workspace_server/content_views.mjs +25 -0
- python_codex-0.3.3/workspace_server/editor.css +1 -0
- python_codex-0.3.3/workspace_server/editor.mjs +1260 -0
- python_codex-0.3.3/workspace_server/frontend/.gitignore +1 -0
- python_codex-0.3.3/workspace_server/frontend/build.mjs +98 -0
- python_codex-0.3.3/workspace_server/frontend/content_views.css +83 -0
- python_codex-0.3.3/workspace_server/frontend/content_views.mjs +668 -0
- python_codex-0.3.3/workspace_server/frontend/editor.css +50 -0
- python_codex-0.3.3/workspace_server/frontend/editor.mjs +342 -0
- python_codex-0.3.3/workspace_server/frontend/package-lock.json +541 -0
- python_codex-0.3.3/workspace_server/frontend/package.json +17 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/workspace.html +118 -62
- python_codex-0.3.3/workspace_server/workspace_views.py +533 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/workspaces.html +2 -2
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/workspaces.py +4 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/.github/workflows/test.yml +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/.gitignore +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/LICENSE +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/docs/CONTEXT.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/docs/RELEASE_0.3.0.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/packages/pycodex-ws/pycodex_ws_meta/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/agent.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/bootstrap.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/cli.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/compat.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/context.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/doctor.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/events.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/feishu_card.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/feishu_link.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/model_metadata.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/portable.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/portable_server.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/default_base_instructions.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/models.json +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/protocol.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/runtime.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/runtime_services.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/agent_tool_schemas.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/apply_patch_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/base_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/clock_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/close_agent_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/code_mode_manager.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/exec_command_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/exec_runtime.js +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/exec_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/grep_files_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/ipython_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/list_dir_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/read_file_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/request_permissions_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/request_user_input_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/resume_agent_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/send_input_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/shell_command_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/shell_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/spawn_agent_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/unified_exec_manager.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/update_plan_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/view_image_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/wait_agent_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/wait_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/web_search_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/tools/write_stdin_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/async_bridge.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/compactor.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/debug.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/dotenv.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/event_helpers.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/get_env.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/image_utils.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/random_ids.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/session_persist.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/pycodex/utils/truncation.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/__main__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/app.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/config.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/messages_api.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/payload_processors.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/server.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/session_store.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/tools/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/tools/custom_adapter.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/tools/web_search.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/responses_server/trajectory_dump.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/compare_context_requests.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/compare_steer_request_bodies.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/compare_tool_schemas.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/conftest.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/fake_responses_server.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/fakes.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/responses_server/test_trajectory_dump.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_agent.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_agent_state.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_async_bridge.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_builtin_tools.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_cli.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_compactor.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_context.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_events.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_fake_responses_server.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_feishu_card.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_feishu_link.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_feishu_oauth.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_ipython_tool.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_owned_workspace_server.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_portable.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_py36_syntax.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_runtime_state.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tests/test_session_backend.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tools/feishu_oauth.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/tools/sync_model_prompts.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/__init__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/__main__.py +0 -0
- {python_codex-0.3.1 → python_codex-0.3.3}/workspace_server/owned_process.py +0 -0
|
@@ -117,6 +117,17 @@ jobs:
|
|
|
117
117
|
python -m build --outdir dist/pycodex-ws packages/pycodex-ws
|
|
118
118
|
python -m twine check dist/python-codex/* dist/pycodex-ws/*
|
|
119
119
|
|
|
120
|
+
- name: Smoke test installed wheels
|
|
121
|
+
run: |
|
|
122
|
+
python -m venv "$RUNNER_TEMP/pycodex-wheel"
|
|
123
|
+
"$RUNNER_TEMP/pycodex-wheel/bin/python" -m pip install \
|
|
124
|
+
dist/python-codex/*.whl dist/pycodex-ws/*.whl
|
|
125
|
+
cd "$RUNNER_TEMP"
|
|
126
|
+
"$RUNNER_TEMP/pycodex-wheel/bin/pycodex" --help
|
|
127
|
+
"$RUNNER_TEMP/pycodex-wheel/bin/pycodex-ws" --help
|
|
128
|
+
"$RUNNER_TEMP/pycodex-wheel/bin/python" -m pycodex --help
|
|
129
|
+
"$RUNNER_TEMP/pycodex-wheel/bin/python" -m workspace_server --help
|
|
130
|
+
|
|
120
131
|
- name: Upload distributions
|
|
121
132
|
uses: actions/upload-artifact@v4
|
|
122
133
|
with:
|
|
@@ -29,7 +29,7 @@
|
|
|
29
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
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
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。
|
|
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.
|
|
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. Canvas and HTML file previews use ordinary same-origin iframes with the same script permissions; the browser sends login cookies when loading resources. Do not copy cookies into HTML or add image-fetch/data-URL preprocessing.
|
|
33
33
|
- 交互 CLI 的事件流展示优先表达用户可感知的阶段(例如工具开始/完成、模型回看工具结果),不要直接把内部 `iteration` 计数暴露成主要状态文案;`iterations` 应继续保留在 `TurnResult` 等程序化结果里。
|
|
34
34
|
- 在交互 CLI 里,`stream_error` 表示当前 Responses stream attempt 失败且模型客户端可能马上自动重试;不要在这个事件上 `finish_stream()` 输出当前 assistant delta buffer,否则第一次失败 attempt 的文本和重试成功后的最终回复会重复显示。真正 fatal 的失败仍由 `turn_failed` 走通用 flush,保留 partial 输出。
|
|
35
35
|
- prompt/context 相关逻辑统一放在 `pycodex/context.py`:`AgentLoop` 只维护真实会话历史;每轮请求前由 `ContextManager` 注入 base instructions、developer message、`AGENTS.md` 指令和 `<environment_context>`,且这些注入项不写回 history。
|
|
@@ -49,7 +49,10 @@
|
|
|
49
49
|
- Collaboration mode 已按用户要求彻底移除:不保留模式枚举、ContextConfig/ToolContext 模式字段、协作提示模板、`build_agent` 的 `session_mode` 参数或模式门控;不要为了 upstream 对齐重新引入。移除模式不代表启用 `request_user_input`,它的默认不可用返回单独保留。普通 CLI/Web 交互、`update_plan` 和 subagent 与该模式无关,继续保留。
|
|
50
50
|
- `request_user_input` 保留默认工具注册及参数声明,但调用固定返回 `request_user_input is unavailable in Default mode`,不收集答案、不触发 `input_requested`,有交互 handler 也不启用。工具本身无状态,不注入 request manager,不为此恢复模式系统或增加启用开关。通用 runtime 问答/权限服务继续保留。`ToolResult.success` 仅是本地执行状态,不能序列化到 Responses input;恢复旧 rollout 读到 `success` 时也不得重新发送该字段。
|
|
51
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 执行。
|
|
52
|
-
- 除明确记录的 pycodex
|
|
52
|
+
- 除明确记录的 pycodex 扩展 `clock` 外,我们支持的 tools 必须和原版 Codex 内置 tools 一一对应:名称、定位、参数形状、交互模型、输出语义都应尽量对齐;不要混合多个原版工具的语义做一个“折中工具”。
|
|
53
|
+
- Workspace 文件/diff 由用户点击 Markdown 链接打开,不再注册 `workspace_display`。普通绝对/相对文件路径兼容 `:行号` / `#L行号`,相对路径基于 workspace cwd;Git 文件用 `git:REV:path`,比较用 `diff:REV:path`、`diff:BASE..HEAD:path`、`diff:REV:path..REV:path` 或 `diff:left..right`,diff 行号用 `#L` / `#R`。Git 路径沿用仓库根目录语义,显式 `./` / `../` 基于 workspace cwd;路径特殊字符编码,比较端点文件名中的字面 `..` 编码成 `%2E%2E`。点击经 `POST api/views/open`,独立于 Agent/Runtime,不产生模型消息或工具结果,空 `--toolset` 仍可使用。同一来源或有序比较复用标签的 id、顺序和阅读状态;身份按规范化路径或 Git 仓库/解析后版本/路径判定,标题保留完整路径和版本。本地文件跟随磁盘,Git 内容固定;来源、最新内容、打开列表及 reveal counter 原子保存在 Board 同名 `.pycodex-views.json`。旧记录无来源时保持固定快照。只有发起点击的页面消费返回的 selection/reveal 并切换焦点,轮询只更新列表与内容,不跟随其他页面打开;关闭不修改源文件或会话。
|
|
54
|
+
- Workspace 代码与 diff 查看器使用只读 Monaco;源码和固定依赖在 `workspace_server/frontend/`,修改后用该目录的 `npm ci` / `npm run build` 更新生成的 JS/CSS 和许可证,不手改构建产物。首屏 `content_views.mjs` / CSS 只含轻量控制层,首次打开源码/diff 才并行加载独立的同源 `editor.mjs` / CSS,等待两者完成后创建编辑器;Canvas/Markdown/HTML/图片预览不加载 Monaco。编辑器保留全部语言高亮及查看器需要的功能,JSON 直接注册 tokenizer 和语言配置,避免语言服务入口间接带回全量功能。diff worker 从内嵌 Blob URL 启动,字体内嵌编辑器 CSS,随 wheel 分发,Python 启动不依赖 Node。静态资源按 Accept-Encoding 协商 gzip,压缩结果按应用实例缓存并随文件变化失效,使用 Vary/ETag/304;不对会话流加压缩,不在 wheel 重复保存压缩副本。`MonacoEnvironment.getWorker` 是库要求的全局 host hook,其余查看器状态按实例维护。只保留活动视图的编辑器和 model,切换时先保存阅读状态再隐藏/销毁;diff 按内容容器宽度调整原实例布局。沿用视图列表的两秒轮询检查已记录路径,按内容 revision 失效缓存;内容更新复用编辑器/model 并保留阅读状态,不切换标签或手机面板。标签按 VS Code 的文件名/次要说明方式展示:优先显示 basename,同名不同路径才补最短可区分目录,Git 版本用 7 位 commit ID 作为次要说明,同一路径比较只显示一次文件名。宽度上限复用会话标签规则,次要说明先截断,完整标题继续用于悬停、存储及 API 回复。内容/会话标签栏将普通竖向鼠标滚轮转换成横向滚动,保留原生横向、Shift/Ctrl 手势。
|
|
55
|
+
- Workspace 整个左侧展示区称为看板,实时 HTML 首标签称为 Canvas;内部 `board` id、配置字段及路由名保持不变。装配提示沿用自然语言介绍 Canvas 文件的位置、修改实时可见及可随时创建/修改,再简要说明回复和 Canvas 中可用的扩展链接、行号后缀和返回 Canvas 的链接;不规定展示策略,也不加入冗长实现细节。`workspace://canvas` 返回现有实时页面;Markdown 和 HTML(含 `.htm`)文件链接默认预览,带行号打开源码,再次点击无行号链接在同一标签回到预览。普通刷新和手动切换保留本页所选模式及各自阅读位置,不重放旧定位;行号和模式不参与标签身份/标题,其他页面的打开不改变本页模式。Canvas 是常驻的同源 HTML iframe,普通 HTML 预览沿用同源权限及浏览器原生资源加载;预览的父页面消息只用于滚动位置恢复并校验 frame 和文档代数,无变化时保留当前实例,切换时释放。Canvas 普通 HTML 导航保持不变,仅接管显式 git/diff/Canvas URI。异步打开/创建/更新/diff 完成时只应用当前请求;Markdown/HTML diff 始终显示代码。窄屏定位 diff 左侧时保留双栏,聚焦/定位右侧恢复自动布局。
|
|
53
56
|
- 代码风格上不要使用 `*` 定义 keyword-only 参数;接口默认允许位置参数。
|
|
54
57
|
- runtime 包和会在 import 阶段执行的测试辅助代码需要保持 Python 3.6.2 语法兼容;不要引入 walrus `:=`、`match` 等仅 3.8+/3.10+ 可解析的新语法,哪怕分支在运行时不会走到。
|
|
55
58
|
- 本仓库使用 `uv`;本地默认没有预装测试依赖,开始工作前先跑 `uv sync --dev`,验证用 `uv run pytest`。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-codex
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: A minimal Python extraction of Codex's main agent loop
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.6.2
|
|
@@ -25,6 +25,10 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
|
|
26
26
|
English README. Chinese version: `README_ZH.md`
|
|
27
27
|
|
|
28
|
+
0.3.3 workspace viewers and reasoning stream fix: [release notes](docs/RELEASE_0.3.3.md).
|
|
29
|
+
|
|
30
|
+
0.3.2 startup fixes: [release notes](docs/RELEASE_0.3.2.md).
|
|
31
|
+
|
|
28
32
|
0.3.0 release preparation and Python API migration: `docs/RELEASE_0.3.0.md`.
|
|
29
33
|
|
|
30
34
|
PyPI distributions:
|
|
@@ -60,11 +64,24 @@ Relevant Rust reference points:
|
|
|
60
64
|
Install the full package or the workspace-oriented alias:
|
|
61
65
|
|
|
62
66
|
```bash
|
|
63
|
-
pip install python-codex
|
|
64
|
-
pip install pycodex-ws
|
|
67
|
+
python3 -m pip install python-codex
|
|
68
|
+
python3 -m pip install pycodex-ws
|
|
65
69
|
```
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
Use Python 3.6.2 or newer. Both console commands are installed into that
|
|
72
|
+
interpreter's scripts directory. On a machine with multiple Python installations,
|
|
73
|
+
you can select the same interpreter explicitly for startup:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
python3 -m pycodex
|
|
77
|
+
python3 -m workspace_server --help
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If `pycodex` is missing from `PATH` or resolves to an older installation, use these
|
|
81
|
+
module entry points. `python3 -m pip --version` shows which Python environment
|
|
82
|
+
received the installation.
|
|
83
|
+
|
|
84
|
+
For development from this repository, install dependencies first:
|
|
68
85
|
|
|
69
86
|
```bash
|
|
70
87
|
uv sync
|
|
@@ -200,6 +217,18 @@ from pycodex import ResponsesModelClient
|
|
|
200
217
|
client = ResponsesModelClient.from_codex_config()
|
|
201
218
|
```
|
|
202
219
|
|
|
220
|
+
`model_provider` is optional and defaults to `openai`. The built-in provider
|
|
221
|
+
does not require a `[model_providers.openai]` table: it uses
|
|
222
|
+
`https://api.openai.com/v1` and reads `OPENAI_API_KEY`. Set `openai_base_url` to
|
|
223
|
+
override this address. Explicit provider tables retain their configured
|
|
224
|
+
`base_url` and optional `env_key`; unknown provider names raise a configuration
|
|
225
|
+
error. The model still comes from `model` in the configuration or selected
|
|
226
|
+
profile.
|
|
227
|
+
|
|
228
|
+
Authentication currently uses API keys from environment variables or `.env`;
|
|
229
|
+
Codex desktop/CLI ChatGPT sign-in credentials in `auth.json` or the OS keychain
|
|
230
|
+
are not loaded.
|
|
231
|
+
|
|
203
232
|
The current implementation uses the streaming OpenAI-compatible `/responses`
|
|
204
233
|
endpoint. This path has already been validated against the local
|
|
205
234
|
`~/.codex/config.toml` setup.
|
|
@@ -237,6 +266,45 @@ Current behavior:
|
|
|
237
266
|
- with an argv prompt or piped stdin, run a single turn
|
|
238
267
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
239
268
|
workspace with a board pane and a pycodex session pane
|
|
269
|
+
- the left pane is the board, containing a live HTML Canvas tab and closable read-only file/diff tabs that
|
|
270
|
+
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
271
|
+
horizontally.
|
|
272
|
+
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
273
|
+
`[source](/data/project/app.py#L42)` to open a view. Git-style diff links use
|
|
274
|
+
`[changes](diff:HEAD:src/app.py)` for working changes,
|
|
275
|
+
`[versions](diff:HEAD~1..HEAD:src/app.py)` for two revisions, and
|
|
276
|
+
`[files](diff:old.py..new.py)` for two local files. Append `#L42` or `#R42`
|
|
277
|
+
to a diff link to select a 1-based line on the left or right.
|
|
278
|
+
Views open when the user clicks; model replies alone do not create tabs.
|
|
279
|
+
Reopening the same file or comparison selects its existing tab in that
|
|
280
|
+
browser, including when the line changes. Other pages keep their selection.
|
|
281
|
+
Tabs show filenames first, adding a short directory suffix
|
|
282
|
+
for duplicate names. Git versions use short commit IDs in a secondary label.
|
|
283
|
+
Long labels use the same width limit as session tabs, shortening the secondary
|
|
284
|
+
information before the filename;
|
|
285
|
+
hover titles retain the complete paths and revisions. Text,
|
|
286
|
+
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
287
|
+
provides syntax highlighting, find, folding and character-level diffs.
|
|
288
|
+
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
289
|
+
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
290
|
+
when supported and revalidate cached content with ETags.
|
|
291
|
+
Narrow content panes automatically use a unified diff; targeting the left
|
|
292
|
+
side keeps both sides visible. Markdown and HTML links default to previews;
|
|
293
|
+
line targets open their source. Clicking a link without a line returns that
|
|
294
|
+
same tab to preview. Manual tab switches preserve the chosen mode and reading state.
|
|
295
|
+
All views remain
|
|
296
|
+
read-only, with text selection and copying available. Local files update
|
|
297
|
+
automatically, including both sides of file diffs and the working side of
|
|
298
|
+
Git diffs; Git revisions stay fixed. Updates keep the active editor and
|
|
299
|
+
reading state without replaying an earlier line request.
|
|
300
|
+
Canvas is for explanations and custom visuals; source and diffs use links.
|
|
301
|
+
`[Canvas](workspace://canvas)` returns to the live page; an HTML file link opens
|
|
302
|
+
a preview tab, and `page.html:1` opens its source. File links work even with an empty `--toolset`.
|
|
303
|
+
Canvas and HTML previews share the same origin and script permissions;
|
|
304
|
+
the browser loads their resources with the workspace login cookie.
|
|
305
|
+
Open views survive reloads and server restarts. See
|
|
306
|
+
[workspace content views](docs/RUNTIME.md#workspace-content-views) for the
|
|
307
|
+
complete syntax and limits.
|
|
240
308
|
- interactive mode exits through `/exit`, `/quit`, Ctrl+D on an empty prompt,
|
|
241
309
|
or a single Ctrl+C; accepted work finishes before cleanup and normal exit.
|
|
242
310
|
A `[closing]` message explains the wait. Press Ctrl+C again while closing
|
|
@@ -339,7 +407,7 @@ Current behavior:
|
|
|
339
407
|
time when it expires.
|
|
340
408
|
- while a background command or clock is pending, the idle status is
|
|
341
409
|
`idle: sleeping`
|
|
342
|
-
- only the active workspace tab shows its close button; closing it restores
|
|
410
|
+
- only the active workspace session tab shows its close button; closing it restores
|
|
343
411
|
the selected tab's conversation, draft, and scroll position immediately
|
|
344
412
|
after its snapshot loads
|
|
345
413
|
- `--vllm-endpoint http://host:port` automatically launches a local
|
|
@@ -360,6 +428,10 @@ Current behavior:
|
|
|
360
428
|
reasoning, retries the same downstream request once, and only then emits
|
|
361
429
|
`response.failed` with `type = "model_output_invalid"` if the retry is still
|
|
362
430
|
reasoning-only
|
|
431
|
+
- compat reasoning fragments are forwarded immediately as
|
|
432
|
+
`response.reasoning_text.delta`, including thinking from `/v1/messages`.
|
|
433
|
+
Continuous reasoning keeps the client's read idle timeout from expiring
|
|
434
|
+
while it waits for assistant text; only finalized reasoning items enter history
|
|
363
435
|
- malformed JSON in ordinary downstream function-call arguments is detected by
|
|
364
436
|
`responses_server` and returned as `response.failed` with `type = "server_error"`;
|
|
365
437
|
the client's existing `stream_max_retries` policy retries the current request
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
English README. Chinese version: `README_ZH.md`
|
|
4
4
|
|
|
5
|
+
0.3.3 workspace viewers and reasoning stream fix: [release notes](docs/RELEASE_0.3.3.md).
|
|
6
|
+
|
|
7
|
+
0.3.2 startup fixes: [release notes](docs/RELEASE_0.3.2.md).
|
|
8
|
+
|
|
5
9
|
0.3.0 release preparation and Python API migration: `docs/RELEASE_0.3.0.md`.
|
|
6
10
|
|
|
7
11
|
PyPI distributions:
|
|
@@ -37,11 +41,24 @@ Relevant Rust reference points:
|
|
|
37
41
|
Install the full package or the workspace-oriented alias:
|
|
38
42
|
|
|
39
43
|
```bash
|
|
40
|
-
pip install python-codex
|
|
41
|
-
pip install pycodex-ws
|
|
44
|
+
python3 -m pip install python-codex
|
|
45
|
+
python3 -m pip install pycodex-ws
|
|
42
46
|
```
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
Use Python 3.6.2 or newer. Both console commands are installed into that
|
|
49
|
+
interpreter's scripts directory. On a machine with multiple Python installations,
|
|
50
|
+
you can select the same interpreter explicitly for startup:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
python3 -m pycodex
|
|
54
|
+
python3 -m workspace_server --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If `pycodex` is missing from `PATH` or resolves to an older installation, use these
|
|
58
|
+
module entry points. `python3 -m pip --version` shows which Python environment
|
|
59
|
+
received the installation.
|
|
60
|
+
|
|
61
|
+
For development from this repository, install dependencies first:
|
|
45
62
|
|
|
46
63
|
```bash
|
|
47
64
|
uv sync
|
|
@@ -177,6 +194,18 @@ from pycodex import ResponsesModelClient
|
|
|
177
194
|
client = ResponsesModelClient.from_codex_config()
|
|
178
195
|
```
|
|
179
196
|
|
|
197
|
+
`model_provider` is optional and defaults to `openai`. The built-in provider
|
|
198
|
+
does not require a `[model_providers.openai]` table: it uses
|
|
199
|
+
`https://api.openai.com/v1` and reads `OPENAI_API_KEY`. Set `openai_base_url` to
|
|
200
|
+
override this address. Explicit provider tables retain their configured
|
|
201
|
+
`base_url` and optional `env_key`; unknown provider names raise a configuration
|
|
202
|
+
error. The model still comes from `model` in the configuration or selected
|
|
203
|
+
profile.
|
|
204
|
+
|
|
205
|
+
Authentication currently uses API keys from environment variables or `.env`;
|
|
206
|
+
Codex desktop/CLI ChatGPT sign-in credentials in `auth.json` or the OS keychain
|
|
207
|
+
are not loaded.
|
|
208
|
+
|
|
180
209
|
The current implementation uses the streaming OpenAI-compatible `/responses`
|
|
181
210
|
endpoint. This path has already been validated against the local
|
|
182
211
|
`~/.codex/config.toml` setup.
|
|
@@ -214,6 +243,45 @@ Current behavior:
|
|
|
214
243
|
- with an argv prompt or piped stdin, run a single turn
|
|
215
244
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
216
245
|
workspace with a board pane and a pycodex session pane
|
|
246
|
+
- the left pane is the board, containing a live HTML Canvas tab and closable read-only file/diff tabs that
|
|
247
|
+
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
248
|
+
horizontally.
|
|
249
|
+
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
250
|
+
`[source](/data/project/app.py#L42)` to open a view. Git-style diff links use
|
|
251
|
+
`[changes](diff:HEAD:src/app.py)` for working changes,
|
|
252
|
+
`[versions](diff:HEAD~1..HEAD:src/app.py)` for two revisions, and
|
|
253
|
+
`[files](diff:old.py..new.py)` for two local files. Append `#L42` or `#R42`
|
|
254
|
+
to a diff link to select a 1-based line on the left or right.
|
|
255
|
+
Views open when the user clicks; model replies alone do not create tabs.
|
|
256
|
+
Reopening the same file or comparison selects its existing tab in that
|
|
257
|
+
browser, including when the line changes. Other pages keep their selection.
|
|
258
|
+
Tabs show filenames first, adding a short directory suffix
|
|
259
|
+
for duplicate names. Git versions use short commit IDs in a secondary label.
|
|
260
|
+
Long labels use the same width limit as session tabs, shortening the secondary
|
|
261
|
+
information before the filename;
|
|
262
|
+
hover titles retain the complete paths and revisions. Text,
|
|
263
|
+
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
264
|
+
provides syntax highlighting, find, folding and character-level diffs.
|
|
265
|
+
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
266
|
+
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
267
|
+
when supported and revalidate cached content with ETags.
|
|
268
|
+
Narrow content panes automatically use a unified diff; targeting the left
|
|
269
|
+
side keeps both sides visible. Markdown and HTML links default to previews;
|
|
270
|
+
line targets open their source. Clicking a link without a line returns that
|
|
271
|
+
same tab to preview. Manual tab switches preserve the chosen mode and reading state.
|
|
272
|
+
All views remain
|
|
273
|
+
read-only, with text selection and copying available. Local files update
|
|
274
|
+
automatically, including both sides of file diffs and the working side of
|
|
275
|
+
Git diffs; Git revisions stay fixed. Updates keep the active editor and
|
|
276
|
+
reading state without replaying an earlier line request.
|
|
277
|
+
Canvas is for explanations and custom visuals; source and diffs use links.
|
|
278
|
+
`[Canvas](workspace://canvas)` returns to the live page; an HTML file link opens
|
|
279
|
+
a preview tab, and `page.html:1` opens its source. File links work even with an empty `--toolset`.
|
|
280
|
+
Canvas and HTML previews share the same origin and script permissions;
|
|
281
|
+
the browser loads their resources with the workspace login cookie.
|
|
282
|
+
Open views survive reloads and server restarts. See
|
|
283
|
+
[workspace content views](docs/RUNTIME.md#workspace-content-views) for the
|
|
284
|
+
complete syntax and limits.
|
|
217
285
|
- interactive mode exits through `/exit`, `/quit`, Ctrl+D on an empty prompt,
|
|
218
286
|
or a single Ctrl+C; accepted work finishes before cleanup and normal exit.
|
|
219
287
|
A `[closing]` message explains the wait. Press Ctrl+C again while closing
|
|
@@ -316,7 +384,7 @@ Current behavior:
|
|
|
316
384
|
time when it expires.
|
|
317
385
|
- while a background command or clock is pending, the idle status is
|
|
318
386
|
`idle: sleeping`
|
|
319
|
-
- only the active workspace tab shows its close button; closing it restores
|
|
387
|
+
- only the active workspace session tab shows its close button; closing it restores
|
|
320
388
|
the selected tab's conversation, draft, and scroll position immediately
|
|
321
389
|
after its snapshot loads
|
|
322
390
|
- `--vllm-endpoint http://host:port` automatically launches a local
|
|
@@ -337,6 +405,10 @@ Current behavior:
|
|
|
337
405
|
reasoning, retries the same downstream request once, and only then emits
|
|
338
406
|
`response.failed` with `type = "model_output_invalid"` if the retry is still
|
|
339
407
|
reasoning-only
|
|
408
|
+
- compat reasoning fragments are forwarded immediately as
|
|
409
|
+
`response.reasoning_text.delta`, including thinking from `/v1/messages`.
|
|
410
|
+
Continuous reasoning keeps the client's read idle timeout from expiring
|
|
411
|
+
while it waits for assistant text; only finalized reasoning items enter history
|
|
340
412
|
- malformed JSON in ordinary downstream function-call arguments is detected by
|
|
341
413
|
`responses_server` and returned as `response.failed` with `type = "server_error"`;
|
|
342
414
|
the client's existing `stream_max_retries` policy retries the current request
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
中文 README。English version: `README.md`
|
|
4
4
|
|
|
5
|
+
0.3.3 看板文件/diff 查看器与推理流修复:[发布说明](docs/RELEASE_0.3.3.md)。
|
|
6
|
+
|
|
7
|
+
0.3.2 启动修复:[发布说明](docs/RELEASE_0.3.2.md)。
|
|
8
|
+
|
|
5
9
|
0.3.0 发版准备与 Python API 迁移说明:`docs/RELEASE_0.3.0.md`。
|
|
6
10
|
|
|
7
11
|
PyPI distributions:
|
|
@@ -34,11 +38,22 @@ Import 路径仍保持 `pycodex`;CLI 命令为 `pycodex` 和 `pycodex-ws`。
|
|
|
34
38
|
安装完整包或 workspace 安装别名:
|
|
35
39
|
|
|
36
40
|
```bash
|
|
37
|
-
pip install python-codex
|
|
38
|
-
pip install pycodex-ws
|
|
41
|
+
python3 -m pip install python-codex
|
|
42
|
+
python3 -m pip install pycodex-ws
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
要求 Python 3.6.2 或更新版本。两个命令会安装到该解释器的 scripts 目录。
|
|
46
|
+
在同时存在 Python 2/3 或多套 Python 的机器上,可以明确使用安装时的解释器启动:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python3 -m pycodex
|
|
50
|
+
python3 -m workspace_server --help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
如果 `PATH` 中找不到 `pycodex`,或者命中了旧安装,使用以上模块入口即可。
|
|
54
|
+
`python3 -m pip --version` 可确认包安装到了哪个 Python 环境。
|
|
55
|
+
|
|
56
|
+
从本仓库开发时,先安装依赖:
|
|
42
57
|
|
|
43
58
|
```bash
|
|
44
59
|
uv sync
|
|
@@ -188,6 +203,16 @@ from pycodex import ResponsesModelClient
|
|
|
188
203
|
client = ResponsesModelClient.from_codex_config()
|
|
189
204
|
```
|
|
190
205
|
|
|
206
|
+
`model_provider` 可省略,默认使用 `openai`。内置 provider 不要求
|
|
207
|
+
`[model_providers.openai]` 表,默认地址为 `https://api.openai.com/v1`,
|
|
208
|
+
从 `OPENAI_API_KEY` 读取密钥;可用 `openai_base_url` 覆盖地址。
|
|
209
|
+
显式 provider 表仍使用其配置的 `base_url` 和可选 `env_key`,
|
|
210
|
+
未知 provider 名称会报明确的配置错误。模型名仍从配置或所选 profile 的
|
|
211
|
+
`model` 字段读取。
|
|
212
|
+
|
|
213
|
+
当前认证通过环境变量或 `.env` 中的 API key 完成,尚不读取官方 Codex
|
|
214
|
+
桌面端/CLI 保存在 `auth.json` 或系统钥匙串中的 ChatGPT 登录凭据。
|
|
215
|
+
|
|
191
216
|
当前实现走 OpenAI-compatible Responses API 的流式 `/responses` 接口。这个点
|
|
192
217
|
已经用本机 `~/.codex/config.toml` 做过联调验证。
|
|
193
218
|
|
|
@@ -237,8 +262,34 @@ pycodex doctor
|
|
|
237
262
|
- 当前默认工具集由上游对齐子集和 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`
|
|
238
263
|
- `clock(period_m)` 为当前 Agent session 设置一个周期计时器,传 `null` 取消;每次回复后重新计时,到期后用包含当前时区时间的 `<clock_tick>` 消息唤醒 Agent
|
|
239
264
|
- 后台命令或 clock 正在等待时,空闲状态统一显示为 `idle: sleeping`
|
|
240
|
-
- workspace
|
|
265
|
+
- workspace 整个左侧展示区称为看板,包含实时 HTML Canvas 首标签和只读文件/diff 标签;
|
|
266
|
+
所有标签在同一行共同滚动,溢出时可用鼠标滚轮横向滚动。点击普通 Markdown 文件链接
|
|
267
|
+
`[源码](src/app.py:42)` 或 `[源码](/data/project/app.py#L42)` 即可打开视图。
|
|
268
|
+
diff 使用 Git 风格链接:`[工作区改动](diff:HEAD:src/app.py)`、
|
|
269
|
+
`[两个版本](diff:HEAD~1..HEAD:src/app.py)`、`[两个文件](diff:old.py..new.py)`。
|
|
270
|
+
只有用户点击后才创建或复用标签,模型输出链接本身不会打开文件。
|
|
271
|
+
再次打开同一文件或比较会切换到已有标签,保持原有顺序;其他页面的焦点不变。
|
|
272
|
+
diff 后加 `#L42` / `#R42` 可居中并选中左/右侧第 42 行,行号从 1 开始。
|
|
273
|
+
行号不参与标签身份,改变行号仍复用已有标签;普通刷新不会重放旧定位。
|
|
274
|
+
标签优先显示文件名,同名文件补充可区分的短目录;Git 版本用短 commit ID 作为次要说明。
|
|
275
|
+
长标题沿用会话标签的宽度上限,优先截断次要说明,悬停标题保留完整路径和 Git revision。
|
|
276
|
+
支持文本、Markdown、HTML、PNG/JPEG/GIF/WebP 和文本 diff。
|
|
277
|
+
代码与 diff 使用 Monaco,支持语法高亮、查找、折叠、字符级差异和差异跳转;
|
|
278
|
+
编辑器代码和样式在首次打开源码或 diff 时才加载,Canvas、Markdown/HTML 预览
|
|
279
|
+
不加载 Monaco。查看器静态资源支持 gzip 传输及 ETag 缓存校验。
|
|
280
|
+
内容区变窄时自动切换单栏 diff,定位左侧行号时保留双栏以显示目标。
|
|
281
|
+
Markdown 和 HTML 不带行号时默认预览,带行号时显示源码;再次点击无行号链接会在
|
|
282
|
+
同一标签回到预览,手动切换标签保留所选模式和阅读位置。用户可以选中复制,不能在查看器中修改源文件。
|
|
283
|
+
本地文件自动更新,包括文件 diff 两侧和 Git diff 的工作区一侧;Git 提交版本保持固定。
|
|
284
|
+
更新复用当前编辑器并保留阅读状态。Canvas 用于导读和自定义图示,源码和 diff 通过链接查看;
|
|
285
|
+
`[Canvas](workspace://canvas)` 返回实时页面,HTML 文件链接打开预览标签,`page.html:1` 查看源码。
|
|
286
|
+
Canvas 与 HTML 预览使用相同的同源权限,资源请求由浏览器自动携带工作区登录 cookie。
|
|
287
|
+
空 `--toolset` 不影响用户点击文件链接。
|
|
288
|
+
用户可关闭标签,打开列表和视图在刷新及服务重启
|
|
289
|
+
后恢复,完整语法和大小限制见 [workspace content views](docs/RUNTIME.md#workspace-content-views)。
|
|
290
|
+
- workspace 右侧会话区只在当前活动 tab 上显示关闭按钮
|
|
241
291
|
- `--vllm-endpoint http://host:port` 会自动拉起一个本地 `responses_server` compat 层;当 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` 翻回 Responses `reasoning` item,并把历史里的 `reasoning` item 回放成下游 assistant message 的 `reasoning` 字段;同时会向 vLLM 请求 streaming usage,并在最终 `response.completed.response.usage` 中回传
|
|
292
|
+
- compat 层会立即将 reasoning 分片转发为 `response.reasoning_text.delta`,也适用于 `/v1/messages` 的 thinking 流。持续到达的思考分片可避免等待正文期间触发客户端读空闲超时;只有最终确认的 reasoning item 才进入历史
|
|
242
293
|
- `pycodex doctor` 会检查配置、`.env`、API key、DNS、TCP/TLS,以及可选的 live Responses API 请求
|
|
243
294
|
|
|
244
295
|
它目前主要用于:
|
|
@@ -48,6 +48,29 @@ Tool-specific status uses two inputs:
|
|
|
48
48
|
- proxy captures of actual upstream Codex and `pycodex` requests/results
|
|
49
49
|
- source inspection against the latest upstream tool specifications
|
|
50
50
|
|
|
51
|
+
## Startup and provider defaults (2026-10-10)
|
|
52
|
+
|
|
53
|
+
Provider selection uses `openai` when `model_provider` is omitted, matching
|
|
54
|
+
[`config/mod.rs` at the 0.153.4 source baseline](https://github.com/openai/codex/blob/3d2ee51ca2d5db578f328aa75e20aa22c0197c9a/codex-rs/core/src/config/mod.rs).
|
|
55
|
+
The built-in OpenAI provider needs no user-defined provider table. For pycodex's
|
|
56
|
+
API-key transport, its default address is `https://api.openai.com/v1`, with the
|
|
57
|
+
top-level/profile `openai_base_url` override and `OPENAI_API_KEY` environment
|
|
58
|
+
variable. Custom providers must be selected explicitly; an unknown provider
|
|
59
|
+
raises a descriptive configuration error.
|
|
60
|
+
|
|
61
|
+
Two local boundaries remain: explicit provider tables retain their existing
|
|
62
|
+
pycodex override behavior, and authentication reads environment API keys rather
|
|
63
|
+
than Codex's stored ChatGPT credentials. `model` must still be specified in the
|
|
64
|
+
configuration or selected profile. This change aligns provider selection,
|
|
65
|
+
not the full upstream authentication or model-discovery surface.
|
|
66
|
+
|
|
67
|
+
The package also supports `python3 -m pycodex`, alongside the existing
|
|
68
|
+
`python3 -m workspace_server`, so installation and startup can use the same
|
|
69
|
+
interpreter on hosts with multiple Python installations. Console scripts remain
|
|
70
|
+
owned by `python-codex` and are generated by the installer. The publish workflow
|
|
71
|
+
installs the built wheels into a fresh environment and checks both console and
|
|
72
|
+
module entry points outside the source checkout before uploading artifacts.
|
|
73
|
+
|
|
51
74
|
## Context audit (2026-09-23)
|
|
52
75
|
|
|
53
76
|
This audit uses installed `codex-cli 0.153.4` and its matching
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# 0.3.2 release notes
|
|
2
|
+
|
|
3
|
+
Both `python-codex` and `pycodex-ws` use version **0.3.2**. The workspace
|
|
4
|
+
metapackage depends on exactly `python-codex==0.3.2`; publish the core package
|
|
5
|
+
first.
|
|
6
|
+
|
|
7
|
+
## Startup fixes
|
|
8
|
+
|
|
9
|
+
- Codex configurations may omit `model_provider`. In that case, use the built-in
|
|
10
|
+
`openai` provider without requiring a `[model_providers.openai]` table.
|
|
11
|
+
Its default API address is `https://api.openai.com/v1`, with
|
|
12
|
+
`openai_base_url` available as an override and `OPENAI_API_KEY` supplying
|
|
13
|
+
authentication. Existing explicit provider tables keep their behavior;
|
|
14
|
+
unknown provider names produce a descriptive configuration error.
|
|
15
|
+
- Add `python3 -m pycodex` so installation and startup can explicitly use the
|
|
16
|
+
same interpreter on hosts with multiple Python installations.
|
|
17
|
+
The browser frontend remains available through
|
|
18
|
+
`python3 -m workspace_server` or the `pycodex-ws` command.
|
|
19
|
+
- Check installed wheel entry points in a fresh environment before publication,
|
|
20
|
+
covering both console scripts and both module entry points outside the source
|
|
21
|
+
checkout. Add provider-selection and module-exit-status regressions.
|
|
22
|
+
|
|
23
|
+
The configuration still needs `model`, either at the top level or in the
|
|
24
|
+
selected profile. Authentication uses environment API keys or `.env`;
|
|
25
|
+
stored ChatGPT sign-in credentials from the official Codex CLI/desktop app
|
|
26
|
+
are not loaded.
|
|
27
|
+
|
|
28
|
+
## Upgrade
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
python3 -m pip install --upgrade pycodex-ws==0.3.2
|
|
32
|
+
python3 -m pycodex
|
|
33
|
+
python3 -m workspace_server --help
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`python3 -m pycodex-ws` is not a module entry point.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 0.3.3 release notes
|
|
2
|
+
|
|
3
|
+
Both `python-codex` and `pycodex-ws` use version **0.3.3**. The workspace
|
|
4
|
+
metapackage depends on exactly `python-codex==0.3.3`; publish the core package
|
|
5
|
+
first.
|
|
6
|
+
|
|
7
|
+
## Workspace file and diff viewers
|
|
8
|
+
|
|
9
|
+
- Open file, Git revision, and diff links from replies or Canvas in persistent
|
|
10
|
+
board tabs. Source and diff views use read-only Monaco editors with line
|
|
11
|
+
navigation and syntax highlighting.
|
|
12
|
+
- Preview Markdown, HTML, and images directly. Add a line number to a Markdown
|
|
13
|
+
or HTML link to open its source; click the link without a line number to return
|
|
14
|
+
to the preview in the same tab. `workspace://canvas` returns to Canvas.
|
|
15
|
+
- Local files refresh as they change, while Git views retain their resolved
|
|
16
|
+
revision. Each browser page keeps its own active tab, preview mode, and reading
|
|
17
|
+
position. Opening a view does not submit a message to the agent.
|
|
18
|
+
- Load the editor only when opening source or a diff. The wheel includes editor
|
|
19
|
+
assets, fonts, and the diff worker, so installed workspaces do not need Node.
|
|
20
|
+
Static assets support cached gzip responses and conditional requests.
|
|
21
|
+
|
|
22
|
+
## Reasoning stream fix
|
|
23
|
+
|
|
24
|
+
Chat-completions compatibility mode now forwards `reasoning` and
|
|
25
|
+
`reasoning_content` increments immediately as `response.reasoning_text.delta`
|
|
26
|
+
events. Long reasoning phases continue to send data to the client, avoiding
|
|
27
|
+
stream idle timeouts while the backend is still generating.
|
|
28
|
+
|
|
29
|
+
Repeated reasoning aliases are deduplicated. Final reasoning items and the
|
|
30
|
+
existing retry behavior for responses containing only reasoning are preserved.
|
|
31
|
+
Regression coverage includes a client request whose reasoning phase lasts
|
|
32
|
+
longer than its configured stream idle timeout.
|
|
33
|
+
|
|
34
|
+
## Upgrade
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python3 -m pip install --upgrade pycodex-ws==0.3.3
|
|
38
|
+
python3 -m pycodex
|
|
39
|
+
python3 -m workspace_server --help
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Installing `pycodex-ws==0.3.3` also installs `python-codex==0.3.3`. The import
|
|
43
|
+
path and both console commands remain unchanged.
|