codex-agent-framework 0.1.65__tar.gz → 0.1.67__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.65/codex_agent_framework.egg-info → codex_agent_framework-0.1.67}/PKG-INFO +1 -1
  2. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/agent.py +8 -5
  3. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/ai.py +6 -11
  4. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/browser.py +1 -2
  5. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/bash/__init__.py +0 -1
  6. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/manager.py +0 -1
  7. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/client.py +1 -1
  8. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/latex.py +2 -6
  9. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/lifecycle.py +1 -2
  10. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/utils.py +1 -2
  11. codex_agent_framework-0.1.67/codex_agent/version.py +1 -0
  12. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67/codex_agent_framework.egg-info}/PKG-INFO +1 -1
  13. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/pyproject.toml +1 -1
  14. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_context.py +0 -2
  15. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_plugins.py +0 -3
  16. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_response.py +0 -1
  17. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_ai.py +21 -0
  18. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_chat.py +0 -1
  19. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_client.py +20 -1
  20. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_server.py +1 -1
  21. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_token_counter.py +1 -3
  22. codex_agent_framework-0.1.65/codex_agent/version.py +0 -1
  23. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/CHANGELOG.md +0 -0
  24. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/LICENSE +0 -0
  25. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/MANIFEST.in +0 -0
  26. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/README.md +0 -0
  27. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/__init__.py +0 -0
  28. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/__main__.py +0 -0
  29. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/agent_runtime.py +0 -0
  30. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_commands.py +0 -0
  31. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/__init__.py +0 -0
  32. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
  33. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
  34. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
  35. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/content/__init__.py +0 -0
  36. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
  37. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/content/system.py +0 -0
  38. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/content/vision.py +0 -0
  39. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/context/__init__.py +0 -0
  40. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
  41. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
  42. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/environment/__init__.py +0 -0
  43. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
  44. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/files/__init__.py +0 -0
  45. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
  46. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/files/tools.py +0 -0
  47. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
  48. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
  49. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
  50. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/interface/__init__.py +0 -0
  51. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
  52. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
  53. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
  54. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
  55. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
  56. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/python/__init__.py +0 -0
  57. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
  58. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/__init__.py +0 -0
  59. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
  60. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
  61. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
  62. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/realtime/session.py +0 -0
  63. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
  64. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
  65. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/subagents/__init__.py +0 -0
  66. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
  67. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
  68. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/tts/__init__.py +0 -0
  69. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
  70. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/builtin_plugins/web_search/__init__.py +0 -0
  71. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/__init__.py +0 -0
  72. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/headless.py +0 -0
  73. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/main.py +0 -0
  74. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/output.py +0 -0
  75. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/root.py +0 -0
  76. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/cli/runner.py +0 -0
  77. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/command.py +0 -0
  78. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/config.py +0 -0
  79. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/context.py +0 -0
  80. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/desktop.py +0 -0
  81. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/event.py +0 -0
  82. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/get_text/__init__.py +0 -0
  83. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/get_text/default_gitignore +0 -0
  84. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/get_text/get_text.py +0 -0
  85. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/get_text/simpler_get_text.py +0 -0
  86. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/hooks.py +0 -0
  87. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/image.py +0 -0
  88. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/mainloop.py +0 -0
  89. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/message.py +0 -0
  90. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/plugin.py +0 -0
  91. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/prompts/compaction_prompt.txt +0 -0
  92. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/prompts/system_prompt.txt +0 -0
  93. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/provider.py +0 -0
  94. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/runtime.py +0 -0
  95. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/scheduler.py +0 -0
  96. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/scripts/install-system-dependencies.sh +0 -0
  97. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/server/__init__.py +0 -0
  98. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/server/app.py +0 -0
  99. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/server/core.py +0 -0
  100. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/service.py +0 -0
  101. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/sessions.py +0 -0
  102. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/status.py +0 -0
  103. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/stream.py +0 -0
  104. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/stream_utils.py +0 -0
  105. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/token_counter.py +0 -0
  106. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tool.py +0 -0
  107. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tray.py +0 -0
  108. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/__init__.py +0 -0
  109. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/app.py +0 -0
  110. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/chat.py +0 -0
  111. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/log.py +0 -0
  112. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/perf.py +0 -0
  113. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/state.py +0 -0
  114. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/status_bar.py +0 -0
  115. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/stream_debug.py +0 -0
  116. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/style.py +0 -0
  117. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/transcript.py +0 -0
  118. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/tui/widgets.py +0 -0
  119. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent/worker.py +0 -0
  120. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent_framework.egg-info/SOURCES.txt +0 -0
  121. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
  122. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent_framework.egg-info/entry_points.txt +0 -0
  123. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent_framework.egg-info/requires.txt +0 -0
  124. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/codex_agent_framework.egg-info/top_level.txt +0 -0
  125. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/dependencies.txt +0 -0
  126. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/setup.cfg +0 -0
  127. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent.py +0 -0
  128. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_audio_hooks.py +0 -0
  129. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_commands.py +0 -0
  130. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_desktop.py +0 -0
  131. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_environment.py +0 -0
  132. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_image_generation.py +0 -0
  133. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_observe.py +0 -0
  134. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_providers_config.py +0 -0
  135. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_realtime.py +0 -0
  136. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_runtime.py +0 -0
  137. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_sessions.py +0 -0
  138. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_subagents.py +0 -0
  139. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_tools.py +0 -0
  140. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_agent_turns.py +0 -0
  141. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_browser.py +0 -0
  142. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_builtin_config.py +0 -0
  143. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_cli.py +0 -0
  144. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_cli_headless.py +0 -0
  145. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_cli_root.py +0 -0
  146. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_events.py +0 -0
  147. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_get_text_browser.py +0 -0
  148. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_hooks.py +0 -0
  149. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_image_message.py +0 -0
  150. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_local_desktop.py +0 -0
  151. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_memory.py +0 -0
  152. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_messages.py +0 -0
  153. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_planner.py +0 -0
  154. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_scheduler.py +0 -0
  155. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_service.py +0 -0
  156. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_tui.py +0 -0
  157. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/tests/test_utils.py +0 -0
  158. {codex_agent_framework-0.1.65 → codex_agent_framework-0.1.67}/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.65
3
+ Version: 0.1.67
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -322,7 +322,11 @@ class Agent:
322
322
  )
323
323
 
324
324
  def add_message(self, msg, pending=False):
325
- """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
+ """
326
330
  if isinstance(msg, ToolResultMessage):
327
331
  return self.sessions_manager.append_message(msg)
328
332
  if self.mainloop_manager.dumping_pending:
@@ -333,7 +337,8 @@ class Agent:
333
337
  """Helper to create and add a message based on provided keyword arguments.
334
338
 
335
339
  Args:
336
- 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.
337
342
  **kwargs: Message fields. Must include an explicit ``type``.
338
343
 
339
344
  Returns:
@@ -505,14 +510,12 @@ class Agent:
505
510
  if source is None:
506
511
  raise ValueError("An audio source must be provided")
507
512
 
508
- transcribed_text = self.ai.audio_to_text(
513
+ return self.ai.audio_to_text(
509
514
  source=source,
510
515
  language=language,
511
516
  **kwargs,
512
517
  )
513
518
 
514
- return transcribed_text
515
-
516
519
  def upload_file(self, source, name=None):
517
520
  """
518
521
  description: Upload a file into the workfolder and notify the agent.
@@ -44,17 +44,14 @@ class ChunkStreamer(MappingStreamProcessor):
44
44
 
45
45
  class AIClientError(Exception):
46
46
  """Base exception for AI client errors."""
47
- pass
48
47
 
49
48
 
50
49
  class AIBadRequestError(AIClientError):
51
50
  """Raised when the backend rejects the request as malformed."""
52
- pass
53
51
 
54
52
 
55
53
  class APIAuthenticationError(AIClientError):
56
54
  """Exception raised for API authentication failures."""
57
- pass
58
55
 
59
56
 
60
57
  MAX_EMBEDDING_INPUT_TOKENS = 7500
@@ -172,9 +169,7 @@ class AIClient:
172
169
 
173
170
  mp3_buffer.seek(0)
174
171
 
175
- audio = AudioSegment.from_file(mp3_buffer,format="mp3").set_channels(1)
176
-
177
- return audio
172
+ return AudioSegment.from_file(mp3_buffer,format="mp3").set_channels(1)
178
173
 
179
174
  except Exception as e:
180
175
  raise AIClientError(f"TTS generation failed: {str(e)}")
@@ -327,11 +322,11 @@ class AIClient:
327
322
 
328
323
  def is_bad_request_error(self, exc):
329
324
  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:
325
+ status_codes = (
326
+ getattr(response, "status_code", None),
327
+ getattr(exc, "status_code", None),
328
+ )
329
+ if 400 in status_codes:
335
330
  return True
336
331
  return "400" in str(exc) and "Bad Request" in str(exc)
337
332
 
@@ -396,8 +396,7 @@ class BrowserSession:
396
396
  page = await self.current_page()
397
397
  if url:
398
398
  await self.goto(url, page=page, **goto_kwargs)
399
- text = await page.locator(selector).inner_text(timeout=goto_kwargs.get("timeout", 30_000))
400
- return text
399
+ return await page.locator(selector).inner_text(timeout=goto_kwargs.get("timeout", 30_000))
401
400
 
402
401
  async def screenshot(
403
402
  self,
@@ -1,6 +1,5 @@
1
1
  """Built-in Bash execution plugin."""
2
2
 
3
- import os
4
3
  import subprocess
5
4
 
6
5
  from ...plugin import Plugin
@@ -111,7 +111,6 @@ class RealtimeManager:
111
111
  with self._lock:
112
112
  session = self._session
113
113
  thread = self._thread
114
- session_id = self._session_id or ""
115
114
  if session is None and thread is None:
116
115
  self._state = "stopped" if not self._last_error else "error"
117
116
  return modict(status="stopped", **self.status())
@@ -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
@@ -29,9 +29,7 @@ def escape_formula_specials(formula: str) -> str:
29
29
 
30
30
  # 2) Quotes : \" et \'
31
31
  pattern_quotes = re.compile(r'(?<!\\)\\(["\'])')
32
- formula = pattern_quotes.sub(r'\\\1', formula)
33
-
34
- return formula
32
+ return pattern_quotes.sub(r'\\\1', formula)
35
33
 
36
34
  def _normalize_latex_delimiters(text: str) -> str:
37
35
  r"""
@@ -51,14 +49,12 @@ def _normalize_latex_delimiters(text: str) -> str:
51
49
  )
52
50
 
53
51
  # Inline math : \( ... \) -> $ ... $
54
- text = re.sub(
52
+ return re.sub(
55
53
  r'(?<!\\)\\\((?P<inl>[^\)\n]+?)\\\)', # \( ... \)
56
54
  lambda m: f"${m.group('inl')}$",
57
55
  text,
58
56
  )
59
57
 
60
- return text
61
-
62
58
  def _escape_katex_formulas(text: str) -> str:
63
59
  r"""
64
60
  Traite uniquement les formules KaTeX dans `text` (hors blocs de code).
@@ -113,8 +113,7 @@ def open_tui_terminal(base_url="http://127.0.0.1:8765"):
113
113
  def tui_terminal_env(env=None):
114
114
  env = project_python_env(env)
115
115
  env["AGENT_RUNTIME_DIR"] = os.path.expanduser(env.get("AGENT_RUNTIME_DIR") or runtime_join(""))
116
- env = sanitize_terminal_env(env)
117
- return env
116
+ return sanitize_terminal_env(env)
118
117
 
119
118
 
120
119
  def sanitize_terminal_env(env):
@@ -192,8 +192,7 @@ def tokenizer_for_model(model=None):
192
192
  def tokenize(string, model=None):
193
193
  tokenizer = tokenizer_for_model(model)
194
194
  int_tokens = tokenizer.encode(string)
195
- str_tokens = [tokenizer.decode([int_token]) for int_token in int_tokens]
196
- return str_tokens
195
+ return [tokenizer.decode([int_token]) for int_token in int_tokens]
197
196
 
198
197
  def utf8_safe_tokenize(s):
199
198
  return regex.findall(r'\X', s)
@@ -0,0 +1 @@
1
+ __version__ = "0.1.67"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.65
3
+ Version: 0.1.67
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.65"
7
+ version = "0.1.67"
8
8
  description = "A lightweight event-driven Codex agent runtime."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -1,12 +1,10 @@
1
1
  import json
2
- import os
3
2
 
4
3
  from modict import modict
5
4
 
6
5
  import codex_agent.utils as utils
7
6
  from codex_agent import (
8
7
  Agent,
9
- AssistantStepEndEvent,
10
8
  CompactionCompletedEvent,
11
9
  CompactionMessage,
12
10
  CompactionRequestedEvent,
@@ -1,9 +1,6 @@
1
- import json
2
-
3
1
  import pytest
4
2
 
5
3
  import codex_agent.utils as utils
6
- from modict import modict
7
4
  from codex_agent import Agent, AssistantTurnEndEvent
8
5
  from codex_agent.message import DeveloperMessage, ToolResultWrapper
9
6
 
@@ -3,7 +3,6 @@ import os
3
3
  from types import SimpleNamespace
4
4
 
5
5
  import codex_agent.utils as utils
6
- from modict import modict
7
6
  from codex_agent import Agent, ResponseContentDeltaEvent, ServerToolCallEvent, WebSearchTool
8
7
  from codex_agent.builtin_plugins.image_generation import ImageGenerationTool
9
8
  from codex_agent.message import (
@@ -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)
@@ -5,7 +5,6 @@ from rich.text import Text
5
5
  from textual.app import App
6
6
  from textual.events import MouseMove
7
7
  from textual.geometry import Offset
8
- from textual.widgets import Static
9
8
  import pytest
10
9
  from modict import modict
11
10
 
@@ -1,6 +1,5 @@
1
1
  import json
2
2
  import threading
3
- import time
4
3
 
5
4
  import requests
6
5
 
@@ -151,6 +150,26 @@ def test_agent_client_http_error_payload_includes_status_and_detail():
151
150
  assert payload.error == "an event client is already connected"
152
151
 
153
152
 
153
+ def test_agent_client_http_error_payload_falls_back_to_text_for_non_json_body():
154
+ client = AgentClient()
155
+
156
+ class Response:
157
+ status_code = 502
158
+ text = "gateway unavailable"
159
+
160
+ def json(self):
161
+ raise ValueError("not json")
162
+
163
+ error = requests.HTTPError("502 Bad Gateway")
164
+ error.response = Response()
165
+
166
+ payload = client.event_error_payload(error)
167
+
168
+ assert payload.status_code == 502
169
+ assert payload.detail == "gateway unavailable"
170
+ assert payload.error == "gateway unavailable"
171
+
172
+
154
173
  def test_agent_client_context_status_delegates_to_get_status(monkeypatch):
155
174
  client = AgentClient(base_url="http://agent.local")
156
175
  calls = []
@@ -746,7 +746,7 @@ def test_agent_server_persists_current_session_from_session_command():
746
746
  first_id = first.current_session_id
747
747
  second = Agent(session="new")
748
748
  second_id = second.current_session_id
749
- service = AgentServer(InProcessAgentRuntime(second))
749
+ AgentServer(InProcessAgentRuntime(second))
750
750
 
751
751
  assert load_server_config().current_session_id == second_id
752
752
 
@@ -1,6 +1,4 @@
1
- from types import SimpleNamespace
2
-
3
- from codex_agent.message import CompactionMessage, DeveloperMessage, SystemMessage, UserMessage
1
+ from codex_agent.message import CompactionMessage, SystemMessage, UserMessage
4
2
  from codex_agent.token_counter import TokenCounter
5
3
  from codex_agent.builtin_plugins.image_generation import ImageGenerationTool
6
4
  from codex_agent.tool import Tool, WebSearchTool
@@ -1 +0,0 @@
1
- __version__ = "0.1.65"