python-codex 0.3.3__tar.gz → 0.4.1__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.1/PKG-INFO +141 -36
- python_codex-0.3.3/PKG-INFO → python_codex-0.4.1/README.md +121 -59
- {python_codex-0.3.3 → python_codex-0.4.1}/README_ZH.md +105 -22
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/__init__.py +3 -27
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/bootstrap.py +5 -45
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/cli.py +1 -14
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/context.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/events.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/model.py +2 -2
- python_codex-0.4.1/pycodex/portable/__init__.py +45 -0
- python_codex-0.3.3/pycodex/portable.py → python_codex-0.4.1/pycodex/portable/client.py +4 -7
- python_codex-0.3.3/pycodex/portable_server.py → python_codex-0.4.1/pycodex/portable/server.py +3 -3
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/protocol.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/runtime.py +2 -2
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/base_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/close_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/code_mode_manager.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/request_permissions_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/resume_agent_tool.py +1 -1
- {python_codex-0.3.3/pycodex → python_codex-0.4.1/pycodex/tools}/runtime_services.py +5 -5
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/send_input_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/spawn_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/unified_exec_manager.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/update_plan_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/view_image_tool.py +5 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/wait_agent_tool.py +1 -1
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/__init__.py +0 -4
- python_codex-0.4.1/pycodex/utils/_aes_gcm/LICENSE +56 -0
- python_codex-0.4.1/pycodex/utils/_aes_gcm/README.md +61 -0
- python_codex-0.4.1/pycodex/utils/_aes_gcm/__init__.py +1 -0
- python_codex-0.4.1/pycodex/utils/_aes_gcm/aes.py +175 -0
- python_codex-0.4.1/pycodex/utils/_aes_gcm/gcm.py +73 -0
- python_codex-0.4.1/pycodex/utils/_aes_gcm/source-sha256.json +4 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/async_bridge.py +3 -4
- {python_codex-0.3.3/pycodex → python_codex-0.4.1/pycodex/utils}/compat.py +2 -0
- python_codex-0.4.1/pycodex/utils/crypto.py +35 -0
- python_codex-0.4.1/pycodex/utils/debug.py +36 -0
- {python_codex-0.3.3/pycodex → python_codex-0.4.1/pycodex/utils}/doctor.py +3 -3
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/image_utils.py +3 -2
- {python_codex-0.3.3/pycodex → python_codex-0.4.1/pycodex/utils}/model_metadata.py +2 -2
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/session_persist.py +28 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pyproject.toml +23 -23
- {python_codex-0.3.3 → python_codex-0.4.1}/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.1}/.gitignore +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/LICENSE +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/__main__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/agent.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/default_base_instructions.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/models.json +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/agent_tool_schemas.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/apply_patch_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/clock_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/exec_command_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/exec_runtime.js +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/exec_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/grep_files_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/list_dir_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/read_file_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/request_user_input_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/shell_command_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/shell_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/wait_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/web_search_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/tools/write_stdin_tool.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/compactor.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/dotenv.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/event_helpers.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/get_env.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/random_ids.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/pycodex/utils/truncation.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/__main__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/config.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/messages_api.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/payload_processors.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/server.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/session_store.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/stream_router.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/tools/__init__.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/tools/custom_adapter.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/tools/web_search.py +0 -0
- {python_codex-0.3.3 → python_codex-0.4.1}/responses_server/trajectory_dump.py +0 -0
|
@@ -1,7 +1,29 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-codex
|
|
3
|
+
Version: 0.4.1
|
|
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,37 @@ 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
|
+
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.
|
|
22
66
|
|
|
23
67
|
This repository extracts the core Codex agent loop from upstream Codex
|
|
24
68
|
(`https://github.com/openai/codex`) into a deliberately small Python version,
|
|
@@ -38,16 +82,17 @@ Relevant Rust reference points:
|
|
|
38
82
|
|
|
39
83
|
## Quick Start
|
|
40
84
|
|
|
41
|
-
Install the
|
|
85
|
+
Install the core CLI, or install the workspace package for the browser frontend:
|
|
42
86
|
|
|
43
87
|
```bash
|
|
44
88
|
python3 -m pip install python-codex
|
|
45
89
|
python3 -m pip install pycodex-ws
|
|
46
90
|
```
|
|
47
91
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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:
|
|
51
96
|
|
|
52
97
|
```bash
|
|
53
98
|
python3 -m pycodex
|
|
@@ -58,10 +103,14 @@ If `pycodex` is missing from `PATH` or resolves to an older installation, use th
|
|
|
58
103
|
module entry points. `python3 -m pip --version` shows which Python environment
|
|
59
104
|
received the installation.
|
|
60
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
|
+
|
|
61
110
|
For development from this repository, install dependencies first:
|
|
62
111
|
|
|
63
112
|
```bash
|
|
64
|
-
uv sync
|
|
113
|
+
uv sync --dev
|
|
65
114
|
```
|
|
66
115
|
|
|
67
116
|
Try the real entry points:
|
|
@@ -71,8 +120,22 @@ uv run pycodex "Reply with exactly OK."
|
|
|
71
120
|
uv run pycodex
|
|
72
121
|
```
|
|
73
122
|
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
76
139
|
or older backends are installed/upgraded with pip in the selected Python
|
|
77
140
|
environment on the workspace host; compatible versions need no network check.
|
|
78
141
|
It starts a dedicated `pycodex-ws` workspace on the project's host and opens a
|
|
@@ -120,19 +183,35 @@ nailing the core tool-augmented reasoning loop first.
|
|
|
120
183
|
|
|
121
184
|
## Layout
|
|
122
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
|
|
123
193
|
- `pycodex/protocol.py`: minimal conversation item / prompt protocol
|
|
124
194
|
- `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
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
|
|
130
197
|
- `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
|
|
131
|
-
- `pycodex/tools
|
|
132
|
-
- `pycodex/
|
|
133
|
-
- `pycodex/
|
|
134
|
-
- `
|
|
135
|
-
- `
|
|
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).
|
|
136
215
|
|
|
137
216
|
## Current Alignment Status
|
|
138
217
|
|
|
@@ -243,7 +322,7 @@ Current behavior:
|
|
|
243
322
|
- with an argv prompt or piped stdin, run a single turn
|
|
244
323
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
245
324
|
workspace with a board pane and a pycodex session pane
|
|
246
|
-
- 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
|
|
247
326
|
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
248
327
|
horizontally.
|
|
249
328
|
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
@@ -262,6 +341,14 @@ Current behavior:
|
|
|
262
341
|
hover titles retain the complete paths and revisions. Text,
|
|
263
342
|
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
264
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.
|
|
265
352
|
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
266
353
|
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
267
354
|
when supported and revalidate cached content with ETags.
|
|
@@ -330,28 +417,38 @@ Current behavior:
|
|
|
330
417
|
non-persisted follow-up session and submits the file contents as the next
|
|
331
418
|
user instruction; this is intended for side-effect follow-ups such as
|
|
332
419
|
Feishu notifications
|
|
333
|
-
- `/link <feishu-email|open_id|chat_id>`
|
|
334
|
-
|
|
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
|
|
335
423
|
one Feishu long-connection listener and route card actions by message id
|
|
336
424
|
- Feishu user OAuth stores its refresh token only in
|
|
337
425
|
`~/.codex/.feishu_refresh_token` (mode `0600`). Run
|
|
338
|
-
`
|
|
339
|
-
|
|
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
|
|
340
429
|
the latest token from the dedicated file and saves its replacement there.
|
|
341
430
|
`FEISHU_REFRESH_TOKEN` in `.env` or the environment is no longer used and
|
|
342
431
|
can be removed. Refresh is triggered by API calls, with no idle keepalive.
|
|
343
432
|
- `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
|
|
344
433
|
one process. The JSON file can be either a list or
|
|
345
|
-
`{"workspaces": [...]}`; each entry uses `
|
|
346
|
-
display/URL `id
|
|
347
|
-
`
|
|
348
|
-
|
|
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
|
|
349
442
|
resolve from the config file directory. The root path `/` shows a workspaces
|
|
350
|
-
management page with
|
|
351
|
-
`
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
|
355
452
|
images beside the board (including nested paths) with relative URLs; only
|
|
356
453
|
`image/*` files contained by the board directory are served.
|
|
357
454
|
Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
|
|
@@ -443,6 +540,13 @@ pycodex doctor --json
|
|
|
443
540
|
`Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
|
|
444
541
|
fresh machine, container, or debug image.
|
|
445
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
|
+
|
|
446
550
|
Use it like this:
|
|
447
551
|
|
|
448
552
|
```bash
|
|
@@ -636,7 +740,8 @@ CLI, Web and Feishu all use `AgentRuntime.submit_input`: not just `/model`
|
|
|
636
740
|
and `/resume`, but every session command, steer/queue admission, interactive
|
|
637
741
|
questions and permissions, state notifications and shutdown. Frontends only
|
|
638
742
|
adapt input and render events. Web no longer imports or runs the CLI shell.
|
|
639
|
-
|
|
743
|
+
Workspace assembly uses `pycodex_ws.build_runtime()` to add
|
|
744
|
+
`/link` and `/unlink`; `pycodex.bootstrap.build_runtime()` provides core commands.
|
|
640
745
|
|
|
641
746
|
```python
|
|
642
747
|
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,37 @@ 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
|
+
and optional Feishu integration. It owns the
|
|
25
|
+
`workspace_server` and `pycodex_ws` modules and the `pycodex-ws` command.
|
|
26
|
+
|
|
27
|
+
The Feishu SDK is not installed automatically. Install it in the workspace's
|
|
28
|
+
Python environment with `python3 -m pip install lark-oapi` to enable `/link`.
|
|
29
|
+
If `lark_oapi` cannot be imported, `/link` reports that it is unavailable.
|
|
30
|
+
|
|
31
|
+
Core does not require Pillow. Without it, `view_image` sends the original image
|
|
32
|
+
bytes with `detail="original"`, including when `high` is requested. With Pillow
|
|
33
|
+
installed, the default path retains resizing to a maximum dimension of 2048.
|
|
34
|
+
`pycodex-ws` installs Pillow for image preview validation.
|
|
35
|
+
|
|
36
|
+
Portable encryption uses a bundled pure Python AES-GCM subset of pyaes and
|
|
37
|
+
tlslite-ng, under MIT and BSD licenses. Core does not require a crypto package
|
|
38
|
+
or compiler and ships a `py3-none-any` wheel. Existing `PCX1` bundles and call
|
|
39
|
+
tokens remain compatible; large bundles take longer to encrypt and decrypt.
|
|
40
|
+
See the [source notes](pycodex/utils/_aes_gcm/README.md).
|
|
41
|
+
|
|
42
|
+
The Responses compatibility server and workspace HTTP server use Starlette
|
|
43
|
+
and Uvicorn directly. Neither package requires FastAPI, Pydantic or
|
|
44
|
+
`pydantic-core`. Python 3.6 uses Starlette 0.19.x; newer interpreters resolve
|
|
45
|
+
a compatible Starlette release through its Python version metadata.
|
|
45
46
|
|
|
46
47
|
This repository extracts the core Codex agent loop from upstream Codex
|
|
47
48
|
(`https://github.com/openai/codex`) into a deliberately small Python version,
|
|
@@ -61,16 +62,17 @@ Relevant Rust reference points:
|
|
|
61
62
|
|
|
62
63
|
## Quick Start
|
|
63
64
|
|
|
64
|
-
Install the
|
|
65
|
+
Install the core CLI, or install the workspace package for the browser frontend:
|
|
65
66
|
|
|
66
67
|
```bash
|
|
67
68
|
python3 -m pip install python-codex
|
|
68
69
|
python3 -m pip install pycodex-ws
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
The core supports Python 3.6.2 or newer. The workspace package requires Python
|
|
73
|
+
3.7 or newer. Commands are installed into
|
|
74
|
+
that interpreter's scripts directory. On a machine with multiple Python
|
|
75
|
+
installations, select the same interpreter explicitly for startup:
|
|
74
76
|
|
|
75
77
|
```bash
|
|
76
78
|
python3 -m pycodex
|
|
@@ -81,10 +83,14 @@ If `pycodex` is missing from `PATH` or resolves to an older installation, use th
|
|
|
81
83
|
module entry points. `python3 -m pip --version` shows which Python environment
|
|
82
84
|
received the installation.
|
|
83
85
|
|
|
86
|
+
For an existing Web installation, use `python3 -m pip install --upgrade pycodex-ws`
|
|
87
|
+
to upgrade the workspace and its matching core together. Installing only
|
|
88
|
+
`python-codex` provides the CLI and core API.
|
|
89
|
+
|
|
84
90
|
For development from this repository, install dependencies first:
|
|
85
91
|
|
|
86
92
|
```bash
|
|
87
|
-
uv sync
|
|
93
|
+
uv sync --dev
|
|
88
94
|
```
|
|
89
95
|
|
|
90
96
|
Try the real entry points:
|
|
@@ -94,8 +100,22 @@ uv run pycodex "Reply with exactly OK."
|
|
|
94
100
|
uv run pycodex
|
|
95
101
|
```
|
|
96
102
|
|
|
97
|
-
|
|
98
|
-
|
|
103
|
+
Tests are split by package. `uv run --dev pytest` runs both suites;
|
|
104
|
+
`uv run --dev pytest packages/pycodex-ws/tests` runs workspace and integration
|
|
105
|
+
tests. To check core without installing workspace, use a separate
|
|
106
|
+
environment:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv sync --group test
|
|
110
|
+
UV_PROJECT_ENVIRONMENT=.tmp/core-tests uv run --group test pytest tests
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
See [test environments and coverage](tests/TESTS.md). Core tests support Python
|
|
114
|
+
3.6.2+; workspace tests require Python 3.7+.
|
|
115
|
+
|
|
116
|
+
A VS Code frontend is available in [`packages/pycodex-ws/extensions/vscode`](packages/pycodex-ws/extensions/vscode/README.md).
|
|
117
|
+
It belongs to the workspace frontend and is packaged separately as a VSIX.
|
|
118
|
+
It reuses an existing `pycodex-ws>=0.4.0` installation. On first use, missing
|
|
99
119
|
or older backends are installed/upgraded with pip in the selected Python
|
|
100
120
|
environment on the workspace host; compatible versions need no network check.
|
|
101
121
|
It starts a dedicated `pycodex-ws` workspace on the project's host and opens a
|
|
@@ -143,19 +163,35 @@ nailing the core tool-augmented reasoning loop first.
|
|
|
143
163
|
|
|
144
164
|
## Layout
|
|
145
165
|
|
|
166
|
+
The top level of `pycodex/` contains the core components and package entry points.
|
|
167
|
+
Supporting services live in `tools/`, `portable/` and `utils/`.
|
|
168
|
+
|
|
169
|
+
- `pycodex/agent.py`: inner turn loop
|
|
170
|
+
- `pycodex/runtime.py`: session commands, submission queues and frontend event subscriptions
|
|
171
|
+
- `pycodex/model.py`: model client protocol and Responses API adapter
|
|
172
|
+
- `pycodex/context.py`: configuration, prompt assembly and instruction loading
|
|
146
173
|
- `pycodex/protocol.py`: minimal conversation item / prompt protocol
|
|
147
174
|
- `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
175
|
- `pycodex/bootstrap.py`: frontend-independent model, tools, Agent and session assembly
|
|
176
|
+
- `pycodex/cli.py`: single-turn/interactive entry points, terminal I/O executor and input loop
|
|
153
177
|
- `pycodex/tools/base_tool.py`: `BaseTool`, `ToolRegistry`, `ToolContext`
|
|
154
|
-
- `pycodex/tools
|
|
155
|
-
- `pycodex/
|
|
156
|
-
- `pycodex/
|
|
157
|
-
- `
|
|
158
|
-
- `
|
|
178
|
+
- `pycodex/tools/runtime_services.py`: plan, sub-agent, user-input and permissions services
|
|
179
|
+
- `pycodex/tools/`: concrete tools and their execution managers
|
|
180
|
+
- `pycodex/portable/`: Codex home storage client and server, both included in core
|
|
181
|
+
- `pycodex/utils/compat.py`: supported-Python compatibility helpers
|
|
182
|
+
- `pycodex/utils/doctor.py`: configuration and connectivity diagnostics
|
|
183
|
+
- `pycodex/utils/model_metadata.py`: vendored model metadata lookup
|
|
184
|
+
- `pycodex/utils/debug.py`: debug paths and the `pycodex.debug()` implementation
|
|
185
|
+
- `pycodex/utils/event_helpers.py`: stateless text, color, summary and result-formatting helpers
|
|
186
|
+
- `pycodex/utils/image_utils.py`: image loading, resizing and data-URL preparation
|
|
187
|
+
- `pycodex/prompts/`: vendored prompts and model metadata
|
|
188
|
+
- `packages/pycodex-ws/workspace_server/`: Web board, API and file/diff viewers
|
|
189
|
+
- `packages/pycodex-ws/pycodex_ws/`: Feishu and workspace assembly
|
|
190
|
+
- `packages/pycodex-ws/extensions/vscode/`: workspace's VS Code frontend, built separately as a VSIX
|
|
191
|
+
- `tests/`: core tests
|
|
192
|
+
- `packages/pycodex-ws/tests/`: workspace and cross-frontend integration tests
|
|
193
|
+
|
|
194
|
+
See [package layout and import paths](docs/RUNTIME.md#package-layout).
|
|
159
195
|
|
|
160
196
|
## Current Alignment Status
|
|
161
197
|
|
|
@@ -266,7 +302,7 @@ Current behavior:
|
|
|
266
302
|
- with an argv prompt or piped stdin, run a single turn
|
|
267
303
|
- `pycodex-ws` starts the standalone browser workspace manager and serves each
|
|
268
304
|
workspace with a board pane and a pycodex session pane
|
|
269
|
-
- the left pane is the board, containing
|
|
305
|
+
- the left pane is the board, containing an optional live HTML Canvas tab and closable read-only file/diff tabs that
|
|
270
306
|
scroll together in one toolbar; a mouse wheel scrolls overflowing tab strips
|
|
271
307
|
horizontally.
|
|
272
308
|
Click Markdown file links such as `[source](src/app.py:42)` or
|
|
@@ -285,6 +321,14 @@ Current behavior:
|
|
|
285
321
|
hover titles retain the complete paths and revisions. Text,
|
|
286
322
|
Markdown, HTML, common raster images and text diffs are supported. Monaco
|
|
287
323
|
provides syntax highlighting, find, folding and character-level diffs.
|
|
324
|
+
Right-click code and choose **Insert into chat**, or select text and use the
|
|
325
|
+
toolbar button, to insert context at the current chat draft's cursor.
|
|
326
|
+
Context appears as a separate block among your words. Click it to edit or
|
|
327
|
+
remove it; Backspace and Delete also remove a block as one element.
|
|
328
|
+
Context identifies the full view label, including both revisions of a diff.
|
|
329
|
+
Selections include only the selected text and range; otherwise it records the
|
|
330
|
+
cursor location. Diff context also identifies the selected side.
|
|
331
|
+
The draft stays editable until you send it.
|
|
288
332
|
Its code and styles load only when a code or diff view opens, so Canvas,
|
|
289
333
|
Markdown and HTML previews do not load the editor. Viewer assets use gzip
|
|
290
334
|
when supported and revalidate cached content with ETags.
|
|
@@ -353,28 +397,38 @@ Current behavior:
|
|
|
353
397
|
non-persisted follow-up session and submits the file contents as the next
|
|
354
398
|
user instruction; this is intended for side-effect follow-ups such as
|
|
355
399
|
Feishu notifications
|
|
356
|
-
- `/link <feishu-email|open_id|chat_id>`
|
|
357
|
-
|
|
400
|
+
- `/link <feishu-email|open_id|chat_id>` in a workspace session attaches it
|
|
401
|
+
to a Feishu card when the optional `lark-oapi` SDK can be imported;
|
|
402
|
+
multiple sessions in the same workspace process share
|
|
358
403
|
one Feishu long-connection listener and route card actions by message id
|
|
359
404
|
- Feishu user OAuth stores its refresh token only in
|
|
360
405
|
`~/.codex/.feishu_refresh_token` (mode `0600`). Run
|
|
361
|
-
`
|
|
362
|
-
|
|
406
|
+
`python3 -m pycodex_ws.feishu_oauth` after installing `pycodex-ws` to authorize.
|
|
407
|
+
From this repository, use `env -u VIRTUAL_ENV uv run --dev python -m pycodex_ws.feishu_oauth`.
|
|
408
|
+
App credentials can stay in `~/.codex/.env`. Each refresh reads
|
|
363
409
|
the latest token from the dedicated file and saves its replacement there.
|
|
364
410
|
`FEISHU_REFRESH_TOKEN` in `.env` or the environment is no longer used and
|
|
365
411
|
can be removed. Refresh is triggered by API calls, with no idle keepalive.
|
|
366
412
|
- `pycodex-ws --workspace-config workspaces.json` serves workspace boards from
|
|
367
413
|
one process. The JSON file can be either a list or
|
|
368
|
-
`{"workspaces": [...]}`; each entry uses `
|
|
369
|
-
display/URL `id
|
|
370
|
-
`
|
|
371
|
-
|
|
414
|
+
`{"workspaces": [...]}`; each entry uses `state_path` and `work_dir`, with optional
|
|
415
|
+
display/URL `id` and `enable_board` (default `true`), and is exposed at `/w/<id>/`.
|
|
416
|
+
`state_path` is a filename prefix: `/data/demo` uses
|
|
417
|
+
`/data/demo.pycodex-ws.json` for the session index,
|
|
418
|
+
`/data/demo.pycodex-views.json` for file views and `/data/demo.html` for Canvas.
|
|
419
|
+
Suffixes are appended, so prefixes containing dots remain distinct.
|
|
420
|
+
The resolved `state_path` is the workspace identity; duplicates are rejected
|
|
421
|
+
regardless of name or Canvas setting. Relative `state_path` and `work_dir` paths
|
|
372
422
|
resolve from the config file directory. The root path `/` shows a workspaces
|
|
373
|
-
management page with
|
|
374
|
-
`
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
423
|
+
management page with create/delete controls; omitted names become `workspace-1`,
|
|
424
|
+
`workspace-2`, etc. Omitted `state_path` when creating a workspace generates a
|
|
425
|
+
writable `/tmp/pcws-*` prefix. `enable_board: false` hides Canvas and disables its
|
|
426
|
+
routes, polling and context injection; sessions and file views still persist.
|
|
427
|
+
Existing `board: "demo.html"` and `board: false` configurations load with their
|
|
428
|
+
original state paths and are saved in the new format. See the
|
|
429
|
+
[workspace configuration example](packages/pycodex-ws/README.md).
|
|
430
|
+
Add/delete actions and later session-state saves refresh the JSON file.
|
|
431
|
+
Board HTML can reference local
|
|
378
432
|
images beside the board (including nested paths) with relative URLs; only
|
|
379
433
|
`image/*` files contained by the board directory are served.
|
|
380
434
|
Assistant Markdown supports KaTeX formulas with `$...$`, `$$...$$`,
|
|
@@ -466,6 +520,13 @@ pycodex doctor --json
|
|
|
466
520
|
`Portable Mode` is the quickest way to bring your usual `pycodex` setup into a
|
|
467
521
|
fresh machine, container, or debug image.
|
|
468
522
|
|
|
523
|
+
The storage client and server are both included in `python-codex`. To start a
|
|
524
|
+
local storage service, run this in a separate terminal:
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
python -m pycodex.portable.server --root .tmp/pycodex_storage --host 127.0.0.1 --port 5577
|
|
528
|
+
```
|
|
529
|
+
|
|
469
530
|
Use it like this:
|
|
470
531
|
|
|
471
532
|
```bash
|
|
@@ -659,7 +720,8 @@ CLI, Web and Feishu all use `AgentRuntime.submit_input`: not just `/model`
|
|
|
659
720
|
and `/resume`, but every session command, steer/queue admission, interactive
|
|
660
721
|
questions and permissions, state notifications and shutdown. Frontends only
|
|
661
722
|
adapt input and render events. Web no longer imports or runs the CLI shell.
|
|
662
|
-
|
|
723
|
+
Workspace assembly uses `pycodex_ws.build_runtime()` to add
|
|
724
|
+
`/link` and `/unlink`; `pycodex.bootstrap.build_runtime()` provides core commands.
|
|
663
725
|
|
|
664
726
|
```python
|
|
665
727
|
from pycodex.bootstrap import build_agent, build_model, build_runtime
|