codex-agent-framework 0.1.32__tar.gz → 0.1.34__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 (151) hide show
  1. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/CHANGELOG.md +17 -0
  2. {codex_agent_framework-0.1.32/codex_agent_framework.egg-info → codex_agent_framework-0.1.34}/PKG-INFO +1 -1
  3. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/agent.py +39 -33
  4. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/plugin.py +7 -13
  5. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/sessions.py +9 -8
  6. codex_agent_framework-0.1.34/codex_agent/version.py +1 -0
  7. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34/codex_agent_framework.egg-info}/PKG-INFO +1 -1
  8. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/pyproject.toml +1 -1
  9. codex_agent_framework-0.1.32/codex_agent/version.py +0 -1
  10. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/LICENSE +0 -0
  11. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/MANIFEST.in +0 -0
  12. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/README.md +0 -0
  13. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/__init__.py +0 -0
  14. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/__main__.py +0 -0
  15. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/agent_runtime.py +0 -0
  16. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/ai.py +0 -0
  17. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/browser.py +0 -0
  18. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_commands.py +0 -0
  19. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/__init__.py +0 -0
  20. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/bash/__init__.py +0 -0
  21. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
  22. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
  23. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
  24. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/content/__init__.py +0 -0
  25. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
  26. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/content/system.py +0 -0
  27. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/content/vision.py +0 -0
  28. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/context/__init__.py +0 -0
  29. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
  30. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
  31. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/environment/__init__.py +0 -0
  32. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
  33. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/files/__init__.py +0 -0
  34. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
  35. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/files/tools.py +0 -0
  36. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
  37. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
  38. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
  39. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/interface/__init__.py +0 -0
  40. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
  41. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
  42. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
  43. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
  44. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
  45. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/python/__init__.py +0 -0
  46. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
  47. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/__init__.py +0 -0
  48. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
  49. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
  50. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/manager.py +0 -0
  51. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
  52. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/realtime/session.py +0 -0
  53. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
  54. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
  55. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/subagents/__init__.py +0 -0
  56. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
  57. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
  58. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/tts/__init__.py +0 -0
  59. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
  60. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/__init__.py +0 -0
  61. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/headless.py +0 -0
  62. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/main.py +0 -0
  63. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/output.py +0 -0
  64. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/root.py +0 -0
  65. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/cli/runner.py +0 -0
  66. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/client.py +0 -0
  67. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/command.py +0 -0
  68. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/config.py +0 -0
  69. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/context.py +0 -0
  70. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/desktop.py +0 -0
  71. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/event.py +0 -0
  72. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/get_text/__init__.py +0 -0
  73. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/get_text/default_gitignore +0 -0
  74. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/get_text/get_text.py +0 -0
  75. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/get_text/simpler_get_text.py +0 -0
  76. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/hooks.py +0 -0
  77. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/image.py +0 -0
  78. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/latex.py +0 -0
  79. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/mainloop.py +0 -0
  80. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/message.py +0 -0
  81. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/prompts/system_prompt.txt +0 -0
  82. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/provider.py +0 -0
  83. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/runtime.py +0 -0
  84. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/scheduler.py +0 -0
  85. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/scripts/install-system-dependencies.sh +0 -0
  86. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/server/__init__.py +0 -0
  87. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/server/app.py +0 -0
  88. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/server/core.py +0 -0
  89. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/service.py +0 -0
  90. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/status.py +0 -0
  91. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/stream.py +0 -0
  92. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/stream_utils.py +0 -0
  93. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tool.py +0 -0
  94. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tray.py +0 -0
  95. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/__init__.py +0 -0
  96. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/app.py +0 -0
  97. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/chat.py +0 -0
  98. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/lifecycle.py +0 -0
  99. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/log.py +0 -0
  100. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/state.py +0 -0
  101. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/status_bar.py +0 -0
  102. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/style.py +0 -0
  103. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/tui/transcript.py +0 -0
  104. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/utils.py +0 -0
  105. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent/worker.py +0 -0
  106. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent_framework.egg-info/SOURCES.txt +0 -0
  107. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
  108. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent_framework.egg-info/entry_points.txt +0 -0
  109. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent_framework.egg-info/requires.txt +0 -0
  110. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/codex_agent_framework.egg-info/top_level.txt +0 -0
  111. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/dependencies.txt +0 -0
  112. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/setup.cfg +0 -0
  113. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent.py +0 -0
  114. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_audio_hooks.py +0 -0
  115. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_commands.py +0 -0
  116. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_context.py +0 -0
  117. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_desktop.py +0 -0
  118. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_environment.py +0 -0
  119. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_image_generation.py +0 -0
  120. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_observe.py +0 -0
  121. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_plugins.py +0 -0
  122. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_providers_config.py +0 -0
  123. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_realtime.py +0 -0
  124. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_response.py +0 -0
  125. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_runtime.py +0 -0
  126. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_sessions.py +0 -0
  127. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_subagents.py +0 -0
  128. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_tools.py +0 -0
  129. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_agent_turns.py +0 -0
  130. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_ai.py +0 -0
  131. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_browser.py +0 -0
  132. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_builtin_config.py +0 -0
  133. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_chat.py +0 -0
  134. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_cli.py +0 -0
  135. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_cli_headless.py +0 -0
  136. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_cli_root.py +0 -0
  137. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_client.py +0 -0
  138. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_events.py +0 -0
  139. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_get_text_browser.py +0 -0
  140. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_hooks.py +0 -0
  141. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_image_message.py +0 -0
  142. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_local_desktop.py +0 -0
  143. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_memory.py +0 -0
  144. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_messages.py +0 -0
  145. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_planner.py +0 -0
  146. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_scheduler.py +0 -0
  147. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_server.py +0 -0
  148. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_service.py +0 -0
  149. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_tui.py +0 -0
  150. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_utils.py +0 -0
  151. {codex_agent_framework-0.1.32 → codex_agent_framework-0.1.34}/tests/test_worker.py +0 -0
@@ -4,6 +4,23 @@ 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.34] - 2026-05-16
8
+ ### Changed
9
+ - Share the broken-session backup path used by session repair and truncation flows.
10
+ - Simplify plugin requirements lookup by removing redundant path branching.
11
+
12
+ ### Tests
13
+ - Validate with session repair/context/response coverage, plugin tests, and the 553-test offline CI suite.
14
+
15
+ ## [0.1.33] - 2026-05-16
16
+ ### Changed
17
+ - Simplify plugin decorated-method accessors by sharing the handler pair construction path.
18
+ - Deduplicate queued Agent state-command dispatch for scheduler and hook registration operations.
19
+ - Tighten Agent tool-facing docstrings for audio transcription and workfolder uploads without changing runtime behavior.
20
+
21
+ ### Tests
22
+ - Validate the cleanup pass with targeted plugin, Agent, scheduler, hook, tool, audio, and image tests plus the 553-test offline CI suite.
23
+
7
24
  ## [0.1.32] - 2026-05-16
8
25
  ### Changed
9
26
  - Split the former `tests/test_agent.py` monolith into focused agent test modules for audio hooks, commands, context, desktop, environment, image generation, observe, plugins, providers/config, realtime, response handling, sessions, subagents, tools, and turns.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.32
3
+ Version: 0.1.34
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -137,6 +137,11 @@ class Agent:
137
137
  def submit(self, command, **payload):
138
138
  return self.mainloop_manager.submit(command, **payload)
139
139
 
140
+ def _run_or_queue_state_command(self, command, action, **payload):
141
+ if hasattr(self, "mainloop_manager") and self.mainloop_manager.should_queue_state_command():
142
+ return self.submit(command, **payload).wait().result
143
+ return action()
144
+
140
145
  def start_turn(self):
141
146
  return self.mainloop_manager.start_turn()
142
147
 
@@ -157,19 +162,25 @@ class Agent:
157
162
  return self.scheduler.list(include_done=include_done)
158
163
 
159
164
  def schedule_wakeup(self, **kwargs):
160
- if self.mainloop_manager.should_queue_state_command():
161
- return self.submit("schedule_wakeup", **kwargs).wait().result
162
- return self.scheduler.schedule(**kwargs)
165
+ return self._run_or_queue_state_command(
166
+ "schedule_wakeup",
167
+ lambda: self.scheduler.schedule(**kwargs),
168
+ **kwargs,
169
+ )
163
170
 
164
171
  def cancel_wakeup(self, job_id):
165
- if self.mainloop_manager.should_queue_state_command():
166
- return self.submit("cancel_wakeup", job_id=job_id).wait().result
167
- return self.scheduler.cancel(job_id)
172
+ return self._run_or_queue_state_command(
173
+ "cancel_wakeup",
174
+ lambda: self.scheduler.cancel(job_id),
175
+ job_id=job_id,
176
+ )
168
177
 
169
178
  def delete_wakeup(self, job_id):
170
- if self.mainloop_manager.should_queue_state_command():
171
- return self.submit("delete_wakeup", job_id=job_id).wait().result
172
- return self.scheduler.delete(job_id)
179
+ return self._run_or_queue_state_command(
180
+ "delete_wakeup",
181
+ lambda: self.scheduler.delete(job_id),
182
+ job_id=job_id,
183
+ )
173
184
 
174
185
  def interrupt(self, reason="user"):
175
186
  abort_error = None
@@ -373,10 +384,13 @@ class Agent:
373
384
  return self.add_hook(key, f, owner=owner)
374
385
  return decorator
375
386
 
376
- if hasattr(self, "mainloop_manager") and self.mainloop_manager.should_queue_state_command():
377
- return self.submit("add_hook", key=key, func=func, owner=owner).wait().result
378
-
379
- return self.hooks.add(key, func, owner=owner)
387
+ return self._run_or_queue_state_command(
388
+ "add_hook",
389
+ lambda: self.hooks.add(key, func, owner=owner),
390
+ key=key,
391
+ func=func,
392
+ owner=owner,
393
+ )
380
394
 
381
395
  def has_hook(self, key):
382
396
  return self.hooks.has(key)
@@ -434,34 +448,29 @@ class Agent:
434
448
  def listen(self, source, language=None, **kwargs):
435
449
  """
436
450
  description: |
437
- Listen to audio input and transcribe it to text, then process it as a user message.
438
- Accepts either audio data (BytesIO/bytes) or a file path.
451
+ Transcribe audio from bytes, BytesIO, or a file path, then add the text as a user message.
439
452
  parameters:
440
453
  source:
441
- description: Audio data as file_path string, BytesIO object or bytes
454
+ description: Audio source as a path string, BytesIO object, or bytes.
442
455
  language:
443
- description: ISO-639-1 language code (e.g., "en", "fr")
456
+ description: Optional ISO-639-1 language code, such as "en" or "fr".
444
457
  kwargs:
445
- description: Additional parameters for the transcription (model, prompt, temperature, etc.)
458
+ description: Extra transcription options forwarded to the backend.
446
459
  """
447
460
 
448
461
  transcribed_text = self.transcribe(source, language, **kwargs)
449
-
450
- # Add transcribed text as a user message
451
462
  self.add_message(UserMessage(content=transcribed_text))
452
463
 
453
464
  def transcribe(self, source, language=None, **kwargs):
454
465
  """
455
- description: |
456
- Transcribe audio to text.
457
- Accepts either audio data (BytesIO/bytes) or a file path.
466
+ description: Transcribe audio from bytes, BytesIO, or a file path.
458
467
  parameters:
459
468
  source:
460
- description: Audio data as file_path string, BytesIO object or bytes
469
+ description: Audio source as a path string, BytesIO object, or bytes.
461
470
  language:
462
- description: ISO-639-1 language code (e.g., "en", "fr")
471
+ description: Optional ISO-639-1 language code, such as "en" or "fr".
463
472
  kwargs:
464
- description: Additional parameters for the transcription (model, prompt, temperature, etc.)
473
+ description: Extra transcription options forwarded to the backend.
465
474
  """
466
475
  if source is None:
467
476
  raise ValueError("An audio source must be provided")
@@ -477,17 +486,14 @@ class Agent:
477
486
 
478
487
  def upload_file(self, source, name=None):
479
488
  """
480
- description: |
481
- Upload a file to the agent's workfolder and inform the agent via system message.
482
- Supports file paths (str), BytesIO objects, or raw bytes.
489
+ description: Upload a file into the workfolder and notify the agent.
483
490
  parameters:
484
491
  source:
485
- description: File source - can be a file path (str), BytesIO object, or bytes
492
+ description: File path, BytesIO object, or bytes to upload.
486
493
  name:
487
- description: Optional name for the file. Required when source is bytes without a name attribute.
488
- Can include extension to override detection.
494
+ description: Optional destination name; required for unnamed bytes and may include an extension.
489
495
  returns:
490
- description: Absolute path to the uploaded file
496
+ description: Absolute path to the uploaded file.
491
497
  """
492
498
  dest_path = upload_file_to_folder(source, self.config.workfolder, name=name)
493
499
  dest_filename = os.path.basename(dest_path)
@@ -101,24 +101,15 @@ class Plugin:
101
101
 
102
102
  def get_event_handlers(self):
103
103
  """Return ``(event, method)`` pairs declared by this plugin."""
104
- return [
105
- (event_handler_options(method), method)
106
- for method in self._decorated_methods(event_handler_options)
107
- ]
104
+ return self._decorated_method_pairs(event_handler_options)
108
105
 
109
106
  def get_hook_handlers(self):
110
107
  """Return ``(hook_name, method)`` pairs declared by this plugin."""
111
- return [
112
- (hook_handler_options(method), method)
113
- for method in self._decorated_methods(hook_handler_options)
114
- ]
108
+ return self._decorated_method_pairs(hook_handler_options)
115
109
 
116
110
  def get_stream_processors(self):
117
111
  """Return ``(chunk_key, method)`` pairs declared by this plugin."""
118
- return [
119
- (stream_processor_options(method), method)
120
- for method in self._decorated_methods(stream_processor_options)
121
- ]
112
+ return self._decorated_method_pairs(stream_processor_options)
122
113
 
123
114
  def get_system_prompt_sections(self):
124
115
  """Return system prompt sections contributed by this plugin."""
@@ -190,6 +181,9 @@ class Plugin:
190
181
  methods.append(member)
191
182
  return methods
192
183
 
184
+ def _decorated_method_pairs(self, options_for):
185
+ return [(options_for(method), method) for method in self._decorated_methods(options_for)]
186
+
193
187
 
194
188
  class PluginsManager:
195
189
  def __init__(self, agent):
@@ -268,7 +262,7 @@ class PluginsManager:
268
262
  module_file = getattr(module, "__file__", None)
269
263
  if not module_file:
270
264
  return None
271
- base = os.path.dirname(os.path.abspath(module_file)) if os.path.basename(module_file) == "__init__.py" else os.path.dirname(os.path.abspath(module_file))
265
+ base = os.path.dirname(os.path.abspath(module_file))
272
266
  candidate = os.path.join(base, "requirements.txt")
273
267
  return candidate if os.path.isfile(candidate) else None
274
268
 
@@ -352,6 +352,13 @@ class AgentSession(modict):
352
352
  def save_api_success_backup(self):
353
353
  return self.write_messages_file(self.api_success_backup_file)
354
354
 
355
+ def save_broken_backup(self):
356
+ if not os.path.isfile(self.session_file):
357
+ return ""
358
+ backup_file = f"{self.session_file}.broken_{timestamp()}"
359
+ shutil.copy2(self.session_file, backup_file)
360
+ return backup_file
361
+
355
362
  def restore_api_success_backup(self):
356
363
  if not os.path.isfile(self.api_success_backup_file):
357
364
  return False
@@ -471,10 +478,7 @@ class AgentSession(modict):
471
478
  if not removed and not added:
472
479
  return modict(repaired=False, removed=0, added=0, backup_file="", issues=issues)
473
480
 
474
- backup_file = ""
475
- if backup and os.path.isfile(self.session_file):
476
- backup_file = f"{self.session_file}.broken_{timestamp()}"
477
- shutil.copy2(self.session_file, backup_file)
481
+ backup_file = self.save_broken_backup() if backup else ""
478
482
 
479
483
  self.messages = kept
480
484
  if save:
@@ -498,10 +502,7 @@ class AgentSession(modict):
498
502
  if not removed:
499
503
  return modict(repaired=False, removed=0, index=index, backup_file="")
500
504
 
501
- backup_file = ""
502
- if backup and os.path.isfile(self.session_file):
503
- backup_file = f"{self.session_file}.broken_{timestamp()}"
504
- shutil.copy2(self.session_file, backup_file)
505
+ backup_file = self.save_broken_backup() if backup else ""
505
506
 
506
507
  self.messages = self.messages[:index]
507
508
  if save:
@@ -0,0 +1 @@
1
+ __version__ = "0.1.34"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.32
3
+ Version: 0.1.34
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codex-agent-framework"
7
- version = "0.1.32"
7
+ version = "0.1.34"
8
8
  description = "A lightweight event-driven Codex agent runtime."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1 +0,0 @@
1
- __version__ = "0.1.32"