codex-agent-framework 0.1.84__tar.gz → 0.1.86__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 (214) hide show
  1. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/CHANGELOG.md +22 -0
  2. {codex_agent_framework-0.1.84/codex_agent_framework.egg-info → codex_agent_framework-0.1.86}/PKG-INFO +2 -1
  3. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/README.md +1 -0
  4. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/App.test.ts +63 -0
  5. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/App.tsx +63 -13
  6. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/SettingsPanel.tsx +10 -8
  7. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/models.test.ts +7 -2
  8. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/models.ts +11 -5
  9. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/src/main.rs +6 -1
  10. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/agent.py +8 -22
  11. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/ai.py +2 -2
  12. codex_agent_framework-0.1.86/codex_agent/builtin_plugins/interface/__init__.py +108 -0
  13. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/tts/__init__.py +0 -2
  14. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/headless.py +140 -4
  15. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/main.py +58 -8
  16. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/root.py +26 -2
  17. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/runner.py +12 -0
  18. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/client.py +69 -8
  19. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/config.py +2 -14
  20. codex_agent_framework-0.1.86/codex_agent/dock.py +92 -0
  21. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/mainloop.py +33 -43
  22. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/message.py +1 -1
  23. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/plugin.py +1 -10
  24. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/prompts/system_prompt.txt +36 -28
  25. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/server/app.py +19 -0
  26. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/server/core.py +31 -48
  27. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/service.py +25 -8
  28. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/status.py +4 -64
  29. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tool.py +21 -58
  30. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tray.py +8 -31
  31. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/__init__.py +2 -0
  32. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/app.py +26 -11
  33. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/lifecycle.py +29 -0
  34. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/state.py +6 -1
  35. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/widgets.py +29 -6
  36. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/utils.py +3 -0
  37. codex_agent_framework-0.1.86/codex_agent/version.py +1 -0
  38. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86/codex_agent_framework.egg-info}/PKG-INFO +2 -1
  39. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent_framework.egg-info/SOURCES.txt +1 -0
  40. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/pyproject.toml +1 -1
  41. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_context.py +36 -0
  42. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_plugins.py +86 -0
  43. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_response.py +1 -1
  44. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_builtin_config.py +0 -14
  45. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_chat.py +1 -17
  46. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_cli.py +108 -0
  47. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_cli_root.py +16 -0
  48. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_memory.py +1 -1
  49. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_server.py +53 -0
  50. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_service.py +12 -0
  51. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_tui.py +29 -0
  52. codex_agent_framework-0.1.84/codex_agent/builtin_plugins/interface/__init__.py +0 -53
  53. codex_agent_framework-0.1.84/codex_agent/version.py +0 -1
  54. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/LICENSE +0 -0
  55. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/MANIFEST.in +0 -0
  56. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/.gitignore +0 -0
  57. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/README.md +0 -0
  58. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/eslint.config.js +0 -0
  59. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/index.html +0 -0
  60. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/package.json +0 -0
  61. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/pnpm-lock.yaml +0 -0
  62. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/public/favicon.svg +0 -0
  63. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/public/icons.svg +0 -0
  64. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/public/pandora-logo.png +0 -0
  65. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/api.test.ts +0 -0
  66. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/api.ts +0 -0
  67. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/assets/hero.png +0 -0
  68. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/assets/pandora-logo.png +0 -0
  69. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/assets/vite.svg +0 -0
  70. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/Chat.tsx +0 -0
  71. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/ChatArea.tsx +0 -0
  72. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/Composer.tsx +0 -0
  73. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/Header.tsx +0 -0
  74. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/IconButton.tsx +0 -0
  75. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/InteractionModal.tsx +0 -0
  76. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/ShowRenderer.tsx +0 -0
  77. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/SidePanel.tsx +0 -0
  78. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/Splash.tsx +0 -0
  79. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/StatusBar.tsx +0 -0
  80. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/components/icons.tsx +0 -0
  81. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/index.css +0 -0
  82. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/main.tsx +0 -0
  83. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/store.test.ts +0 -0
  84. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/store.ts +0 -0
  85. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src/vite-env.d.ts +0 -0
  86. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/Cargo.lock +0 -0
  87. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/Cargo.toml +0 -0
  88. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/build.rs +0 -0
  89. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/capabilities/default.json +0 -0
  90. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/gen/schemas/acl-manifests.json +0 -0
  91. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/gen/schemas/capabilities.json +0 -0
  92. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/gen/schemas/desktop-schema.json +0 -0
  93. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/gen/schemas/linux-schema.json +0 -0
  94. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/icons/icon-32.png +0 -0
  95. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/icons/icon.png +0 -0
  96. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/icons/icon.svg +0 -0
  97. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/src-tauri/tauri.conf.json +0 -0
  98. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/tsconfig.app.json +0 -0
  99. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/tsconfig.json +0 -0
  100. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/tsconfig.node.json +0 -0
  101. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/apps/desktop/vite.config.ts +0 -0
  102. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/__init__.py +0 -0
  103. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/__main__.py +0 -0
  104. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/agent_runtime.py +0 -0
  105. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/browser.py +0 -0
  106. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_commands.py +0 -0
  107. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/__init__.py +0 -0
  108. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/bash/__init__.py +0 -0
  109. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/bash/requirements.txt +0 -0
  110. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/browser/__init__.py +0 -0
  111. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/browser/requirements.txt +0 -0
  112. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/content/__init__.py +0 -0
  113. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/content/requirements.txt +0 -0
  114. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/content/system.py +0 -0
  115. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/content/vision.py +0 -0
  116. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/context/__init__.py +0 -0
  117. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/desktop/__init__.py +0 -0
  118. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/desktop/requirements.txt +0 -0
  119. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/environment/__init__.py +0 -0
  120. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/environment/requirements.txt +0 -0
  121. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/files/__init__.py +0 -0
  122. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/files/requirements.txt +0 -0
  123. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/files/tools.py +0 -0
  124. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/image_generation/__init__.py +0 -0
  125. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/image_generation/image_generation_system_prompt.txt +0 -0
  126. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/image_generation/requirements.txt +0 -0
  127. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/interface/requirements.txt +0 -0
  128. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/memory/__init__.py +0 -0
  129. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/memory/requirements.txt +0 -0
  130. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/planner/__init__.py +0 -0
  131. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/planner/requirements.txt +0 -0
  132. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/python/__init__.py +0 -0
  133. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/python/requirements.txt +0 -0
  134. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/__init__.py +0 -0
  135. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/audio.py +0 -0
  136. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/bridge.py +0 -0
  137. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/manager.py +0 -0
  138. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/requirements.txt +0 -0
  139. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/realtime/session.py +0 -0
  140. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/scheduler/__init__.py +0 -0
  141. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/scheduler/requirements.txt +0 -0
  142. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/subagents/__init__.py +0 -0
  143. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/subagents/profiles/explorer.json +0 -0
  144. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/subagents/requirements.txt +0 -0
  145. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/tts/requirements.txt +0 -0
  146. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/builtin_plugins/web_search/__init__.py +0 -0
  147. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/__init__.py +0 -0
  148. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/cli/output.py +0 -0
  149. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/command.py +0 -0
  150. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/context.py +0 -0
  151. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/desktop.py +0 -0
  152. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/event.py +0 -0
  153. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/get_text/__init__.py +0 -0
  154. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/get_text/default_gitignore +0 -0
  155. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/get_text/get_text.py +0 -0
  156. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/get_text/simpler_get_text.py +0 -0
  157. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/hooks.py +0 -0
  158. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/image.py +0 -0
  159. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/interactions.py +0 -0
  160. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/latex.py +0 -0
  161. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/prompts/compaction_prompt.txt +0 -0
  162. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/provider.py +0 -0
  163. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/runtime.py +0 -0
  164. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/scheduler.py +0 -0
  165. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/scripts/install-system-dependencies.sh +0 -0
  166. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/server/__init__.py +0 -0
  167. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/sessions.py +0 -0
  168. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/stream.py +0 -0
  169. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/stream_utils.py +0 -0
  170. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/token_counter.py +0 -0
  171. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/chat.py +0 -0
  172. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/log.py +0 -0
  173. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/perf.py +0 -0
  174. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/status_bar.py +0 -0
  175. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/stream_debug.py +0 -0
  176. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/style.py +0 -0
  177. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/tui/transcript.py +0 -0
  178. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent/worker.py +0 -0
  179. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent_framework.egg-info/dependency_links.txt +0 -0
  180. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent_framework.egg-info/entry_points.txt +0 -0
  181. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent_framework.egg-info/requires.txt +0 -0
  182. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/codex_agent_framework.egg-info/top_level.txt +0 -0
  183. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/dependencies.txt +0 -0
  184. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/setup.cfg +0 -0
  185. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/setup.py +0 -0
  186. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent.py +0 -0
  187. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_audio_hooks.py +0 -0
  188. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_commands.py +0 -0
  189. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_desktop.py +0 -0
  190. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_environment.py +0 -0
  191. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_image_generation.py +0 -0
  192. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_observe.py +0 -0
  193. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_providers_config.py +0 -0
  194. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_realtime.py +0 -0
  195. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_runtime.py +0 -0
  196. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_sessions.py +0 -0
  197. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_subagents.py +0 -0
  198. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_tools.py +0 -0
  199. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_agent_turns.py +0 -0
  200. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_ai.py +0 -0
  201. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_browser.py +0 -0
  202. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_cli_headless.py +0 -0
  203. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_client.py +0 -0
  204. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_events.py +0 -0
  205. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_get_text_browser.py +0 -0
  206. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_hooks.py +0 -0
  207. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_image_message.py +0 -0
  208. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_local_desktop.py +0 -0
  209. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_messages.py +0 -0
  210. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_planner.py +0 -0
  211. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_scheduler.py +0 -0
  212. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_token_counter.py +0 -0
  213. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_utils.py +0 -0
  214. {codex_agent_framework-0.1.84 → codex_agent_framework-0.1.86}/tests/test_worker.py +0 -0
@@ -4,6 +4,28 @@ 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.86] - 2026-07-10
8
+ ### Changed
9
+ - Simplify tool schema token accounting around a shared Responses-tool primitive while preserving local and server tool formats.
10
+ - Remove inert plugin-config compatibility arguments, message `pending` hints, and a stale TUI transcript shim.
11
+ - Restructure the code-quality guidance into concise, actionable maintainer principles.
12
+
13
+ ### Tests
14
+ - Validate the simplification pass with the full offline suite (700 passed).
15
+
16
+ ## [0.1.85] - 2026-07-05
17
+ ### Changed
18
+ - Simplify the CLI around the persisted active session: `codex-agent` and `run` now target the active session by default, with `--new` for starting fresh.
19
+ - Add a human-oriented `plugins` CLI/API surface for listing, loading, unloading, and reloading builtin or custom plugins.
20
+ - Improve TUI stream responsiveness with faster live flushes, local delta coalescing, and batched event queue draining.
21
+
22
+ ### Fixed
23
+ - Make TUI reopening wait for real registration before reporting success, avoiding stale immediate status snapshots.
24
+ - Preserve compaction summaries before recent conversation messages while keeping provider messages at the end of the active context.
25
+
26
+ ### Tests
27
+ - Validate the CLI, server, context, plugin, TUI, and service changes with targeted coverage.
28
+
7
29
  ## [0.1.84] - 2026-07-03
8
30
  ### Changed
9
31
  - Include the desktop dock Tauri sources in Python source and wheel distributions, excluding generated build artifacts.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-agent-framework
3
- Version: 0.1.84
3
+ Version: 0.1.86
4
4
  Summary: A lightweight event-driven Codex agent runtime.
5
5
  Author: Baptiste
6
6
  License-Expression: MIT
@@ -163,6 +163,7 @@ Useful CLI commands:
163
163
  ```bash
164
164
  codex-agent status --json
165
165
  codex-agent tools
166
+ codex-agent plugins list
166
167
  codex-agent sessions list
167
168
  codex-agent config get
168
169
  codex-agent run "Run a quick repository health check."
@@ -114,6 +114,7 @@ Useful CLI commands:
114
114
  ```bash
115
115
  codex-agent status --json
116
116
  codex-agent tools
117
+ codex-agent plugins list
117
118
  codex-agent sessions list
118
119
  codex-agent config get
119
120
  codex-agent run "Run a quick repository health check."
@@ -115,6 +115,69 @@ describe("dock native SSE event handling", () => {
115
115
  });
116
116
  });
117
117
 
118
+ it("ignores live-only duplicate events during replay", async () => {
119
+ const { handleSSE } = await import("./App");
120
+
121
+ handleSSE({ type: "message_submitted_event", message: { role: "user", content: "hello" } }, true);
122
+ handleSSE({ type: "tool_call_start_event", tool_call: { id: "tool-1", name: "read", input: { file_path: "README.md" } } }, true);
123
+ handleSSE({ type: "tool_call_done_event", tool_call: { id: "tool-1" }, content: "ok" }, true);
124
+ handleSSE({ type: "desktop_control_event", action: "close" }, true);
125
+
126
+ expect(useStore.getState().messages).toHaveLength(0);
127
+ expect(useStore.getState().toolRegistry).toEqual({});
128
+ });
129
+
130
+ it("still handles durable replay messages", async () => {
131
+ const { handleSSE } = await import("./App");
132
+
133
+ handleSSE({ type: "message_added_event", message: { role: "user", content: "hello" } }, true);
134
+ handleSSE({
135
+ type: "message_added_event",
136
+ message: {
137
+ role: "assistant",
138
+ content: "checking",
139
+ tool_calls: [{ call_id: "tool-1", name: "read", arguments: JSON.stringify({ file_path: "README.md" }) }],
140
+ },
141
+ }, true);
142
+
143
+ expect(useStore.getState().messages).toHaveLength(2);
144
+ expect(useStore.getState().messages[0]).toMatchObject({ role: "user", content: [{ type: "text", text: "hello" }] });
145
+ expect(useStore.getState().toolRegistry["tool-1"]).toMatchObject({ id: "tool-1", name: "read" });
146
+ });
147
+
148
+ it("does not duplicate live tool calls when finalized messages arrive", async () => {
149
+ const { handleSSE } = await import("./App");
150
+
151
+ handleSSE({
152
+ type: "tool_call_start_event",
153
+ tool_call: { id: "tool-1", name: "read", input: { file_path: "README.md" } },
154
+ });
155
+ handleSSE({
156
+ type: "tool_call_done_event",
157
+ tool_call: { id: "tool-1" },
158
+ content: "ok",
159
+ });
160
+ handleSSE({
161
+ type: "message_added_event",
162
+ message: {
163
+ role: "assistant",
164
+ content: "checking",
165
+ tool_calls: [{ call_id: "tool-1", name: "read", arguments: JSON.stringify({ file_path: "README.md" }) }],
166
+ },
167
+ });
168
+ handleSSE({
169
+ type: "message_added_event",
170
+ message: { type: "tool_result_message", role: "tool", call_id: "tool-1", content: "ok" },
171
+ });
172
+
173
+ const toolUseBlocks = useStore.getState().messages.flatMap((message) => message.content).filter((block) => block.type === "tool_use");
174
+ const toolResultBlocks = useStore.getState().messages.flatMap((message) => message.content).filter((block) => block.type === "tool_result");
175
+
176
+ expect(toolUseBlocks).toHaveLength(1);
177
+ expect(toolResultBlocks).toHaveLength(1);
178
+ expect(useStore.getState().toolRegistry["tool-1"]).toMatchObject({ done: true, output: "ok" });
179
+ });
180
+
118
181
  it("tracks native tool start and done events", async () => {
119
182
  const { handleSSE } = await import("./App");
120
183
 
@@ -6,7 +6,8 @@ import { SettingsPanel } from "./components/SettingsPanel";
6
6
  import { Chat } from "./components/Chat";
7
7
  import { Splash, isSplashDone, resetSplash } from "./components/Splash";
8
8
  import { useStore, type ContentBlock, type ShowBlock } from "./store";
9
- import { getStatus, getRecentEvents, subscribeSSE, getDockUI, saveDockUI, registerDesktop, unregisterDesktop, type SSEEvent, type DockUI } from "./api";
9
+ import { invoke } from "@tauri-apps/api/core";
10
+ import { getStatus, getRecentEvents, subscribeSSE, getDockUI, saveDockUI, registerDesktop, unregisterDesktop, type SSEEvent, type DockUI, type DesktopState } from "./api";
10
11
 
11
12
  const isTauri = "__TAURI_INTERNALS__" in window;
12
13
  // Cache dock UI in localStorage for instant restore, sync with server file
@@ -30,6 +31,23 @@ function getLogicalContentHeight(el: HTMLElement): number {
30
31
  return Math.ceil(el.offsetHeight * zoom);
31
32
  }
32
33
 
34
+ async function dockRegistrationState(collapsed: boolean): Promise<DesktopState> {
35
+ const state: DesktopState = {
36
+ label: "main",
37
+ url: window.location.href,
38
+ user_agent: navigator.userAgent,
39
+ visible: true,
40
+ focused: document.hasFocus(),
41
+ collapsed,
42
+ };
43
+ if (isTauri) {
44
+ try {
45
+ state.pid = await invoke<number>("current_pid");
46
+ } catch { /* PID is best-effort; server unregister fallback still applies. */ }
47
+ }
48
+ return state;
49
+ }
50
+
33
51
  async function trackWindowGeo() {
34
52
  if (!isTauri) return;
35
53
  const { getCurrentWindow } = await import("@tauri-apps/api/window");
@@ -56,7 +74,15 @@ async function trackWindowGeo() {
56
74
 
57
75
 
58
76
  // ── SSE event handler ──────────────────────────────────────────────
77
+ const REPLAY_IGNORED_EVENT_TYPES = new Set([
78
+ "message_submitted_event",
79
+ "tool_call_start_event",
80
+ "tool_call_done_event",
81
+ "desktop_control_event",
82
+ ]);
83
+
59
84
  export function handleSSE(event: SSEEvent, isReplay = false) {
85
+ if (isReplay && REPLAY_IGNORED_EVENT_TYPES.has(event.type)) return;
60
86
  const store = useStore.getState();
61
87
  if (event.session_id) store.setSessionId(event.session_id);
62
88
 
@@ -181,6 +207,18 @@ function handleStatusEvent(event: SSEEvent) {
181
207
  if (typeof status.session_id === "string") useStore.getState().setSessionId(status.session_id);
182
208
  }
183
209
 
210
+ function hasDisplayedToolUse(id: string): boolean {
211
+ return useStore.getState().messages.some((message) =>
212
+ message.content.some((block) => block.type === "tool_use" && block.id === id),
213
+ );
214
+ }
215
+
216
+ function hasDisplayedToolResult(id: string): boolean {
217
+ return useStore.getState().messages.some((message) =>
218
+ message.content.some((block) => block.type === "tool_result" && block.tool_use_id === id),
219
+ );
220
+ }
221
+
184
222
  function handleMessageEvent(event: SSEEvent) {
185
223
  const message = isRecord(event.message) ? event.message : null;
186
224
  if (!message) return;
@@ -207,7 +245,9 @@ function handleMessageEvent(event: SSEEvent) {
207
245
  useStore.getState().registerToolUse(callId, toolName, {});
208
246
  useStore.getState().resolveToolResult(callId, isError, output);
209
247
  }
210
- useStore.getState().addMessage({ role: "assistant", content: [{ type: "tool_result", tool_use_id: callId, output, is_error: isError }] });
248
+ if (!callId || !hasDisplayedToolResult(callId)) {
249
+ useStore.getState().addMessage({ role: "assistant", content: [{ type: "tool_result", tool_use_id: callId, output, is_error: isError }] });
250
+ }
211
251
  return;
212
252
  }
213
253
 
@@ -237,7 +277,9 @@ function handleToolCallStart(
237
277
  const input = toolCallInput(toolCall);
238
278
  if (id) {
239
279
  useStore.getState().registerToolUse(id, name, input, opts);
240
- useStore.getState().addMessage({ role: "assistant", content: [{ type: "tool_use", id, name, input }] });
280
+ if (!hasDisplayedToolUse(id)) {
281
+ useStore.getState().addMessage({ role: "assistant", content: [{ type: "tool_use", id, name, input }] });
282
+ }
241
283
  }
242
284
  useStore.getState().setAgentPhase("tool_use");
243
285
  useStore.getState().setLastToolName(name);
@@ -249,10 +291,12 @@ function handleToolCallDone(event: SSEEvent) {
249
291
  const output = textFromContent(event.content ?? event.result ?? objectField(toolCall, "output"));
250
292
  const isError = Boolean(event.is_error) || output.startsWith("<error>");
251
293
  if (id) useStore.getState().resolveToolResult(id, isError, output);
252
- useStore.getState().addMessage({
253
- role: "assistant",
254
- content: [{ type: "tool_result", tool_use_id: id, output, is_error: isError }],
255
- });
294
+ if (!id || !hasDisplayedToolResult(id)) {
295
+ useStore.getState().addMessage({
296
+ role: "assistant",
297
+ content: [{ type: "tool_result", tool_use_id: id, output, is_error: isError }],
298
+ });
299
+ }
256
300
  }
257
301
 
258
302
  function handleInteractionRequested(event: SSEEvent) {
@@ -318,7 +362,7 @@ function blocksFromToolCalls(toolCalls: unknown): ContentBlock[] {
318
362
  const name = stringField(call, "name") || "unknown";
319
363
  const input = toolCallInput(call);
320
364
  if (id) store.registerToolUse(id, name, input);
321
- blocks.push({ type: "tool_use", id, name, input });
365
+ if (id && !hasDisplayedToolUse(id)) blocks.push({ type: "tool_use", id, name, input });
322
366
  }
323
367
  return blocks;
324
368
  }
@@ -604,16 +648,22 @@ export default function App() {
604
648
  };
605
649
  }, [setConnected]);
606
650
 
607
- // Register the desktop dock with the local agent server for lightweight control/status.
651
+ // Register the desktop dock like the TUI: the server tracks a live PID and
652
+ // discards stale state automatically when that process exits.
608
653
  useEffect(() => {
609
- const state = { label: "main", url: window.location.href, user_agent: navigator.userAgent, visible: true, focused: document.hasFocus(), collapsed };
610
- registerDesktop(state).catch(() => {});
654
+ dockRegistrationState(collapsed).then(registerDesktop).catch(() => {});
611
655
  }, [collapsed]);
612
656
 
613
657
  useEffect(() => {
614
658
  if (!isTauri) return;
615
- registerDesktop({ label: "main", url: window.location.href, user_agent: navigator.userAgent, visible: true, focused: document.hasFocus(), collapsed }).catch(() => {});
616
- const cleanup = () => { unregisterDesktop().catch(() => {}); };
659
+ let pid: number | undefined;
660
+ dockRegistrationState(collapsed)
661
+ .then((state) => {
662
+ pid = state.pid;
663
+ return registerDesktop(state);
664
+ })
665
+ .catch(() => {});
666
+ const cleanup = () => { unregisterDesktop(pid).catch(() => {}); };
617
667
  window.addEventListener("beforeunload", cleanup);
618
668
  return () => {
619
669
  window.removeEventListener("beforeunload", cleanup);
@@ -3,7 +3,7 @@ import { useStore } from "../store";
3
3
  import { MODELS, normalizeModel } from "../models";
4
4
  import { XIcon } from "./icons";
5
5
  import {
6
- getServerInfo, getStatus, getUsage, getRateLimits, getMcpStatus,
6
+ getServerInfo, getStatus, getConfig, getUsage, getRateLimits, getMcpStatus,
7
7
  getWakeups, scheduleWakeup, cancelWakeup,
8
8
  getCurrentSession, getSessions, newSession, loadSession, renameSession, deleteSession,
9
9
  getPlugins, loadPlugin, unloadPlugin, reloadPlugin,
@@ -506,9 +506,9 @@ function SchedulerSettings() {
506
506
  export function SettingsPanel() {
507
507
  const { settingsOpen, toggleSettings } = useStore();
508
508
  const sessionId = useStore((s) => s.sessionId);
509
- const [model, setModelState] = useState("gpt-5.4");
509
+ const [model, setModelState] = useState("gpt-5.6-terra");
510
510
  const [permMode, setPermModeState] = useState("bypassPermissions");
511
- const [effort, setEffortState] = useState("high");
511
+ const [effort, setEffortState] = useState("medium");
512
512
  const [usage, setUsage] = useState<UsageInfo | null>(null);
513
513
  const [rateLimits, setRateLimits] = useState<RateLimits | null>(null);
514
514
  const [account, setAccount] = useState<{ email: string; planType: string } | null>(null);
@@ -517,11 +517,13 @@ export function SettingsPanel() {
517
517
 
518
518
  useEffect(() => {
519
519
  if (!settingsOpen) return;
520
- getStatus()
521
- .then((s) => {
522
- if (s.model) setModelState((cur) => normalizeModel(s.model || cur, cur));
523
- if (s.permission_mode) setPermModeState(s.permission_mode);
524
- if (s.thinking_effort) setEffortState(s.thinking_effort);
520
+ Promise.all([getStatus().catch(() => null), getConfig().catch(() => null)])
521
+ .then(([status, config]) => {
522
+ const configuredModel = status?.model || config?.model;
523
+ if (configuredModel) setModelState((cur) => normalizeModel(configuredModel, cur));
524
+ if (status?.permission_mode) setPermModeState(status.permission_mode);
525
+ const configuredEffort = config?.reasoning?.effort || status?.thinking_effort;
526
+ if (configuredEffort) setEffortState(configuredEffort);
525
527
  })
526
528
  .catch(() => {});
527
529
  getUsage().then(setUsage).catch(() => {});
@@ -3,23 +3,28 @@ import { modelLabel, normalizeModel } from "./models";
3
3
 
4
4
  describe("model helpers", () => {
5
5
  it("keeps known model ids unchanged", () => {
6
+ expect(normalizeModel("gpt-5.6-sol")).toBe("gpt-5.6-sol");
7
+ expect(normalizeModel("gpt-5.6-terra")).toBe("gpt-5.6-terra");
8
+ expect(normalizeModel("gpt-5.6-luna")).toBe("gpt-5.6-luna");
6
9
  expect(normalizeModel("gpt-5.5")).toBe("gpt-5.5");
7
10
  expect(normalizeModel("gpt-5.4")).toBe("gpt-5.4");
8
11
  expect(normalizeModel("gpt-5.4-mini")).toBe("gpt-5.4-mini");
9
12
  });
10
13
 
11
14
  it("maps backend variants to dock-supported models", () => {
15
+ expect(normalizeModel("openai/gpt-5.6-terra-latest")).toBe("gpt-5.6-terra");
12
16
  expect(normalizeModel("openai/gpt-5.5-latest")).toBe("gpt-5.5");
13
17
  expect(normalizeModel("gpt-5.4-mini-2026-04-01")).toBe("gpt-5.4-mini");
14
- expect(normalizeModel("unknown-model")).toBe("gpt-5.4");
18
+ expect(normalizeModel("unknown-model")).toBe("gpt-5.6-terra");
15
19
  });
16
20
 
17
21
  it("falls back to the current model when raw model is empty", () => {
18
22
  expect(normalizeModel("", "gpt-5.5")).toBe("gpt-5.5");
19
- expect(normalizeModel("")).toBe("gpt-5.4");
23
+ expect(normalizeModel("")).toBe("gpt-5.6-terra");
20
24
  });
21
25
 
22
26
  it("returns compact status labels", () => {
27
+ expect(modelLabel("gpt-5.6-terra")).toBe("gpt-5.6 terra");
23
28
  expect(modelLabel("gpt-5.5")).toBe("gpt-5.5");
24
29
  expect(modelLabel("gpt-5.4-mini")).toBe("gpt-5.4 mini");
25
30
  expect(modelLabel("")).toBe("");
@@ -11,20 +11,26 @@ export interface ModelDef {
11
11
  }
12
12
 
13
13
  export const MODELS: ModelDef[] = [
14
- { id: "gpt-5.5", label: "GPT-5.5", cmd: "5.5", desc: "Puissant" },
15
- { id: "gpt-5.4", label: "GPT-5.4", cmd: "5.4", desc: "Intermédiaire" },
16
- { id: "gpt-5.4-mini", label: "GPT-5.4 Mini", cmd: "mini", desc: "Économique" },
14
+ { id: "gpt-5.6-sol", label: "GPT-5.6 Sol", cmd: "sol", desc: "Puissant" },
15
+ { id: "gpt-5.6-terra", label: "GPT-5.6 Terra", cmd: "terra", desc: "Équilibré" },
16
+ { id: "gpt-5.6-luna", label: "GPT-5.6 Luna", cmd: "luna", desc: "Léger" },
17
+ { id: "gpt-5.5", label: "GPT-5.5", cmd: "5.5", desc: "Puissant" },
18
+ { id: "gpt-5.4", label: "GPT-5.4", cmd: "5.4", desc: "Intermédiaire" },
19
+ { id: "gpt-5.4-mini", label: "GPT-5.4 Mini", cmd: "mini", desc: "Économique" },
17
20
  ];
18
21
 
19
22
  /**
20
23
  * Map a raw backend model string to a canonical MODELS id.
21
24
  */
22
25
  export function normalizeModel(raw: string, current?: string): string {
23
- if (!raw) return current ?? "gpt-5.4";
26
+ if (!raw) return current ?? "gpt-5.6-terra";
24
27
  if (MODELS.some((m) => m.id === raw)) return raw;
28
+ if (raw.includes("5.6-sol")) return "gpt-5.6-sol";
29
+ if (raw.includes("5.6-terra")) return "gpt-5.6-terra";
30
+ if (raw.includes("5.6-luna")) return "gpt-5.6-luna";
25
31
  if (raw.includes("5.5")) return "gpt-5.5";
26
32
  if (raw.includes("mini")) return "gpt-5.4-mini";
27
- return "gpt-5.4";
33
+ return "gpt-5.6-terra";
28
34
  }
29
35
 
30
36
  /** Short display label for the status bar. */
@@ -42,6 +42,11 @@ fn ensure_background_services() {
42
42
  }
43
43
  }
44
44
 
45
+ #[tauri::command]
46
+ fn current_pid() -> u32 {
47
+ std::process::id()
48
+ }
49
+
45
50
  #[tauri::command]
46
51
  fn open_external_url(url: String) -> Result<(), String> {
47
52
  let lower = url.to_ascii_lowercase();
@@ -67,7 +72,7 @@ fn main() {
67
72
  std::env::set_var("GDK_BACKEND", "x11");
68
73
 
69
74
  tauri::Builder::default()
70
- .invoke_handler(tauri::generate_handler![open_external_url])
75
+ .invoke_handler(tauri::generate_handler![current_pid, open_external_url])
71
76
  .setup(|_app| {
72
77
  std::thread::spawn(ensure_background_services);
73
78
  Ok(())
@@ -247,7 +247,7 @@ class Agent:
247
247
  """Authenticate the Codex backend client through stored or interactive OAuth credentials."""
248
248
  from codex_backend_sdk import CodexClient
249
249
 
250
- client = CodexClient(model=self.config.get("model") or "gpt-5.4").authenticate(
250
+ client = CodexClient(model=self.config.get("model") or "gpt-5.6-terra").authenticate(
251
251
  interactive=interactive,
252
252
  request_api_key=request_api_key,
253
253
  )
@@ -395,33 +395,19 @@ class Agent:
395
395
  max_compacted_turns=max_compacted_turns,
396
396
  )
397
397
 
398
- def add_message(self, msg, pending=False):
399
- """Queue a message for the next flush, except tool results.
400
-
401
- The ``pending`` argument is kept for compatibility; pending routing is
402
- controlled by the current mainloop state.
403
- """
398
+ def add_message(self, msg):
399
+ """Queue a message for the next flush, except tool results."""
404
400
  if isinstance(msg, ToolResultMessage):
405
401
  return self.sessions_manager.append_message(msg)
406
402
  if self.mainloop_manager.dumping_pending:
407
403
  return self.sessions_manager.append_message(msg)
408
404
  return self.mainloop_manager.add_pending_message(msg)
409
405
 
410
- def new_message(self, pending=False, **kwargs):
411
- """Helper to create and add a message based on provided keyword arguments.
412
-
413
- Args:
414
- pending: Backward-compatible hint; pending routing is controlled by
415
- the current mainloop state.
416
- **kwargs: Message fields. Must include an explicit ``type``.
417
-
418
- Returns:
419
- The created message object.
420
- """
421
- msg = message_from_data(kwargs)
422
- return self.add_message(msg, pending=pending)
406
+ def new_message(self, **kwargs):
407
+ """Create and queue a message from explicit message fields."""
408
+ return self.add_message(message_from_data(kwargs))
423
409
 
424
- def add_image(self, source, pending=False, **kwargs):
410
+ def add_image(self, source, **kwargs):
425
411
  if source:
426
412
  img = ImageMessage(
427
413
  content=source,
@@ -429,7 +415,7 @@ class Agent:
429
415
  )
430
416
  if not img.is_valid():
431
417
  raise ValueError(f"Invalid or inaccessible image source: {source!r}")
432
- self.add_message(img, pending=pending)
418
+ self.add_message(img)
433
419
  return img
434
420
 
435
421
  def add_tool(
@@ -90,7 +90,7 @@ class AIClient:
90
90
  def codex_client(self):
91
91
  """Client used for LLM calls through the ChatGPT Codex backend."""
92
92
  if self._codex_client is None:
93
- model = self.agent.config.get('model') or "gpt-5.4"
93
+ model = self.agent.config.get('model') or "gpt-5.6-terra"
94
94
  self._codex_client = CodexClient(model=model).authenticate(request_api_key=False)
95
95
  return self._codex_client
96
96
 
@@ -366,7 +366,7 @@ class AIClient:
366
366
  def _to_codex_response_params(self, params):
367
367
  instructions, history = self._split_codex_messages(params.get("messages", []))
368
368
  tools = params.get("tools") or []
369
- model = params.get("model") or "gpt-5.4"
369
+ model = params.get("model") or "gpt-5.6-terra"
370
370
  reasoning = modict(params.get("reasoning") or {})
371
371
  text = modict(params.get("text") or {})
372
372
  if not reasoning and params.get("reasoning_effort"):
@@ -0,0 +1,108 @@
1
+ """Built-in local interface plugin."""
2
+
3
+ import time
4
+
5
+ from ...dock import current_dock, open_dock
6
+ from ...plugin import Plugin
7
+ from ...provider import provider
8
+ from ...tool import tool
9
+ from ...tui import current_tui, open_tui_terminal, terminate_tui, wait_for_tui_registration
10
+
11
+
12
+ class InterfacePlugin(Plugin):
13
+ name = "interface"
14
+ description = "Control the local TUI and Pandora desktop dock."
15
+ prefix_tools = False
16
+
17
+ @provider
18
+ def tui_status(self):
19
+ """Expose whether the local TUI client is currently open."""
20
+ tui = current_tui()
21
+ if not tui:
22
+ return "TUI status: closed."
23
+ return (
24
+ "TUI status: open. "
25
+ f"pid={tui.get('pid')} "
26
+ f"base_url={tui.get('base_url')} "
27
+ f"timestamp={tui.get('timestamp')}"
28
+ )
29
+
30
+ @provider
31
+ def dock_status(self):
32
+ """Expose whether the local Pandora desktop dock is currently open."""
33
+ dock = current_dock()
34
+ if not dock:
35
+ return "Dock status: closed."
36
+ return f"Dock status: open. pid={dock.get('pid')} timestamp={dock.get('timestamp')}"
37
+
38
+ def control_dock(self, action):
39
+ dock = current_dock()
40
+ if not dock:
41
+ return {"status": "not_open"}
42
+ self.agent.emit("desktop_control_event", action=action, desktop=dock)
43
+ return {"status": "requested", "action": action, "dock": dock}
44
+
45
+ @tool(name="open_dock")
46
+ def open_dock(self):
47
+ """
48
+ description: Open the local Pandora desktop dock, or show it when it is already open.
49
+ parameters: {}
50
+ required: []
51
+ """
52
+ dock = current_dock()
53
+ return self.control_dock("open") if dock else dict(open_dock())
54
+
55
+ @tool(name="focus_dock")
56
+ def focus_dock(self):
57
+ """
58
+ description: Focus the currently open Pandora desktop dock window.
59
+ parameters: {}
60
+ required: []
61
+ """
62
+ return self.control_dock("focus")
63
+
64
+ @tool(name="close_dock")
65
+ def close_dock(self):
66
+ """
67
+ description: Close the currently open Pandora desktop dock window.
68
+ parameters: {}
69
+ required: []
70
+ """
71
+ return self.control_dock("close")
72
+
73
+ @tool(name="open_tui")
74
+ def open_tui(self):
75
+ """
76
+ description: Open the Textual chat TUI client in a separate terminal connected to the local agent server.
77
+ parameters: {}
78
+ required: []
79
+ """
80
+ tui = current_tui()
81
+ if tui:
82
+ return {"status": "already_open", "tui": tui}
83
+ base_url = self.agent.config.get("server_url", "http://127.0.0.1:8765")
84
+ process = open_tui_terminal(base_url=base_url)
85
+ if process is None:
86
+ raise RuntimeError("No supported terminal emulator found to open the TUI")
87
+ registered_tui = wait_for_tui_registration()
88
+ if not registered_tui:
89
+ return {
90
+ "status": "not_registered",
91
+ "pid": process.pid,
92
+ "reason": "terminal launched but TUI did not register",
93
+ }
94
+ time.sleep(0.25)
95
+ return {"status": "opened", "pid": process.pid, "tui": registered_tui}
96
+
97
+ @tool(name="close_tui")
98
+ def close_tui(self):
99
+ """
100
+ description: Close the currently registered Textual chat TUI client process.
101
+ parameters: {}
102
+ required: []
103
+ """
104
+ tui = current_tui()
105
+ if not tui:
106
+ return {"status": "not_open"}
107
+ terminate_tui(tui.pid)
108
+ return {"status": "closed", "tui": tui}
@@ -240,8 +240,6 @@ class TTSPlugin(Plugin):
240
240
  enabled=False,
241
241
  buffer_size=2,
242
242
  )
243
- config_legacy_aliases = {}
244
- config_legacy_sections = ("plugins.tts",)
245
243
  system_prompt = """
246
244
  # TTS and Conversation tone
247
245