python-codex 0.3.3__py3-none-any.whl → 0.4.1__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.
- pycodex/__init__.py +3 -27
- pycodex/bootstrap.py +5 -45
- pycodex/cli.py +1 -14
- pycodex/context.py +1 -1
- pycodex/events.py +1 -1
- pycodex/model.py +2 -2
- pycodex/portable/__init__.py +45 -0
- pycodex/{portable.py → portable/client.py} +4 -7
- pycodex/{portable_server.py → portable/server.py} +3 -3
- pycodex/protocol.py +1 -1
- pycodex/runtime.py +2 -2
- pycodex/tools/base_tool.py +1 -1
- pycodex/tools/close_agent_tool.py +1 -1
- pycodex/tools/code_mode_manager.py +1 -1
- pycodex/tools/request_permissions_tool.py +1 -1
- pycodex/tools/resume_agent_tool.py +1 -1
- pycodex/{runtime_services.py → tools/runtime_services.py} +5 -5
- pycodex/tools/send_input_tool.py +1 -1
- pycodex/tools/spawn_agent_tool.py +1 -1
- pycodex/tools/unified_exec_manager.py +1 -1
- pycodex/tools/update_plan_tool.py +1 -1
- pycodex/tools/view_image_tool.py +5 -0
- pycodex/tools/wait_agent_tool.py +1 -1
- pycodex/utils/__init__.py +0 -4
- pycodex/utils/_aes_gcm/LICENSE +56 -0
- pycodex/utils/_aes_gcm/README.md +61 -0
- pycodex/utils/_aes_gcm/__init__.py +1 -0
- pycodex/utils/_aes_gcm/aes.py +175 -0
- pycodex/utils/_aes_gcm/gcm.py +73 -0
- pycodex/utils/_aes_gcm/source-sha256.json +4 -0
- pycodex/utils/async_bridge.py +3 -4
- pycodex/{compat.py → utils/compat.py} +2 -0
- pycodex/utils/crypto.py +35 -0
- pycodex/utils/debug.py +24 -0
- pycodex/{doctor.py → utils/doctor.py} +3 -3
- pycodex/utils/image_utils.py +3 -2
- pycodex/{model_metadata.py → utils/model_metadata.py} +2 -2
- pycodex/utils/session_persist.py +28 -0
- {python_codex-0.3.3.dist-info → python_codex-0.4.1.dist-info}/METADATA +124 -42
- python_codex-0.4.1.dist-info/RECORD +90 -0
- {python_codex-0.3.3.dist-info → python_codex-0.4.1.dist-info}/entry_points.txt +0 -1
- responses_server/app.py +28 -15
- pycodex/feishu_card.py +0 -793
- pycodex/feishu_link.py +0 -440
- pycodex/tools/ipython_tool.py +0 -142
- python_codex-0.3.3.dist-info/RECORD +0 -98
- workspace_server/__init__.py +0 -39
- workspace_server/__main__.py +0 -4
- workspace_server/app.py +0 -1906
- workspace_server/content_views.LICENSE.txt +0 -470
- workspace_server/content_views.css +0 -1
- workspace_server/content_views.mjs +0 -25
- workspace_server/editor.css +0 -1
- workspace_server/editor.mjs +0 -1260
- workspace_server/owned_process.py +0 -27
- workspace_server/workspace.html +0 -2267
- workspace_server/workspace_views.py +0 -533
- workspace_server/workspaces.html +0 -550
- workspace_server/workspaces.py +0 -632
- {python_codex-0.3.3.dist-info → python_codex-0.4.1.dist-info}/WHEEL +0 -0
- {python_codex-0.3.3.dist-info → python_codex-0.4.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-codex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
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
|
|
7
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
8
|
Requires-Dist: importlib-metadata>=4.8.3; python_version < '3.8'
|
|
11
9
|
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
10
|
Requires-Dist: prompt-toolkit>=3.0.36
|
|
15
|
-
Requires-Dist: pycryptodomex>=3.20
|
|
16
11
|
Requires-Dist: pyyaml>=6.0
|
|
17
12
|
Requires-Dist: requests>=2.27.1
|
|
13
|
+
Requires-Dist: starlette<0.20,>=0.19.1; python_version < '3.7'
|
|
14
|
+
Requires-Dist: starlette>=0.19.1; python_version >= '3.7'
|
|
18
15
|
Requires-Dist: tomli<2,>=1.2.3; python_version < '3.11'
|
|
19
16
|
Requires-Dist: typing-extensions>=4.1.1; python_version < '3.8'
|
|
20
17
|
Requires-Dist: uvicorn<0.17,>=0.16.0; python_version < '3.7'
|
|
@@ -25,6 +22,8 @@ Description-Content-Type: text/markdown
|
|
|
25
22
|
|
|
26
23
|
English README. Chinese version: `README_ZH.md`
|
|
27
24
|
|
|
25
|
+
0.4.0 core/workspace package split and dependency cleanup: [release notes](docs/RELEASE_0.4.0.md).
|
|
26
|
+
|
|
28
27
|
0.3.3 workspace viewers and reasoning stream fix: [release notes](docs/RELEASE_0.3.3.md).
|
|
29
28
|
|
|
30
29
|
0.3.2 startup fixes: [release notes](docs/RELEASE_0.3.2.md).
|
|
@@ -33,15 +32,37 @@ English README. Chinese version: `README_ZH.md`
|
|
|
33
32
|
|
|
34
33
|
PyPI distributions:
|
|
35
34
|
|
|
36
|
-
-
|
|
37
|
-
- Workspace
|
|
35
|
+
- Core package: `python-codex`
|
|
36
|
+
- Workspace and integrations: `pycodex-ws`
|
|
38
37
|
|
|
39
38
|
The import path remains `pycodex`; the CLI commands are `pycodex` and
|
|
40
39
|
`pycodex-ws`.
|
|
41
40
|
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
`python-codex` contains the Agent, runtime, CLI, standard tools, Responses
|
|
42
|
+
compatibility server and portable storage support. `pycodex-ws` depends on the
|
|
43
|
+
exact matching core version and contains the browser workspace, viewer assets
|
|
44
|
+
and optional Feishu integration. It owns the
|
|
45
|
+
`workspace_server` and `pycodex_ws` modules and the `pycodex-ws` command.
|
|
46
|
+
|
|
47
|
+
The Feishu SDK is not installed automatically. Install it in the workspace's
|
|
48
|
+
Python environment with `python3 -m pip install lark-oapi` to enable `/link`.
|
|
49
|
+
If `lark_oapi` cannot be imported, `/link` reports that it is unavailable.
|
|
50
|
+
|
|
51
|
+
Core does not require Pillow. Without it, `view_image` sends the original image
|
|
52
|
+
bytes with `detail="original"`, including when `high` is requested. With Pillow
|
|
53
|
+
installed, the default path retains resizing to a maximum dimension of 2048.
|
|
54
|
+
`pycodex-ws` installs Pillow for image preview validation.
|
|
55
|
+
|
|
56
|
+
Portable encryption uses a bundled pure Python AES-GCM subset of pyaes and
|
|
57
|
+
tlslite-ng, under MIT and BSD licenses. Core does not require a crypto package
|
|
58
|
+
or compiler and ships a `py3-none-any` wheel. Existing `PCX1` bundles and call
|
|
59
|
+
tokens remain compatible; large bundles take longer to encrypt and decrypt.
|
|
60
|
+
See the [source notes](pycodex/utils/_aes_gcm/README.md).
|
|
61
|
+
|
|
62
|
+
The Responses compatibility server and workspace HTTP server use Starlette
|
|
63
|
+
and Uvicorn directly. Neither package requires FastAPI, Pydantic or
|
|
64
|
+
`pydantic-core`. Python 3.6 uses Starlette 0.19.x; newer interpreters resolve
|
|
65
|
+
a compatible Starlette release through its Python version metadata.
|
|
45
66
|
|
|
46
67
|
This repository extracts the core Codex agent loop from upstream Codex
|
|
47
68
|
(`https://github.com/openai/codex`) into a deliberately small Python version,
|
|
@@ -61,16 +82,17 @@ Relevant Rust reference points:
|
|
|
61
82
|
|
|
62
83
|
## Quick Start
|
|
63
84
|
|
|
64
|
-
Install the
|
|
85
|
+
Install the core CLI, or install the workspace package for the browser frontend:
|
|
65
86
|
|
|
66
87
|
```bash
|
|
67
88
|
python3 -m pip install python-codex
|
|
68
89
|
python3 -m pip install pycodex-ws
|
|
69
90
|
```
|
|
70
91
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
92
|
+
The core supports Python 3.6.2 or newer. The workspace package requires Python
|
|
93
|
+
3.7 or newer. Commands are installed into
|
|
94
|
+
that interpreter's scripts directory. On a machine with multiple Python
|
|
95
|
+
installations, select the same interpreter explicitly for startup:
|
|
74
96
|
|
|
75
97
|
```bash
|
|
76
98
|
python3 -m pycodex
|
|
@@ -81,10 +103,14 @@ If `pycodex` is missing from `PATH` or resolves to an older installation, use th
|
|
|
81
103
|
module entry points. `python3 -m pip --version` shows which Python environment
|
|
82
104
|
received the installation.
|
|
83
105
|
|
|
106
|
+
For an existing Web installation, use `python3 -m pip install --upgrade pycodex-ws`
|
|
107
|
+
to upgrade the workspace and its matching core together. Installing only
|
|
108
|
+
`python-codex` provides the CLI and core API.
|
|
109
|
+
|
|
84
110
|
For development from this repository, install dependencies first:
|
|
85
111
|
|
|
86
112
|
```bash
|
|
87
|
-
uv sync
|
|
113
|
+
uv sync --dev
|
|
88
114
|
```
|
|
89
115
|
|
|
90
116
|
Try the real entry points:
|
|
@@ -94,8 +120,22 @@ uv run pycodex "Reply with exactly OK."
|
|
|
94
120
|
uv run pycodex
|
|
95
121
|
```
|
|
96
122
|
|
|
97
|
-
|
|
98
|
-
|
|
123
|
+
Tests are split by package. `uv run --dev pytest` runs both suites;
|
|
124
|
+
`uv run --dev pytest packages/pycodex-ws/tests` runs workspace and integration
|
|
125
|
+
tests. To check core without installing workspace, use a separate
|
|
126
|
+
environment:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv sync --group test
|
|
130
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv run --group test pytest tests
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See [test environments and coverage](tests/TESTS.md). Core tests support Python
|
|
134
|
+
3.6.2+; workspace tests require Python 3.7+.
|
|
135
|
+
|
|
136
|
+
A VS Code frontend is available in [`packages/pycodex-ws/extensions/vscode`](packages/pycodex-ws/extensions/vscode/README.md).
|
|
137
|
+
It belongs to the workspace frontend and is packaged separately as a VSIX.
|
|
138
|
+
It reuses an existing `pycodex-ws>=0.4.0` installation. On first use, missing
|
|
99
139
|
or older backends are installed/upgraded with pip in the selected Python
|
|
100
140
|
environment on the workspace host; compatible versions need no network check.
|
|
101
141
|
It starts a dedicated `pycodex-ws` workspace on the project's host and opens a
|
|
@@ -143,19 +183,35 @@ nailing the core tool-augmented reasoning loop first.
|
|
|
143
183
|
|
|
144
184
|
## Layout
|
|
145
185
|
|
|
186
|
+
The top level of `pycodex/` contains the core components and package entry points.
|
|
187
|
+
Supporting services live in `tools/`, `portable/` and `utils/`.
|
|
188
|
+
|
|
189
|
+
- `pycodex/agent.py`: inner turn loop
|
|
190
|
+
- `pycodex/runtime.py`: session commands, submission queues and frontend event subscriptions
|
|
191
|
+
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
192
|
+
- `pycodex/context.py`: configuration, prompt assembly and instruction loading
|
|
146
193
|
- `pycodex/protocol.py`: minimal conversation item / prompt protocol
|
|
147
194
|
- `pycodex/events.py`: typed events, plain-text views and stateful presentation
|
|
148
|
-
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
149
|
-
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
150
|
-
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
151
|
-
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
152
195
|
- `pycodex/bootstrap.py`: frontend-independent model, tools, Agent and session assembly
|
|
196
|
+
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
153
197
|
- `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
|
|
154
|
-
- `pycodex/tools
|
|
155
|
-
- `pycodex/
|
|
156
|
-
- `pycodex/
|
|
157
|
-
- `
|
|
158
|
-
- `
|
|
198
|
+
- `pycodex/tools/runtime_services.py`: plan, sub-agent, user-input and permissions services
|
|
199
|
+
- `pycodex/tools/`: concrete tools and their execution managers
|
|
200
|
+
- `pycodex/portable/`: Codex home storage client and server, both included in core
|
|
201
|
+
- `pycodex/utils/compat.py`: supported-Python compatibility helpers
|
|
202
|
+
- `pycodex/utils/doctor.py`: configuration and connectivity diagnostics
|
|
203
|
+
- `pycodex/utils/model_metadata.py`: vendored model metadata lookup
|
|
204
|
+
- `pycodex/utils/debug.py`: debug paths and the `pycodex.debug()` implementation
|
|
205
|
+
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
206
|
+
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
207
|
+
- `pycodex/prompts/`: vendored prompts and model metadata
|
|
208
|
+
- `packages/pycodex-ws/workspace_server/`: Web board, API and file/diff viewers
|
|
209
|
+
- `packages/pycodex-ws/pycodex_ws/`: Feishu and workspace assembly
|
|
210
|
+
- `packages/pycodex-ws/extensions/vscode/`: workspace's VS Code frontend, built separately as a VSIX
|
|
211
|
+
- `tests/`: core tests
|
|
212
|
+
- `packages/pycodex-ws/tests/`: workspace and cross-frontend integration tests
|
|
213
|
+
|
|
214
|
+
See [package layout and import paths](docs/RUNTIME.md#package-layout).
|
|
159
215
|
|
|
160
216
|
## Current Alignment Status
|
|
161
217
|
|
|
@@ -266,7 +322,7 @@ Current behavior:
|
|
|
266
322
|
- with an argv prompt or piped stdin, run a single turn
|
|
267
323
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
268
324
|
workspace with a board pane and a pycodex session pane
|
|
269
|
-
- the left pane is the board, containing
|
|
325
|
+
- the left pane is the board, containing an optional live HTML Canvas tab and closable read-only file/diff tabs that
|
|
270
326
|
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
271
327
|
horizontally.
|
|
272
328
|
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
@@ -285,6 +341,14 @@ Current behavior:
|
|
|
285
341
|
hover titles retain the complete paths and revisions. Text,
|
|
286
342
|
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
287
343
|
provides syntax highlighting, find, folding and character-level diffs.
|
|
344
|
+
Right-click code and choose **Insert into chat**, or select text and use the
|
|
345
|
+
toolbar button, to insert context at the current chat draft's cursor.
|
|
346
|
+
Context appears as a separate block among your words. Click it to edit or
|
|
347
|
+
remove it; Backspace and Delete also remove a block as one element.
|
|
348
|
+
Context identifies the full view label, including both revisions of a diff.
|
|
349
|
+
Selections include only the selected text and range; otherwise it records the
|
|
350
|
+
cursor location. Diff context also identifies the selected side.
|
|
351
|
+
The draft stays editable until you send it.
|
|
288
352
|
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
289
353
|
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
290
354
|
when supported and revalidate cached content with ETags.
|
|
@@ -353,28 +417,38 @@ Current behavior:
|
|
|
353
417
|
non-persisted follow-up session and submits the file contents as the next
|
|
354
418
|
user instruction; this is intended for side-effect follow-ups such as
|
|
355
419
|
Feishu notifications
|
|
356
|
-
- `/link <feishu-email|open_id|chat_id>`
|
|
357
|
-
|
|
420
|
+
- `/link <feishu-email|open_id|chat_id>` in a workspace session attaches it
|
|
421
|
+
to a Feishu card when the optional `lark-oapi` SDK can be imported;
|
|
422
|
+
multiple sessions in the same workspace process share
|
|
358
423
|
one Feishu long-connection listener and route card actions by message id
|
|
359
424
|
- Feishu user OAuth stores its refresh token only in
|
|
360
425
|
`~/.codex/.feishu_refresh_token` (mode `0600`). Run
|
|
361
|
-
`
|
|
362
|
-
|
|
426
|
+
`python3 -m pycodex_ws.feishu_oauth` after installing `pycodex-ws` to authorize.
|
|
427
|
+
From this repository, use `env -u VIRTUAL_ENV uv run --dev python -m pycodex_ws.feishu_oauth`.
|
|
428
|
+
App credentials can stay in `~/.codex/.env`. Each refresh reads
|
|
363
429
|
the latest token from the dedicated file and saves its replacement there.
|
|
364
430
|
`FEISHU_REFRESH_TOKEN` in `.env` or the environment is no longer used and
|
|
365
431
|
can be removed. Refresh is triggered by API calls, with no idle keepalive.
|
|
366
432
|
- `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
|
|
367
433
|
one process. The JSON file can be either a list or
|
|
368
|
-
`{"workspaces": [...]}`; each entry uses `
|
|
369
|
-
display/URL `id
|
|
370
|
-
`
|
|
371
|
-
|
|
434
|
+
`{"workspaces": [...]}`; each entry uses `state_path` and `work_dir`, with optional
|
|
435
|
+
display/URL `id` and `enable_board` (default `true`), and is exposed at `/w/<id>/`.
|
|
436
|
+
`state_path` is a filename prefix: `/data/demo` uses
|
|
437
|
+
`/data/demo.pycodex-ws.json` for the session index,
|
|
438
|
+
`/data/demo.pycodex-views.json` for file views and `/data/demo.html` for Canvas.
|
|
439
|
+
Suffixes are appended, so prefixes containing dots remain distinct.
|
|
440
|
+
The resolved `state_path` is the workspace identity; duplicates are rejected
|
|
441
|
+
regardless of name or Canvas setting. Relative `state_path` and `work_dir` paths
|
|
372
442
|
resolve from the config file directory. The root path `/` shows a workspaces
|
|
373
|
-
management page with
|
|
374
|
-
`
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
443
|
+
management page with create/delete controls; omitted names become `workspace-1`,
|
|
444
|
+
`workspace-2`, etc. Omitted `state_path` when creating a workspace generates a
|
|
445
|
+
writable `/tmp/pcws-*` prefix. `enable_board: false` hides Canvas and disables its
|
|
446
|
+
routes, polling and context injection; sessions and file views still persist.
|
|
447
|
+
Existing `board: "demo.html"` and `board: false` configurations load with their
|
|
448
|
+
original state paths and are saved in the new format. See the
|
|
449
|
+
[workspace configuration example](packages/pycodex-ws/README.md).
|
|
450
|
+
Add/delete actions and later session-state saves refresh the JSON file.
|
|
451
|
+
Board HTML can reference local
|
|
378
452
|
images beside the board (including nested paths) with relative URLs; only
|
|
379
453
|
`image/*` files contained by the board directory are served.
|
|
380
454
|
Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
|
|
@@ -466,6 +540,13 @@ pycodex doctor --json
|
|
|
466
540
|
`Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
|
|
467
541
|
fresh machine, container, or debug image.
|
|
468
542
|
|
|
543
|
+
The storage client and server are both included in `python-codex`. To start a
|
|
544
|
+
local storage service, run this in a separate terminal:
|
|
545
|
+
|
|
546
|
+
```bash
|
|
547
|
+
python -m pycodex.portable.server --root .tmp/pycodex_storage --host 127.0.0.1 --port 5577
|
|
548
|
+
```
|
|
549
|
+
|
|
469
550
|
Use it like this:
|
|
470
551
|
|
|
471
552
|
```bash
|
|
@@ -659,7 +740,8 @@ CLI, Web and Feishu all use `AgentRuntime.submit_input`: not just `/model`
|
|
|
659
740
|
and `/resume`, but every session command, steer/queue admission, interactive
|
|
660
741
|
questions and permissions, state notifications and shutdown. Frontends only
|
|
661
742
|
adapt input and render events. Web no longer imports or runs the CLI shell.
|
|
662
|
-
|
|
743
|
+
Workspace assembly uses `pycodex_ws.build_runtime()` to add
|
|
744
|
+
`/link` and `/unlink`; `pycodex.bootstrap.build_runtime()` provides core commands.
|
|
663
745
|
|
|
664
746
|
```python
|
|
665
747
|
from pycodex.bootstrap import build_agent, build_model, build_runtime
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
pycodex/__init__.py,sha256=fHEyhylULeRo-5xEnl-UxT5ZpBzbFzRW7vLwdy_7oxU,2660
|
|
2
|
+
pycodex/__main__.py,sha256=MHKZ_ae3fSLGTLUUMOx15fWdeOnJSHhq-zslRP5F5Lc,79
|
|
3
|
+
pycodex/agent.py,sha256=zCIG2DV0oQntLXHFj8FVRkgBp5TCC0YJ7sz0lni9J1s,21177
|
|
4
|
+
pycodex/bootstrap.py,sha256=U1X5kwORpS5JnPk9HhIiOVWPQzDLlk_ro_cY2knwL8I,12421
|
|
5
|
+
pycodex/cli.py,sha256=MLvXpVwrb-HJuVWmPFmNMTR-4cqR3X08ZfAevYlVSQI,12646
|
|
6
|
+
pycodex/context.py,sha256=yfNY2alT3caQQwhay47pSSrGUbgEAcLKhTVaZqtQ4yU,26610
|
|
7
|
+
pycodex/events.py,sha256=wysYXHLiCHzW3k1yaAuoRTw90NRhHPa3jtY0ANGOqH4,29694
|
|
8
|
+
pycodex/model.py,sha256=3mWXTN-oV2Q50SgQYac45WT5Qk2NSmPTxSWyF-w8TRg,44583
|
|
9
|
+
pycodex/protocol.py,sha256=uzUz_06iA4m9vAoqZeCGiJ4SocKZDzOfCJUU4Bpt5dI,12033
|
|
10
|
+
pycodex/runtime.py,sha256=3wHKoNjwzOgE6dXeT6Vbpu6Nf7RWqIfHwrjsmOnk81I,23814
|
|
11
|
+
pycodex/portable/__init__.py,sha256=FmspRPmblYuZIVXMpXaxE1uosCaz2hZDpkpOzxDJQic,1084
|
|
12
|
+
pycodex/portable/client.py,sha256=DOxzZljVfN1ynmhqrChX7NsT1IFSFVKzEn1J3wvV3XQ,16038
|
|
13
|
+
pycodex/portable/server.py,sha256=w4YD71Sxb7MD5q57GPuIgx7AoicTv0R9xzX2kAaibPA,7503
|
|
14
|
+
pycodex/prompts/default_base_instructions.md,sha256=D65mcj6bo4CDvVom-D9cbJRJVNquo0NghKt164_fRsg,20923
|
|
15
|
+
pycodex/prompts/models.json,sha256=u-bS5xtI7ZHbrG_nbzrt-xmp5RtQT6YL8PHbd_4XZB4,397650
|
|
16
|
+
pycodex/prompts/permissions/approval_policy/never.md,sha256=QceTG6wjkaJARjYr0HYV1aPnPcpGcrkRUW-smWRr6MQ,120
|
|
17
|
+
pycodex/prompts/permissions/approval_policy/on_failure.md,sha256=dfJjpXkpO6_ANdCKxbVJ8o4vyLxevrJWfKsGHTqtbkc,289
|
|
18
|
+
pycodex/prompts/permissions/approval_policy/on_request.md,sha256=hVQalzh0FAdkKzw5u-N4H7-LtC9ijVDlYsh3OKsZKzo,3661
|
|
19
|
+
pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md,sha256=mOinishp1k-wlPsaEuIOMn5GoVm_dAIsWIuEMmv2r7o,1725
|
|
20
|
+
pycodex/prompts/permissions/approval_policy/unless_trusted.md,sha256=XHpi1Lfx1iIXFbbQ_ho_kGstA3JN-RLho291HM30UNw,247
|
|
21
|
+
pycodex/prompts/permissions/sandbox_mode/danger_full_access.md,sha256=nZ7YHacBd3cAHKRZc9XClOOOnXJPXPh0WFBueh5C2D0,197
|
|
22
|
+
pycodex/prompts/permissions/sandbox_mode/read_only.md,sha256=2rAPEXsBYCcuttI5j3euS-3uv_v97catIsnhxlSQSIM,173
|
|
23
|
+
pycodex/prompts/permissions/sandbox_mode/workspace_write.md,sha256=lVN-LwrBbHqlv5yVjcd_mU8tzZW8jfKpTatJKIZu9HI,277
|
|
24
|
+
pycodex/tools/__init__.py,sha256=UYwmsX_Ckw_YaYQ6TYhUU6w5pxi2qzZoTrq6BAgNErM,1857
|
|
25
|
+
pycodex/tools/agent_tool_schemas.py,sha256=8cL9ml4So0H6IIeK0ZzjAo9bk3VeprDOSYPpIamOqEU,2048
|
|
26
|
+
pycodex/tools/apply_patch_tool.py,sha256=t8XFCGZ7q-s9C1Ty6qkReBRk-QD3ONvcKXLAz9djKRY,13956
|
|
27
|
+
pycodex/tools/base_tool.py,sha256=Oqe-0RgH3mz70YckgBFD-tdvNJ9TQXrb0tuMbdy3bfc,6477
|
|
28
|
+
pycodex/tools/clock_tool.py,sha256=2_RYbBEw4V9_f1L-qZl3hhJ6XNPM_gBDmOlCh1cCAjo,6575
|
|
29
|
+
pycodex/tools/close_agent_tool.py,sha256=uIbCjsQx9MLkjVYheS8ZVf5VVPbC6Iviwox4pneJpmI,2030
|
|
30
|
+
pycodex/tools/code_mode_manager.py,sha256=HUgtXxj3hGj2i4_tsToHLr8mGTV8uIob9vtYAZeLnQc,19166
|
|
31
|
+
pycodex/tools/exec_command_tool.py,sha256=iqRiKaaX-AjG6LjATAMOakHIP0gpCWCj2o8af_8eAiQ,4464
|
|
32
|
+
pycodex/tools/exec_runtime.js,sha256=DR1uocKailTqNWAcJNFJuQgFFMSUzTpT_uQsRaneg2s,3643
|
|
33
|
+
pycodex/tools/exec_tool.py,sha256=tuC21rlhP8CPSYml4XnSDSRV0UPGkQ6aHj0DLIoOOvM,2274
|
|
34
|
+
pycodex/tools/grep_files_tool.py,sha256=Ysw68VKI9OEvUH5haYx8FWuthkHykc1wskbuzjj8gTk,5293
|
|
35
|
+
pycodex/tools/list_dir_tool.py,sha256=_U6ouRcVbGHT5mChVyUsiMgDGrFK7EFMFaspPLAHtH8,5337
|
|
36
|
+
pycodex/tools/read_file_tool.py,sha256=YK__uhIVldBjAQega5S_ZuZU5jgP_kLOwr-YhjAmRo4,9735
|
|
37
|
+
pycodex/tools/request_permissions_tool.py,sha256=nEt3_uw3lmFXyydqcN3PxuKwrEvaRPtfjA_U8nikCtU,3978
|
|
38
|
+
pycodex/tools/request_user_input_tool.py,sha256=_7siHF2p3KiNDFwsTqKKIUw2kPCXMzLaR12PkZ1wdIQ,4050
|
|
39
|
+
pycodex/tools/resume_agent_tool.py,sha256=bZvXEUNdc1RVD2N5Msjv63Rni62FQk4gj9LAXK1Vsy8,1613
|
|
40
|
+
pycodex/tools/runtime_services.py,sha256=vZHIHGAeTA-DoEoHulAKvjcfHLXkuK1t3T0Mob9VJ8A,15044
|
|
41
|
+
pycodex/tools/send_input_tool.py,sha256=w63SKM05_e3oXvdaBtL-hk941TvkWKuTUDEqTSyWEMQ,3761
|
|
42
|
+
pycodex/tools/shell_command_tool.py,sha256=US63I5xiV5zfO1Oox2yHUg7F6XoKzmyxtohfaQIsmrw,4216
|
|
43
|
+
pycodex/tools/shell_tool.py,sha256=lqFH2XosfBg7yQKhpB7i4vLGz9sNQtEZihD0rjsmBCQ,4068
|
|
44
|
+
pycodex/tools/spawn_agent_tool.py,sha256=Jx5jYpxsH_CQ3BLkXYPZuIINW5deO_zY8tyw8kZpreY,6208
|
|
45
|
+
pycodex/tools/unified_exec_manager.py,sha256=XPN6PgBnjZ5WFZATNIqpWKUAuw8HMMD7mlfHJQjJQZM,14544
|
|
46
|
+
pycodex/tools/update_plan_tool.py,sha256=xwrSrerw5qfkbFc9Ltx1OZEmD__CWtryOy3UhL0-Jp4,3198
|
|
47
|
+
pycodex/tools/view_image_tool.py,sha256=SCoiIHaQ51oYjYX69MRxjAK9b1P6_wOCIuZqzsC2rj8,4082
|
|
48
|
+
pycodex/tools/wait_agent_tool.py,sha256=9Os6RzzCxIU5KJI5l6MzdwO6QKLNxLFwFXGeDMfYlP4,3828
|
|
49
|
+
pycodex/tools/wait_tool.py,sha256=0_OO_DvMsBhG3oDKZePTOjZTBq1lmWntXAzqIqvebdA,3206
|
|
50
|
+
pycodex/tools/web_search_tool.py,sha256=3ao1IvJw7MwcP35UKLbqrM-nlm5Z-UUFVdEzkJYOV1o,988
|
|
51
|
+
pycodex/tools/write_stdin_tool.py,sha256=jvBDchLLmoDITd7g-ZVeEVXHRhWKkmnjM5laL-53FOM,3609
|
|
52
|
+
pycodex/utils/__init__.py,sha256=ih_KyZ2_bajR5YlZ1QMTWOHnuEBda-S3gQ7PwnBtLZQ,453
|
|
53
|
+
pycodex/utils/async_bridge.py,sha256=BXsKTUTUvUtPJnItQlulFRdV7opdKKDlsKLdtVTYshs,1732
|
|
54
|
+
pycodex/utils/compactor.py,sha256=0tlszw1n54aMEGH6sL1U1dEgFSU5ioYL2NI5uSvHSiM,6119
|
|
55
|
+
pycodex/utils/compat.py,sha256=QxcI4AQuUD-gE2494qPGezgm0OIX98qSHdAiof1JrlU,3550
|
|
56
|
+
pycodex/utils/crypto.py,sha256=HRCXF26Ft3S8CG2X0YpZwa8GMU9YJ0Loo8Q9PMPMcNw,1249
|
|
57
|
+
pycodex/utils/debug.py,sha256=5XMpWpwFSm6woyx6RGXvN2qL0afRtTQbwlOAv-LotTw,913
|
|
58
|
+
pycodex/utils/doctor.py,sha256=fI66oQqB5zNL7aEpFbiHnzhELyp9XydwMyAGznw5YSE,10616
|
|
59
|
+
pycodex/utils/dotenv.py,sha256=h7ZgvqpEswetqjhtwfiaHyokAHwNKPakizTAHPHz5Ds,1865
|
|
60
|
+
pycodex/utils/event_helpers.py,sha256=pnxL0-nBC7cnOheHPCIfkHqJjMbkJg3C348_EzAVhFA,6342
|
|
61
|
+
pycodex/utils/get_env.py,sha256=L4S8h84tkgxZKvrxY7ezTgePbXepG-yIigUTKeY6uuE,6094
|
|
62
|
+
pycodex/utils/image_utils.py,sha256=OUzUs0Cow4L8Z2np0EBeEUotAqqsCmRmhrV8AxZUXRw,2460
|
|
63
|
+
pycodex/utils/model_metadata.py,sha256=uK3iI4yC7Ge7yN4I1_gQYalQ4MYKddz2qMwsmQb-P80,1337
|
|
64
|
+
pycodex/utils/random_ids.py,sha256=jLTxZZ0MBbRdQOFDFWGVRjWzIo6FKSQ5ADXbQSLPp1s,379
|
|
65
|
+
pycodex/utils/session_persist.py,sha256=_7Lz1jO7D0Qf16UVuZBKU_Si-k_cUVinnLMlsd1jVj4,23600
|
|
66
|
+
pycodex/utils/truncation.py,sha256=5D6vAorT8EgXgjd7ASwtraAyIZdlCR-w5jKZqJxDzho,5446
|
|
67
|
+
pycodex/utils/_aes_gcm/LICENSE,sha256=KvdHagY3sYIK34GldJaRi34sNnGwMVJIIoDhbC9MRu8,2805
|
|
68
|
+
pycodex/utils/_aes_gcm/README.md,sha256=D9XGeewCgU2PVqJCO6WusUs0Mw2FbMnABCqaVktqCnE,3045
|
|
69
|
+
pycodex/utils/_aes_gcm/__init__.py,sha256=p0U1CVy6dQBDAfGvSYG0opn6iP2VGF5rqUUM-mNLJxU,70
|
|
70
|
+
pycodex/utils/_aes_gcm/aes.py,sha256=12p_5O7gX-e-LQ08nNe2CBdP_H4eX3J84LlXaVr9i8A,9269
|
|
71
|
+
pycodex/utils/_aes_gcm/gcm.py,sha256=Z8fYHpnLpqJyTPmjDOZtryqe0xmT_93vscNuJe5ZY-w,2762
|
|
72
|
+
pycodex/utils/_aes_gcm/source-sha256.json,sha256=g9uPWXuA0D9Wq9EGnduyiVanTgi8QWRFW-9T69FG-fc,215
|
|
73
|
+
responses_server/__init__.py,sha256=sx9C88YWqmehASZy24FUMqT14A36doM_rj0MIZtQ9iQ,377
|
|
74
|
+
responses_server/__main__.py,sha256=876xZTqhPeDBD2GKKr8pKX33Af8PhFTosAI8bYQsFgQ,61
|
|
75
|
+
responses_server/app.py,sha256=PE-jWn_hmL5os1xsVL81KwU0kDZHOkZoVdSOK-7x3xQ,8400
|
|
76
|
+
responses_server/config.py,sha256=sCJYGisPHW9Uup26-R9Zv0o9W_kRVt-ETc2MFCVjG90,2795
|
|
77
|
+
responses_server/messages_api.py,sha256=ialAYTMmN0y-uxQB3Y51ukq-kvkSVO84WVLXaqLsKw0,18775
|
|
78
|
+
responses_server/payload_processors.py,sha256=dqPwqHD-FhyiIwjzFEMf2wCtQDxkRyerZzbdqnH1aDE,3561
|
|
79
|
+
responses_server/server.py,sha256=k4DbsOYkaHHcy38uF9u_QXahJC1cplKsTu-MdC3DCIs,2286
|
|
80
|
+
responses_server/session_store.py,sha256=nwGxQL6nUVKnDVeDHz8IzqNQ7dWk8Ybf0URekOHdxTo,1133
|
|
81
|
+
responses_server/stream_router.py,sha256=TQX2-8uOGad3TBJnRu9SOtDaHBHjYwE-WERYz6rcuo8,46274
|
|
82
|
+
responses_server/trajectory_dump.py,sha256=5_Wy6tslszrqx3j1JeP_boyTbzIicKy8No84PzMnmHk,5111
|
|
83
|
+
responses_server/tools/__init__.py,sha256=ivsBSEy0SBUhY-Uea5v1XMLXShkwHdCVl0id-1FwdZg,150
|
|
84
|
+
responses_server/tools/custom_adapter.py,sha256=SnIiNUdomff3APtTriURAC9YCeEdhCDjzGMEYusfUdk,8340
|
|
85
|
+
responses_server/tools/web_search.py,sha256=pnKH9JyTScRehWpZS3HpXRvjWsQvC0QZqxjEOCT4ndg,8936
|
|
86
|
+
python_codex-0.4.1.dist-info/METADATA,sha256=oeFno9KHzkjQBQWXIQILZpJBRydqouzo7BqtpoKh9_g,47510
|
|
87
|
+
python_codex-0.4.1.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
|
|
88
|
+
python_codex-0.4.1.dist-info/entry_points.txt,sha256=sNUVakoVuTrzJH505ZgRTQxmtRRPUHV_EH0i6EbYTyM,45
|
|
89
|
+
python_codex-0.4.1.dist-info/licenses/LICENSE,sha256=0X8ifk312hYAORM4hlzg8wVSEXYKNmiPgWlB1YIy2Nw,10926
|
|
90
|
+
python_codex-0.4.1.dist-info/RECORD,,
|
responses_server/app.py
CHANGED
|
@@ -9,8 +9,11 @@ from dataclasses import replace
|
|
|
9
9
|
from typing import Iterator
|
|
10
10
|
|
|
11
11
|
import uvicorn
|
|
12
|
-
from
|
|
13
|
-
from
|
|
12
|
+
from starlette.applications import Starlette
|
|
13
|
+
from starlette.exceptions import HTTPException
|
|
14
|
+
from starlette.requests import Request
|
|
15
|
+
from starlette.responses import JSONResponse, StreamingResponse
|
|
16
|
+
from starlette.routing import Route
|
|
14
17
|
|
|
15
18
|
from .config import CompatServerConfig
|
|
16
19
|
from .server import ResponseServer
|
|
@@ -22,6 +25,12 @@ def _run_uvicorn_server(server) -> "None":
|
|
|
22
25
|
server.run()
|
|
23
26
|
|
|
24
27
|
|
|
28
|
+
async def _http_exception_response(request: "Request", exc: "HTTPException"):
|
|
29
|
+
return JSONResponse(
|
|
30
|
+
{"detail": exc.detail}, status_code=exc.status_code, headers=exc.headers
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
25
34
|
def _format_sse_event(
|
|
26
35
|
event_name: "str", payload: "typing.Dict[str, object]"
|
|
27
36
|
) -> "bytes":
|
|
@@ -113,33 +122,25 @@ class ManagedResponseServer:
|
|
|
113
122
|
config: "CompatServerConfig",
|
|
114
123
|
session_store=None,
|
|
115
124
|
stream_router=None,
|
|
116
|
-
) -> "
|
|
125
|
+
) -> "Starlette":
|
|
117
126
|
response_server = ResponseServer(
|
|
118
127
|
config,
|
|
119
128
|
session_store=session_store,
|
|
120
129
|
stream_router=stream_router,
|
|
121
130
|
)
|
|
122
|
-
app = FastAPI(title="ResponsesCompat", version="0.1.0")
|
|
123
|
-
app.state.response_server = response_server
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
async def health() -> "typing.Dict[str, bool]":
|
|
128
|
-
return {"ok": True}
|
|
132
|
+
async def health(request: "Request"):
|
|
133
|
+
return JSONResponse({"ok": True})
|
|
129
134
|
|
|
130
|
-
|
|
131
|
-
@app.get("/v1/models")
|
|
132
|
-
async def list_models():
|
|
135
|
+
async def list_models(request: "Request"):
|
|
133
136
|
try:
|
|
134
|
-
return response_server.list_models()
|
|
137
|
+
return JSONResponse(response_server.list_models())
|
|
135
138
|
except OutcommingChatError as exc:
|
|
136
139
|
return JSONResponse(
|
|
137
140
|
{"error": {"message": str(exc)}},
|
|
138
141
|
status_code=502,
|
|
139
142
|
)
|
|
140
143
|
|
|
141
|
-
@app.post("/responses")
|
|
142
|
-
@app.post("/v1/responses")
|
|
143
144
|
async def responses(request: "Request"):
|
|
144
145
|
try:
|
|
145
146
|
request_body = await request.json()
|
|
@@ -174,6 +175,18 @@ class ManagedResponseServer:
|
|
|
174
175
|
},
|
|
175
176
|
)
|
|
176
177
|
|
|
178
|
+
app = Starlette(
|
|
179
|
+
routes=[
|
|
180
|
+
Route("/health", health, methods=["GET"]),
|
|
181
|
+
Route("/healthz", health, methods=["GET"]),
|
|
182
|
+
Route("/models", list_models, methods=["GET"]),
|
|
183
|
+
Route("/v1/models", list_models, methods=["GET"]),
|
|
184
|
+
Route("/responses", responses, methods=["POST"]),
|
|
185
|
+
Route("/v1/responses", responses, methods=["POST"]),
|
|
186
|
+
],
|
|
187
|
+
exception_handlers={HTTPException: _http_exception_response},
|
|
188
|
+
)
|
|
189
|
+
app.state.response_server = response_server
|
|
177
190
|
return app
|
|
178
191
|
|
|
179
192
|
def __init__(self, config: "CompatServerConfig") -> "None":
|