python-codex 0.2.7__py3-none-any.whl → 0.3.0__py3-none-any.whl

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.
Files changed (84) hide show
  1. pycodex/__init__.py +14 -14
  2. pycodex/agent.py +465 -499
  3. pycodex/bootstrap.py +417 -0
  4. pycodex/cli.py +236 -510
  5. pycodex/compat.py +19 -5
  6. pycodex/context.py +222 -212
  7. pycodex/doctor.py +52 -48
  8. pycodex/events.py +857 -0
  9. pycodex/feishu_card.py +217 -163
  10. pycodex/feishu_link.py +43 -83
  11. pycodex/model.py +324 -253
  12. pycodex/model_metadata.py +19 -7
  13. pycodex/portable.py +76 -45
  14. pycodex/portable_server.py +32 -24
  15. pycodex/prompts/models.json +245 -983
  16. pycodex/protocol.py +177 -137
  17. pycodex/runtime.py +579 -176
  18. pycodex/runtime_services.py +204 -157
  19. pycodex/tools/__init__.py +1 -1
  20. pycodex/tools/apply_patch_tool.py +69 -48
  21. pycodex/tools/base_tool.py +89 -42
  22. pycodex/tools/clock_tool.py +58 -25
  23. pycodex/tools/close_agent_tool.py +2 -2
  24. pycodex/tools/code_mode_manager.py +77 -64
  25. pycodex/tools/exec_command_tool.py +26 -11
  26. pycodex/tools/exec_tool.py +4 -4
  27. pycodex/tools/grep_files_tool.py +12 -10
  28. pycodex/tools/ipython_tool.py +10 -13
  29. pycodex/tools/list_dir_tool.py +13 -9
  30. pycodex/tools/read_file_tool.py +29 -17
  31. pycodex/tools/request_permissions_tool.py +15 -5
  32. pycodex/tools/request_user_input_tool.py +13 -104
  33. pycodex/tools/resume_agent_tool.py +2 -2
  34. pycodex/tools/send_input_tool.py +11 -8
  35. pycodex/tools/shell_command_tool.py +7 -5
  36. pycodex/tools/shell_tool.py +7 -5
  37. pycodex/tools/spawn_agent_tool.py +7 -4
  38. pycodex/tools/unified_exec_manager.py +102 -69
  39. pycodex/tools/update_plan_tool.py +8 -5
  40. pycodex/tools/view_image_tool.py +7 -5
  41. pycodex/tools/wait_agent_tool.py +27 -4
  42. pycodex/tools/wait_tool.py +5 -4
  43. pycodex/tools/web_search_tool.py +4 -2
  44. pycodex/tools/write_stdin_tool.py +12 -11
  45. pycodex/utils/__init__.py +2 -17
  46. pycodex/utils/compactor.py +41 -72
  47. pycodex/utils/debug.py +2 -2
  48. pycodex/utils/dotenv.py +6 -7
  49. pycodex/utils/event_helpers.py +190 -0
  50. pycodex/utils/get_env.py +27 -70
  51. pycodex/{image_utils.py → utils/image_utils.py} +8 -11
  52. pycodex/utils/random_ids.py +1 -2
  53. pycodex/utils/session_persist.py +217 -163
  54. pycodex/utils/truncation.py +21 -45
  55. python_codex-0.3.0.dist-info/METADATA +704 -0
  56. python_codex-0.3.0.dist-info/RECORD +90 -0
  57. responses_server/__init__.py +1 -5
  58. responses_server/__main__.py +0 -1
  59. responses_server/app.py +36 -31
  60. responses_server/config.py +23 -23
  61. responses_server/messages_api.py +51 -53
  62. responses_server/payload_processors.py +25 -20
  63. responses_server/server.py +11 -11
  64. responses_server/session_store.py +14 -11
  65. responses_server/stream_router.py +101 -98
  66. responses_server/tools/custom_adapter.py +17 -16
  67. responses_server/tools/web_search.py +39 -36
  68. responses_server/trajectory_dump.py +36 -14
  69. workspace_server/__main__.py +0 -1
  70. workspace_server/app.py +461 -375
  71. workspace_server/workspace.html +852 -228
  72. workspace_server/workspaces.html +94 -95
  73. workspace_server/workspaces.py +137 -79
  74. pycodex/collaboration.py +0 -20
  75. pycodex/interactive_session.py +0 -415
  76. pycodex/prompts/collaboration_default.md +0 -11
  77. pycodex/prompts/collaboration_plan.md +0 -128
  78. pycodex/utils/toolcall_visualize.py +0 -713
  79. pycodex/utils/visualize.py +0 -560
  80. python_codex-0.2.7.dist-info/METADATA +0 -455
  81. python_codex-0.2.7.dist-info/RECORD +0 -93
  82. {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/WHEEL +0 -0
  83. {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/entry_points.txt +0 -0
  84. {python_codex-0.2.7.dist-info → python_codex-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,455 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: python-codex
3
- Version: 0.2.7
4
- Summary: A minimal Python extraction of Codex's main agent loop
5
- License-File: LICENSE
6
- Requires-Python: >=3.6.2
7
- Requires-Dist: dataclasses>=0.8; python_version < '3.7'
8
- Requires-Dist: fastapi<0.84,>=0.83.0; python_version < '3.7'
9
- Requires-Dist: fastapi>=0.83.0; python_version >= '3.7'
10
- Requires-Dist: importlib-metadata>=4.8.3; python_version < '3.8'
11
- Requires-Dist: loguru>=0.7.3
12
- Requires-Dist: pillow>=8.4.0; python_version < '3.7'
13
- Requires-Dist: pillow>=9.0.0; python_version >= '3.7'
14
- Requires-Dist: prompt-toolkit>=3.0.36
15
- Requires-Dist: pycryptodomex>=3.20
16
- Requires-Dist: requests>=2.27.1
17
- Requires-Dist: tomli<2,>=1.2.3; python_version < '3.11'
18
- Requires-Dist: typing-extensions>=4.1.1; python_version < '3.8'
19
- Requires-Dist: uvicorn<0.17,>=0.16.0; python_version < '3.7'
20
- Requires-Dist: uvicorn>=0.16.0; python_version >= '3.7'
21
- Description-Content-Type: text/markdown
22
-
23
- # pycodex
24
-
25
- English README. Chinese version: `README_ZH.md`
26
-
27
- PyPI distributions:
28
-
29
- - Primary package: `python-codex`
30
- - Workspace install alias: `pycodex-ws`
31
-
32
- The import path remains `pycodex`; the CLI commands are `pycodex` and
33
- `pycodex-ws`.
34
-
35
- `pycodex-ws` is a thin metapackage that depends on the exact matching
36
- `python-codex` version. The implementation and console script remain owned by
37
- `python-codex`, so the two distributions never install duplicate modules.
38
-
39
- This repository extracts the core Codex agent loop from upstream Codex
40
- (`https://github.com/openai/codex`) into a deliberately small Python version,
41
- while preserving the two most important layers:
42
-
43
- - `submission_loop`: sequentially consumes submitted operations.
44
- - `run_turn`: keeps executing `model sample -> tool call -> feed tool result
45
- back into the model` inside a single turn until a final answer is reached.
46
-
47
- Relevant Rust reference points:
48
-
49
- - `codex-rs/core/src/codex.rs` -> `submission_loop`
50
- - `codex-rs/core/src/codex.rs` -> `run_turn`
51
- - `codex-rs/core/src/codex.rs` -> `run_sampling_request`
52
- - `codex-rs/core/src/tools/router.rs` -> `ToolRouter`
53
- - `codex-rs/core/src/stream_events_utils.rs` -> `handle_output_item_done`
54
-
55
- ## Quick Start
56
-
57
- Install the full package or the workspace-oriented alias:
58
-
59
- ```bash
60
- pip install python-codex
61
- pip install pycodex-ws
62
- ```
63
-
64
- Install dependencies first:
65
-
66
- ```bash
67
- uv sync
68
- ```
69
-
70
- Try the real entry points:
71
-
72
- ```bash
73
- uv run pycodex "Reply with exactly OK."
74
- uv run pycodex
75
- ```
76
-
77
- ## Design Tradeoffs
78
-
79
- This is not a 1:1 port of the Rust implementation. The current goal is a
80
- minimal reusable kernel that converges on the upstream behavior over time:
81
-
82
- 1. Use a thin `ModelClient` protocol to abstract the model side.
83
- 2. Use `ToolRegistry` to manage tool specs and executors.
84
- 3. Use `AgentLoop` to implement the core closed loop.
85
- 4. Use `AgentRuntime` to preserve the outer submission queue so it can keep
86
- converging toward Rust's `submission_loop` later.
87
-
88
- Intentionally not included yet:
89
-
90
- - TUI / streaming incremental rendering
91
- - MCP / connectors / sandbox / approvals
92
- - memory / compact / review mode
93
- - a full production OpenAI adapter surface
94
-
95
- All of those can be layered on later. For now, the project is focused on
96
- nailing the core tool-augmented reasoning loop first.
97
-
98
- ## Layout
99
-
100
- - `pycodex/protocol.py`: minimal conversation item / prompt / event protocol
101
- - `pycodex/model.py`: model client protocol and Responses API adapter
102
- - `pycodex/cli.py`: single-turn and interactive `pycodex` CLI entry points
103
- - `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
104
- - `pycodex/tools/`: concrete tool implementations
105
- - `pycodex/agent.py`: inner turn loop
106
- - `pycodex/runtime.py`: outer submission queue
107
- - `tests/test_agent.py`: core behavior tests
108
-
109
- ## Current Alignment Status
110
-
111
- Current progress is easiest to read in layers:
112
-
113
- - prompt/context alignment:
114
- - on the non-interactive `exec` path, `instructions` and `input` already
115
- match upstream Codex;
116
- - this layer is now mainly handled by `pycodex/context.py` plus vendored
117
- prompt data.
118
- - turn-loop semantic alignment:
119
- - `AgentLoop` no longer uses a fixed 12-iteration cap by default;
120
- - like upstream, it now converges naturally based on whether there is still
121
- follow-up work or tool handoff to do;
122
- - the local iteration-limit parameter is gone.
123
- - request-level alignment:
124
- - the non-interactive `exec` request body is mostly aligned;
125
- - the default CLI non-exec first request now also follows the upstream
126
- `codex-tui` + `<collaboration_mode>` path;
127
- - the default CLI two-turn main-thread request/header behavior has also been
128
- captured and aligned, including omitting `workspaces` on later turns;
129
- - the remaining work is now more about outer behavior branches than this
130
- already-compared request/header path.
131
- - tool round-trip alignment:
132
- - the Default-mode unavailable path for `request_user_input` is aligned to
133
- real upstream captures;
134
- - the Plan-mode happy path is also aligned at the tool/protocol layer based
135
- on upstream source: it forces `isOther=true`, requires non-empty `options`,
136
- and returns structured answers as a JSON string plus `success=true`;
137
- - there is now a deterministic round-trip comparison helper,
138
- `tests/compare_request_user_input_roundtrip.py`, built on the proxy mode in
139
- `tests/fake_responses_server.py`; against the locally installed
140
- `codex-cli 0.115.0`, the only remaining Plan-mode live-capture schema
141
- difference is that `pycodex` includes `success=true` in
142
- `function_call_output`.
143
-
144
- See `docs/ALIGNMENT.md` for more detailed notes.
145
-
146
- ## Live Model Integration
147
-
148
- If this machine already has a Codex CLI configuration, `pycodex` can reuse the
149
- `model`, `model_provider`, `base_url`, and `env_key` from
150
- `~/.codex/config.toml` directly:
151
-
152
- ```python
153
- from pycodex import ResponsesModelClient
154
-
155
- client = ResponsesModelClient.from_codex_config()
156
- ```
157
-
158
- The current implementation uses the streaming OpenAI-compatible `/responses`
159
- endpoint. This path has already been validated against the local
160
- `~/.codex/config.toml` setup.
161
-
162
- When launched through the CLI, `pycodex` also loads `.env` from the same
163
- configuration directory before reading config (typically `~/.codex/.env`), so
164
- provider keys and similar environment variables can live there. To match
165
- upstream Codex, variables starting with `CODEX_` are not imported from `.env`.
166
-
167
- ## pycodex CLI
168
-
169
- `pycodex` now defaults to a minimal interactive entry point. Internally it uses
170
- `AgentRuntime` to drive the turn submission loop and reuses
171
- `~/.codex/config.toml` by default:
172
-
173
- ```bash
174
- pycodex
175
- pycodex "Summarize this repo in one sentence."
176
- printf 'Reply with exactly OK.' | pycodex
177
- pycodex --json "Reply with exactly OK."
178
- pycodex --profile model_proxy "Reply with exactly OK."
179
- pycodex --profile opus --use-messages "Reply with exactly OK."
180
- pycodex --vllm-endpoint http://127.0.0.1:18000 "Reply with exactly OK."
181
- pycodex --put @127.0.0.1:5577
182
- pycodex --put /data/.codex/@127.0.0.1:5577
183
- pycodex --call SECRET-CALLID@127.0.0.1:5577 "Reply with exactly OK."
184
- pycodex doctor
185
- pycodex-ws --listen 0.0.0.0:6007 --workspace-config ./workspaces.json
186
- pycodex-ws --listen 0.0.0.0:6007 --workspace-config ./workspaces.json --password 12345
187
- ```
188
-
189
- Current behavior:
190
-
191
- - with no argv prompt and a TTY stdin, enter interactive mode
192
- - with an argv prompt or piped stdin, run a single turn
193
- - `pycodex-ws` starts the standalone browser workspace manager and serves each
194
- workspace with a board pane and a pycodex session pane
195
- - interactive mode supports `/exit` and `/quit`
196
- - interactive mode shows a compact event stream for user-visible phases such as
197
- tool execution and model follow-up after tool results
198
- - assistant text is printed from streaming deltas directly
199
- - interactive mode supports `/history`, `/title`, `/model`, `/resume`, `/compact`,
200
- and `/fork`
201
- - `/model <name>` switches the model used by later turns in the current
202
- interactive session; `/model` shows the current model and available choices
203
- - `/resume` with no argument lists the currently resumable sessions by their
204
- first user-message preview; `/resume 1` resumes the first listed session
205
- - `/resume <number>` replaces the in-memory history with the selected recorded
206
- Codex rollout from `CODEX_HOME/sessions`
207
- - `/compact` synthesizes a local handoff summary, replaces the in-memory
208
- conversation history with the compacted view, and appends a compacted-history
209
- entry to the rollout so later `/resume` sees the same state
210
- - `/fork` generates a new model session id while preserving the current history,
211
- rollout, and workspace tab
212
- - `model_auto_compact_token_limit = <tokens>` in `config.toml` enables the same
213
- compaction path automatically when the latest reported usage reaches that
214
- threshold before a follow-up sampling request or the next user turn
215
- - `service_tier = "fast"` enables Fast mode for models whose vendored metadata
216
- advertises the `priority` service tier; pycodex follows upstream Codex by
217
- sending `service_tier = "priority"` on the Responses request, while
218
- `service_tier = "default"` or unsupported tiers are omitted
219
- - if a model request fails with `context_length_exceeded`, pycodex now treats
220
- the provider-reported requested token count as a failed-request usage sample,
221
- triggers the same compact path immediately, and retries the request once; if
222
- the compact request is also over the limit, it repeatedly drops the oldest
223
- tool response plus its matching tool call before retrying compact
224
- - new sessions are now recorded under `CODEX_HOME/sessions/.../rollout-*.jsonl`
225
- with a stable session/thread id and per-item append+flush semantics so
226
- `/resume` reads back the same rollout format
227
- - if `TURN_HOOK.md` exists in the workspace root and is non-empty, each
228
- completed turn also forks the just-finished history into a temporary,
229
- non-persisted follow-up session and submits the file contents as the next
230
- user instruction; this is intended for side-effect follow-ups such as
231
- Feishu notifications
232
- - `/link <feishu-email|open_id|chat_id>` attaches the current interactive
233
- session to a Feishu card; multiple sessions in the same pycodex process share
234
- one Feishu long-connection listener and route card actions by message id
235
- - `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
236
- one process. The JSON file can be either a list or
237
- `{"workspaces": [...]}`; each entry uses `board` and `work_dir`, with optional
238
- display/URL `id`, and is exposed at `/w/<id>/`. Internally the resolved
239
- `board` path is the workspace identity, so adding the same board path twice is
240
- rejected even with a different name. Relative `board` and `work_dir` paths
241
- resolve from the config file directory. The root path `/` shows a workspaces
242
- management page with `add_workspace(name=None, dir="./", board=None)` and
243
- `delete(name)` controls; omitted names become `workspace-1`, `workspace-2`,
244
- etc. If `board` is omitted when adding a workspace, pycodex assigns a random
245
- writable `/tmp/pcws-*.html` board path. Add/delete actions and later
246
- session-state saves refresh the JSON file. Board HTML can reference local
247
- images beside the board (including nested paths) with relative URLs; only
248
- `image/*` files contained by the board directory are served.
249
- Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
250
- `\(...\)`, and `\[...\]` delimiters.
251
- `--password <value>` enables a password-only login page for workspace pages,
252
- APIs, and websocket connections.
253
- - steer is enabled by default in interactive mode: normal input goes into the
254
- runtime steer path, the current request stops at the next safe boundary, and
255
- later steer text is appended to the next model request's `input` in order;
256
- for explicit queueing, use `/queue <message>`, which prints
257
- `[steer] queued: ...` and later `[steer] inserted: ...`
258
- - the default local tool set includes the upstream-aligned subset plus the
259
- pycodex `clock` extension: `shell`, `shell_command`, `exec_command`,
260
- `write_stdin`, `clock`, `exec`, `wait`, `web_search`, `update_plan`,
261
- `request_user_input`, `request_permissions`, `spawn_agent`, `send_input`,
262
- `resume_agent`, `wait_agent`, `close_agent`, `apply_patch`, `grep_files`,
263
- `read_file`, `list_dir`, `view_image`
264
- - `clock(period_m)` sets one periodic clock for the current Agent session;
265
- `null` cancels it. The countdown restarts after each reply and wakes the
266
- Agent with a `<clock_tick>` message containing the current timezone-aware
267
- time when it expires.
268
- - while a background command or clock is pending, the idle status is
269
- `idle: sleeping`
270
- - only the active workspace tab shows its close button
271
- - `--vllm-endpoint http://host:port` automatically launches a local
272
- `responses_server` compatibility layer; when the URL path is empty it is
273
- normalized to `/v1`, and `/responses` requests are still forwarded to the
274
- downstream `/v1/chat/completions` endpoint. This local compat path always
275
- uses the canonical Responses request shape, even when the selected model's
276
- metadata enables `responses_lite`. With `--vllm-endpoint`, startup also reads
277
- `/v1/models` and uses the last returned model id for the downstream request.
278
- For `model_provider = "vllm"`, reasoning is preserved across this path:
279
- chat chunks with `reasoning` or `reasoning_content` are translated back into
280
- Responses `reasoning` items, and
281
- historical `reasoning` items are replayed into downstream assistant messages
282
- via the `reasoning` field. Streaming token usage is also requested from vLLM
283
- and forwarded to the final `response.completed.response.usage`. If a
284
- downstream chat stream terminates after emitting only reasoning, with no
285
- assistant content and no tool call, the compat layer discards that partial
286
- reasoning, retries the same downstream request once, and only then emits
287
- `response.failed` with `type = "model_output_invalid"` if the retry is still
288
- reasoning-only
289
- - standalone `responses_server` now also supports downstream `/v1/messages`
290
- backends via `--outcomming-api messages`, while keeping the internal
291
- canonical request/route logic in chat-completions shape
292
- - `pycodex doctor` checks config, `.env`, API keys, DNS, TCP/TLS, and an
293
- optional live Responses API request
294
-
295
- Current primary uses:
296
-
297
- - verify provider / model / auth configuration
298
- - debug `ResponsesModelClient`
299
- - run minimal single-turn and multi-turn smoke tests
300
-
301
- `doctor` examples:
302
-
303
- ```bash
304
- pycodex doctor
305
- pycodex doctor --skip-live
306
- pycodex doctor --json
307
- ```
308
-
309
- ## Portable Mode
310
-
311
- `Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
312
- fresh machine, container, or debug image.
313
-
314
- Use it like this:
315
-
316
- ```bash
317
- pycodex --put @127.0.0.1:5577
318
- pycodex --put /data/.codex/@127.0.0.1:5577
319
- ```
320
-
321
- - `--put` prints a reusable `SECRET-CALLID@host:port` plus a final one-line
322
- `pycodex --call ...` command
323
- - on the new environment or image, run that printed `--call` command directly
324
- - quickly restoring your usual `config.toml`, `.env`, `AGENTS.md`, and
325
- `skills/` into a clean debug environment
326
- - keeping a new image focused on the bug you are debugging instead of spending
327
- time rebuilding local Codex setup by hand
328
- - bootstrapping `pycodex` even when the target environment does not already
329
- have a populated `~/.codex`
330
- - bare `--put` uses the current user's `~/.codex`
331
- - `--put /path/.codex/@host:port` lets you publish a different Codex home
332
-
333
- ## Example
334
-
335
- ```python
336
- import asyncio
337
-
338
- from pycodex import (
339
- AgentLoop,
340
- BaseTool,
341
- ContextManager,
342
- ResponsesModelClient,
343
- ToolRegistry,
344
- )
345
-
346
-
347
- class EchoTool(BaseTool):
348
- name = "echo"
349
- description = "Echo the provided text."
350
- input_schema = {
351
- "type": "object",
352
- "properties": {"text": {"type": "string"}},
353
- "required": ["text"],
354
- }
355
-
356
- async def run(self, context, args):
357
- del context
358
- return args["text"]
359
-
360
-
361
- async def main() -> None:
362
- model = ResponsesModelClient.from_codex_config()
363
- context_manager = ContextManager.from_codex_config()
364
-
365
- tools = ToolRegistry()
366
- tools.register(EchoTool())
367
-
368
- agent = AgentLoop(model, tools, context_manager)
369
- result = await agent.run_turn(
370
- ["Call the echo tool with text=hello, then tell me what it returned."]
371
- )
372
- print(result.output_text)
373
-
374
-
375
- asyncio.run(main())
376
- ```
377
-
378
- ## Alignment Checklist
379
-
380
- See `docs/ALIGNMENT.md` for more detail. This section keeps a high-level
381
- checklist for quick status scanning.
382
-
383
- ### Tool Alignment
384
-
385
- Official upstream tools:
386
-
387
- - [x] `shell` - run shell commands in argv form.
388
- - [x] `shell_command` - run shell scripts in string form.
389
- - [x] `exec_command` - start long-running commands with a session.
390
- - [x] `write_stdin` - write stdin to an existing execution session or poll
391
- output.
392
- - [x] `web_search` - expose provider-native web search capability.
393
- - [x] `update_plan` - update the task plan and maintain step status.
394
- - [x] `request_user_input` - ask the user structured questions and wait for an
395
- answer.
396
- - [x] `request_permissions` - request extra permissions before continuing.
397
- - [x] `spawn_agent` - create and start a sub-agent.
398
- - [x] `send_input` - continue feeding input to an existing sub-agent.
399
- - [x] `resume_agent` - reopen a closed sub-agent.
400
- - [x] `wait_agent` - wait for a sub-agent to reach a terminal state.
401
- - [x] `close_agent` - close a sub-agent that is no longer needed.
402
- - [x] `apply_patch` - edit files precisely with a freeform patch.
403
- - [x] `grep_files` - search file contents by pattern.
404
- - [x] `read_file` - read file slices while preserving line-number semantics.
405
- - [x] `list_dir` - list directory tree slices.
406
- - [x] `view_image` - turn a local image into model-visible input.
407
-
408
- Upstream low-frequency / special-mode tools not yet modeled separately:
409
-
410
- - [ ] `wait_infinite` - long blocking wait for external events or later input.
411
- - [ ] `spawn_agents_on_csv` - create sub-agent jobs in bulk from CSV.
412
- - [ ] `report_agent_job_result` - report batch agent job results.
413
- - [ ] `js_repl` - JavaScript REPL / code-mode primary entry point.
414
- - [ ] `js_repl_reset` - reset `js_repl` state.
415
- - [ ] `artifacts` - generate or manage structured artifact outputs.
416
- - [ ] `list_mcp_resources` - list MCP resources.
417
- - [ ] `list_mcp_resource_templates` - list MCP resource templates.
418
- - [ ] `read_mcp_resource` - read MCP resource contents.
419
- - [ ] `multi_tool_use.parallel` - parallel wrapper around multiple developer
420
- tool calls.
421
-
422
- Repository-specific compatibility / transition tools:
423
-
424
- - [x] `clock` - pycodex periodic Agent wake-up extension.
425
- - [x] `exec` - current local approximation of code mode.
426
- - [x] `wait` - current local approximation of code-mode waiting behavior.
427
-
428
- ### Behavior Alignment
429
-
430
- - [x] `AgentLoop` / `AgentRuntime` main loop skeleton - turn loop and submission
431
- queue are in place.
432
- - [x] non-interactive `exec` `instructions` alignment - base instructions match
433
- upstream.
434
- - [x] non-interactive `exec` `input` alignment - prompt input matches upstream.
435
- - [x] developer/contextual-user message shape alignment - message/content shape
436
- matches upstream.
437
- - [x] `AGENTS.md` + `<environment_context>` injection alignment - context
438
- assembly order matches upstream.
439
- - [x] non-interactive `exec` upstream tool subset alignment - the aligned
440
- subset has converged; pycodex additionally exposes `clock`.
441
- - [x] `include = ["reasoning.encrypted_content"]` - reasoning include field is
442
- aligned.
443
- - [x] `prompt_cache_key` - request-level prompt cache key is implemented.
444
- - [x] `x-client-request-id` - request id header is implemented.
445
- - [x] `x-codex-turn-metadata` - turn id / sandbox header is implemented.
446
- - [x] `originator` - mode-aware originator header is implemented.
447
- - [x] exact `user-agent` string alignment - aligned on the non-interactive
448
- `exec` path.
449
- - [x] field-by-field upstream exec-mode tool schema alignment - aligned tools
450
- use class-level specs; `clock` is documented separately as an extension.
451
- - [ ] full interactive-mode and non-`exec` behavior alignment - the non-exec
452
- first-turn context is now on the `codex-tui` path, but continuous REPL
453
- multi-turn behavior is not fully verified yet.
454
- - [ ] sandbox / approvals / compact / memory and other outer behavior alignment
455
- - these systems are still in later scope.
@@ -1,93 +0,0 @@
1
- pycodex/__init__.py,sha256=dzSorjXWi2XYzUU1l_zcCxO_WRb3B0a5OzMyCzQ9WC4,3266
2
- pycodex/agent.py,sha256=sz0qAvCP52tpKlmPZc5LA1e9hY_vWWQ3tgHpvLNqojY,22968
3
- pycodex/cli.py,sha256=XGiYLjK5s5ObvKRejuT3KQh-ua-TlmOw-BcT9K0VYF0,22809
4
- pycodex/collaboration.py,sha256=yQ6pBD-R3ZWR4_FAYQFoS7KF0m4LLD42otXIbPqw2ys,641
5
- pycodex/compat.py,sha256=l35JE0vGAOCn9NWbWbqwGURGk83HXddXQ5wJIfcG41o,3254
6
- pycodex/context.py,sha256=NRCJpYpEm76cAK1akid0BvQ-Z0mAvw1ZNboVxjPtm6U,26219
7
- pycodex/doctor.py,sha256=De3M4hRBJq8ZeqsUJgHz0vitqrH18YugrEnz7oHhTdQ,10572
8
- pycodex/feishu_card.py,sha256=De6pM--3MfhgGo-WcWfhm-fop5UtzjwKrZ4gI2Lls3w,26198
9
- pycodex/feishu_link.py,sha256=DDQCYXQXgo_2SpXPyWlK8KYcumNO1-sqFuQDsEMQpTg,16427
10
- pycodex/image_utils.py,sha256=9TvowOPq0vTX3J4F-WLgz_Cfl7-jt3zLNM0oL3Vbhq8,2432
11
- pycodex/interactive_session.py,sha256=WzOD06d43ckF7SPer12JKzUPIK42Djw4kEjFRdM6_Lw,16420
12
- pycodex/model.py,sha256=cgCFtOhB2GBFDiGU1OvqtBh5ngFmBhN53PphonCY5ek,42066
13
- pycodex/model_metadata.py,sha256=7fHntKSUXhG5eASJi4yw4jU_IyzGbYBp-WE6af19ATA,877
14
- pycodex/portable.py,sha256=HdgfVwEoooh_eaZwiu4lqLXYes8ONyTnCMDqKuM8-Tc,15901
15
- pycodex/portable_server.py,sha256=6I3pQkWj3e_SFlDXY2mGdCPns1w_3PSxByBV9wv5epI,7331
16
- pycodex/protocol.py,sha256=4qiEcBQc3d3RZqsIKBjwORsHsQa78cqwvNljtnIuNbM,10795
17
- pycodex/runtime.py,sha256=_-d0nMSFTlLK7UxMcGnjtktSCfVTxy8dCNl355j5D9Y,8758
18
- pycodex/runtime_services.py,sha256=6PQMI4MM8F9imijaVKBIz_0ADtoKDcdYs6vQ-c4frtQ,13931
19
- pycodex/prompts/collaboration_default.md,sha256=MBTmPuMubeWfZgIeFVj49wwnwD4n_o3fVYAbgWKwu6Q,955
20
- pycodex/prompts/collaboration_plan.md,sha256=IzjQAA5oHJz-3FmJdOjsJ4LHq6LW1tlEYMoy09n0HKk,8777
21
- pycodex/prompts/default_base_instructions.md,sha256=D65mcj6bo4CDvVom-D9cbJRJVNquo0NghKt164_fRsg,20923
22
- pycodex/prompts/models.json,sha256=3J0FN5UUUj2oPBXWRR2AFo2LXB3-2PJ_5T52-F-eVh8,525055
23
- pycodex/prompts/permissions/approval_policy/never.md,sha256=QceTG6wjkaJARjYr0HYV1aPnPcpGcrkRUW-smWRr6MQ,120
24
- pycodex/prompts/permissions/approval_policy/on_failure.md,sha256=dfJjpXkpO6_ANdCKxbVJ8o4vyLxevrJWfKsGHTqtbkc,289
25
- pycodex/prompts/permissions/approval_policy/on_request.md,sha256=hVQalzh0FAdkKzw5u-N4H7-LtC9ijVDlYsh3OKsZKzo,3661
26
- pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md,sha256=mOinishp1k-wlPsaEuIOMn5GoVm_dAIsWIuEMmv2r7o,1725
27
- pycodex/prompts/permissions/approval_policy/unless_trusted.md,sha256=XHpi1Lfx1iIXFbbQ_ho_kGstA3JN-RLho291HM30UNw,247
28
- pycodex/prompts/permissions/sandbox_mode/danger_full_access.md,sha256=nZ7YHacBd3cAHKRZc9XClOOOnXJPXPh0WFBueh5C2D0,197
29
- pycodex/prompts/permissions/sandbox_mode/read_only.md,sha256=2rAPEXsBYCcuttI5j3euS-3uv_v97catIsnhxlSQSIM,173
30
- pycodex/prompts/permissions/sandbox_mode/workspace_write.md,sha256=lVN-LwrBbHqlv5yVjcd_mU8tzZW8jfKpTatJKIZu9HI,277
31
- pycodex/tools/__init__.py,sha256=-d08bLB5pI0GzYKdY7OKpvj1kPk8u7xwD0_mqFoZpgY,1857
32
- pycodex/tools/agent_tool_schemas.py,sha256=8cL9ml4So0H6IIeK0ZzjAo9bk3VeprDOSYPpIamOqEU,2048
33
- pycodex/tools/apply_patch_tool.py,sha256=wLHk5sl_UkR7iv0yqMJBMLHbGkZlMmCuX9a0yTevzps,13802
34
- pycodex/tools/base_tool.py,sha256=0aQ69ygvSYKtDq1wHXr_j7EF3NtKIfmj0A9AbB-pD4Q,5431
35
- pycodex/tools/clock_tool.py,sha256=lV4gtx51nGlbYyHRan-pvdOLzQWlJePA5o6xvWvApWg,5410
36
- pycodex/tools/close_agent_tool.py,sha256=79qr4ljPTvjnpH-Oe83yFTUGZdgNNnGoLZbpdqp4eOY,2031
37
- pycodex/tools/code_mode_manager.py,sha256=T8RHM8tyJvHWwS6AD2g9hsaOmvApMmlWuSCRfmDVMDE,19053
38
- pycodex/tools/exec_command_tool.py,sha256=KIt-pni7b2I41EMXGa1NW9YWJ1AoiWlPW_Ljlu7kLpk,4082
39
- pycodex/tools/exec_runtime.js,sha256=DR1uocKailTqNWAcJNFJuQgFFMSUzTpT_uQsRaneg2s,3643
40
- pycodex/tools/exec_tool.py,sha256=6uACLanhMxa5_5dZGO8CPztnM20O2ACANbaf9AUBS8M,2278
41
- pycodex/tools/grep_files_tool.py,sha256=7M5xLQX6RJ_45korFmwBic97zDToiuojcmi1t9s-cko,5279
42
- pycodex/tools/ipython_tool.py,sha256=7kn04RmR7GxSX3vDvFPhniEsChsoWl7_lVHyUCxouO4,4576
43
- pycodex/tools/list_dir_tool.py,sha256=XMo1_hqDKX1004OfkyTcHz_8Shz9-4ikXd05z71U2gA,5283
44
- pycodex/tools/read_file_tool.py,sha256=csClKG5Ldc38NKa2Enc3thBGxS8CU9lLAuMjmRKPgNw,9549
45
- pycodex/tools/request_permissions_tool.py,sha256=Px0gvuYp5nPMCK-NotVmURRcwHG_0C0d44_s5tEaKPo,3787
46
- pycodex/tools/request_user_input_tool.py,sha256=AF_EYdIrm-z8irHiJJzh7ubhEnDxaBdGtCprmvoh9m4,7201
47
- pycodex/tools/resume_agent_tool.py,sha256=o62xdrsRxGFdRLxEhKEny-YEcaBOeqIneImrkME35II,1614
48
- pycodex/tools/send_input_tool.py,sha256=vRg-f7LI2Sr01j1LeCPKeXto_ROQZ7bcUC5GIjx9NcI,3747
49
- pycodex/tools/shell_command_tool.py,sha256=wUw4lw8VLGIQ-7BIgyEsI0oqjj-Yr-MZn-_VDrnimAw,4202
50
- pycodex/tools/shell_tool.py,sha256=1m-Tcbn3His4ggyK5ec8Mkg6ihopqTvBd9F6fJlm6m4,4054
51
- pycodex/tools/spawn_agent_tool.py,sha256=7Me4Frjz7_fTpjMMFCvNmDHPOK2G1qTfXUr2Ugs61bU,6194
52
- pycodex/tools/unified_exec_manager.py,sha256=YM0mKGygkprV51iAgt-A2YXJCG8Fyg3wuGGHktXuuQM,13957
53
- pycodex/tools/update_plan_tool.py,sha256=UsChtCBqI1RnVnPQbByPmD2LMZXMoCwfe6NpGqP8qu0,3174
54
- pycodex/tools/view_image_tool.py,sha256=TbeO3vY0GlXCaonPGTut1TiJ91Co0I7V3qHuVku9aGc,3882
55
- pycodex/tools/wait_agent_tool.py,sha256=0Uj9-IrXe2dSvOtOMq-RAc0XzaidwFH5q7Mri3BXWyM,3135
56
- pycodex/tools/wait_tool.py,sha256=N6IrwzMp-fr1EohF-bxSwUlVs7KvZO2vV2csm3xCmS0,3205
57
- pycodex/tools/web_search_tool.py,sha256=mhiK_G6VC6K6-01KctmIpsr-BURDF8L4ZJyY6IFGlNA,964
58
- pycodex/tools/write_stdin_tool.py,sha256=K--XMp-AyEdp8yQ9EseYHsK3QrGrK4AgzOyvUk4swmw,3608
59
- pycodex/utils/__init__.py,sha256=p3jaERPxkimNDhmMIsm4glvKiazf3UMv1X-qoH5Zl3U,963
60
- pycodex/utils/async_bridge.py,sha256=d21Pjim-nsQbSG5pJddd0WaQ03CzA3w3TINWDmmjWbg,1815
61
- pycodex/utils/compactor.py,sha256=MqsJ_wcuDGPM8vndOGamLJ8j-51ivYDMlBek-Z7zZ8k,7111
62
- pycodex/utils/debug.py,sha256=JeEB5JfzYfbdG0fXlrWFmXyR1ts86fKsI_97IqgF6R0,296
63
- pycodex/utils/dotenv.py,sha256=rGKmurHjm7GdP4giyjHBPpSPv2Oi45qBqDB6HG3CnfA,1866
64
- pycodex/utils/get_env.py,sha256=5fNhcNhujOakWV6AS66rGW3jEA68WGpuE4YVXJZFE6U,7427
65
- pycodex/utils/random_ids.py,sha256=zBphjVGc7OXk9ZNExAbxRi_bk7ipyLG491qTv7hi8jM,380
66
- pycodex/utils/session_persist.py,sha256=X4SkBDWz9hIIETfZMkKrNUP4Lx7fi2agtGQtnXIypqo,20171
67
- pycodex/utils/toolcall_visualize.py,sha256=zIqmdsOfyYaLy_P4jpKnRxDsfTgYLRBx55R8m1P_lBE,24708
68
- pycodex/utils/truncation.py,sha256=B_RvfXC2-M1oKz--eQIqDLqMD0g7_J-MSQd3WD6Rh08,6110
69
- pycodex/utils/visualize.py,sha256=NfmAQdleK-yd62zJRB_oDX9SXii0wr3F3U313QlgNlU,20751
70
- responses_server/__init__.py,sha256=3yPv_zeGT7P11tTnmj5kXktISLNsNW-02MUnnbiZcb0,394
71
- responses_server/__main__.py,sha256=9SRp-Yw7ShGxc6DhSIXcDLKgGEdAVm3oBZ59rBOPjT0,62
72
- responses_server/app.py,sha256=ack2a0otiBwq_DpsFURqLMlQzcf9oJPwo8o6iJ1fuig,7885
73
- responses_server/config.py,sha256=9CR9gxIhNa5yAaH6u-jgJAS1EgweTejuP6EPx0vFC4I,2792
74
- responses_server/messages_api.py,sha256=4jlLHJjoa50qy4ZnVN4NjMXu52qnIngldw2g55qx-A0,18835
75
- responses_server/payload_processors.py,sha256=e0IqDGOtxpJElfQNvy6IiIfnjnMOOw9uaexhAdFpU1o,3546
76
- responses_server/server.py,sha256=Ko-Cqz_kW-uve091itucMklsPhEei77v-YcTjtjEdqU,2286
77
- responses_server/session_store.py,sha256=ZD3cH2aEOkWaQsu5qTzcal2mThTSFQPAhAhPUN9srgI,1115
78
- responses_server/stream_router.py,sha256=3aEPqagupgP-_fiI6MC9C5IAnf3m7RAmj11NA1MAx1E,40906
79
- responses_server/trajectory_dump.py,sha256=t9WO5h40h5MSs2bB_b6xdct84YUWQlp-5CiY_071Lhg,4006
80
- responses_server/tools/__init__.py,sha256=ivsBSEy0SBUhY-Uea5v1XMLXShkwHdCVl0id-1FwdZg,150
81
- responses_server/tools/custom_adapter.py,sha256=LxO7ldydvR-GWachDz8GKC0Q8KGGFoFPbZxM0QvxuZ0,8350
82
- responses_server/tools/web_search.py,sha256=pm4ZUiHUfxc0bGY1kEvt-BCzDrZIyP24xzPUcga2ul0,8908
83
- workspace_server/__init__.py,sha256=PRM4ONODb6hxjBUHkBD4TprE_pkTCIlT9sfftK5ic6M,866
84
- workspace_server/__main__.py,sha256=9SRp-Yw7ShGxc6DhSIXcDLKgGEdAVm3oBZ59rBOPjT0,62
85
- workspace_server/app.py,sha256=vRhnBzWRVRKxVrcLY2LLHssCaAw9tsVunCMUqE7697U,56797
86
- workspace_server/workspace.html,sha256=zfnPejztriVQ3vyYSwAX5rQnUEM17fExDhMQRDuYklA,48598
87
- workspace_server/workspaces.html,sha256=GuYlFiOm1RJINrCKncClHt24D5i7XNABiP9C0xGxBA0,15679
88
- workspace_server/workspaces.py,sha256=4sZ7YDvsOeqCqO2azJkJD5Lw5BtQFcpHol4f7ZCWfi8,20393
89
- python_codex-0.2.7.dist-info/METADATA,sha256=7YqrDbroneodIA_xL4ilQFjA5X4erzKTdOHGCgM2rYk,20124
90
- python_codex-0.2.7.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
91
- python_codex-0.2.7.dist-info/entry_points.txt,sha256=vkV2UWCtEKvQNMJuPNjt8HyBKiwp83JyqBatrBNGDp8,80
92
- python_codex-0.2.7.dist-info/licenses/LICENSE,sha256=0X8ifk312hYAORM4hlzg8wVSEXYKNmiPgWlB1YIy2Nw,10926
93
- python_codex-0.2.7.dist-info/RECORD,,