codex-agent-framework 0.1.6__tar.gz → 0.1.8__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.
Files changed (71) hide show
  1. codex_agent_framework-0.1.8/CHANGELOG.md +110 -0
  2. {codex_agent_framework-0.1.6/codex_agent_framework.egg-info → codex_agent_framework-0.1.8}/PKG-INFO +71 -13
  3. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/README.md +68 -9
  4. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/__init__.py +2 -0
  5. codex_agent_framework-0.1.8/codex_agent/__main__.py +107 -0
  6. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/agent.py +419 -25
  7. codex_agent_framework-0.1.8/codex_agent/agent_runtime.py +458 -0
  8. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/ai.py +35 -11
  9. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/builtin_commands.py +1 -1
  10. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/builtin_tools.py +124 -3
  11. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/chat.py +185 -47
  12. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/client.py +140 -5
  13. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/event.py +24 -5
  14. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/get_text/get_text.py +2 -2
  15. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/image.py +151 -0
  16. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/message.py +58 -0
  17. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/prompts/system_prompt.txt +3 -1
  18. codex_agent_framework-0.1.8/codex_agent/scheduler.py +199 -0
  19. codex_agent_framework-0.1.8/codex_agent/server.py +664 -0
  20. codex_agent_framework-0.1.8/codex_agent/service.py +316 -0
  21. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/stream_utils.py +7 -7
  22. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/tool.py +14 -7
  23. codex_agent_framework-0.1.8/codex_agent/tray.py +292 -0
  24. codex_agent_framework-0.1.8/codex_agent/tui.py +148 -0
  25. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/utils.py +84 -48
  26. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/voice.py +28 -4
  27. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8/codex_agent_framework.egg-info}/PKG-INFO +71 -13
  28. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent_framework.egg-info/SOURCES.txt +9 -0
  29. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent_framework.egg-info/requires.txt +4 -4
  30. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/pyproject.toml +3 -5
  31. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_agent.py +212 -11
  32. codex_agent_framework-0.1.8/tests/test_ai.py +96 -0
  33. codex_agent_framework-0.1.8/tests/test_chat.py +332 -0
  34. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_cli.py +17 -7
  35. codex_agent_framework-0.1.8/tests/test_client.py +444 -0
  36. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_messages.py +8 -0
  37. codex_agent_framework-0.1.8/tests/test_scheduler.py +62 -0
  38. codex_agent_framework-0.1.8/tests/test_server.py +747 -0
  39. codex_agent_framework-0.1.8/tests/test_service.py +110 -0
  40. codex_agent_framework-0.1.8/tests/test_tray.py +381 -0
  41. codex_agent_framework-0.1.8/tests/test_tui.py +82 -0
  42. codex_agent_framework-0.1.8/tests/test_utils.py +223 -0
  43. codex_agent_framework-0.1.6/CHANGELOG.md +0 -70
  44. codex_agent_framework-0.1.6/codex_agent/__main__.py +0 -73
  45. codex_agent_framework-0.1.6/codex_agent/server.py +0 -245
  46. codex_agent_framework-0.1.6/tests/test_ai.py +0 -40
  47. codex_agent_framework-0.1.6/tests/test_chat.py +0 -38
  48. codex_agent_framework-0.1.6/tests/test_client.py +0 -87
  49. codex_agent_framework-0.1.6/tests/test_server.py +0 -167
  50. codex_agent_framework-0.1.6/tests/test_utils.py +0 -88
  51. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/LICENSE +0 -0
  52. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/MANIFEST.in +0 -0
  53. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/builtin_providers.py +0 -0
  54. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/command.py +0 -0
  55. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/get_text/__init__.py +0 -0
  56. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/get_text/default_gitignore +0 -0
  57. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/get_text/simpler_get_text.py +0 -0
  58. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/get_webdriver.py +0 -0
  59. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/latex.py +0 -0
  60. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/memory.py +0 -0
  61. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/prompts/image_generation_system_prompt.txt +0 -0
  62. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/provider.py +0 -0
  63. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent/worker.py +0 -0
  64. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
  65. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent_framework.egg-info/entry_points.txt +0 -0
  66. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/codex_agent_framework.egg-info/top_level.txt +0 -0
  67. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/setup.cfg +0 -0
  68. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_events.py +0 -0
  69. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_image_message.py +0 -0
  70. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_memory.py +0 -0
  71. {codex_agent_framework-0.1.6 → codex_agent_framework-0.1.8}/tests/test_worker.py +0 -0
@@ -0,0 +1,110 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ This project loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses semantic versioning where practical.
6
+ ## [0.1.8] - 2026-05-05
7
+ ### Changed
8
+ - Scope TUI startup replay and SSE catch-up events to the current session so reopening the UI after session navigation cannot replay turns from another session.
9
+ - Make the agent process normalize its execution environment from `sys.executable`, putting the project interpreter first on `PATH` and exposing `PYTHON` / `PYTHON_EXECUTABLE`.
10
+ - Generate systemd and launchd service definitions with the project Python environment propagated explicitly to server and tray processes.
11
+
12
+ ### Fixed
13
+ - Ensure the agent `bash` tool resolves `python` and `pytest` from the environment where `codex-agent-framework` is installed, even when launched by a minimal service manager environment.
14
+ - Preserve direct `agent.tools.<name>(...)` calls by binding registered tools back to their owning agent for runtime context lookup.
15
+
16
+ ### Tests
17
+ - Add regression coverage for session-scoped replay, same-session SSE catch-up filtering, service environment generation, and bash tool Python resolution.
18
+
19
+ ## [0.1.7] - 2026-05-05
20
+ ### Added
21
+ - Add durable RAG memory backed by `memory.json`, with memory entries modeled as developer messages and retrieved by semantic similarity plus optional recency scoring.
22
+ - Add memory tools for creating, editing, deleting, and searching entries, with XML-formatted search output.
23
+ - Add automatic fire-and-forget turn summarization into memory after completed agent turns.
24
+ - Add scheduled wakeups backed by `wakeups.json`, including one-shot and periodic wakeups plus server restart wakeup recovery.
25
+ - Add a desktop tray controller, user service install/uninstall helpers, and agent tools/endpoints to open or close the TUI.
26
+ - Add `/status`, `/wakeups`, `/tui`, `/events/replay`, and related server endpoints for a purely client-driven TUI.
27
+ - Add compact UI status data for context usage, message ratio, WHAM quota percentages, and current model.
28
+
29
+ ### Changed
30
+ - Run the long-lived agent in a separate worker process behind the FastAPI bridge so the server remains responsive while the agent is busy.
31
+ - Make the Textual TUI robust to server restarts and reconnects by replaying the latest turn, tracking SSE event sequence cursors, and allowing same-client SSE replacement.
32
+ - Remove SSE read timeouts for the event stream while keeping immediate reconnect attempts after connection loss.
33
+ - Improve token counting by making messages responsible for cached API token estimates and including tool specs in context estimates.
34
+ - Treat leading system messages as Responses API instructions rather than ordinary history messages.
35
+ - Remove the legacy Streamlit dependency and replace `PyPDF2` with `pypdf`.
36
+
37
+ ### Fixed
38
+ - Prevent stale SSE subscribers from blocking a reconnecting TUI with a false second-client error.
39
+ - Prevent local TUI handler errors from being displayed as server disconnects.
40
+ - Truncate long embedding inputs to avoid backend embedding context length errors.
41
+ - Add `audioop-lts` for Python 3.13+ compatibility with `pydub`.
42
+
43
+ ### Tests
44
+ - Expand coverage for memory, token estimates, server replay, SSE reconnects, process runtime shutdown, tray/service helpers, scheduler wakeups, and TUI status behavior.
45
+
46
+ ## [0.1.6] - 2026-05-04
47
+ ### Added
48
+ - Add an async-style agent mainloop with command futures so turns and state mutations can be coordinated through one runtime.
49
+ - Add a FastAPI REST/SSE bridge and an `AgentClient` HTTP/SSE client for decoupled interfaces.
50
+ - Add CLI modes for local embedded server + TUI client, server-only, and client-only chat operation.
51
+
52
+ ### Changed
53
+ - Decouple the Textual chat UI from direct `Agent` access; the TUI now communicates with the server through HTTP and SSE.
54
+ - Stream lightweight response deltas instead of cumulative content, reducing SSE traffic and client backpressure.
55
+ - Use unbounded subscriber queues with ping events for more reliable SSE client delivery.
56
+
57
+ ### Tests
58
+ - Add coverage for the server bridge, HTTP/SSE client, async runtime behavior, CLI modes, and event lifecycle.
59
+
60
+ ## [0.1.5] - 2026-05-03
61
+ ### Changed
62
+ - Refine the default Textual chat UI with a pure black background, black multiline input area, subtler scrollbars, a smaller step-end marker, and English UI labels.
63
+
64
+
65
+ ## [0.1.4] - 2026-05-03
66
+ ### Added
67
+ - Make the Textual REPL UI the default chat interface, with multiline input, subdued colors, visual speaker separators, step-end markers, and cleaner tool-call rendering.
68
+ - Add assistant turn and assistant step lifecycle events for UI and runtime integrations.
69
+ - Add a `/voice` command to show, toggle, or select the configured voice mode.
70
+
71
+ ### Changed
72
+ - Remove the legacy prompt-toolkit chat UI and the temporary `--textual` CLI flag.
73
+
74
+ ### Tests
75
+ - Add CLI coverage for starting the default chat UI and update chat status formatting tests.
76
+
77
+
78
+ ## [0.1.3] - 2026-05-03
79
+ ### Added
80
+ - Send the current session id as `prompt_cache_key` to the Codex backend, enabling server-side prompt cache reuse across calls from the same session.
81
+
82
+ ### Tests
83
+ - Add regression coverage for prompt cache key propagation through agent response calls and Codex stream parameters.
84
+
85
+
86
+ ## [0.1.2] - 2026-05-03
87
+ ### Added
88
+ - Add a `/clear` terminal chat command that clears the screen without touching session history.
89
+
90
+ ### Tests
91
+ - Add regression coverage ensuring terminal screen clearing does not append session messages.
92
+
93
+
94
+ ## [0.1.1] - 2026-05-03
95
+ ### Fixed
96
+ - Validate `ImageMessage` content before adding it to session state.
97
+ - Prevent invalid or inaccessible observed images from polluting a session and breaking later SDK calls.
98
+
99
+ ### Tests
100
+ - Add regression coverage for valid and invalid `ImageMessage` validation.
101
+ - Verify `Agent.add_image()` rejects invalid images without appending a broken session message.
102
+
103
+
104
+ ## [0.1.0] - 2026-05-03
105
+
106
+ ### Added
107
+
108
+ - Initial package metadata and console entry point.
109
+ - Event-driven agent runtime, session persistence, tools, providers, commands, voice, image, and document extraction modules.
110
+ - Test suite for core agent behavior, events, messages, image messages, utilities, and workers.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -15,6 +15,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
15
  Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
+ Requires-Dist: audioop-lts; python_version >= "3.13"
18
19
  Requires-Dist: beautifulsoup4
19
20
  Requires-Dist: codex-backend-sdk
20
21
  Requires-Dist: fastapi
@@ -28,7 +29,7 @@ Requires-Dist: openpyxl
28
29
  Requires-Dist: pathspec
29
30
  Requires-Dist: pillow
30
31
  Requires-Dist: pydub
31
- Requires-Dist: PyPDF2
32
+ Requires-Dist: pypdf
32
33
  Requires-Dist: pynteract
33
34
  Requires-Dist: python-docx
34
35
  Requires-Dist: PyYAML
@@ -43,8 +44,6 @@ Requires-Dist: uvicorn
43
44
  Provides-Extra: dev
44
45
  Requires-Dist: build; extra == "dev"
45
46
  Requires-Dist: pytest; extra == "dev"
46
- Provides-Extra: streamlit
47
- Requires-Dist: streamlit; extra == "streamlit"
48
47
  Dynamic: license-file
49
48
 
50
49
  # codex-agent
@@ -57,19 +56,23 @@ It provides a reusable `Agent` abstraction with persistent sessions, local tools
57
56
 
58
57
  ## Highlights
59
58
 
60
- - Interactive terminal agent exposed as `codex-agent`.
59
+ - Local FastAPI agent server with a terminal TUI client and GTK tray controller.
60
+ - Process-isolated agent runtime so the local server stays responsive while the agent works.
61
61
  - Persistent JSON sessions with `latest`, explicit session IDs, and session navigation commands.
62
+ - Durable RAG memory backed by runtime JSON, with semantic search and automatic turn summaries.
63
+ - Scheduled wakeups for one-shot or periodic autonomous agent turns.
62
64
  - Built-in local tools for reading, writing, editing, showing, observing, Bash, and Python execution.
63
65
  - Extensible tool, command, and provider decorators.
64
66
  - Event-driven internals for UI, streaming, voice, and automation integrations.
65
67
  - Document extraction helpers for folders, text files, URLs, PDFs, DOCX, XLSX, ODT, HTML, and more.
66
- - Optional image generation, image observation, voice, LaTeX, and Streamlit-oriented integration points.
68
+ - Optional image generation, image observation, voice, and LaTeX integration points.
67
69
  - Packaged prompt assets and runtime defaults.
68
70
 
69
71
  ## Requirements
70
72
 
71
73
  - Python 3.10 or newer.
72
74
  - A working model backend configuration compatible with `codex-backend-sdk` / OpenAI usage.
75
+ - GTK 3 plus Ayatana AppIndicator or AppIndicator bindings are needed for the tray controller on Linux.
73
76
  - Firefox / GeckoDriver may be needed for Selenium-backed web extraction paths.
74
77
 
75
78
  ## Installation
@@ -86,18 +89,36 @@ For development:
86
89
  python -m pip install -e '.[dev]'
87
90
  ```
88
91
 
89
- Optional Streamlit support:
92
+ ## Quick start
93
+
94
+ Run the local server plus terminal TUI:
90
95
 
91
96
  ```bash
92
- python -m pip install -e '.[streamlit]'
97
+ codex-agent
93
98
  ```
94
99
 
95
- ## Quick start
100
+ Run only the long-lived local server:
101
+
102
+ ```bash
103
+ codex-agent server
104
+ ```
96
105
 
97
- Run the bundled terminal assistant:
106
+ Connect a TUI to an already running server:
98
107
 
99
108
  ```bash
100
- codex-agent
109
+ codex-agent chat
110
+ ```
111
+
112
+ Start only the tray controller:
113
+
114
+ ```bash
115
+ codex-agent tray
116
+ ```
117
+
118
+ Install the user services for the server and tray controller:
119
+
120
+ ```bash
121
+ codex-agent install-service
101
122
  ```
102
123
 
103
124
  Or use the agent from Python:
@@ -140,6 +161,9 @@ tools/ user runtime tools
140
161
  providers/ user runtime context providers
141
162
  commands/ user runtime slash commands
142
163
  images/ generated or persisted image outputs
164
+ memory.json durable RAG memory entries
165
+ wakeups.json scheduled autonomous wakeups
166
+ tui.json currently registered TUI client process
143
167
  ```
144
168
 
145
169
  You can override the runtime location with:
@@ -194,9 +218,41 @@ The default agent registers local tools that can be exposed to the model:
194
218
  | `bash` | Execute shell commands. |
195
219
  | `observe` | Load an image into the conversation for visual analysis. |
196
220
  | `show` | Open a file, folder, or URL with the system default app/browser. |
221
+ | `memory_add` / `memory_edit` / `memory_delete` / `memory_search` | Manage durable semantic memory entries. |
222
+ | `schedule_wakeup` / `cancel_wakeup` / `list_wakeups` | Manage automatic future turns. |
223
+ | `open_tui` / `close_tui` | Open or close the local TUI through the running server. |
197
224
 
198
225
  Use these with care: Bash, Python, write, and edit run with the current user's privileges.
199
226
 
227
+ ## Local server, TUI, and tray
228
+
229
+ The server exposes the agent through a thin FastAPI bridge. Its REST and SSE endpoints intentionally mirror the Python agent surface where practical, returning the same `modict`/dict-backed payloads used internally.
230
+
231
+ Key endpoints:
232
+
233
+ ```text
234
+ GET /health
235
+ GET /status
236
+ GET /config
237
+ GET /session
238
+ GET /sessions
239
+ GET /messages
240
+ GET /memory
241
+ GET /tools
242
+ GET /wakeups
243
+ GET /events
244
+ GET /events/replay
245
+ POST /turns
246
+ POST /interrupt
247
+ POST /tui/open
248
+ POST /tui/close
249
+ POST /restart
250
+ ```
251
+
252
+ The TUI is a visual client only. It connects over SSE, replays the latest turn when opened mid-session, tracks event sequence cursors, and reconnects after server restarts or transient stream loss. The server accepts one TUI client at a time, while allowing the same client process to replace a stale SSE subscription during reconnect.
253
+
254
+ The tray can start or stop the user service, open or close the TUI, and keep the local agent available independently of the terminal UI.
255
+
200
256
  ## Extending the agent
201
257
 
202
258
  ### Define a tool
@@ -329,7 +385,7 @@ The tests isolate `AGENT_RUNTIME_DIR` automatically, so they should not create o
329
385
  Current baseline:
330
386
 
331
387
  ```text
332
- 102 passed
388
+ 293 passed
333
389
  ```
334
390
 
335
391
  ## Packaging
@@ -344,11 +400,13 @@ python -m build
344
400
  The distribution includes prompt text files and `codex_agent/get_text/default_gitignore` through package data and `MANIFEST.in`.
345
401
 
346
402
  ## Recent changes
403
+ - `0.1.8`: scope TUI replay/SSE catch-up to the active session and make bash/python subprocesses inherit the project Python environment, including service-launched agents.
404
+ - `0.1.7`: add durable RAG memory, scheduled wakeups, process-isolated server runtime, tray/service controls, robust SSE replay/reconnect, richer TUI status, and improved token estimates.
405
+ - `0.1.6`: add the FastAPI REST/SSE bridge, HTTP/SSE client, async-style agent mainloop, and decoupled TUI operation.
347
406
  - `0.1.5`: refine the Textual chat UI with pure black backgrounds, subtler markers/scrollbars, and English UI labels.
348
407
  - `0.1.4`: make the Textual REPL UI the default, add multiline input, assistant turn/step events, cleaner tool-call rendering, and `/voice` configuration.
349
408
  - `0.1.3`: pass the current session id as `prompt_cache_key` to the Codex backend for prompt cache reuse.
350
409
  - `0.1.2`: add `/clear` in the terminal chat to clear the screen without changing session history.
351
- - `0.1.1`: image observations are now validated before session persistence, preventing broken `ImageMessage` entries from poisoning later turns.
352
410
 
353
411
  ## Safety notes
354
412
 
@@ -8,19 +8,23 @@ It provides a reusable `Agent` abstraction with persistent sessions, local tools
8
8
 
9
9
  ## Highlights
10
10
 
11
- - Interactive terminal agent exposed as `codex-agent`.
11
+ - Local FastAPI agent server with a terminal TUI client and GTK tray controller.
12
+ - Process-isolated agent runtime so the local server stays responsive while the agent works.
12
13
  - Persistent JSON sessions with `latest`, explicit session IDs, and session navigation commands.
14
+ - Durable RAG memory backed by runtime JSON, with semantic search and automatic turn summaries.
15
+ - Scheduled wakeups for one-shot or periodic autonomous agent turns.
13
16
  - Built-in local tools for reading, writing, editing, showing, observing, Bash, and Python execution.
14
17
  - Extensible tool, command, and provider decorators.
15
18
  - Event-driven internals for UI, streaming, voice, and automation integrations.
16
19
  - Document extraction helpers for folders, text files, URLs, PDFs, DOCX, XLSX, ODT, HTML, and more.
17
- - Optional image generation, image observation, voice, LaTeX, and Streamlit-oriented integration points.
20
+ - Optional image generation, image observation, voice, and LaTeX integration points.
18
21
  - Packaged prompt assets and runtime defaults.
19
22
 
20
23
  ## Requirements
21
24
 
22
25
  - Python 3.10 or newer.
23
26
  - A working model backend configuration compatible with `codex-backend-sdk` / OpenAI usage.
27
+ - GTK 3 plus Ayatana AppIndicator or AppIndicator bindings are needed for the tray controller on Linux.
24
28
  - Firefox / GeckoDriver may be needed for Selenium-backed web extraction paths.
25
29
 
26
30
  ## Installation
@@ -37,18 +41,36 @@ For development:
37
41
  python -m pip install -e '.[dev]'
38
42
  ```
39
43
 
40
- Optional Streamlit support:
44
+ ## Quick start
45
+
46
+ Run the local server plus terminal TUI:
41
47
 
42
48
  ```bash
43
- python -m pip install -e '.[streamlit]'
49
+ codex-agent
44
50
  ```
45
51
 
46
- ## Quick start
52
+ Run only the long-lived local server:
53
+
54
+ ```bash
55
+ codex-agent server
56
+ ```
47
57
 
48
- Run the bundled terminal assistant:
58
+ Connect a TUI to an already running server:
49
59
 
50
60
  ```bash
51
- codex-agent
61
+ codex-agent chat
62
+ ```
63
+
64
+ Start only the tray controller:
65
+
66
+ ```bash
67
+ codex-agent tray
68
+ ```
69
+
70
+ Install the user services for the server and tray controller:
71
+
72
+ ```bash
73
+ codex-agent install-service
52
74
  ```
53
75
 
54
76
  Or use the agent from Python:
@@ -91,6 +113,9 @@ tools/ user runtime tools
91
113
  providers/ user runtime context providers
92
114
  commands/ user runtime slash commands
93
115
  images/ generated or persisted image outputs
116
+ memory.json durable RAG memory entries
117
+ wakeups.json scheduled autonomous wakeups
118
+ tui.json currently registered TUI client process
94
119
  ```
95
120
 
96
121
  You can override the runtime location with:
@@ -145,9 +170,41 @@ The default agent registers local tools that can be exposed to the model:
145
170
  | `bash` | Execute shell commands. |
146
171
  | `observe` | Load an image into the conversation for visual analysis. |
147
172
  | `show` | Open a file, folder, or URL with the system default app/browser. |
173
+ | `memory_add` / `memory_edit` / `memory_delete` / `memory_search` | Manage durable semantic memory entries. |
174
+ | `schedule_wakeup` / `cancel_wakeup` / `list_wakeups` | Manage automatic future turns. |
175
+ | `open_tui` / `close_tui` | Open or close the local TUI through the running server. |
148
176
 
149
177
  Use these with care: Bash, Python, write, and edit run with the current user's privileges.
150
178
 
179
+ ## Local server, TUI, and tray
180
+
181
+ The server exposes the agent through a thin FastAPI bridge. Its REST and SSE endpoints intentionally mirror the Python agent surface where practical, returning the same `modict`/dict-backed payloads used internally.
182
+
183
+ Key endpoints:
184
+
185
+ ```text
186
+ GET /health
187
+ GET /status
188
+ GET /config
189
+ GET /session
190
+ GET /sessions
191
+ GET /messages
192
+ GET /memory
193
+ GET /tools
194
+ GET /wakeups
195
+ GET /events
196
+ GET /events/replay
197
+ POST /turns
198
+ POST /interrupt
199
+ POST /tui/open
200
+ POST /tui/close
201
+ POST /restart
202
+ ```
203
+
204
+ The TUI is a visual client only. It connects over SSE, replays the latest turn when opened mid-session, tracks event sequence cursors, and reconnects after server restarts or transient stream loss. The server accepts one TUI client at a time, while allowing the same client process to replace a stale SSE subscription during reconnect.
205
+
206
+ The tray can start or stop the user service, open or close the TUI, and keep the local agent available independently of the terminal UI.
207
+
151
208
  ## Extending the agent
152
209
 
153
210
  ### Define a tool
@@ -280,7 +337,7 @@ The tests isolate `AGENT_RUNTIME_DIR` automatically, so they should not create o
280
337
  Current baseline:
281
338
 
282
339
  ```text
283
- 102 passed
340
+ 293 passed
284
341
  ```
285
342
 
286
343
  ## Packaging
@@ -295,11 +352,13 @@ python -m build
295
352
  The distribution includes prompt text files and `codex_agent/get_text/default_gitignore` through package data and `MANIFEST.in`.
296
353
 
297
354
  ## Recent changes
355
+ - `0.1.8`: scope TUI replay/SSE catch-up to the active session and make bash/python subprocesses inherit the project Python environment, including service-launched agents.
356
+ - `0.1.7`: add durable RAG memory, scheduled wakeups, process-isolated server runtime, tray/service controls, robust SSE replay/reconnect, richer TUI status, and improved token estimates.
357
+ - `0.1.6`: add the FastAPI REST/SSE bridge, HTTP/SSE client, async-style agent mainloop, and decoupled TUI operation.
298
358
  - `0.1.5`: refine the Textual chat UI with pure black backgrounds, subtler markers/scrollbars, and English UI labels.
299
359
  - `0.1.4`: make the Textual REPL UI the default, add multiline input, assistant turn/step events, cleaner tool-call rendering, and `/voice` configuration.
300
360
  - `0.1.3`: pass the current session id as `prompt_cache_key` to the Codex backend for prompt cache reuse.
301
361
  - `0.1.2`: add `/clear` in the terminal chat to clear the screen without changing session history.
302
- - `0.1.1`: image observations are now validated before session persistence, preventing broken `ImageMessage` entries from poisoning later turns.
303
362
 
304
363
  ## Safety notes
305
364
 
@@ -12,6 +12,8 @@ from .event import (
12
12
  AssistantTurnEndEvent,
13
13
  AssistantTurnStartEvent,
14
14
  AudioPlaybackEvent,
15
+ CompactionCompletedEvent,
16
+ CompactionRequestedEvent,
15
17
  Event,
16
18
  EventBus,
17
19
  MessageAddedEvent,
@@ -0,0 +1,107 @@
1
+ from pathlib import Path
2
+
3
+ from . import Agent
4
+ from .chat import Chat
5
+ from .server import create_app
6
+ from .service import install_user_service, uninstall_user_service
7
+ from .tray import run_tray
8
+ from .utils import load_runtime_env
9
+
10
+
11
+ def default_agent_kwargs(host=None, port=None):
12
+ package_dir = Path(__file__).parent
13
+ kwargs = dict(
14
+ system=str(package_dir / 'prompts' / 'system_prompt.txt'),
15
+ voice_instructions="You're a lively and friendly female in her mid twenties. You speak french with a easy-going and cheerful tone.",
16
+ username="Baptiste",
17
+ userage="40",
18
+ )
19
+ if host is not None and port is not None:
20
+ kwargs["server_url"] = f"http://{host}:{port}"
21
+ return kwargs
22
+
23
+
24
+ def default_agent():
25
+ return Agent(**default_agent_kwargs())
26
+
27
+
28
+ def configure_server_url(agent, host, port):
29
+ if hasattr(agent, "update_config"):
30
+ agent.update_config(server_url=f"http://{host}:{port}", save=False)
31
+ return agent
32
+
33
+
34
+ def run_server(host="127.0.0.1", port=8765):
35
+ import uvicorn
36
+
37
+ app = create_app(process_agent=True, **default_agent_kwargs(host, port))
38
+ if hasattr(app, "state") and hasattr(app.state, "agent_service"):
39
+ app.state.agent_service.start()
40
+ uvicorn.run(app, host=host, port=port, timeout_graceful_shutdown=2)
41
+
42
+
43
+ def run_chat(base_url="http://127.0.0.1:8765"):
44
+ Chat(base_url=base_url).run()
45
+
46
+
47
+ def run_tray_mode(base_url="http://127.0.0.1:8765"):
48
+ run_tray(base_url=base_url)
49
+
50
+
51
+ def run_local(host="127.0.0.1", port=8765):
52
+ import threading
53
+ import time
54
+
55
+ import uvicorn
56
+
57
+ app = create_app(process_agent=True, **default_agent_kwargs(host, port))
58
+ if hasattr(app, "state") and hasattr(app.state, "agent_service"):
59
+ app.state.agent_service.start()
60
+ config = uvicorn.Config(app, host=host, port=port, log_level="warning", timeout_graceful_shutdown=2)
61
+ server = uvicorn.Server(config)
62
+ thread = threading.Thread(target=server.run, name="codex-agent-server", daemon=True)
63
+ thread.start()
64
+ time.sleep(0.4)
65
+ try:
66
+ run_chat(f"http://{host}:{port}")
67
+ finally:
68
+ server.should_exit = True
69
+ thread.join(timeout=1.0)
70
+
71
+
72
+ def main(argv=None):
73
+ import argparse
74
+
75
+ load_runtime_env()
76
+
77
+ parser = argparse.ArgumentParser(prog="codex-agent")
78
+ parser.add_argument(
79
+ "mode",
80
+ nargs="?",
81
+ choices=["local", "server", "chat", "tray", "install-service", "uninstall-service"],
82
+ default="local",
83
+ help="local starts an embedded server then the TUI client; server runs only the API; chat connects to an existing API; tray starts the desktop tray controller; install-service installs a user systemd service.",
84
+ )
85
+ parser.add_argument("--host", default="127.0.0.1")
86
+ parser.add_argument("--port", type=int, default=8765)
87
+ parser.add_argument("--url", default=None, help="Base URL for chat mode, e.g. http://127.0.0.1:8765")
88
+ args = parser.parse_args(argv)
89
+
90
+ if args.mode == "server":
91
+ run_server(args.host, args.port)
92
+ elif args.mode == "chat":
93
+ run_chat(args.url or f"http://{args.host}:{args.port}")
94
+ elif args.mode == "tray":
95
+ run_tray_mode(args.url or f"http://{args.host}:{args.port}")
96
+ elif args.mode == "install-service":
97
+ path = install_user_service(host=args.host, port=args.port, enable=True, start=True)
98
+ print(f"Installed and started user service: {path}")
99
+ elif args.mode == "uninstall-service":
100
+ path = uninstall_user_service(disable=True, stop=True)
101
+ print(f"Uninstalled user service: {path}")
102
+ else:
103
+ run_local(args.host, args.port)
104
+
105
+
106
+ if __name__ == '__main__':
107
+ main()