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