codex-agent-framework 0.1.25__tar.gz → 0.1.26__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.
- {codex_agent_framework-0.1.25/codex_agent_framework.egg-info → codex_agent_framework-0.1.26}/PKG-INFO +16 -13
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/README.md +14 -11
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/agent.py +3 -3
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/ai.py +117 -93
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_commands.py +21 -10
- codex_agent_framework-0.1.26/codex_agent/builtin_plugins/context/__init__.py +190 -0
- codex_agent_framework-0.1.26/codex_agent/builtin_plugins/environment/__init__.py +152 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/image_generation/__init__.py +10 -4
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/interface/__init__.py +15 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/memory/__init__.py +13 -4
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/__init__.py +2 -2
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/subagents/__init__.py +4 -3
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +1 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/tts/__init__.py +1 -7
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/config.py +29 -2
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/context.py +3 -3
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/sessions.py +30 -19
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/status.py +1 -1
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/tui/chat.py +203 -103
- codex_agent_framework-0.1.26/codex_agent/version.py +1 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/worker.py +88 -40
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26/codex_agent_framework.egg-info}/PKG-INFO +16 -13
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent_framework.egg-info/SOURCES.txt +1 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent_framework.egg-info/requires.txt +1 -1
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/pyproject.toml +3 -2
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_agent.py +298 -238
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_ai.py +51 -14
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_chat.py +176 -36
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_hooks.py +7 -7
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_memory.py +65 -16
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_planner.py +9 -9
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_scheduler.py +5 -5
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_server.py +58 -58
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_worker.py +74 -51
- codex_agent_framework-0.1.25/codex_agent/builtin_plugins/environment/__init__.py +0 -285
- codex_agent_framework-0.1.25/codex_agent/version.py +0 -1
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/CHANGELOG.md +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/LICENSE +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/MANIFEST.in +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/__main__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/agent_runtime.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/browser.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/bash/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/content/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/content/system.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/content/vision.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/files/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/files/tools.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/python/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/manager.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/realtime/session.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/headless.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/main.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/output.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/root.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/cli/runner.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/client.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/command.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/desktop.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/event.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/get_text/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/get_text/default_gitignore +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/get_text/get_text.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/get_text/simpler_get_text.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/hooks.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/image.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/latex.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/mainloop.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/message.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/plugin.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/prompts/system_prompt.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/provider.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/runtime.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/scheduler.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/scripts/install-system-dependencies.sh +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/server/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/server/app.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/server/core.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/service.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/stream.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/stream_utils.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/tool.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/tray.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/tui/__init__.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/tui/lifecycle.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/utils.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent_framework.egg-info/entry_points.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent_framework.egg-info/top_level.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/dependencies.txt +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/setup.cfg +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_agent_runtime.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_browser.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_builtin_config.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_cli.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_cli_headless.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_cli_root.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_client.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_events.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_get_text_browser.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_image_message.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_local_desktop.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_messages.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_service.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_tray.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_tui.py +0 -0
- {codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-agent-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.26
|
|
4
4
|
Summary: A lightweight event-driven Codex agent runtime.
|
|
5
5
|
Author: Baptiste
|
|
6
6
|
License-Expression: MIT
|
|
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: audioop-lts; python_version >= "3.13"
|
|
19
19
|
Requires-Dist: beautifulsoup4
|
|
20
|
-
Requires-Dist: codex-backend-sdk
|
|
20
|
+
Requires-Dist: codex-backend-sdk>=0.3.1
|
|
21
21
|
Requires-Dist: fastapi
|
|
22
22
|
Requires-Dist: filetype
|
|
23
23
|
Requires-Dist: modict
|
|
@@ -176,17 +176,16 @@ agent = Agent(session="latest")
|
|
|
176
176
|
agent.interact()
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Voice
|
|
179
|
+
Voice features are disabled by default. The realtime voice plugin uses Codex/ChatGPT auth through `codex-backend-sdk`; the legacy synchronized TTS stream still uses the OpenAI SDK speech endpoint when explicitly enabled.
|
|
180
180
|
|
|
181
181
|
```python
|
|
182
182
|
from codex_agent import Agent
|
|
183
183
|
|
|
184
184
|
agent = Agent(
|
|
185
185
|
session="latest",
|
|
186
|
-
|
|
187
|
-
voice_enabled=True,
|
|
188
|
-
voice="nova",
|
|
186
|
+
builtin_plugins=["realtime", "memory", "planner", "scheduler"],
|
|
189
187
|
)
|
|
188
|
+
agent.load_builtin_plugin("realtime")
|
|
190
189
|
agent.interact()
|
|
191
190
|
```
|
|
192
191
|
|
|
@@ -473,7 +472,7 @@ The default agent includes practical local tools grouped as plugins:
|
|
|
473
472
|
| Desktop | `desktop_start_session`, `desktop_run_commands` | Screenshot-backed Linux desktop automation. |
|
|
474
473
|
| Subagents | `subagents_run` | Ephemeral child agents from predefined profiles. |
|
|
475
474
|
|
|
476
|
-
Current built-in plugin modules include `files`, `content`, `bash`, `python`, `interface`, `environment`, `memory`, `planner`, `scheduler`, `browser`, `desktop`, and `subagents`.
|
|
475
|
+
Current built-in plugin modules include `files`, `content`, `bash`, `python`, `interface`, `environment`, `context`, `memory`, `planner`, `scheduler`, `browser`, `desktop`, and `subagents`.
|
|
477
476
|
|
|
478
477
|
The `subagents` plugin ships an `explorer` profile: a read-only codebase inspection agent.
|
|
479
478
|
|
|
@@ -482,7 +481,7 @@ Select built-ins explicitly when you want a smaller agent:
|
|
|
482
481
|
```python
|
|
483
482
|
agent = Agent(
|
|
484
483
|
session="latest",
|
|
485
|
-
builtin_plugins=["files", "content", "bash", "python", "memory", "planner"],
|
|
484
|
+
builtin_plugins=["files", "content", "bash", "python", "environment", "context", "memory", "planner"],
|
|
486
485
|
)
|
|
487
486
|
```
|
|
488
487
|
|
|
@@ -534,8 +533,8 @@ from codex_agent import Agent
|
|
|
534
533
|
agent = Agent(
|
|
535
534
|
session="latest",
|
|
536
535
|
model="gpt-5.5",
|
|
537
|
-
|
|
538
|
-
|
|
536
|
+
reasoning={"effort": "medium", "summary": "auto"},
|
|
537
|
+
text={"verbosity": "medium"},
|
|
539
538
|
input_token_limit=128000,
|
|
540
539
|
auto_compact=True,
|
|
541
540
|
web_search_enabled=False,
|
|
@@ -550,9 +549,8 @@ Or update saved config from the CLI:
|
|
|
550
549
|
```bash
|
|
551
550
|
codex-agent config get
|
|
552
551
|
codex-agent config set input_token_limit 128000
|
|
553
|
-
codex-agent config set
|
|
554
|
-
codex-agent config set
|
|
555
|
-
codex-agent config set --no-save verbosity low
|
|
552
|
+
codex-agent config set builtin_plugins='["environment", "context", "memory", "planner", "scheduler", "realtime"]'
|
|
553
|
+
codex-agent config set --no-save text='{"verbosity":"low"}'
|
|
556
554
|
```
|
|
557
555
|
|
|
558
556
|
Saved local state lives in `~/.codex-agent` by default:
|
|
@@ -622,8 +620,13 @@ python -m build
|
|
|
622
620
|
python -m twine check dist/*
|
|
623
621
|
```
|
|
624
622
|
|
|
623
|
+
### Auth model for backend-backed features
|
|
624
|
+
|
|
625
|
+
Core LLM calls, memory embeddings, non-streaming STT transcription, and realtime voice use the Codex backend SDK with Codex/ChatGPT auth. Legacy synchronized TTS playback and OpenAI input-token counting still use the OpenAI SDK and may require `openai_api_key` or `OPENAI_API_KEY` when those paths are enabled.
|
|
626
|
+
|
|
625
627
|
## Recent releases
|
|
626
628
|
|
|
629
|
+
- `0.1.26`: align SDK-facing config with Responses API shapes, add the `context` management plugin with selective non-destructive wrapper pruning, keep wrappers out of memory retrieval and compaction payloads, move embeddings/STT/realtime onto Codex backend auth, streamline voice/TTS plugin config, and improve TUI streaming/windowing.
|
|
627
630
|
- `0.1.25`: move built-in capabilities further into plugin-scoped modules, add bundled plugin requirement metadata, and replace the TUI conversation pane with a selectable rich chat area that preserves mouse scrolling, copy selection, lazy transcript loading, and bottom-aware auto-scroll.
|
|
628
631
|
- `0.1.24`: add slash-command lifecycle events and TUI progress/result rendering so commands such as `/compact` and `/help` show running, done, failed, result, and error feedback instead of going silent.
|
|
629
632
|
- `0.1.23`: add SDK event streaming with `Agent.stream()`, root `Agent.add_plugin()`, a faster README flow, the `~/.codex-agent` runtime default, text-first voice defaults, safer prompt templating limited to system messages, smarter `codex-agent` local-server attachment, and clearer TUI tool-call progress lines.
|
|
@@ -127,17 +127,16 @@ agent = Agent(session="latest")
|
|
|
127
127
|
agent.interact()
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
Voice
|
|
130
|
+
Voice features are disabled by default. The realtime voice plugin uses Codex/ChatGPT auth through `codex-backend-sdk`; the legacy synchronized TTS stream still uses the OpenAI SDK speech endpoint when explicitly enabled.
|
|
131
131
|
|
|
132
132
|
```python
|
|
133
133
|
from codex_agent import Agent
|
|
134
134
|
|
|
135
135
|
agent = Agent(
|
|
136
136
|
session="latest",
|
|
137
|
-
|
|
138
|
-
voice_enabled=True,
|
|
139
|
-
voice="nova",
|
|
137
|
+
builtin_plugins=["realtime", "memory", "planner", "scheduler"],
|
|
140
138
|
)
|
|
139
|
+
agent.load_builtin_plugin("realtime")
|
|
141
140
|
agent.interact()
|
|
142
141
|
```
|
|
143
142
|
|
|
@@ -424,7 +423,7 @@ The default agent includes practical local tools grouped as plugins:
|
|
|
424
423
|
| Desktop | `desktop_start_session`, `desktop_run_commands` | Screenshot-backed Linux desktop automation. |
|
|
425
424
|
| Subagents | `subagents_run` | Ephemeral child agents from predefined profiles. |
|
|
426
425
|
|
|
427
|
-
Current built-in plugin modules include `files`, `content`, `bash`, `python`, `interface`, `environment`, `memory`, `planner`, `scheduler`, `browser`, `desktop`, and `subagents`.
|
|
426
|
+
Current built-in plugin modules include `files`, `content`, `bash`, `python`, `interface`, `environment`, `context`, `memory`, `planner`, `scheduler`, `browser`, `desktop`, and `subagents`.
|
|
428
427
|
|
|
429
428
|
The `subagents` plugin ships an `explorer` profile: a read-only codebase inspection agent.
|
|
430
429
|
|
|
@@ -433,7 +432,7 @@ Select built-ins explicitly when you want a smaller agent:
|
|
|
433
432
|
```python
|
|
434
433
|
agent = Agent(
|
|
435
434
|
session="latest",
|
|
436
|
-
builtin_plugins=["files", "content", "bash", "python", "memory", "planner"],
|
|
435
|
+
builtin_plugins=["files", "content", "bash", "python", "environment", "context", "memory", "planner"],
|
|
437
436
|
)
|
|
438
437
|
```
|
|
439
438
|
|
|
@@ -485,8 +484,8 @@ from codex_agent import Agent
|
|
|
485
484
|
agent = Agent(
|
|
486
485
|
session="latest",
|
|
487
486
|
model="gpt-5.5",
|
|
488
|
-
|
|
489
|
-
|
|
487
|
+
reasoning={"effort": "medium", "summary": "auto"},
|
|
488
|
+
text={"verbosity": "medium"},
|
|
490
489
|
input_token_limit=128000,
|
|
491
490
|
auto_compact=True,
|
|
492
491
|
web_search_enabled=False,
|
|
@@ -501,9 +500,8 @@ Or update saved config from the CLI:
|
|
|
501
500
|
```bash
|
|
502
501
|
codex-agent config get
|
|
503
502
|
codex-agent config set input_token_limit 128000
|
|
504
|
-
codex-agent config set
|
|
505
|
-
codex-agent config set
|
|
506
|
-
codex-agent config set --no-save verbosity low
|
|
503
|
+
codex-agent config set builtin_plugins='["environment", "context", "memory", "planner", "scheduler", "realtime"]'
|
|
504
|
+
codex-agent config set --no-save text='{"verbosity":"low"}'
|
|
507
505
|
```
|
|
508
506
|
|
|
509
507
|
Saved local state lives in `~/.codex-agent` by default:
|
|
@@ -573,8 +571,13 @@ python -m build
|
|
|
573
571
|
python -m twine check dist/*
|
|
574
572
|
```
|
|
575
573
|
|
|
574
|
+
### Auth model for backend-backed features
|
|
575
|
+
|
|
576
|
+
Core LLM calls, memory embeddings, non-streaming STT transcription, and realtime voice use the Codex backend SDK with Codex/ChatGPT auth. Legacy synchronized TTS playback and OpenAI input-token counting still use the OpenAI SDK and may require `openai_api_key` or `OPENAI_API_KEY` when those paths are enabled.
|
|
577
|
+
|
|
576
578
|
## Recent releases
|
|
577
579
|
|
|
580
|
+
- `0.1.26`: align SDK-facing config with Responses API shapes, add the `context` management plugin with selective non-destructive wrapper pruning, keep wrappers out of memory retrieval and compaction payloads, move embeddings/STT/realtime onto Codex backend auth, streamline voice/TTS plugin config, and improve TUI streaming/windowing.
|
|
578
581
|
- `0.1.25`: move built-in capabilities further into plugin-scoped modules, add bundled plugin requirement metadata, and replace the TUI conversation pane with a selectable rich chat area that preserves mouse scrolling, copy selection, lazy transcript loading, and bottom-aware auto-scroll.
|
|
579
582
|
- `0.1.24`: add slash-command lifecycle events and TUI progress/result rendering so commands such as `/compact` and `/help` show running, done, failed, result, and error feedback instead of going silent.
|
|
580
583
|
- `0.1.23`: add SDK event streaming with `Agent.stream()`, root `Agent.add_plugin()`, a faster README flow, the `~/.codex-agent` runtime default, text-first voice defaults, safer prompt templating limited to system messages, smarter `codex-agent` local-server attachment, and clearer TUI tool-call progress lines.
|
|
@@ -200,12 +200,12 @@ class Agent:
|
|
|
200
200
|
def save_session(self):
|
|
201
201
|
return self.sessions_manager.save()
|
|
202
202
|
|
|
203
|
-
def compact_session(self, client=None, model=None, instructions=None,
|
|
203
|
+
def compact_session(self, client=None, model=None, instructions=None, max_compacted_turns=None):
|
|
204
204
|
return self.sessions_manager.compact(
|
|
205
205
|
client=client,
|
|
206
206
|
model=model,
|
|
207
207
|
instructions=instructions,
|
|
208
|
-
|
|
208
|
+
max_compacted_turns=max_compacted_turns,
|
|
209
209
|
)
|
|
210
210
|
|
|
211
211
|
def add_message(self,msg,pending=False):
|
|
@@ -363,7 +363,7 @@ class Agent:
|
|
|
363
363
|
messages=messages,
|
|
364
364
|
tools=self.tools_manager.get_response_tools(),
|
|
365
365
|
prompt_cache_key=self.current_session_id,
|
|
366
|
-
**self.config.extract('model','
|
|
366
|
+
**self.config.extract('model','reasoning','text','parallel_tool_calls')
|
|
367
367
|
)
|
|
368
368
|
self.sessions_manager.append_message(message)
|
|
369
369
|
for item in message.output_items:
|
|
@@ -21,16 +21,7 @@ from .event import (
|
|
|
21
21
|
ResponseToolCallsDeltaEvent,
|
|
22
22
|
ServerToolCallEvent,
|
|
23
23
|
)
|
|
24
|
-
from codex_backend_sdk import
|
|
25
|
-
CodexClient,
|
|
26
|
-
OutputItem,
|
|
27
|
-
ResponseAborted,
|
|
28
|
-
ResponseCompleted,
|
|
29
|
-
ReasoningDelta,
|
|
30
|
-
ResponseFailed,
|
|
31
|
-
TextDelta,
|
|
32
|
-
ToolCall,
|
|
33
|
-
)
|
|
24
|
+
from codex_backend_sdk import CodexClient
|
|
34
25
|
|
|
35
26
|
class ChunkStreamer(MappingStreamProcessor):
|
|
36
27
|
"""Stream processor for AI response chunks, handling content, reasoning, and tool calls.
|
|
@@ -61,14 +52,14 @@ class AIBadRequestError(AIClientError):
|
|
|
61
52
|
|
|
62
53
|
|
|
63
54
|
class APIAuthenticationError(AIClientError):
|
|
64
|
-
"""Exception raised for
|
|
55
|
+
"""Exception raised for API authentication failures."""
|
|
65
56
|
pass
|
|
66
57
|
|
|
67
58
|
|
|
68
59
|
MAX_EMBEDDING_INPUT_TOKENS = 7500
|
|
69
60
|
|
|
70
61
|
class AIClient:
|
|
71
|
-
"""Client for Codex backend LLM calls
|
|
62
|
+
"""Client for Codex backend LLM/embedding/STT calls plus OpenAI-key TTS/token helpers."""
|
|
72
63
|
|
|
73
64
|
def __init__(self, agent):
|
|
74
65
|
"""Initialize AI clients from agent config.
|
|
@@ -99,11 +90,11 @@ class AIClient:
|
|
|
99
90
|
"""Client used for LLM calls through the ChatGPT Codex backend."""
|
|
100
91
|
if self._codex_client is None:
|
|
101
92
|
model = self.agent.config.get('model') or "gpt-5.4"
|
|
102
|
-
self._codex_client = CodexClient(model=model).authenticate()
|
|
93
|
+
self._codex_client = CodexClient(model=model).authenticate(request_api_key=False)
|
|
103
94
|
return self._codex_client
|
|
104
95
|
|
|
105
96
|
def abort(self):
|
|
106
|
-
if self._codex_client is not None:
|
|
97
|
+
if self._codex_client is not None and hasattr(self._codex_client, "abort"):
|
|
107
98
|
self._codex_client.abort()
|
|
108
99
|
|
|
109
100
|
def api_key_is_valid(self):
|
|
@@ -168,70 +159,63 @@ class AIClient:
|
|
|
168
159
|
def audio_to_text(
|
|
169
160
|
self,
|
|
170
161
|
source: Union[str, io.BytesIO, bytes],
|
|
171
|
-
model: str = "
|
|
162
|
+
model: str = "gpt-4o-mini-transcribe",
|
|
172
163
|
language: str = None,
|
|
173
164
|
prompt: str = None,
|
|
174
165
|
response_format: str = "text",
|
|
175
166
|
temperature: float = 0.0
|
|
176
167
|
) -> str:
|
|
177
168
|
"""
|
|
178
|
-
Convert audio to text using
|
|
169
|
+
Convert audio to text using the Codex backend SDK OAuth client.
|
|
179
170
|
|
|
180
171
|
Args:
|
|
181
172
|
source: Audio data as file_path string, BytesIO object or bytes
|
|
182
|
-
model:
|
|
173
|
+
model: Transcription model to use (default: "gpt-4o-mini-transcribe")
|
|
183
174
|
language: ISO-639-1 language code (e.g., "en", "fr"). If None, language is auto-detected.
|
|
184
175
|
prompt: Optional text to guide the model's style
|
|
185
176
|
response_format: Format of output ("text", "json", "verbose_json", "srt", "vtt")
|
|
186
177
|
temperature: Sampling temperature between 0 and 1 (default: 0.0)
|
|
187
178
|
|
|
188
179
|
Returns:
|
|
189
|
-
Transcribed text as a string
|
|
180
|
+
Transcribed text as a string, or raw subtitle text for srt/vtt formats.
|
|
190
181
|
"""
|
|
182
|
+
filename = "audio.mp3"
|
|
191
183
|
if isinstance(source, str) and os.path.isfile(source):
|
|
184
|
+
filename = os.path.basename(source) or filename
|
|
192
185
|
with open(source, "rb") as f:
|
|
193
186
|
audio = io.BytesIO(f.read())
|
|
194
187
|
elif isinstance(source, bytes):
|
|
195
|
-
|
|
188
|
+
audio = io.BytesIO(source)
|
|
196
189
|
elif isinstance(source, io.BytesIO):
|
|
197
190
|
audio = source
|
|
191
|
+
filename = getattr(source, "name", filename) or filename
|
|
198
192
|
else:
|
|
199
193
|
raise NotImplementedError(f"Unsupported audio source: {source}")
|
|
200
194
|
|
|
201
|
-
# Ensure the BytesIO object is at the start
|
|
202
195
|
audio.seek(0)
|
|
196
|
+
audio.name = filename
|
|
203
197
|
|
|
204
|
-
# Prepare the file for upload
|
|
205
|
-
audio.name = "audio.mp3" # Add a name attribute
|
|
206
|
-
|
|
207
|
-
# Prepare transcription parameters
|
|
208
198
|
transcription_params = {
|
|
209
199
|
"model": model,
|
|
210
200
|
"file": audio,
|
|
211
201
|
"response_format": response_format,
|
|
212
|
-
"temperature": temperature
|
|
202
|
+
"temperature": temperature,
|
|
213
203
|
}
|
|
214
|
-
|
|
215
|
-
# Add optional parameters if provided
|
|
216
204
|
if language:
|
|
217
205
|
transcription_params["language"] = language
|
|
218
206
|
if prompt:
|
|
219
207
|
transcription_params["prompt"] = prompt
|
|
220
208
|
|
|
221
|
-
# Call OpenAI transcription API (retries handled by client)
|
|
222
209
|
try:
|
|
223
|
-
transcript = self.
|
|
210
|
+
transcript = self.codex_client.audio.transcriptions.create(**transcription_params)
|
|
224
211
|
except Exception as e:
|
|
225
|
-
raise AIClientError(f"Failed to transcribe audio: {str(e)}")
|
|
212
|
+
raise AIClientError(f"Failed to transcribe audio with Codex backend SDK: {str(e)}")
|
|
226
213
|
|
|
227
|
-
|
|
228
|
-
if response_format == "text":
|
|
214
|
+
if isinstance(transcript, str):
|
|
229
215
|
return transcript
|
|
230
|
-
|
|
216
|
+
if hasattr(transcript, "text"):
|
|
231
217
|
return transcript.text
|
|
232
|
-
|
|
233
|
-
# For srt and vtt formats, return as-is
|
|
234
|
-
return transcript
|
|
218
|
+
return transcript
|
|
235
219
|
|
|
236
220
|
def _stream_chunks(self, params):
|
|
237
221
|
params['tools'] = [
|
|
@@ -240,11 +224,8 @@ class AIClient:
|
|
|
240
224
|
] or None
|
|
241
225
|
|
|
242
226
|
try:
|
|
243
|
-
|
|
244
|
-
response = self.codex_client.stream
|
|
245
|
-
stream_params.pop('user_message'),
|
|
246
|
-
**stream_params
|
|
247
|
-
)
|
|
227
|
+
response_params = self._to_codex_response_params(params)
|
|
228
|
+
response = self.codex_client.responses.create(**response_params, stream=True)
|
|
248
229
|
except Exception as e:
|
|
249
230
|
if self.is_bad_request_error(e):
|
|
250
231
|
raise AIBadRequestError(str(e)) from e
|
|
@@ -259,10 +240,11 @@ class AIClient:
|
|
|
259
240
|
tool_call_index = 0
|
|
260
241
|
for event in self._iter_response_events(response):
|
|
261
242
|
self.agent.mainloop_manager.touch_activity("response_stream")
|
|
262
|
-
if
|
|
243
|
+
if getattr(event, "type", None) == "response.completed":
|
|
244
|
+
completed = self._event_response(event)
|
|
263
245
|
self.agent.status_manager.cache_api_status(
|
|
264
|
-
usage=
|
|
265
|
-
model=
|
|
246
|
+
usage=modict(completed.get("usage") or {}),
|
|
247
|
+
model=completed.get("model") or response_params.get("model"),
|
|
266
248
|
quota=self.get_quota_usage(),
|
|
267
249
|
)
|
|
268
250
|
continue
|
|
@@ -271,8 +253,6 @@ class AIClient:
|
|
|
271
253
|
tool_call_index += 1
|
|
272
254
|
if msg_chunk:
|
|
273
255
|
yield msg_chunk
|
|
274
|
-
except ResponseAborted:
|
|
275
|
-
raise AssistantInterrupted()
|
|
276
256
|
except Exception as e:
|
|
277
257
|
if self.is_bad_request_error(e):
|
|
278
258
|
raise AIBadRequestError(str(e)) from e
|
|
@@ -325,7 +305,7 @@ class AIClient:
|
|
|
325
305
|
|
|
326
306
|
def get_quota_usage(self):
|
|
327
307
|
try:
|
|
328
|
-
return self.codex_client.usage()
|
|
308
|
+
return self.codex_client.codex.usage()
|
|
329
309
|
except Exception:
|
|
330
310
|
return None
|
|
331
311
|
|
|
@@ -356,59 +336,103 @@ class AIClient:
|
|
|
356
336
|
history.append(response_format)
|
|
357
337
|
return "\n\n".join(instructions), history
|
|
358
338
|
|
|
359
|
-
def
|
|
339
|
+
def _to_codex_response_params(self, params):
|
|
360
340
|
instructions, history = self._split_codex_messages(params.get("messages", []))
|
|
361
341
|
tools = params.get("tools") or []
|
|
362
|
-
reasoning = params.get("reasoning_effort")
|
|
363
342
|
model = params.get("model") or "gpt-5.4"
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
"
|
|
368
|
-
|
|
343
|
+
reasoning = modict(params.get("reasoning") or {})
|
|
344
|
+
text = modict(params.get("text") or {})
|
|
345
|
+
if not reasoning and params.get("reasoning_effort"):
|
|
346
|
+
reasoning = modict(effort=params.get("reasoning_effort"), summary="auto")
|
|
347
|
+
if not text and params.get("verbosity"):
|
|
348
|
+
text = modict(verbosity=params.get("verbosity"))
|
|
349
|
+
payload = {
|
|
350
|
+
"input": history,
|
|
369
351
|
"instructions": instructions,
|
|
370
352
|
"model": model,
|
|
371
|
-
"verbosity": verbosity,
|
|
372
353
|
"tools": tools or None,
|
|
373
354
|
"tool_choice": "auto" if tools else "none",
|
|
374
|
-
"parallel_tool_calls":
|
|
375
|
-
"reasoning": reasoning,
|
|
376
|
-
"reasoning_summary": "auto" if reasoning else None,
|
|
377
|
-
"include_reasoning": bool(reasoning),
|
|
355
|
+
"parallel_tool_calls": params.get("parallel_tool_calls"),
|
|
378
356
|
"prompt_cache_key": params.get("prompt_cache_key"),
|
|
379
357
|
}
|
|
358
|
+
if reasoning:
|
|
359
|
+
payload["reasoning"] = reasoning
|
|
360
|
+
payload["include"] = ["reasoning.encrypted_content"]
|
|
361
|
+
if text:
|
|
362
|
+
payload["text"] = text
|
|
363
|
+
return payload
|
|
380
364
|
|
|
381
365
|
def _codex_event_to_message_chunk(self, event, tool_call_index=0):
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
366
|
+
event_type = getattr(event, "type", "")
|
|
367
|
+
if event_type in {"response.output_text.delta", "response.content_part.delta"}:
|
|
368
|
+
return MessageChunk(content=self._event_delta_text(event))
|
|
369
|
+
if event_type == "response.reasoning_summary_part.delta":
|
|
370
|
+
return MessageChunk(reasoning=self._event_delta_text(event))
|
|
371
|
+
if event_type == "response.output_item.done":
|
|
372
|
+
item = modict(getattr(event, "item", None) or {})
|
|
373
|
+
if item.get("type") in {"function_call", "custom_tool_call"}:
|
|
374
|
+
return self._tool_call_item_to_message_chunk(item, tool_call_index)
|
|
375
|
+
if item.get("type") == "reasoning":
|
|
376
|
+
return MessageChunk(reasoning=self._reasoning_item_text(item))
|
|
377
|
+
return MessageChunk(output_items=[item])
|
|
378
|
+
if event_type in {"response.failed", "error"}:
|
|
379
|
+
error = self._event_error(event)
|
|
380
|
+
code = str(error.get("code") or "")
|
|
381
|
+
message = str(error.get("message") or "Response failed")
|
|
382
|
+
if code == "400" or "bad_request" in code.lower():
|
|
383
|
+
raise AIBadRequestError(message)
|
|
384
|
+
return MessageChunk(
|
|
385
|
+
content=(
|
|
386
|
+
"Hmmm, sorry! The Codex backend returned an error:\n\n"
|
|
387
|
+
f"```\n[{code or 'error'}] {message}\n```"
|
|
388
|
+
)
|
|
389
|
+
)
|
|
390
|
+
return None
|
|
391
|
+
|
|
392
|
+
def _tool_call_item_to_message_chunk(self, item, tool_call_index=0):
|
|
393
|
+
if item.get("type") == "custom_tool_call":
|
|
387
394
|
tool_call = modict({
|
|
388
395
|
"index": tool_call_index,
|
|
389
|
-
"type": "
|
|
390
|
-
"call_id":
|
|
391
|
-
"name":
|
|
392
|
-
"
|
|
396
|
+
"type": "custom_tool_call",
|
|
397
|
+
"call_id": item.get("call_id", ""),
|
|
398
|
+
"name": item.get("name", ""),
|
|
399
|
+
"input": item.get("input", ""),
|
|
393
400
|
})
|
|
394
401
|
return MessageChunk(tool_calls=[tool_call])
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
402
|
+
tool_call = modict({
|
|
403
|
+
"index": tool_call_index,
|
|
404
|
+
"type": "function_call",
|
|
405
|
+
"call_id": item.get("call_id", ""),
|
|
406
|
+
"name": item.get("name", ""),
|
|
407
|
+
"arguments": item.get("arguments", "{}"),
|
|
408
|
+
})
|
|
409
|
+
return MessageChunk(tool_calls=[tool_call])
|
|
410
|
+
|
|
411
|
+
def _event_delta_text(self, event):
|
|
412
|
+
delta = getattr(event, "delta", "")
|
|
413
|
+
if isinstance(delta, dict):
|
|
414
|
+
return delta.get("text", "")
|
|
415
|
+
return delta or ""
|
|
416
|
+
|
|
417
|
+
def _reasoning_item_text(self, item):
|
|
418
|
+
parts = []
|
|
419
|
+
for part in item.get("summary") or []:
|
|
420
|
+
if isinstance(part, dict):
|
|
421
|
+
parts.append(part.get("text", ""))
|
|
422
|
+
return "".join(parts) or item.get("encrypted_content", "")
|
|
423
|
+
|
|
424
|
+
def _event_response(self, event):
|
|
425
|
+
response = getattr(event, "response", None)
|
|
426
|
+
if hasattr(response, "model_dump"):
|
|
427
|
+
return response.model_dump()
|
|
428
|
+
return response if isinstance(response, dict) else {}
|
|
429
|
+
|
|
430
|
+
def _event_error(self, event):
|
|
431
|
+
response = self._event_response(event)
|
|
432
|
+
error = response.get("error") or getattr(event, "error", None) or {}
|
|
433
|
+
if hasattr(error, "model_dump"):
|
|
434
|
+
return error.model_dump()
|
|
435
|
+
return error if isinstance(error, dict) else {"message": str(error)}
|
|
412
436
|
|
|
413
437
|
def run(self, **params):
|
|
414
438
|
stream = ChunkStreamer(self.agent)(self._stream_chunks(params))
|
|
@@ -481,13 +505,13 @@ class AIClient:
|
|
|
481
505
|
|
|
482
506
|
def embed_content(self, content: str, precision=5, dimensions=128, model="text-embedding-3-small"):
|
|
483
507
|
"""
|
|
484
|
-
Embed a text string using
|
|
508
|
+
Embed a text string using the Codex backend SDK OAuth client.
|
|
485
509
|
|
|
486
510
|
Args:
|
|
487
511
|
content: Text string to embed
|
|
488
512
|
precision: Number of decimal places for rounding (default: 5)
|
|
489
513
|
dimensions: Embedding dimensions (default: 128)
|
|
490
|
-
model:
|
|
514
|
+
model: Embedding model to use (default: text-embedding-3-small)
|
|
491
515
|
|
|
492
516
|
Returns:
|
|
493
517
|
A normalized embedding vector
|
|
@@ -499,7 +523,7 @@ class AIClient:
|
|
|
499
523
|
raise ValueError("Content must not be empty")
|
|
500
524
|
|
|
501
525
|
try:
|
|
502
|
-
response = self.
|
|
526
|
+
response = self.codex_client.embeddings.create(
|
|
503
527
|
model=model,
|
|
504
528
|
input=content,
|
|
505
529
|
dimensions=dimensions
|
|
@@ -512,19 +536,19 @@ class AIClient:
|
|
|
512
536
|
|
|
513
537
|
def embed_contents(self, contents: List[str], precision=5, dimensions=128, model="text-embedding-3-small"):
|
|
514
538
|
"""
|
|
515
|
-
Embed multiple text strings using
|
|
539
|
+
Embed multiple text strings using the Codex backend SDK OAuth client.
|
|
516
540
|
|
|
517
541
|
Args:
|
|
518
542
|
contents: List of text strings to embed
|
|
519
543
|
precision: Number of decimal places for rounding (default: 5)
|
|
520
544
|
dimensions: Embedding dimensions (default: 128)
|
|
521
|
-
model:
|
|
545
|
+
model: Embedding model to use (default: text-embedding-3-small)
|
|
522
546
|
|
|
523
547
|
Returns:
|
|
524
548
|
List of normalized embedding vectors
|
|
525
549
|
|
|
526
550
|
Note:
|
|
527
|
-
|
|
551
|
+
The embeddings API handles batching automatically for better performance.
|
|
528
552
|
"""
|
|
529
553
|
if not contents:
|
|
530
554
|
return []
|
|
@@ -535,7 +559,7 @@ class AIClient:
|
|
|
535
559
|
raise ValueError("Embedding contents must not contain empty strings")
|
|
536
560
|
|
|
537
561
|
try:
|
|
538
|
-
response = self.
|
|
562
|
+
response = self.codex_client.embeddings.create(
|
|
539
563
|
model=model,
|
|
540
564
|
input=contents,
|
|
541
565
|
dimensions=dimensions
|
|
@@ -569,7 +593,7 @@ class AIClient:
|
|
|
569
593
|
msg: Message object with text content
|
|
570
594
|
precision: Number of decimal places for rounding (default: 5)
|
|
571
595
|
dimensions: Embedding dimensions (default: 128)
|
|
572
|
-
model:
|
|
596
|
+
model: Embedding model to use through the Codex backend SDK (default: text-embedding-3-small)
|
|
573
597
|
|
|
574
598
|
Returns:
|
|
575
599
|
The embedding vector (also assigned to msg.embedding)
|
{codex_agent_framework-0.1.25 → codex_agent_framework-0.1.26}/codex_agent/builtin_commands.py
RENAMED
|
@@ -6,8 +6,9 @@ from .tool import get_agent
|
|
|
6
6
|
|
|
7
7
|
MODEL_CONFIG_KEYS = (
|
|
8
8
|
"model",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"reasoning",
|
|
10
|
+
"text",
|
|
11
|
+
"parallel_tool_calls",
|
|
11
12
|
"input_token_limit",
|
|
12
13
|
"max_input_tokens",
|
|
13
14
|
"auto_compact",
|
|
@@ -27,6 +28,9 @@ def parse_config_value(value):
|
|
|
27
28
|
return False
|
|
28
29
|
if value.isdigit():
|
|
29
30
|
return int(value)
|
|
31
|
+
if (value.startswith("{") and value.endswith("}")) or (value.startswith("[") and value.endswith("]")):
|
|
32
|
+
import json
|
|
33
|
+
return json.loads(value)
|
|
30
34
|
return value
|
|
31
35
|
|
|
32
36
|
|
|
@@ -53,19 +57,19 @@ def help():
|
|
|
53
57
|
|
|
54
58
|
|
|
55
59
|
@command
|
|
56
|
-
def compact(
|
|
60
|
+
def compact(max_compacted_turns=None):
|
|
57
61
|
agent = get_agent()
|
|
58
|
-
|
|
62
|
+
max_compacted_turns = None if max_compacted_turns in (None, "", "all") else int(max_compacted_turns)
|
|
59
63
|
message = agent.compact_session(
|
|
60
64
|
model=agent.config.model,
|
|
61
65
|
instructions=agent.config_manager.system_message().content,
|
|
62
|
-
|
|
66
|
+
max_compacted_turns=max_compacted_turns,
|
|
63
67
|
)
|
|
64
68
|
if message is None:
|
|
65
69
|
return "Nothing to compact."
|
|
66
70
|
if message.get("status") == "failed":
|
|
67
71
|
return f"Compaction failed: {message.error}"
|
|
68
|
-
suffix = "" if
|
|
72
|
+
suffix = "" if max_compacted_turns is None else f" from {max_compacted_turns} compacted turn(s)"
|
|
69
73
|
return f"Compacted {message.compacted_message_count} messages{suffix}."
|
|
70
74
|
|
|
71
75
|
|
|
@@ -129,13 +133,20 @@ def model(value=None):
|
|
|
129
133
|
|
|
130
134
|
@command
|
|
131
135
|
def reasoning(value=None):
|
|
136
|
+
agent = get_agent()
|
|
132
137
|
if value is None:
|
|
133
|
-
return f"
|
|
134
|
-
|
|
138
|
+
return f"reasoning: {agent.config.get('reasoning')!r}"
|
|
139
|
+
current = dict(agent.config.get("reasoning") or {})
|
|
140
|
+
current["effort"] = value
|
|
141
|
+
current.setdefault("summary", "auto")
|
|
142
|
+
return update_model_config(reasoning=current)
|
|
135
143
|
|
|
136
144
|
|
|
137
145
|
@command
|
|
138
146
|
def verbosity(value=None):
|
|
147
|
+
agent = get_agent()
|
|
139
148
|
if value is None:
|
|
140
|
-
return f"
|
|
141
|
-
|
|
149
|
+
return f"text: {agent.config.get('text')!r}"
|
|
150
|
+
current = dict(agent.config.get("text") or {})
|
|
151
|
+
current["verbosity"] = value
|
|
152
|
+
return update_model_config(text=current)
|