codex-agent-framework 0.1.28__tar.gz → 0.1.30__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.28 → codex_agent_framework-0.1.30}/CHANGELOG.md +13 -0
- codex_agent_framework-0.1.30/PKG-INFO +220 -0
- codex_agent_framework-0.1.30/README.md +171 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/agent.py +52 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/agent_runtime.py +7 -6
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_commands.py +2 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/bash/__init__.py +2 -1
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/content/system.py +1 -1
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/content/vision.py +19 -3
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/environment/__init__.py +62 -1
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/files/tools.py +6 -3
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/python/__init__.py +6 -3
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/client.py +81 -14
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/config.py +2 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/mainloop.py +4 -1
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/server/app.py +7 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/server/core.py +2 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/sessions.py +44 -8
- codex_agent_framework-0.1.30/codex_agent/tui/app.py +226 -0
- codex_agent_framework-0.1.30/codex_agent/tui/chat.py +362 -0
- codex_agent_framework-0.1.30/codex_agent/tui/log.py +225 -0
- codex_agent_framework-0.1.30/codex_agent/tui/state.py +148 -0
- codex_agent_framework-0.1.30/codex_agent/tui/status_bar.py +86 -0
- codex_agent_framework-0.1.30/codex_agent/tui/style.py +56 -0
- codex_agent_framework-0.1.30/codex_agent/tui/transcript.py +337 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/utils.py +13 -5
- codex_agent_framework-0.1.30/codex_agent/version.py +1 -0
- codex_agent_framework-0.1.30/codex_agent_framework.egg-info/PKG-INFO +220 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent_framework.egg-info/SOURCES.txt +6 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent_framework.egg-info/requires.txt +1 -1
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/pyproject.toml +2 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_agent.py +262 -4
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_chat.py +293 -106
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_client.py +167 -2
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_server.py +37 -1
- codex_agent_framework-0.1.28/PKG-INFO +0 -655
- codex_agent_framework-0.1.28/README.md +0 -606
- codex_agent_framework-0.1.28/codex_agent/tui/chat.py +0 -1293
- codex_agent_framework-0.1.28/codex_agent/version.py +0 -1
- codex_agent_framework-0.1.28/codex_agent_framework.egg-info/PKG-INFO +0 -655
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/LICENSE +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/MANIFEST.in +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/__main__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/ai.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/browser.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/content/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/context/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/files/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/interface/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/manager.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/realtime/session.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/subagents/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/tts/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/headless.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/main.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/output.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/root.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/cli/runner.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/command.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/context.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/desktop.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/event.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/get_text/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/get_text/default_gitignore +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/get_text/get_text.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/get_text/simpler_get_text.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/hooks.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/image.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/latex.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/message.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/plugin.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/prompts/system_prompt.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/provider.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/runtime.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/scheduler.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/scripts/install-system-dependencies.sh +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/server/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/service.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/status.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/stream.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/stream_utils.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/tool.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/tray.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/tui/__init__.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/tui/lifecycle.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/worker.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent_framework.egg-info/entry_points.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent_framework.egg-info/top_level.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/dependencies.txt +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/setup.cfg +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_agent_runtime.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_ai.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_browser.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_builtin_config.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_cli.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_cli_headless.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_cli_root.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_events.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_get_text_browser.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_hooks.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_image_message.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_local_desktop.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_memory.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_messages.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_planner.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_scheduler.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_service.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_tray.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_tui.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_utils.py +0 -0
- {codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/tests/test_worker.py +0 -0
|
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
This project loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses semantic versioning where practical.
|
|
6
6
|
|
|
7
|
+
## [0.1.29] - 2026-05-15
|
|
8
|
+
### Changed
|
|
9
|
+
- Split the Textual TUI implementation into focused modules for app wiring, transcript rendering, status display, styling, log windowing, and render state.
|
|
10
|
+
- Replace ad hoc TUI app calls and duplicate display tracking with a typed bridge and centralized deduplication state.
|
|
11
|
+
- Move terminal resize handling into the Textual app so transcript, input sizing, layout cache, and status refresh stay coordinated.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- Invalidate selectable log layout metrics cleanly on terminal resize to keep wrapped transcript rendering accurate.
|
|
15
|
+
- Keep TUI turn rendering state scoped to the active turn without leaking tool or slash-command display markers.
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
- Update TUI/chat regression coverage for the extracted bridge/state modules and resize handling; the current suite validates at 577 passed.
|
|
19
|
+
|
|
7
20
|
## [0.1.28] - 2026-05-15
|
|
8
21
|
### Added
|
|
9
22
|
- Add `StreamManager` as a dedicated stream-processing manager and expose it through the package API.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codex-agent-framework
|
|
3
|
+
Version: 0.1.30
|
|
4
|
+
Summary: A lightweight event-driven Codex agent runtime.
|
|
5
|
+
Author: Baptiste
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: agent,ai,codex,openai,tools
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: audioop-lts; python_version >= "3.13"
|
|
19
|
+
Requires-Dist: beautifulsoup4
|
|
20
|
+
Requires-Dist: codex-backend-sdk>=0.3.1
|
|
21
|
+
Requires-Dist: fastapi
|
|
22
|
+
Requires-Dist: filetype
|
|
23
|
+
Requires-Dist: modict
|
|
24
|
+
Requires-Dist: mss
|
|
25
|
+
Requires-Dist: numpy
|
|
26
|
+
Requires-Dist: odfpy
|
|
27
|
+
Requires-Dist: openai
|
|
28
|
+
Requires-Dist: openpyxl
|
|
29
|
+
Requires-Dist: pathspec
|
|
30
|
+
Requires-Dist: pillow
|
|
31
|
+
Requires-Dist: playwright
|
|
32
|
+
Requires-Dist: pydub
|
|
33
|
+
Requires-Dist: pypdf
|
|
34
|
+
Requires-Dist: pynteract>=0.1.4
|
|
35
|
+
Requires-Dist: pywinctl
|
|
36
|
+
Requires-Dist: python-docx
|
|
37
|
+
Requires-Dist: PyYAML
|
|
38
|
+
Requires-Dist: regex
|
|
39
|
+
Requires-Dist: requests
|
|
40
|
+
Requires-Dist: rich
|
|
41
|
+
Requires-Dist: textual
|
|
42
|
+
Requires-Dist: tiktoken
|
|
43
|
+
Requires-Dist: trafilatura
|
|
44
|
+
Requires-Dist: uvicorn
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: build; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest; extra == "dev"
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# codex-agent
|
|
51
|
+
|
|
52
|
+
`codex-agent-framework` is a local-first Python framework for building and running tool-using AI agents.
|
|
53
|
+
|
|
54
|
+
Use it as a ready-to-run terminal assistant, or import `Agent` when you want to build your own agentic workflow in Python.
|
|
55
|
+
|
|
56
|
+
> Early alpha: APIs are still evolving and breaking changes are expected while the architecture settles.
|
|
57
|
+
|
|
58
|
+
## Why codex-agent?
|
|
59
|
+
|
|
60
|
+
codex-agent is meant to be a transparent, hackable local harness for power users and developers:
|
|
61
|
+
|
|
62
|
+
- **Local-first runtime**: sessions, memory, config, plugins, logs, and work files live under your local runtime directory.
|
|
63
|
+
- **Multiple entry points**: TUI, headless CLI, Python SDK, and local FastAPI server.
|
|
64
|
+
- **Plugin-first design**: tools, providers, slash commands, hooks, events, prompt sections, and stream processors are extension points.
|
|
65
|
+
- **Observable agent loop**: turns return structured results and emit events that UIs and integrations can stream.
|
|
66
|
+
- **Built-in practical tools**: files, shell, Python, context, memory, planner, scheduler, browser/desktop automation, and subagents.
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
Install the package:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
python -m pip install codex-agent-framework
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
For the recommended local setup, run:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
codex-agent bootstrap -- -y
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`bootstrap` installs desktop/browser/tray dependencies, installs the user services, and starts them. It is currently aimed mostly at Debian-like Linux systems. Use an X11 session for the best desktop automation support; Wayland is fine if you do not use the desktop plugin.
|
|
83
|
+
|
|
84
|
+
Open the assistant:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
codex-agent
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
If a local agent server is already running, the TUI connects to it. Otherwise `codex-agent` starts a temporary server for that TUI session and shuts it down when the TUI exits. New sessions are anchored to the directory where you launch `codex-agent`; see [CLI and runtime](docs/cli-and-runtime.md#session-root-and-working-directory).
|
|
91
|
+
|
|
92
|
+
Inside the TUI, start with:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
/help
|
|
96
|
+
/sessions
|
|
97
|
+
/new_session
|
|
98
|
+
/load_session latest
|
|
99
|
+
/compact
|
|
100
|
+
/config
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use `/compact` when a long session needs to reduce its active context. It keeps a backend summary and prunes older raw history from the active session file.
|
|
104
|
+
|
|
105
|
+
## Python in 30 seconds
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from codex_agent import Agent
|
|
109
|
+
|
|
110
|
+
agent = Agent(session="new")
|
|
111
|
+
turn = agent("Summarize this repository in three practical bullet points.")
|
|
112
|
+
|
|
113
|
+
print(turn.result)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Stream live events when building your own UI or integration:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from codex_agent import Agent, ResponseContentDeltaEvent
|
|
120
|
+
|
|
121
|
+
agent = Agent(session="new")
|
|
122
|
+
stream = agent.stream("Explain what this project does.")
|
|
123
|
+
|
|
124
|
+
for event in stream:
|
|
125
|
+
if isinstance(event, ResponseContentDeltaEvent):
|
|
126
|
+
print(event.delta, end="", flush=True)
|
|
127
|
+
|
|
128
|
+
turn = stream.turn
|
|
129
|
+
print("\ncompleted:", turn.completed)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Add a small tool:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
import subprocess
|
|
136
|
+
from codex_agent import Agent, tool
|
|
137
|
+
|
|
138
|
+
@tool
|
|
139
|
+
def list_changed_files() -> list[str]:
|
|
140
|
+
"""Return modified or untracked files in the current git repository."""
|
|
141
|
+
output = subprocess.check_output(["git", "status", "--short"], text=True)
|
|
142
|
+
return [line[3:] for line in output.splitlines() if line.strip()]
|
|
143
|
+
|
|
144
|
+
agent = Agent(session="latest")
|
|
145
|
+
agent.add_tool(list_changed_files)
|
|
146
|
+
agent("What changed locally?")
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Main ways to use it
|
|
150
|
+
|
|
151
|
+
| Mode | Entry point | Best for |
|
|
152
|
+
| --- | --- | --- |
|
|
153
|
+
| Interactive TUI | `codex-agent` | Daily local assistant usage. |
|
|
154
|
+
| Python SDK | `Agent(...)` | Scripts, notebooks, tests, custom applications. |
|
|
155
|
+
| Headless CLI | `codex-agent run ...` | Automation and shell pipelines. |
|
|
156
|
+
| Persistent server | `codex-agent start server` | Long-lived local service used by UIs or scripts. |
|
|
157
|
+
| Runtime plugins | `~/.codex-agent/plugins/*.py` | Local customization without forking the project. |
|
|
158
|
+
|
|
159
|
+
Useful CLI commands:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
codex-agent status --json
|
|
163
|
+
codex-agent tools
|
|
164
|
+
codex-agent sessions list
|
|
165
|
+
codex-agent config get
|
|
166
|
+
codex-agent run "Run a quick repository health check."
|
|
167
|
+
git diff -- README.md | codex-agent run --stdin "Review this documentation diff."
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Built-in capability map
|
|
171
|
+
|
|
172
|
+
| Area | Examples | Purpose |
|
|
173
|
+
| --- | --- | --- |
|
|
174
|
+
| Files/content | `read`, `view`, `write`, `edit` | Strict text reads, broad extraction, exact-string edits. |
|
|
175
|
+
| Shell/Python | `bash`, `python` | Local command execution and persistent Python work. |
|
|
176
|
+
| Context/status | `context_status`, `context_compact` | Inspect and manage the active context window. |
|
|
177
|
+
| Memory/planner | `memory_add`, `planner_create` | Durable semantic memory and persistent named todos. |
|
|
178
|
+
| Scheduler | `scheduler_schedule` | Future turns and post-restart continuation. |
|
|
179
|
+
| Browser/desktop | browser and desktop tools | Persistent Chromium and Linux desktop automation. |
|
|
180
|
+
| Subagents | `subagents_run` | Focused child agents such as the read-only `explorer` profile. |
|
|
181
|
+
|
|
182
|
+
Select built-ins explicitly when you want a smaller agent:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
agent = Agent(
|
|
186
|
+
session="latest",
|
|
187
|
+
builtin_plugins=["files", "content", "bash", "python", "environment", "context"],
|
|
188
|
+
)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`None` loads all built-ins, `[]` loads none, and an explicit list selects plugin module names.
|
|
192
|
+
|
|
193
|
+
## Documentation
|
|
194
|
+
|
|
195
|
+
The README is intentionally a façade and quick-start guide. Advanced usage lives in `docs/`:
|
|
196
|
+
|
|
197
|
+
- [Python SDK](docs/python-sdk.md): `Agent`, turns, streaming, events, config, and interactive sessions.
|
|
198
|
+
- [Plugins and extensions](docs/plugins.md): tools, providers, commands, runtime plugins, stateful plugins, hooks, events, and stream processors.
|
|
199
|
+
- [CLI and runtime](docs/cli-and-runtime.md): TUI, server, headless CLI, sessions, config, runtime files, and service setup.
|
|
200
|
+
- [Built-in capabilities](docs/built-in-capabilities.md): bundled plugins and common usage patterns.
|
|
201
|
+
- [Safety and trust](docs/safety-and-trust.md): local trust model, runtime plugins, server binding, secrets, and risky actions.
|
|
202
|
+
- [Development](docs/development.md): project layout, tests, build, and release checks.
|
|
203
|
+
|
|
204
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
205
|
+
|
|
206
|
+
## Safety notes
|
|
207
|
+
|
|
208
|
+
This project lets an AI assistant act on the local machine. That is useful, but risky.
|
|
209
|
+
|
|
210
|
+
Recommended practices:
|
|
211
|
+
|
|
212
|
+
- Avoid running the agent with elevated privileges.
|
|
213
|
+
- Review tools and runtime plugins before enabling autonomous workflows.
|
|
214
|
+
- Keep secrets out of prompts, logs, committed runtime files, and shared session exports.
|
|
215
|
+
- Treat browser, desktop, shell, file-write, and edit operations as real user actions.
|
|
216
|
+
- Keep important runtime plugins under version control.
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# codex-agent
|
|
2
|
+
|
|
3
|
+
`codex-agent-framework` is a local-first Python framework for building and running tool-using AI agents.
|
|
4
|
+
|
|
5
|
+
Use it as a ready-to-run terminal assistant, or import `Agent` when you want to build your own agentic workflow in Python.
|
|
6
|
+
|
|
7
|
+
> Early alpha: APIs are still evolving and breaking changes are expected while the architecture settles.
|
|
8
|
+
|
|
9
|
+
## Why codex-agent?
|
|
10
|
+
|
|
11
|
+
codex-agent is meant to be a transparent, hackable local harness for power users and developers:
|
|
12
|
+
|
|
13
|
+
- **Local-first runtime**: sessions, memory, config, plugins, logs, and work files live under your local runtime directory.
|
|
14
|
+
- **Multiple entry points**: TUI, headless CLI, Python SDK, and local FastAPI server.
|
|
15
|
+
- **Plugin-first design**: tools, providers, slash commands, hooks, events, prompt sections, and stream processors are extension points.
|
|
16
|
+
- **Observable agent loop**: turns return structured results and emit events that UIs and integrations can stream.
|
|
17
|
+
- **Built-in practical tools**: files, shell, Python, context, memory, planner, scheduler, browser/desktop automation, and subagents.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
Install the package:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m pip install codex-agent-framework
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For the recommended local setup, run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
codex-agent bootstrap -- -y
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`bootstrap` installs desktop/browser/tray dependencies, installs the user services, and starts them. It is currently aimed mostly at Debian-like Linux systems. Use an X11 session for the best desktop automation support; Wayland is fine if you do not use the desktop plugin.
|
|
34
|
+
|
|
35
|
+
Open the assistant:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
codex-agent
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If a local agent server is already running, the TUI connects to it. Otherwise `codex-agent` starts a temporary server for that TUI session and shuts it down when the TUI exits. New sessions are anchored to the directory where you launch `codex-agent`; see [CLI and runtime](docs/cli-and-runtime.md#session-root-and-working-directory).
|
|
42
|
+
|
|
43
|
+
Inside the TUI, start with:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
/help
|
|
47
|
+
/sessions
|
|
48
|
+
/new_session
|
|
49
|
+
/load_session latest
|
|
50
|
+
/compact
|
|
51
|
+
/config
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Use `/compact` when a long session needs to reduce its active context. It keeps a backend summary and prunes older raw history from the active session file.
|
|
55
|
+
|
|
56
|
+
## Python in 30 seconds
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from codex_agent import Agent
|
|
60
|
+
|
|
61
|
+
agent = Agent(session="new")
|
|
62
|
+
turn = agent("Summarize this repository in three practical bullet points.")
|
|
63
|
+
|
|
64
|
+
print(turn.result)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Stream live events when building your own UI or integration:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from codex_agent import Agent, ResponseContentDeltaEvent
|
|
71
|
+
|
|
72
|
+
agent = Agent(session="new")
|
|
73
|
+
stream = agent.stream("Explain what this project does.")
|
|
74
|
+
|
|
75
|
+
for event in stream:
|
|
76
|
+
if isinstance(event, ResponseContentDeltaEvent):
|
|
77
|
+
print(event.delta, end="", flush=True)
|
|
78
|
+
|
|
79
|
+
turn = stream.turn
|
|
80
|
+
print("\ncompleted:", turn.completed)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Add a small tool:
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import subprocess
|
|
87
|
+
from codex_agent import Agent, tool
|
|
88
|
+
|
|
89
|
+
@tool
|
|
90
|
+
def list_changed_files() -> list[str]:
|
|
91
|
+
"""Return modified or untracked files in the current git repository."""
|
|
92
|
+
output = subprocess.check_output(["git", "status", "--short"], text=True)
|
|
93
|
+
return [line[3:] for line in output.splitlines() if line.strip()]
|
|
94
|
+
|
|
95
|
+
agent = Agent(session="latest")
|
|
96
|
+
agent.add_tool(list_changed_files)
|
|
97
|
+
agent("What changed locally?")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Main ways to use it
|
|
101
|
+
|
|
102
|
+
| Mode | Entry point | Best for |
|
|
103
|
+
| --- | --- | --- |
|
|
104
|
+
| Interactive TUI | `codex-agent` | Daily local assistant usage. |
|
|
105
|
+
| Python SDK | `Agent(...)` | Scripts, notebooks, tests, custom applications. |
|
|
106
|
+
| Headless CLI | `codex-agent run ...` | Automation and shell pipelines. |
|
|
107
|
+
| Persistent server | `codex-agent start server` | Long-lived local service used by UIs or scripts. |
|
|
108
|
+
| Runtime plugins | `~/.codex-agent/plugins/*.py` | Local customization without forking the project. |
|
|
109
|
+
|
|
110
|
+
Useful CLI commands:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
codex-agent status --json
|
|
114
|
+
codex-agent tools
|
|
115
|
+
codex-agent sessions list
|
|
116
|
+
codex-agent config get
|
|
117
|
+
codex-agent run "Run a quick repository health check."
|
|
118
|
+
git diff -- README.md | codex-agent run --stdin "Review this documentation diff."
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Built-in capability map
|
|
122
|
+
|
|
123
|
+
| Area | Examples | Purpose |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| Files/content | `read`, `view`, `write`, `edit` | Strict text reads, broad extraction, exact-string edits. |
|
|
126
|
+
| Shell/Python | `bash`, `python` | Local command execution and persistent Python work. |
|
|
127
|
+
| Context/status | `context_status`, `context_compact` | Inspect and manage the active context window. |
|
|
128
|
+
| Memory/planner | `memory_add`, `planner_create` | Durable semantic memory and persistent named todos. |
|
|
129
|
+
| Scheduler | `scheduler_schedule` | Future turns and post-restart continuation. |
|
|
130
|
+
| Browser/desktop | browser and desktop tools | Persistent Chromium and Linux desktop automation. |
|
|
131
|
+
| Subagents | `subagents_run` | Focused child agents such as the read-only `explorer` profile. |
|
|
132
|
+
|
|
133
|
+
Select built-ins explicitly when you want a smaller agent:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
agent = Agent(
|
|
137
|
+
session="latest",
|
|
138
|
+
builtin_plugins=["files", "content", "bash", "python", "environment", "context"],
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`None` loads all built-ins, `[]` loads none, and an explicit list selects plugin module names.
|
|
143
|
+
|
|
144
|
+
## Documentation
|
|
145
|
+
|
|
146
|
+
The README is intentionally a façade and quick-start guide. Advanced usage lives in `docs/`:
|
|
147
|
+
|
|
148
|
+
- [Python SDK](docs/python-sdk.md): `Agent`, turns, streaming, events, config, and interactive sessions.
|
|
149
|
+
- [Plugins and extensions](docs/plugins.md): tools, providers, commands, runtime plugins, stateful plugins, hooks, events, and stream processors.
|
|
150
|
+
- [CLI and runtime](docs/cli-and-runtime.md): TUI, server, headless CLI, sessions, config, runtime files, and service setup.
|
|
151
|
+
- [Built-in capabilities](docs/built-in-capabilities.md): bundled plugins and common usage patterns.
|
|
152
|
+
- [Safety and trust](docs/safety-and-trust.md): local trust model, runtime plugins, server binding, secrets, and risky actions.
|
|
153
|
+
- [Development](docs/development.md): project layout, tests, build, and release checks.
|
|
154
|
+
|
|
155
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history.
|
|
156
|
+
|
|
157
|
+
## Safety notes
|
|
158
|
+
|
|
159
|
+
This project lets an AI assistant act on the local machine. That is useful, but risky.
|
|
160
|
+
|
|
161
|
+
Recommended practices:
|
|
162
|
+
|
|
163
|
+
- Avoid running the agent with elevated privileges.
|
|
164
|
+
- Review tools and runtime plugins before enabling autonomous workflows.
|
|
165
|
+
- Keep secrets out of prompts, logs, committed runtime files, and shared session exports.
|
|
166
|
+
- Treat browser, desktop, shell, file-write, and edit operations as real user actions.
|
|
167
|
+
- Keep important runtime plugins under version control.
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -31,10 +31,15 @@ class Agent:
|
|
|
31
31
|
**kwargs: Additional keyword arguments to update the agent configuration.
|
|
32
32
|
"""
|
|
33
33
|
ensure_runtime_dir()
|
|
34
|
+
launch_cwd = os.path.abspath(os.getcwd())
|
|
35
|
+
self.process_launch_cwd = launch_cwd
|
|
36
|
+
explicit_root_dir = kwargs.pop("root_dir", None)
|
|
37
|
+
explicit_cwd = kwargs.pop("cwd", None)
|
|
34
38
|
self.init_execution_environment()
|
|
35
39
|
self.config_manager=ConfigManager(self)
|
|
36
40
|
self.config_manager.load()
|
|
37
41
|
self.config_manager.update(kwargs, save=False)
|
|
42
|
+
self.init_working_directories(root_dir=explicit_root_dir or launch_cwd, cwd=explicit_cwd)
|
|
38
43
|
self.config_manager.apply_openai_capability_defaults()
|
|
39
44
|
self.events=EventBus()
|
|
40
45
|
self.tools_manager=ToolsManager(self)
|
|
@@ -198,6 +203,51 @@ class Agent:
|
|
|
198
203
|
"text_content": text_content,
|
|
199
204
|
}
|
|
200
205
|
|
|
206
|
+
def normalize_directory(self, path):
|
|
207
|
+
return os.path.abspath(os.path.expanduser(str(path)))
|
|
208
|
+
|
|
209
|
+
def sync_working_cwd_from_process(self, save_session=False):
|
|
210
|
+
cwd = self.normalize_directory(os.getcwd())
|
|
211
|
+
self.config.cwd = cwd
|
|
212
|
+
session = getattr(self, "session", None)
|
|
213
|
+
if session:
|
|
214
|
+
session.cwd = cwd
|
|
215
|
+
if save_session:
|
|
216
|
+
self.save_session()
|
|
217
|
+
return cwd
|
|
218
|
+
|
|
219
|
+
def set_process_cwd(self, cwd, save_session=False):
|
|
220
|
+
cwd = self.normalize_directory(cwd)
|
|
221
|
+
os.chdir(cwd)
|
|
222
|
+
return self.sync_working_cwd_from_process(save_session=save_session)
|
|
223
|
+
|
|
224
|
+
def init_working_directories(self, root_dir=None, cwd=None):
|
|
225
|
+
root_dir = self.normalize_directory(root_dir or getattr(self, "process_launch_cwd", None) or self.config.root_dir)
|
|
226
|
+
cwd = self.normalize_directory(cwd or root_dir)
|
|
227
|
+
self.config.root_dir = root_dir
|
|
228
|
+
self.set_process_cwd(cwd)
|
|
229
|
+
return self.config.cwd
|
|
230
|
+
|
|
231
|
+
def apply_session_working_directories(self):
|
|
232
|
+
if not self.session:
|
|
233
|
+
return self.config.cwd
|
|
234
|
+
root_dir = getattr(self.session, "root_dir", None) or self.config.root_dir or getattr(self, "process_launch_cwd", None)
|
|
235
|
+
cwd = getattr(self.session, "cwd", None) or root_dir
|
|
236
|
+
self.config.root_dir = self.normalize_directory(root_dir)
|
|
237
|
+
self.session.root_dir = self.config.root_dir
|
|
238
|
+
self.set_process_cwd(cwd)
|
|
239
|
+
self.session.cwd = self.config.cwd
|
|
240
|
+
return self.config.cwd
|
|
241
|
+
|
|
242
|
+
def working_cwd(self):
|
|
243
|
+
return self.sync_working_cwd_from_process(save_session=False)
|
|
244
|
+
|
|
245
|
+
def resolve_path(self, path):
|
|
246
|
+
path = os.path.expanduser(str(path))
|
|
247
|
+
if os.path.isabs(path):
|
|
248
|
+
return os.path.abspath(path)
|
|
249
|
+
return os.path.abspath(os.path.join(self.working_cwd(), path))
|
|
250
|
+
|
|
201
251
|
def init_workfolder(self):
|
|
202
252
|
if not os.path.isdir(self.config.workfolder):
|
|
203
253
|
os.makedirs(self.config.workfolder,exist_ok=True)
|
|
@@ -217,8 +267,8 @@ class Agent:
|
|
|
217
267
|
def load_session(self, session):
|
|
218
268
|
return self.sessions_manager.load(session)
|
|
219
269
|
|
|
220
|
-
def start_new_session(self):
|
|
221
|
-
return self.sessions_manager.start_new()
|
|
270
|
+
def start_new_session(self, root_dir=None, cwd=None):
|
|
271
|
+
return self.sessions_manager.start_new(root_dir=root_dir, cwd=cwd)
|
|
222
272
|
|
|
223
273
|
def delete_session(self, session):
|
|
224
274
|
return self.sessions_manager.delete(session)
|
|
@@ -93,7 +93,7 @@ class AgentRuntime(ABC):
|
|
|
93
93
|
raise NotImplementedError
|
|
94
94
|
|
|
95
95
|
@abstractmethod
|
|
96
|
-
def start_new_session(self):
|
|
96
|
+
def start_new_session(self, root_dir=None, cwd=None):
|
|
97
97
|
raise NotImplementedError
|
|
98
98
|
|
|
99
99
|
@abstractmethod
|
|
@@ -207,8 +207,8 @@ class InProcessAgentRuntime(AgentRuntime):
|
|
|
207
207
|
def wakeups(self, include_done=True):
|
|
208
208
|
return self.agent.scheduler.list(include_done=include_done)
|
|
209
209
|
|
|
210
|
-
def start_new_session(self):
|
|
211
|
-
return self.agent.start_new_session()
|
|
210
|
+
def start_new_session(self, root_dir=None, cwd=None):
|
|
211
|
+
return self.agent.start_new_session(root_dir=root_dir, cwd=cwd)
|
|
212
212
|
|
|
213
213
|
def load_session(self, session_id):
|
|
214
214
|
return self.agent.load_session(session_id)
|
|
@@ -610,8 +610,9 @@ class ProcessAgentRuntime(AgentRuntime):
|
|
|
610
610
|
def wakeups(self, include_done=True):
|
|
611
611
|
return self._cached_call("wakeups", include_done=include_done)
|
|
612
612
|
|
|
613
|
-
def start_new_session(self):
|
|
614
|
-
|
|
613
|
+
def start_new_session(self, root_dir=None, cwd=None):
|
|
614
|
+
payload = {key: value for key, value in {"root_dir": root_dir, "cwd": cwd}.items() if value is not None}
|
|
615
|
+
result = self.call("start_new_session", payload, timeout=self.command_timeout)
|
|
615
616
|
self.refresh_cache()
|
|
616
617
|
return result
|
|
617
618
|
|
|
@@ -760,7 +761,7 @@ def run_worker_command(agent, name, payload):
|
|
|
760
761
|
if name == "wakeups":
|
|
761
762
|
return agent.scheduler.list(include_done=payload.get("include_done", True))
|
|
762
763
|
if name == "start_new_session":
|
|
763
|
-
return agent.start_new_session()
|
|
764
|
+
return agent.start_new_session(root_dir=payload.get("root_dir"), cwd=payload.get("cwd"))
|
|
764
765
|
if name == "load_session":
|
|
765
766
|
return agent.load_session(payload.session_id)
|
|
766
767
|
if name == "delete_session":
|
{codex_agent_framework-0.1.28 → codex_agent_framework-0.1.30}/codex_agent/builtin_commands.py
RENAMED
|
@@ -87,9 +87,9 @@ def sessions():
|
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
@command
|
|
90
|
-
def new_session():
|
|
90
|
+
def new_session(root_dir=None, cwd=None):
|
|
91
91
|
agent = get_agent()
|
|
92
|
-
session = agent.start_new_session()
|
|
92
|
+
session = agent.start_new_session(root_dir=root_dir, cwd=cwd)
|
|
93
93
|
return f"Created session: {session.session_id}"
|
|
94
94
|
|
|
95
95
|
|
|
@@ -28,7 +28,8 @@ Pass raw shell script text to the tool, not JSON, quotes, or a markdown code fen
|
|
|
28
28
|
if not content:
|
|
29
29
|
return "No bash command provided."
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
cwd = self.agent.working_cwd()
|
|
32
|
+
hook = self.agent.run_hook("shell.bash.before", content=content, cwd=cwd, root_dir=self.agent.config.root_dir)
|
|
32
33
|
content = hook.payload.content
|
|
33
34
|
cwd = hook.payload.cwd
|
|
34
35
|
response = subprocess.run(
|
|
@@ -20,7 +20,7 @@ def show(file_or_url: str):
|
|
|
20
20
|
"""
|
|
21
21
|
target = str(file_or_url)
|
|
22
22
|
if not target.startswith(("http://", "https://", "file://")):
|
|
23
|
-
target =
|
|
23
|
+
target = get_agent().resolve_path(target)
|
|
24
24
|
|
|
25
25
|
opened = open_silently(target)
|
|
26
26
|
if opened:
|
|
@@ -5,7 +5,7 @@ from urllib.parse import quote_plus
|
|
|
5
5
|
from ...browser import get_browser_controller
|
|
6
6
|
from ...desktop import DesktopControlError, get_desktop_controller
|
|
7
7
|
from ...image import ImageMessage, persist_image_url
|
|
8
|
-
from ...tool import tool
|
|
8
|
+
from ...tool import get_agent, tool
|
|
9
9
|
from ...utils import runtime_join
|
|
10
10
|
|
|
11
11
|
|
|
@@ -122,10 +122,18 @@ def observe_source(source):
|
|
|
122
122
|
return f"failed: unsupported observe target: {target!r}"
|
|
123
123
|
|
|
124
124
|
|
|
125
|
+
def resolve_agent_path(path):
|
|
126
|
+
try:
|
|
127
|
+
return get_agent().resolve_path(path)
|
|
128
|
+
except RuntimeError:
|
|
129
|
+
return os.path.abspath(os.path.expanduser(str(path)))
|
|
130
|
+
|
|
131
|
+
|
|
125
132
|
def observe_path(item):
|
|
126
133
|
path = item.get("path") or item.get("source")
|
|
127
134
|
if not isinstance(path, str) or not path:
|
|
128
135
|
return "failed: path target requires a non-empty 'path'."
|
|
136
|
+
path = resolve_agent_path(path)
|
|
129
137
|
return validated_image(path, image_name=item.get("image_name"), original_source=path)
|
|
130
138
|
|
|
131
139
|
|
|
@@ -153,8 +161,11 @@ def observe_url(item):
|
|
|
153
161
|
|
|
154
162
|
|
|
155
163
|
def observe_screen(item):
|
|
164
|
+
output_path = item.get("output_path")
|
|
165
|
+
if output_path:
|
|
166
|
+
output_path = resolve_agent_path(output_path)
|
|
156
167
|
try:
|
|
157
|
-
path = get_desktop_controller().capture_screen(
|
|
168
|
+
path = get_desktop_controller().capture_screen(output_path)
|
|
158
169
|
except DesktopControlError as exc:
|
|
159
170
|
return f"failed: local screen screenshot failed: {exc}"
|
|
160
171
|
return validated_image(path, image_name=item.get("image_name", "Screenshot of screen"), original_source="screen")
|
|
@@ -162,8 +173,11 @@ def observe_screen(item):
|
|
|
162
173
|
|
|
163
174
|
def observe_window(item):
|
|
164
175
|
window_id = item.get("window_id") or item.get("id")
|
|
176
|
+
output_path = item.get("output_path")
|
|
177
|
+
if output_path:
|
|
178
|
+
output_path = resolve_agent_path(output_path)
|
|
165
179
|
try:
|
|
166
|
-
path = get_desktop_controller().capture_window(window_id,
|
|
180
|
+
path = get_desktop_controller().capture_window(window_id, output_path)
|
|
167
181
|
except DesktopControlError as exc:
|
|
168
182
|
return f"failed: local window screenshot failed: {exc}"
|
|
169
183
|
return validated_image(path, image_name=item.get("image_name", f"Screenshot of window {window_id}"), original_source=f"window {window_id}")
|
|
@@ -180,6 +194,8 @@ def validated_image(path, image_name=None, original_source=None, url_fallback=Fa
|
|
|
180
194
|
def screenshot_page_url(url, item=None):
|
|
181
195
|
item = item or {}
|
|
182
196
|
path = item.get("output_path")
|
|
197
|
+
if path:
|
|
198
|
+
path = resolve_agent_path(path)
|
|
183
199
|
if not path:
|
|
184
200
|
screenshots_dir = runtime_join("images", "screenshots")
|
|
185
201
|
os.makedirs(screenshots_dir, exist_ok=True)
|