codex-agent-framework 0.1.64__tar.gz → 0.1.66__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 (158) hide show
  1. {codex_agent_framework-0.1.64/codex_agent_framework.egg-info → codex_agent_framework-0.1.66}/PKG-INFO +1 -1
  2. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/agent.py +7 -3
  3. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/ai.py +5 -5
  4. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/client.py +1 -1
  5. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/hooks.py +2 -0
  6. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/provider.py +3 -0
  7. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/stream_utils.py +8 -2
  8. codex_agent_framework-0.1.66/codex_agent/version.py +1 -0
  9. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66/codex_agent_framework.egg-info}/PKG-INFO +1 -1
  10. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/pyproject.toml +1 -1
  11. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_ai.py +21 -0
  12. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_client.py +20 -0
  13. codex_agent_framework-0.1.64/codex_agent/version.py +0 -1
  14. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/CHANGELOG.md +0 -0
  15. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/LICENSE +0 -0
  16. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/MANIFEST.in +0 -0
  17. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/README.md +0 -0
  18. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/__init__.py +0 -0
  19. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/__main__.py +0 -0
  20. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/agent_runtime.py +0 -0
  21. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/browser.py +0 -0
  22. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_commands.py +0 -0
  23. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/__init__.py +0 -0
  24. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/bash/__init__.py +0 -0
  25. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
  26. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
  27. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
  28. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/content/__init__.py +0 -0
  29. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
  30. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/content/system.py +0 -0
  31. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/content/vision.py +0 -0
  32. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/context/__init__.py +0 -0
  33. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
  34. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
  35. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/environment/__init__.py +0 -0
  36. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
  37. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/files/__init__.py +0 -0
  38. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
  39. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/files/tools.py +0 -0
  40. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
  41. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
  42. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
  43. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/interface/__init__.py +0 -0
  44. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
  45. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
  46. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
  47. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
  48. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
  49. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/python/__init__.py +0 -0
  50. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
  51. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/__init__.py +0 -0
  52. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
  53. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
  54. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/manager.py +0 -0
  55. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
  56. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/realtime/session.py +0 -0
  57. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
  58. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
  59. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/subagents/__init__.py +0 -0
  60. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
  61. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
  62. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/tts/__init__.py +0 -0
  63. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
  64. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/builtin_plugins/web_search/__init__.py +0 -0
  65. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/__init__.py +0 -0
  66. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/headless.py +0 -0
  67. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/main.py +0 -0
  68. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/output.py +0 -0
  69. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/root.py +0 -0
  70. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/cli/runner.py +0 -0
  71. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/command.py +0 -0
  72. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/config.py +0 -0
  73. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/context.py +0 -0
  74. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/desktop.py +0 -0
  75. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/event.py +0 -0
  76. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/get_text/__init__.py +0 -0
  77. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/get_text/default_gitignore +0 -0
  78. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/get_text/get_text.py +0 -0
  79. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/get_text/simpler_get_text.py +0 -0
  80. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/image.py +0 -0
  81. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/latex.py +0 -0
  82. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/mainloop.py +0 -0
  83. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/message.py +0 -0
  84. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/plugin.py +0 -0
  85. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/prompts/compaction_prompt.txt +0 -0
  86. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/prompts/system_prompt.txt +0 -0
  87. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/runtime.py +0 -0
  88. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/scheduler.py +0 -0
  89. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/scripts/install-system-dependencies.sh +0 -0
  90. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/server/__init__.py +0 -0
  91. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/server/app.py +0 -0
  92. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/server/core.py +0 -0
  93. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/service.py +0 -0
  94. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/sessions.py +0 -0
  95. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/status.py +0 -0
  96. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/stream.py +0 -0
  97. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/token_counter.py +0 -0
  98. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tool.py +0 -0
  99. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tray.py +0 -0
  100. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/__init__.py +0 -0
  101. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/app.py +0 -0
  102. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/chat.py +0 -0
  103. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/lifecycle.py +0 -0
  104. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/log.py +0 -0
  105. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/perf.py +0 -0
  106. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/state.py +0 -0
  107. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/status_bar.py +0 -0
  108. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/stream_debug.py +0 -0
  109. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/style.py +0 -0
  110. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/transcript.py +0 -0
  111. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/tui/widgets.py +0 -0
  112. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/utils.py +0 -0
  113. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent/worker.py +0 -0
  114. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent_framework.egg-info/SOURCES.txt +0 -0
  115. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
  116. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent_framework.egg-info/entry_points.txt +0 -0
  117. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent_framework.egg-info/requires.txt +0 -0
  118. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/codex_agent_framework.egg-info/top_level.txt +0 -0
  119. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/dependencies.txt +0 -0
  120. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/setup.cfg +0 -0
  121. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent.py +0 -0
  122. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_audio_hooks.py +0 -0
  123. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_commands.py +0 -0
  124. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_context.py +0 -0
  125. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_desktop.py +0 -0
  126. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_environment.py +0 -0
  127. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_image_generation.py +0 -0
  128. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_observe.py +0 -0
  129. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_plugins.py +0 -0
  130. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_providers_config.py +0 -0
  131. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_realtime.py +0 -0
  132. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_response.py +0 -0
  133. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_runtime.py +0 -0
  134. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_sessions.py +0 -0
  135. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_subagents.py +0 -0
  136. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_tools.py +0 -0
  137. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_agent_turns.py +0 -0
  138. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_browser.py +0 -0
  139. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_builtin_config.py +0 -0
  140. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_chat.py +0 -0
  141. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_cli.py +0 -0
  142. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_cli_headless.py +0 -0
  143. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_cli_root.py +0 -0
  144. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_events.py +0 -0
  145. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_get_text_browser.py +0 -0
  146. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_hooks.py +0 -0
  147. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_image_message.py +0 -0
  148. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_local_desktop.py +0 -0
  149. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_memory.py +0 -0
  150. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_messages.py +0 -0
  151. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_planner.py +0 -0
  152. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_scheduler.py +0 -0
  153. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_server.py +0 -0
  154. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_service.py +0 -0
  155. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_token_counter.py +0 -0
  156. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_tui.py +0 -0
  157. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_utils.py +0 -0
  158. {codex_agent_framework-0.1.64 → codex_agent_framework-0.1.66}/tests/test_worker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.64
3
+ Version: 0.1.66
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -7,7 +7,6 @@ from .utils import (
7
7
  upload_file_to_folder,
8
8
  )
9
9
  import os
10
- from modict import modict
11
10
  from .message import (
12
11
  DeveloperMessage,
13
12
  ServerToolResponseMessage,
@@ -323,7 +322,11 @@ class Agent:
323
322
  )
324
323
 
325
324
  def add_message(self, msg, pending=False):
326
- """Queue a message for the next pending flush, except tool results."""
325
+ """Queue a message for the next flush, except tool results.
326
+
327
+ The ``pending`` argument is kept for compatibility; pending routing is
328
+ controlled by the current mainloop state.
329
+ """
327
330
  if isinstance(msg, ToolResultMessage):
328
331
  return self.sessions_manager.append_message(msg)
329
332
  if self.mainloop_manager.dumping_pending:
@@ -334,7 +337,8 @@ class Agent:
334
337
  """Helper to create and add a message based on provided keyword arguments.
335
338
 
336
339
  Args:
337
- pending: If True, stores message in pending list instead of main messages.
340
+ pending: Backward-compatible hint; pending routing is controlled by
341
+ the current mainloop state.
338
342
  **kwargs: Message fields. Must include an explicit ``type``.
339
343
 
340
344
  Returns:
@@ -327,11 +327,11 @@ class AIClient:
327
327
 
328
328
  def is_bad_request_error(self, exc):
329
329
  response = getattr(exc, "response", None)
330
- status_code = getattr(response, "status_code", None)
331
- if status_code == 400:
332
- return True
333
- status_code = getattr(exc, "status_code", None)
334
- if status_code == 400:
330
+ status_codes = (
331
+ getattr(response, "status_code", None),
332
+ getattr(exc, "status_code", None),
333
+ )
334
+ if 400 in status_codes:
335
335
  return True
336
336
  return "400" in str(exc) and "Bad Request" in str(exc)
337
337
 
@@ -281,7 +281,7 @@ class AgentClient:
281
281
  payload.status_code = exc.response.status_code
282
282
  try:
283
283
  detail = exc.response.json().get("detail")
284
- except Exception:
284
+ except ValueError:
285
285
  detail = exc.response.text
286
286
  if detail:
287
287
  payload.detail = detail
@@ -24,6 +24,8 @@ class HookContext(modict):
24
24
 
25
25
 
26
26
  class HookManager:
27
+ """Registry and dispatcher for named extension hooks."""
28
+
27
29
  def __init__(self, agent=None):
28
30
  self.agent = agent
29
31
  self.handlers = modict()
@@ -20,6 +20,7 @@ def provider(func=None, **options):
20
20
 
21
21
 
22
22
  def provider_options(func):
23
+ """Return provider decorator metadata from a function or bound method."""
23
24
  options = getattr(func, PROVIDER_MARKER, None)
24
25
  if options is not None:
25
26
  return options
@@ -27,6 +28,8 @@ def provider_options(func):
27
28
 
28
29
 
29
30
  class ProvidersManager:
31
+ """Registry for context providers contributed by the agent and plugins."""
32
+
30
33
  def __init__(self, agent):
31
34
  self.agent = agent
32
35
  self.providers = modict()
@@ -7,15 +7,18 @@ from typing import Union
7
7
  import json
8
8
 
9
9
  class END:
10
- #sentinel value for end of stream
11
- pass
10
+ """Sentinel value placed in queues to mark the end of a stream."""
12
11
 
13
12
 
14
13
  class StreamError:
14
+ """Wrapper used to propagate producer exceptions through queue readers."""
15
+
15
16
  def __init__(self, error):
16
17
  self.error = error
17
18
 
19
+
18
20
  class Task:
21
+ """Tiny thread-backed task helper used by legacy stream utilities."""
19
22
 
20
23
  def __init__(self,target=None,args=None,kwargs=None):
21
24
  self.target_task=target or self.target
@@ -34,6 +37,7 @@ class Task:
34
37
  self.thread.join()
35
38
 
36
39
  class Tee:
40
+ """Fan out one input stream into independent reader streams."""
37
41
 
38
42
  def __init__(self):
39
43
  self.queues={}
@@ -59,6 +63,7 @@ class Tee:
59
63
  return tuple(reader(queue) for queue in self.queues.values())
60
64
 
61
65
  class Splitter:
66
+ """Split a stream into true/false readers according to a predicate."""
62
67
 
63
68
  def __init__(self,condition=None):
64
69
  self.queue_true=None
@@ -91,6 +96,7 @@ class Splitter:
91
96
  return reader(self.queue_true), reader(self.queue_false)
92
97
 
93
98
  class Streamer:
99
+ """Base helper that optionally runs stream processing in a worker thread."""
94
100
 
95
101
  def __init__(self,stream_processor=None,threaded=True):
96
102
  self.queue=None
@@ -0,0 +1 @@
1
+ __version__ = "0.1.66"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.64
3
+ Version: 0.1.66
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.64"
7
+ version = "0.1.66"
8
8
  description = "A lightweight event-driven Codex agent runtime."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -267,6 +267,27 @@ def test_codex_backend_params_move_leading_system_messages_to_instructions():
267
267
  }]
268
268
 
269
269
 
270
+ def test_is_bad_request_error_uses_response_status_code():
271
+ ai = AIClient(agent=None)
272
+ exc = RuntimeError("request failed")
273
+ exc.response = SimpleNamespace(status_code=400)
274
+
275
+ assert ai.is_bad_request_error(exc) is True
276
+
277
+
278
+ def test_is_bad_request_error_uses_exception_status_code():
279
+ ai = AIClient(agent=None)
280
+ exc = SimpleNamespace(status_code=400)
281
+
282
+ assert ai.is_bad_request_error(exc) is True
283
+
284
+
285
+ def test_is_bad_request_error_keeps_message_fallback():
286
+ ai = AIClient(agent=None)
287
+
288
+ assert ai.is_bad_request_error(RuntimeError("400 Bad Request: nope")) is True
289
+
290
+
270
291
  def test_codex_stream_idle_timeout_aborts_silent_backend_stream():
271
292
  agent = FakeAgent(codex_stream_idle_timeout=0.01)
272
293
  ai = AIClient(agent=agent)
@@ -151,6 +151,26 @@ def test_agent_client_http_error_payload_includes_status_and_detail():
151
151
  assert payload.error == "an event client is already connected"
152
152
 
153
153
 
154
+ def test_agent_client_http_error_payload_falls_back_to_text_for_non_json_body():
155
+ client = AgentClient()
156
+
157
+ class Response:
158
+ status_code = 502
159
+ text = "gateway unavailable"
160
+
161
+ def json(self):
162
+ raise ValueError("not json")
163
+
164
+ error = requests.HTTPError("502 Bad Gateway")
165
+ error.response = Response()
166
+
167
+ payload = client.event_error_payload(error)
168
+
169
+ assert payload.status_code == 502
170
+ assert payload.detail == "gateway unavailable"
171
+ assert payload.error == "gateway unavailable"
172
+
173
+
154
174
  def test_agent_client_context_status_delegates_to_get_status(monkeypatch):
155
175
  client = AgentClient(base_url="http://agent.local")
156
176
  calls = []
@@ -1 +0,0 @@
1
- __version__ = "0.1.64"