python-codex 0.3.3__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- python_codex-0.3.3/README.md → python_codex-0.4.0/PKG-INFO +137 -36
- python_codex-0.3.3/PKG-INFO → python_codex-0.4.0/README.md +117 -59
- {python_codex-0.3.3 → python_codex-0.4.0}/README_ZH.md +102 -22
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/__init__.py +3 -27
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/bootstrap.py +5 -45
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/cli.py +1 -14
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/context.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/events.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/model.py +2 -2
- python_codex-0.4.0/pycodex/portable/__init__.py +45 -0
- python_codex-0.3.3/pycodex/portable.py → python_codex-0.4.0/pycodex/portable/client.py +4 -7
- python_codex-0.3.3/pycodex/portable_server.py → python_codex-0.4.0/pycodex/portable/server.py +3 -3
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/protocol.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/runtime.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/base_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/close_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/code_mode_manager.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/request_permissions_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/resume_agent_tool.py +1 -1
- {python_codex-0.3.3/pycodex → python_codex-0.4.0/pycodex/tools}/runtime_services.py +5 -5
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/send_input_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/spawn_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/unified_exec_manager.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/update_plan_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/view_image_tool.py +5 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/wait_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/__init__.py +0 -4
- python_codex-0.4.0/pycodex/utils/_aes_gcm/LICENSE +56 -0
- python_codex-0.4.0/pycodex/utils/_aes_gcm/README.md +61 -0
- python_codex-0.4.0/pycodex/utils/_aes_gcm/__init__.py +1 -0
- python_codex-0.4.0/pycodex/utils/_aes_gcm/aes.py +175 -0
- python_codex-0.4.0/pycodex/utils/_aes_gcm/gcm.py +73 -0
- python_codex-0.4.0/pycodex/utils/_aes_gcm/source-sha256.json +4 -0
- {python_codex-0.3.3/pycodex → python_codex-0.4.0/pycodex/utils}/compat.py +2 -0
- python_codex-0.4.0/pycodex/utils/crypto.py +35 -0
- python_codex-0.4.0/pycodex/utils/debug.py +36 -0
- {python_codex-0.3.3/pycodex → python_codex-0.4.0/pycodex/utils}/doctor.py +3 -3
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/image_utils.py +3 -2
- {python_codex-0.3.3/pycodex → python_codex-0.4.0/pycodex/utils}/model_metadata.py +2 -2
- {python_codex-0.3.3 → python_codex-0.4.0}/pyproject.toml +23 -23
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/app.py +28 -15
- python_codex-0.3.3/.gitattributes +0 -2
- python_codex-0.3.3/.github/workflows/publish.yml +0 -201
- python_codex-0.3.3/.github/workflows/test.yml +0 -87
- python_codex-0.3.3/AGENTS.md +0 -85
- python_codex-0.3.3/docs/ALIGNMENT.md +0 -777
- python_codex-0.3.3/docs/CONTEXT.md +0 -187
- python_codex-0.3.3/docs/RELEASE_0.3.0.md +0 -74
- python_codex-0.3.3/docs/RELEASE_0.3.2.md +0 -36
- python_codex-0.3.3/docs/RELEASE_0.3.3.md +0 -43
- python_codex-0.3.3/docs/RUNTIME.md +0 -1001
- python_codex-0.3.3/docs/responses_server/README.md +0 -181
- python_codex-0.3.3/packages/pycodex-ws/README.md +0 -21
- python_codex-0.3.3/packages/pycodex-ws/pycodex_ws_meta/__init__.py +0 -1
- python_codex-0.3.3/packages/pycodex-ws/pyproject.toml +0 -16
- python_codex-0.3.3/pycodex/feishu_card.py +0 -793
- python_codex-0.3.3/pycodex/feishu_link.py +0 -440
- python_codex-0.3.3/pycodex/tools/ipython_tool.py +0 -142
- python_codex-0.3.3/pycodex/utils/debug.py +0 -12
- python_codex-0.3.3/tests/TESTS.md +0 -407
- python_codex-0.3.3/tests/__init__.py +0 -2
- python_codex-0.3.3/tests/compare_context_requests.py +0 -485
- python_codex-0.3.3/tests/compare_steer_request_bodies.py +0 -689
- python_codex-0.3.3/tests/compare_tool_schemas.py +0 -499
- python_codex-0.3.3/tests/conftest.py +0 -6
- python_codex-0.3.3/tests/fake_responses_server.py +0 -402
- python_codex-0.3.3/tests/fakes.py +0 -56
- python_codex-0.3.3/tests/responses_server/fake_chat_completions_server.py +0 -512
- python_codex-0.3.3/tests/responses_server/test_server.py +0 -2819
- python_codex-0.3.3/tests/responses_server/test_trajectory_dump.py +0 -127
- python_codex-0.3.3/tests/test_agent.py +0 -1776
- python_codex-0.3.3/tests/test_agent_state.py +0 -1718
- python_codex-0.3.3/tests/test_async_bridge.py +0 -142
- python_codex-0.3.3/tests/test_builtin_tools.py +0 -1613
- python_codex-0.3.3/tests/test_cli.py +0 -744
- python_codex-0.3.3/tests/test_compactor.py +0 -111
- python_codex-0.3.3/tests/test_context.py +0 -491
- python_codex-0.3.3/tests/test_doctor.py +0 -166
- python_codex-0.3.3/tests/test_events.py +0 -792
- python_codex-0.3.3/tests/test_fake_responses_server.py +0 -187
- python_codex-0.3.3/tests/test_feishu_card.py +0 -732
- python_codex-0.3.3/tests/test_feishu_link.py +0 -332
- python_codex-0.3.3/tests/test_feishu_oauth.py +0 -61
- python_codex-0.3.3/tests/test_ipython_tool.py +0 -100
- python_codex-0.3.3/tests/test_model.py +0 -2402
- python_codex-0.3.3/tests/test_owned_workspace_server.py +0 -145
- python_codex-0.3.3/tests/test_packaging.py +0 -71
- python_codex-0.3.3/tests/test_portable.py +0 -194
- python_codex-0.3.3/tests/test_py36_syntax.py +0 -31
- python_codex-0.3.3/tests/test_runtime_state.py +0 -860
- python_codex-0.3.3/tests/test_session_backend.py +0 -726
- python_codex-0.3.3/tests/test_workspace_server.py +0 -1307
- python_codex-0.3.3/tests/test_workspace_views.py +0 -948
- python_codex-0.3.3/tests/workspace_content_views.mjs +0 -919
- python_codex-0.3.3/tools/feishu_oauth.py +0 -185
- python_codex-0.3.3/tools/sync_model_prompts.py +0 -39
- python_codex-0.3.3/workspace_server/__init__.py +0 -39
- python_codex-0.3.3/workspace_server/__main__.py +0 -4
- python_codex-0.3.3/workspace_server/app.py +0 -1906
- python_codex-0.3.3/workspace_server/content_views.LICENSE.txt +0 -470
- python_codex-0.3.3/workspace_server/content_views.css +0 -1
- python_codex-0.3.3/workspace_server/content_views.mjs +0 -25
- python_codex-0.3.3/workspace_server/editor.css +0 -1
- python_codex-0.3.3/workspace_server/editor.mjs +0 -1260
- python_codex-0.3.3/workspace_server/frontend/.gitignore +0 -1
- python_codex-0.3.3/workspace_server/frontend/build.mjs +0 -98
- python_codex-0.3.3/workspace_server/frontend/content_views.css +0 -83
- python_codex-0.3.3/workspace_server/frontend/content_views.mjs +0 -668
- python_codex-0.3.3/workspace_server/frontend/editor.css +0 -50
- python_codex-0.3.3/workspace_server/frontend/editor.mjs +0 -342
- python_codex-0.3.3/workspace_server/frontend/package-lock.json +0 -541
- python_codex-0.3.3/workspace_server/frontend/package.json +0 -17
- python_codex-0.3.3/workspace_server/owned_process.py +0 -27
- python_codex-0.3.3/workspace_server/workspace.html +0 -2267
- python_codex-0.3.3/workspace_server/workspace_views.py +0 -533
- python_codex-0.3.3/workspace_server/workspaces.html +0 -550
- python_codex-0.3.3/workspace_server/workspaces.py +0 -632
- {python_codex-0.3.3 → python_codex-0.4.0}/.gitignore +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/LICENSE +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/__main__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/agent.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/default_base_instructions.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/models.json +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/agent_tool_schemas.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/apply_patch_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/clock_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/exec_command_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/exec_runtime.js +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/exec_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/grep_files_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/list_dir_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/read_file_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/request_user_input_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/shell_command_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/shell_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/wait_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/web_search_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/tools/write_stdin_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/async_bridge.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/compactor.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/dotenv.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/event_helpers.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/get_env.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/random_ids.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/session_persist.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/pycodex/utils/truncation.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/__main__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/config.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/messages_api.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/payload_processors.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/server.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/session_store.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/stream_router.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/tools/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/tools/custom_adapter.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/tools/web_search.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.0}/responses_server/trajectory_dump.py +0 -0
|
@@ -1,7 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-codex
|
|
3
|
+
Version: 0.4.0
|
|
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: importlib-metadata>=4.8.3; python_version < '3.8'
|
|
9
|
+
Requires-Dist: loguru>=0.7.3
|
|
10
|
+
Requires-Dist: prompt-toolkit>=3.0.36
|
|
11
|
+
Requires-Dist: pyyaml>=6.0
|
|
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'
|
|
15
|
+
Requires-Dist: tomli<2,>=1.2.3; python_version < '3.11'
|
|
16
|
+
Requires-Dist: typing-extensions>=4.1.1; python_version < '3.8'
|
|
17
|
+
Requires-Dist: uvicorn<0.17,>=0.16.0; python_version < '3.7'
|
|
18
|
+
Requires-Dist: uvicorn>=0.16.0; python_version >= '3.7'
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
1
21
|
# pycodex
|
|
2
22
|
|
|
3
23
|
English README. Chinese version: `README_ZH.md`
|
|
4
24
|
|
|
25
|
+
0.4.0 core/workspace package split and dependency cleanup: [release notes](docs/RELEASE_0.4.0.md).
|
|
26
|
+
|
|
5
27
|
0.3.3 workspace viewers and reasoning stream fix: [release notes](docs/RELEASE_0.3.3.md).
|
|
6
28
|
|
|
7
29
|
0.3.2 startup fixes: [release notes](docs/RELEASE_0.3.2.md).
|
|
@@ -10,15 +32,33 @@ English README. Chinese version: `README_ZH.md`
|
|
|
10
32
|
|
|
11
33
|
PyPI distributions:
|
|
12
34
|
|
|
13
|
-
-
|
|
14
|
-
- Workspace
|
|
35
|
+
- Core package: `python-codex`
|
|
36
|
+
- Workspace and integrations: `pycodex-ws`
|
|
15
37
|
|
|
16
38
|
The import path remains `pycodex`; the CLI commands are `pycodex` and
|
|
17
39
|
`pycodex-ws`.
|
|
18
40
|
|
|
19
|
-
`
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
Feishu and IPython integrations, including their dependencies. It owns the
|
|
45
|
+
`workspace_server` and `pycodex_ws` modules and the `pycodex-ws` command.
|
|
46
|
+
|
|
47
|
+
Core does not require Pillow. Without it, `view_image` sends the original image
|
|
48
|
+
bytes with `detail="original"`, including when `high` is requested. With Pillow
|
|
49
|
+
installed, the default path retains resizing to a maximum dimension of 2048.
|
|
50
|
+
`pycodex-ws` installs Pillow for image preview validation.
|
|
51
|
+
|
|
52
|
+
Portable encryption uses a bundled pure Python AES-GCM subset of pyaes and
|
|
53
|
+
tlslite-ng, under MIT and BSD licenses. Core does not require a crypto package
|
|
54
|
+
or compiler and ships a `py3-none-any` wheel. Existing `PCX1` bundles and call
|
|
55
|
+
tokens remain compatible; large bundles take longer to encrypt and decrypt.
|
|
56
|
+
See the [source notes](pycodex/utils/_aes_gcm/README.md).
|
|
57
|
+
|
|
58
|
+
The Responses compatibility server and workspace HTTP server use Starlette
|
|
59
|
+
and Uvicorn directly. Neither package requires FastAPI, Pydantic or
|
|
60
|
+
`pydantic-core`. Python 3.6 uses Starlette 0.19.x; newer interpreters resolve
|
|
61
|
+
a compatible Starlette release through its Python version metadata.
|
|
22
62
|
|
|
23
63
|
This repository extracts the core Codex agent loop from upstream Codex
|
|
24
64
|
(`https://github.com/openai/codex`) into a deliberately small Python version,
|
|
@@ -38,16 +78,17 @@ Relevant Rust reference points:
|
|
|
38
78
|
|
|
39
79
|
## Quick Start
|
|
40
80
|
|
|
41
|
-
Install the
|
|
81
|
+
Install the core CLI, or install the workspace package to include all integrations:
|
|
42
82
|
|
|
43
83
|
```bash
|
|
44
84
|
python3 -m pip install python-codex
|
|
45
85
|
python3 -m pip install pycodex-ws
|
|
46
86
|
```
|
|
47
87
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
88
|
+
The core supports Python 3.6.2 or newer. The workspace package requires Python
|
|
89
|
+
3.7 or newer because of its Feishu SDK dependency. Commands are installed into
|
|
90
|
+
that interpreter's scripts directory. On a machine with multiple Python
|
|
91
|
+
installations, select the same interpreter explicitly for startup:
|
|
51
92
|
|
|
52
93
|
```bash
|
|
53
94
|
python3 -m pycodex
|
|
@@ -58,10 +99,14 @@ If `pycodex` is missing from `PATH` or resolves to an older installation, use th
|
|
|
58
99
|
module entry points. `python3 -m pip --version` shows which Python environment
|
|
59
100
|
received the installation.
|
|
60
101
|
|
|
102
|
+
For an existing Web installation, use `python3 -m pip install --upgrade pycodex-ws`
|
|
103
|
+
to upgrade the workspace and its matching core together. Installing only
|
|
104
|
+
`python-codex` provides the CLI and core API.
|
|
105
|
+
|
|
61
106
|
For development from this repository, install dependencies first:
|
|
62
107
|
|
|
63
108
|
```bash
|
|
64
|
-
uv sync
|
|
109
|
+
uv sync --dev
|
|
65
110
|
```
|
|
66
111
|
|
|
67
112
|
Try the real entry points:
|
|
@@ -71,8 +116,22 @@ uv run pycodex "Reply with exactly OK."
|
|
|
71
116
|
uv run pycodex
|
|
72
117
|
```
|
|
73
118
|
|
|
74
|
-
|
|
75
|
-
|
|
119
|
+
Tests are split by package. `uv run --dev pytest` runs both suites;
|
|
120
|
+
`uv run --dev pytest packages/pycodex-ws/tests` runs workspace and integration
|
|
121
|
+
tests. To check core without installing workspace or its SDKs, use a separate
|
|
122
|
+
environment:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv sync --group test
|
|
126
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv run --group test pytest tests
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
See [test environments and coverage](tests/TESTS.md). Core tests support Python
|
|
130
|
+
3.6.2+; workspace tests require Python 3.7+.
|
|
131
|
+
|
|
132
|
+
A VS Code frontend is available in [`packages/pycodex-ws/extensions/vscode`](packages/pycodex-ws/extensions/vscode/README.md).
|
|
133
|
+
It belongs to the workspace frontend and is packaged separately as a VSIX.
|
|
134
|
+
It reuses an existing `pycodex-ws>=0.4.0` installation. On first use, missing
|
|
76
135
|
or older backends are installed/upgraded with pip in the selected Python
|
|
77
136
|
environment on the workspace host; compatible versions need no network check.
|
|
78
137
|
It starts a dedicated `pycodex-ws` workspace on the project's host and opens a
|
|
@@ -120,19 +179,35 @@ nailing the core tool-augmented reasoning loop first.
|
|
|
120
179
|
|
|
121
180
|
## Layout
|
|
122
181
|
|
|
182
|
+
The top level of `pycodex/` contains the core components and package entry points.
|
|
183
|
+
Supporting services live in `tools/`, `portable/` and `utils/`.
|
|
184
|
+
|
|
185
|
+
- `pycodex/agent.py`: inner turn loop
|
|
186
|
+
- `pycodex/runtime.py`: session commands, submission queues and frontend event subscriptions
|
|
187
|
+
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
188
|
+
- `pycodex/context.py`: configuration, prompt assembly and instruction loading
|
|
123
189
|
- `pycodex/protocol.py`: minimal conversation item / prompt protocol
|
|
124
190
|
- `pycodex/events.py`: typed events, plain-text views and stateful presentation
|
|
125
|
-
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
126
|
-
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
127
|
-
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
128
|
-
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
129
191
|
- `pycodex/bootstrap.py`: frontend-independent model, tools, Agent and session assembly
|
|
192
|
+
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
130
193
|
- `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
|
|
131
|
-
- `pycodex/tools
|
|
132
|
-
- `pycodex/
|
|
133
|
-
- `pycodex/
|
|
134
|
-
- `
|
|
135
|
-
- `
|
|
194
|
+
- `pycodex/tools/runtime_services.py`: plan, sub-agent, user-input and permissions services
|
|
195
|
+
- `pycodex/tools/`: concrete tools and their execution managers
|
|
196
|
+
- `pycodex/portable/`: Codex home storage client and server, both included in core
|
|
197
|
+
- `pycodex/utils/compat.py`: supported-Python compatibility helpers
|
|
198
|
+
- `pycodex/utils/doctor.py`: configuration and connectivity diagnostics
|
|
199
|
+
- `pycodex/utils/model_metadata.py`: vendored model metadata lookup
|
|
200
|
+
- `pycodex/utils/debug.py`: debug paths and the `pycodex.debug()` implementation
|
|
201
|
+
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
202
|
+
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
203
|
+
- `pycodex/prompts/`: vendored prompts and model metadata
|
|
204
|
+
- `packages/pycodex-ws/workspace_server/`: Web board, API and file/diff viewers
|
|
205
|
+
- `packages/pycodex-ws/pycodex_ws/`: Feishu, IPython and workspace assembly
|
|
206
|
+
- `packages/pycodex-ws/extensions/vscode/`: workspace's VS Code frontend, built separately as a VSIX
|
|
207
|
+
- `tests/`: core tests
|
|
208
|
+
- `packages/pycodex-ws/tests/`: workspace and cross-frontend integration tests
|
|
209
|
+
|
|
210
|
+
See [package layout and import paths](docs/RUNTIME.md#package-layout).
|
|
136
211
|
|
|
137
212
|
## Current Alignment Status
|
|
138
213
|
|
|
@@ -243,7 +318,7 @@ Current behavior:
|
|
|
243
318
|
- with an argv prompt or piped stdin, run a single turn
|
|
244
319
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
245
320
|
workspace with a board pane and a pycodex session pane
|
|
246
|
-
- the left pane is the board, containing
|
|
321
|
+
- the left pane is the board, containing an optional live HTML Canvas tab and closable read-only file/diff tabs that
|
|
247
322
|
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
248
323
|
horizontally.
|
|
249
324
|
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
@@ -262,6 +337,14 @@ Current behavior:
|
|
|
262
337
|
hover titles retain the complete paths and revisions. Text,
|
|
263
338
|
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
264
339
|
provides syntax highlighting, find, folding and character-level diffs.
|
|
340
|
+
Right-click code and choose **Insert into chat**, or select text and use the
|
|
341
|
+
toolbar button, to insert context at the current chat draft's cursor.
|
|
342
|
+
Context appears as a separate block among your words. Click it to edit or
|
|
343
|
+
remove it; Backspace and Delete also remove a block as one element.
|
|
344
|
+
Context identifies the full view label, including both revisions of a diff.
|
|
345
|
+
Selections include only the selected text and range; otherwise it records the
|
|
346
|
+
cursor location. Diff context also identifies the selected side.
|
|
347
|
+
The draft stays editable until you send it.
|
|
265
348
|
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
266
349
|
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
267
350
|
when supported and revalidate cached content with ETags.
|
|
@@ -330,28 +413,37 @@ Current behavior:
|
|
|
330
413
|
non-persisted follow-up session and submits the file contents as the next
|
|
331
414
|
user instruction; this is intended for side-effect follow-ups such as
|
|
332
415
|
Feishu notifications
|
|
333
|
-
- `/link <feishu-email|open_id|chat_id>`
|
|
334
|
-
|
|
416
|
+
- `/link <feishu-email|open_id|chat_id>` in a workspace session attaches it
|
|
417
|
+
to a Feishu card; multiple sessions in the same workspace process share
|
|
335
418
|
one Feishu long-connection listener and route card actions by message id
|
|
336
419
|
- Feishu user OAuth stores its refresh token only in
|
|
337
420
|
`~/.codex/.feishu_refresh_token` (mode `0600`). Run
|
|
338
|
-
`
|
|
339
|
-
|
|
421
|
+
`python3 -m pycodex_ws.feishu_oauth` after installing `pycodex-ws` to authorize.
|
|
422
|
+
From this repository, use `env -u VIRTUAL_ENV uv run --dev python -m pycodex_ws.feishu_oauth`.
|
|
423
|
+
App credentials can stay in `~/.codex/.env`. Each refresh reads
|
|
340
424
|
the latest token from the dedicated file and saves its replacement there.
|
|
341
425
|
`FEISHU_REFRESH_TOKEN` in `.env` or the environment is no longer used and
|
|
342
426
|
can be removed. Refresh is triggered by API calls, with no idle keepalive.
|
|
343
427
|
- `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
|
|
344
428
|
one process. The JSON file can be either a list or
|
|
345
|
-
`{"workspaces": [...]}`; each entry uses `
|
|
346
|
-
display/URL `id
|
|
347
|
-
`
|
|
348
|
-
|
|
429
|
+
`{"workspaces": [...]}`; each entry uses `state_path` and `work_dir`, with optional
|
|
430
|
+
display/URL `id` and `enable_board` (default `true`), and is exposed at `/w/<id>/`.
|
|
431
|
+
`state_path` is a filename prefix: `/data/demo` uses
|
|
432
|
+
`/data/demo.pycodex-ws.json` for the session index,
|
|
433
|
+
`/data/demo.pycodex-views.json` for file views and `/data/demo.html` for Canvas.
|
|
434
|
+
Suffixes are appended, so prefixes containing dots remain distinct.
|
|
435
|
+
The resolved `state_path` is the workspace identity; duplicates are rejected
|
|
436
|
+
regardless of name or Canvas setting. Relative `state_path` and `work_dir` paths
|
|
349
437
|
resolve from the config file directory. The root path `/` shows a workspaces
|
|
350
|
-
management page with
|
|
351
|
-
`
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
438
|
+
management page with create/delete controls; omitted names become `workspace-1`,
|
|
439
|
+
`workspace-2`, etc. Omitted `state_path` when creating a workspace generates a
|
|
440
|
+
writable `/tmp/pcws-*` prefix. `enable_board: false` hides Canvas and disables its
|
|
441
|
+
routes, polling and context injection; sessions and file views still persist.
|
|
442
|
+
Existing `board: "demo.html"` and `board: false` configurations load with their
|
|
443
|
+
original state paths and are saved in the new format. See the
|
|
444
|
+
[workspace configuration example](packages/pycodex-ws/README.md).
|
|
445
|
+
Add/delete actions and later session-state saves refresh the JSON file.
|
|
446
|
+
Board HTML can reference local
|
|
355
447
|
images beside the board (including nested paths) with relative URLs; only
|
|
356
448
|
`image/*` files contained by the board directory are served.
|
|
357
449
|
Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
|
|
@@ -443,6 +535,13 @@ pycodex doctor --json
|
|
|
443
535
|
`Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
|
|
444
536
|
fresh machine, container, or debug image.
|
|
445
537
|
|
|
538
|
+
The storage client and server are both included in `python-codex`. To start a
|
|
539
|
+
local storage service, run this in a separate terminal:
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
python -m pycodex.portable.server --root .tmp/pycodex_storage --host 127.0.0.1 --port 5577
|
|
543
|
+
```
|
|
544
|
+
|
|
446
545
|
Use it like this:
|
|
447
546
|
|
|
448
547
|
```bash
|
|
@@ -636,7 +735,9 @@ CLI, Web and Feishu all use `AgentRuntime.submit_input`: not just `/model`
|
|
|
636
735
|
and `/resume`, but every session command, steer/queue admission, interactive
|
|
637
736
|
questions and permissions, state notifications and shutdown. Frontends only
|
|
638
737
|
adapt input and render events. Web no longer imports or runs the CLI shell.
|
|
639
|
-
IPython is the deliberate exception: `ipython_agent()`
|
|
738
|
+
IPython is the deliberate exception: `pycodex_ws.ipython.ipython_agent()` returns
|
|
739
|
+
a bare Agent. Workspace assembly uses `pycodex_ws.build_runtime()` to add
|
|
740
|
+
`/link` and `/unlink`; `pycodex.bootstrap.build_runtime()` provides core commands.
|
|
640
741
|
|
|
641
742
|
```python
|
|
642
743
|
from pycodex.bootstrap import build_agent, build_model, build_runtime
|
|
@@ -1,30 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: python-codex
|
|
3
|
-
Version: 0.3.3
|
|
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: pyyaml>=6.0
|
|
17
|
-
Requires-Dist: requests>=2.27.1
|
|
18
|
-
Requires-Dist: tomli<2,>=1.2.3; python_version < '3.11'
|
|
19
|
-
Requires-Dist: typing-extensions>=4.1.1; python_version < '3.8'
|
|
20
|
-
Requires-Dist: uvicorn<0.17,>=0.16.0; python_version < '3.7'
|
|
21
|
-
Requires-Dist: uvicorn>=0.16.0; python_version >= '3.7'
|
|
22
|
-
Description-Content-Type: text/markdown
|
|
23
|
-
|
|
24
1
|
# pycodex
|
|
25
2
|
|
|
26
3
|
English README. Chinese version: `README_ZH.md`
|
|
27
4
|
|
|
5
|
+
0.4.0 core/workspace package split and dependency cleanup: [release notes](docs/RELEASE_0.4.0.md).
|
|
6
|
+
|
|
28
7
|
0.3.3 workspace viewers and reasoning stream fix: [release notes](docs/RELEASE_0.3.3.md).
|
|
29
8
|
|
|
30
9
|
0.3.2 startup fixes: [release notes](docs/RELEASE_0.3.2.md).
|
|
@@ -33,15 +12,33 @@ English README. Chinese version: `README_ZH.md`
|
|
|
33
12
|
|
|
34
13
|
PyPI distributions:
|
|
35
14
|
|
|
36
|
-
-
|
|
37
|
-
- Workspace
|
|
15
|
+
- Core package: `python-codex`
|
|
16
|
+
- Workspace and integrations: `pycodex-ws`
|
|
38
17
|
|
|
39
18
|
The import path remains `pycodex`; the CLI commands are `pycodex` and
|
|
40
19
|
`pycodex-ws`.
|
|
41
20
|
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
-
|
|
21
|
+
`python-codex` contains the Agent, runtime, CLI, standard tools, Responses
|
|
22
|
+
compatibility server and portable storage support. `pycodex-ws` depends on the
|
|
23
|
+
exact matching core version and contains the browser workspace, viewer assets,
|
|
24
|
+
Feishu and IPython integrations, including their dependencies. It owns the
|
|
25
|
+
`workspace_server` and `pycodex_ws` modules and the `pycodex-ws` command.
|
|
26
|
+
|
|
27
|
+
Core does not require Pillow. Without it, `view_image` sends the original image
|
|
28
|
+
bytes with `detail="original"`, including when `high` is requested. With Pillow
|
|
29
|
+
installed, the default path retains resizing to a maximum dimension of 2048.
|
|
30
|
+
`pycodex-ws` installs Pillow for image preview validation.
|
|
31
|
+
|
|
32
|
+
Portable encryption uses a bundled pure Python AES-GCM subset of pyaes and
|
|
33
|
+
tlslite-ng, under MIT and BSD licenses. Core does not require a crypto package
|
|
34
|
+
or compiler and ships a `py3-none-any` wheel. Existing `PCX1` bundles and call
|
|
35
|
+
tokens remain compatible; large bundles take longer to encrypt and decrypt.
|
|
36
|
+
See the [source notes](pycodex/utils/_aes_gcm/README.md).
|
|
37
|
+
|
|
38
|
+
The Responses compatibility server and workspace HTTP server use Starlette
|
|
39
|
+
and Uvicorn directly. Neither package requires FastAPI, Pydantic or
|
|
40
|
+
`pydantic-core`. Python 3.6 uses Starlette 0.19.x; newer interpreters resolve
|
|
41
|
+
a compatible Starlette release through its Python version metadata.
|
|
45
42
|
|
|
46
43
|
This repository extracts the core Codex agent loop from upstream Codex
|
|
47
44
|
(`https://github.com/openai/codex`) into a deliberately small Python version,
|
|
@@ -61,16 +58,17 @@ Relevant Rust reference points:
|
|
|
61
58
|
|
|
62
59
|
## Quick Start
|
|
63
60
|
|
|
64
|
-
Install the
|
|
61
|
+
Install the core CLI, or install the workspace package to include all integrations:
|
|
65
62
|
|
|
66
63
|
```bash
|
|
67
64
|
python3 -m pip install python-codex
|
|
68
65
|
python3 -m pip install pycodex-ws
|
|
69
66
|
```
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
The core supports Python 3.6.2 or newer. The workspace package requires Python
|
|
69
|
+
3.7 or newer because of its Feishu SDK dependency. Commands are installed into
|
|
70
|
+
that interpreter's scripts directory. On a machine with multiple Python
|
|
71
|
+
installations, select the same interpreter explicitly for startup:
|
|
74
72
|
|
|
75
73
|
```bash
|
|
76
74
|
python3 -m pycodex
|
|
@@ -81,10 +79,14 @@ If `pycodex` is missing from `PATH` or resolves to an older installation, use th
|
|
|
81
79
|
module entry points. `python3 -m pip --version` shows which Python environment
|
|
82
80
|
received the installation.
|
|
83
81
|
|
|
82
|
+
For an existing Web installation, use `python3 -m pip install --upgrade pycodex-ws`
|
|
83
|
+
to upgrade the workspace and its matching core together. Installing only
|
|
84
|
+
`python-codex` provides the CLI and core API.
|
|
85
|
+
|
|
84
86
|
For development from this repository, install dependencies first:
|
|
85
87
|
|
|
86
88
|
```bash
|
|
87
|
-
uv sync
|
|
89
|
+
uv sync --dev
|
|
88
90
|
```
|
|
89
91
|
|
|
90
92
|
Try the real entry points:
|
|
@@ -94,8 +96,22 @@ uv run pycodex "Reply with exactly OK."
|
|
|
94
96
|
uv run pycodex
|
|
95
97
|
```
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
Tests are split by package. `uv run --dev pytest` runs both suites;
|
|
100
|
+
`uv run --dev pytest packages/pycodex-ws/tests` runs workspace and integration
|
|
101
|
+
tests. To check core without installing workspace or its SDKs, use a separate
|
|
102
|
+
environment:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv sync --group test
|
|
106
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv run --group test pytest tests
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
See [test environments and coverage](tests/TESTS.md). Core tests support Python
|
|
110
|
+
3.6.2+; workspace tests require Python 3.7+.
|
|
111
|
+
|
|
112
|
+
A VS Code frontend is available in [`packages/pycodex-ws/extensions/vscode`](packages/pycodex-ws/extensions/vscode/README.md).
|
|
113
|
+
It belongs to the workspace frontend and is packaged separately as a VSIX.
|
|
114
|
+
It reuses an existing `pycodex-ws>=0.4.0` installation. On first use, missing
|
|
99
115
|
or older backends are installed/upgraded with pip in the selected Python
|
|
100
116
|
environment on the workspace host; compatible versions need no network check.
|
|
101
117
|
It starts a dedicated `pycodex-ws` workspace on the project's host and opens a
|
|
@@ -143,19 +159,35 @@ nailing the core tool-augmented reasoning loop first.
|
|
|
143
159
|
|
|
144
160
|
## Layout
|
|
145
161
|
|
|
162
|
+
The top level of `pycodex/` contains the core components and package entry points.
|
|
163
|
+
Supporting services live in `tools/`, `portable/` and `utils/`.
|
|
164
|
+
|
|
165
|
+
- `pycodex/agent.py`: inner turn loop
|
|
166
|
+
- `pycodex/runtime.py`: session commands, submission queues and frontend event subscriptions
|
|
167
|
+
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
168
|
+
- `pycodex/context.py`: configuration, prompt assembly and instruction loading
|
|
146
169
|
- `pycodex/protocol.py`: minimal conversation item / prompt protocol
|
|
147
170
|
- `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
171
|
- `pycodex/bootstrap.py`: frontend-independent model, tools, Agent and session assembly
|
|
172
|
+
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
153
173
|
- `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
|
|
154
|
-
- `pycodex/tools
|
|
155
|
-
- `pycodex/
|
|
156
|
-
- `pycodex/
|
|
157
|
-
- `
|
|
158
|
-
- `
|
|
174
|
+
- `pycodex/tools/runtime_services.py`: plan, sub-agent, user-input and permissions services
|
|
175
|
+
- `pycodex/tools/`: concrete tools and their execution managers
|
|
176
|
+
- `pycodex/portable/`: Codex home storage client and server, both included in core
|
|
177
|
+
- `pycodex/utils/compat.py`: supported-Python compatibility helpers
|
|
178
|
+
- `pycodex/utils/doctor.py`: configuration and connectivity diagnostics
|
|
179
|
+
- `pycodex/utils/model_metadata.py`: vendored model metadata lookup
|
|
180
|
+
- `pycodex/utils/debug.py`: debug paths and the `pycodex.debug()` implementation
|
|
181
|
+
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
182
|
+
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
183
|
+
- `pycodex/prompts/`: vendored prompts and model metadata
|
|
184
|
+
- `packages/pycodex-ws/workspace_server/`: Web board, API and file/diff viewers
|
|
185
|
+
- `packages/pycodex-ws/pycodex_ws/`: Feishu, IPython and workspace assembly
|
|
186
|
+
- `packages/pycodex-ws/extensions/vscode/`: workspace's VS Code frontend, built separately as a VSIX
|
|
187
|
+
- `tests/`: core tests
|
|
188
|
+
- `packages/pycodex-ws/tests/`: workspace and cross-frontend integration tests
|
|
189
|
+
|
|
190
|
+
See [package layout and import paths](docs/RUNTIME.md#package-layout).
|
|
159
191
|
|
|
160
192
|
## Current Alignment Status
|
|
161
193
|
|
|
@@ -266,7 +298,7 @@ Current behavior:
|
|
|
266
298
|
- with an argv prompt or piped stdin, run a single turn
|
|
267
299
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
268
300
|
workspace with a board pane and a pycodex session pane
|
|
269
|
-
- the left pane is the board, containing
|
|
301
|
+
- the left pane is the board, containing an optional live HTML Canvas tab and closable read-only file/diff tabs that
|
|
270
302
|
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
271
303
|
horizontally.
|
|
272
304
|
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
@@ -285,6 +317,14 @@ Current behavior:
|
|
|
285
317
|
hover titles retain the complete paths and revisions. Text,
|
|
286
318
|
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
287
319
|
provides syntax highlighting, find, folding and character-level diffs.
|
|
320
|
+
Right-click code and choose **Insert into chat**, or select text and use the
|
|
321
|
+
toolbar button, to insert context at the current chat draft's cursor.
|
|
322
|
+
Context appears as a separate block among your words. Click it to edit or
|
|
323
|
+
remove it; Backspace and Delete also remove a block as one element.
|
|
324
|
+
Context identifies the full view label, including both revisions of a diff.
|
|
325
|
+
Selections include only the selected text and range; otherwise it records the
|
|
326
|
+
cursor location. Diff context also identifies the selected side.
|
|
327
|
+
The draft stays editable until you send it.
|
|
288
328
|
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
289
329
|
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
290
330
|
when supported and revalidate cached content with ETags.
|
|
@@ -353,28 +393,37 @@ Current behavior:
|
|
|
353
393
|
non-persisted follow-up session and submits the file contents as the next
|
|
354
394
|
user instruction; this is intended for side-effect follow-ups such as
|
|
355
395
|
Feishu notifications
|
|
356
|
-
- `/link <feishu-email|open_id|chat_id>`
|
|
357
|
-
|
|
396
|
+
- `/link <feishu-email|open_id|chat_id>` in a workspace session attaches it
|
|
397
|
+
to a Feishu card; multiple sessions in the same workspace process share
|
|
358
398
|
one Feishu long-connection listener and route card actions by message id
|
|
359
399
|
- Feishu user OAuth stores its refresh token only in
|
|
360
400
|
`~/.codex/.feishu_refresh_token` (mode `0600`). Run
|
|
361
|
-
`
|
|
362
|
-
|
|
401
|
+
`python3 -m pycodex_ws.feishu_oauth` after installing `pycodex-ws` to authorize.
|
|
402
|
+
From this repository, use `env -u VIRTUAL_ENV uv run --dev python -m pycodex_ws.feishu_oauth`.
|
|
403
|
+
App credentials can stay in `~/.codex/.env`. Each refresh reads
|
|
363
404
|
the latest token from the dedicated file and saves its replacement there.
|
|
364
405
|
`FEISHU_REFRESH_TOKEN` in `.env` or the environment is no longer used and
|
|
365
406
|
can be removed. Refresh is triggered by API calls, with no idle keepalive.
|
|
366
407
|
- `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
|
|
367
408
|
one process. The JSON file can be either a list or
|
|
368
|
-
`{"workspaces": [...]}`; each entry uses `
|
|
369
|
-
display/URL `id
|
|
370
|
-
`
|
|
371
|
-
|
|
409
|
+
`{"workspaces": [...]}`; each entry uses `state_path` and `work_dir`, with optional
|
|
410
|
+
display/URL `id` and `enable_board` (default `true`), and is exposed at `/w/<id>/`.
|
|
411
|
+
`state_path` is a filename prefix: `/data/demo` uses
|
|
412
|
+
`/data/demo.pycodex-ws.json` for the session index,
|
|
413
|
+
`/data/demo.pycodex-views.json` for file views and `/data/demo.html` for Canvas.
|
|
414
|
+
Suffixes are appended, so prefixes containing dots remain distinct.
|
|
415
|
+
The resolved `state_path` is the workspace identity; duplicates are rejected
|
|
416
|
+
regardless of name or Canvas setting. Relative `state_path` and `work_dir` paths
|
|
372
417
|
resolve from the config file directory. The root path `/` shows a workspaces
|
|
373
|
-
management page with
|
|
374
|
-
`
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
418
|
+
management page with create/delete controls; omitted names become `workspace-1`,
|
|
419
|
+
`workspace-2`, etc. Omitted `state_path` when creating a workspace generates a
|
|
420
|
+
writable `/tmp/pcws-*` prefix. `enable_board: false` hides Canvas and disables its
|
|
421
|
+
routes, polling and context injection; sessions and file views still persist.
|
|
422
|
+
Existing `board: "demo.html"` and `board: false` configurations load with their
|
|
423
|
+
original state paths and are saved in the new format. See the
|
|
424
|
+
[workspace configuration example](packages/pycodex-ws/README.md).
|
|
425
|
+
Add/delete actions and later session-state saves refresh the JSON file.
|
|
426
|
+
Board HTML can reference local
|
|
378
427
|
images beside the board (including nested paths) with relative URLs; only
|
|
379
428
|
`image/*` files contained by the board directory are served.
|
|
380
429
|
Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
|
|
@@ -466,6 +515,13 @@ pycodex doctor --json
|
|
|
466
515
|
`Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
|
|
467
516
|
fresh machine, container, or debug image.
|
|
468
517
|
|
|
518
|
+
The storage client and server are both included in `python-codex`. To start a
|
|
519
|
+
local storage service, run this in a separate terminal:
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
python -m pycodex.portable.server --root .tmp/pycodex_storage --host 127.0.0.1 --port 5577
|
|
523
|
+
```
|
|
524
|
+
|
|
469
525
|
Use it like this:
|
|
470
526
|
|
|
471
527
|
```bash
|
|
@@ -659,7 +715,9 @@ CLI, Web and Feishu all use `AgentRuntime.submit_input`: not just `/model`
|
|
|
659
715
|
and `/resume`, but every session command, steer/queue admission, interactive
|
|
660
716
|
questions and permissions, state notifications and shutdown. Frontends only
|
|
661
717
|
adapt input and render events. Web no longer imports or runs the CLI shell.
|
|
662
|
-
IPython is the deliberate exception: `ipython_agent()`
|
|
718
|
+
IPython is the deliberate exception: `pycodex_ws.ipython.ipython_agent()` returns
|
|
719
|
+
a bare Agent. Workspace assembly uses `pycodex_ws.build_runtime()` to add
|
|
720
|
+
`/link` and `/unlink`; `pycodex.bootstrap.build_runtime()` provides core commands.
|
|
663
721
|
|
|
664
722
|
```python
|
|
665
723
|
from pycodex.bootstrap import build_agent, build_model, build_runtime
|