code-puppy 0.0.374__tar.gz → 0.0.375__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 (232) hide show
  1. {code_puppy-0.0.374 → code_puppy-0.0.375}/PKG-INFO +1 -1
  2. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_manager.py +34 -2
  3. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/base_agent.py +61 -4
  4. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/callbacks.py +125 -0
  5. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/rich_renderer.py +13 -7
  6. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/model_factory.py +63 -258
  7. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/model_utils.py +33 -1
  8. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/register_callbacks.py +106 -1
  9. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/utils.py +2 -3
  10. code_puppy-0.0.375/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +176 -0
  11. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +88 -0
  12. code_puppy-0.0.375/code_puppy/plugins/ralph/__init__.py +13 -0
  13. code_puppy-0.0.375/code_puppy/plugins/ralph/agents.py +433 -0
  14. code_puppy-0.0.375/code_puppy/plugins/ralph/commands.py +208 -0
  15. code_puppy-0.0.375/code_puppy/plugins/ralph/loop_controller.py +285 -0
  16. code_puppy-0.0.375/code_puppy/plugins/ralph/models.py +125 -0
  17. code_puppy-0.0.375/code_puppy/plugins/ralph/register_callbacks.py +133 -0
  18. code_puppy-0.0.375/code_puppy/plugins/ralph/state_manager.py +322 -0
  19. code_puppy-0.0.375/code_puppy/plugins/ralph/tools.py +451 -0
  20. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/__init__.py +31 -0
  21. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/agent_tools.py +1 -1
  22. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/command_runner.py +23 -9
  23. {code_puppy-0.0.374 → code_puppy-0.0.375}/pyproject.toml +1 -1
  24. code_puppy-0.0.374/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -94
  25. {code_puppy-0.0.374 → code_puppy-0.0.375}/.gitignore +0 -0
  26. {code_puppy-0.0.374 → code_puppy-0.0.375}/LICENSE +0 -0
  27. {code_puppy-0.0.374 → code_puppy-0.0.375}/README.md +0 -0
  28. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/__init__.py +0 -0
  29. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/__main__.py +0 -0
  30. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/__init__.py +0 -0
  31. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_c_reviewer.py +0 -0
  32. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_code_puppy.py +0 -0
  33. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_code_reviewer.py +0 -0
  34. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
  35. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_creator_agent.py +0 -0
  36. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_golang_reviewer.py +0 -0
  37. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_helios.py +0 -0
  38. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
  39. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_pack_leader.py +0 -0
  40. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_planning.py +0 -0
  41. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_python_programmer.py +0 -0
  42. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_python_reviewer.py +0 -0
  43. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_qa_expert.py +0 -0
  44. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_qa_kitten.py +0 -0
  45. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_security_auditor.py +0 -0
  46. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_terminal_qa.py +0 -0
  47. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
  48. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/event_stream_handler.py +0 -0
  49. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/json_agent.py +0 -0
  50. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/__init__.py +0 -0
  51. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/bloodhound.py +0 -0
  52. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/husky.py +0 -0
  53. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/retriever.py +0 -0
  54. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/shepherd.py +0 -0
  55. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/terrier.py +0 -0
  56. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/pack/watchdog.py +0 -0
  57. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/prompt_reviewer.py +0 -0
  58. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/agents/subagent_stream_handler.py +0 -0
  59. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/__init__.py +0 -0
  60. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/app.py +0 -0
  61. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/main.py +0 -0
  62. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/pty_manager.py +0 -0
  63. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/routers/__init__.py +0 -0
  64. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/routers/agents.py +0 -0
  65. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/routers/commands.py +0 -0
  66. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/routers/config.py +0 -0
  67. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/routers/sessions.py +0 -0
  68. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/templates/terminal.html +0 -0
  69. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/api/websocket.py +0 -0
  70. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/chatgpt_codex_client.py +0 -0
  71. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/claude_cache_client.py +0 -0
  72. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/cli_runner.py +0 -0
  73. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/__init__.py +0 -0
  74. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/add_model_menu.py +0 -0
  75. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/agent_menu.py +0 -0
  76. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/attachments.py +0 -0
  77. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/autosave_menu.py +0 -0
  78. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/clipboard.py +0 -0
  79. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/colors_menu.py +0 -0
  80. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/command_handler.py +0 -0
  81. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/command_registry.py +0 -0
  82. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/config_commands.py +0 -0
  83. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/core_commands.py +0 -0
  84. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/diff_menu.py +0 -0
  85. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/file_path_completion.py +0 -0
  86. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/load_context_completion.py +0 -0
  87. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/__init__.py +0 -0
  88. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/base.py +0 -0
  89. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
  90. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
  91. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
  92. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/edit_command.py +0 -0
  93. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/handler.py +0 -0
  94. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/help_command.py +0 -0
  95. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/install_command.py +0 -0
  96. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/install_menu.py +0 -0
  97. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/list_command.py +0 -0
  98. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/logs_command.py +0 -0
  99. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/remove_command.py +0 -0
  100. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/restart_command.py +0 -0
  101. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/search_command.py +0 -0
  102. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  103. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/start_command.py +0 -0
  104. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/status_command.py +0 -0
  105. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  106. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/stop_command.py +0 -0
  107. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/test_command.py +0 -0
  108. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/utils.py +0 -0
  109. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  110. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/mcp_completion.py +0 -0
  111. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/model_picker_completion.py +0 -0
  112. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/model_settings_menu.py +0 -0
  113. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/motd.py +0 -0
  114. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/onboarding_slides.py +0 -0
  115. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/onboarding_wizard.py +0 -0
  116. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/pin_command_completion.py +0 -0
  117. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  118. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/session_commands.py +0 -0
  119. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/uc_menu.py +0 -0
  120. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/command_line/utils.py +0 -0
  121. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/config.py +0 -0
  122. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/error_logging.py +0 -0
  123. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/gemini_code_assist.py +0 -0
  124. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/gemini_model.py +0 -0
  125. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/http_utils.py +0 -0
  126. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/keymap.py +0 -0
  127. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/main.py +0 -0
  128. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/__init__.py +0 -0
  129. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/async_lifecycle.py +0 -0
  130. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/blocking_startup.py +0 -0
  131. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  132. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/circuit_breaker.py +0 -0
  133. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/config_wizard.py +0 -0
  134. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/dashboard.py +0 -0
  135. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/error_isolation.py +0 -0
  136. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/examples/retry_example.py +0 -0
  137. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/health_monitor.py +0 -0
  138. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/managed_server.py +0 -0
  139. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/manager.py +0 -0
  140. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/mcp_logs.py +0 -0
  141. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/registry.py +0 -0
  142. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/retry_manager.py +0 -0
  143. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  144. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/status_tracker.py +0 -0
  145. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/mcp_/system_tools.py +0 -0
  146. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/__init__.py +0 -0
  147. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/bus.py +0 -0
  148. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/commands.py +0 -0
  149. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/markdown_patches.py +0 -0
  150. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/message_queue.py +0 -0
  151. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/messages.py +0 -0
  152. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/queue_console.py +0 -0
  153. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/renderers.py +0 -0
  154. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/spinner/__init__.py +0 -0
  155. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/spinner/console_spinner.py +0 -0
  156. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  157. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/messaging/subagent_console.py +0 -0
  158. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/model_switching.py +0 -0
  159. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/models.json +0 -0
  160. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/models_dev_api.json +0 -0
  161. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/models_dev_parser.py +0 -0
  162. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/__init__.py +0 -0
  163. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/__init__.py +0 -0
  164. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/accounts.py +0 -0
  165. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/antigravity_model.py +0 -0
  166. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/config.py +0 -0
  167. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/constants.py +0 -0
  168. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/oauth.py +0 -0
  169. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/storage.py +0 -0
  170. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/test_plugin.py +0 -0
  171. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/token.py +0 -0
  172. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/antigravity_oauth/transport.py +0 -0
  173. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
  174. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
  175. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  176. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  177. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
  178. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  179. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  180. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
  181. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
  182. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
  183. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
  184. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  185. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
  186. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/example_custom_command/README.md +0 -0
  187. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  188. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  189. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
  190. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
  191. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
  192. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
  193. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/oauth_puppy_html.py +0 -0
  194. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  195. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
  196. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
  197. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
  198. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
  199. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/universal_constructor/models.py +0 -0
  200. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
  201. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/universal_constructor/registry.py +0 -0
  202. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
  203. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/prompts/antigravity_system_prompt.md +0 -0
  204. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/pydantic_patches.py +0 -0
  205. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/reopenable_async_client.py +0 -0
  206. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/round_robin_model.py +0 -0
  207. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/session_storage.py +0 -0
  208. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/status_display.py +0 -0
  209. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/summarization_agent.py +0 -0
  210. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/terminal_utils.py +0 -0
  211. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/__init__.py +0 -0
  212. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_control.py +0 -0
  213. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_interactions.py +0 -0
  214. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_locators.py +0 -0
  215. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_manager.py +0 -0
  216. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_navigation.py +0 -0
  217. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_screenshot.py +0 -0
  218. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_scripts.py +0 -0
  219. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/browser_workflows.py +0 -0
  220. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/chromium_terminal_manager.py +0 -0
  221. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/terminal_command_tools.py +0 -0
  222. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/terminal_screenshot_tools.py +0 -0
  223. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/browser/terminal_tools.py +0 -0
  224. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/common.py +0 -0
  225. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/display.py +0 -0
  226. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/file_modifications.py +0 -0
  227. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/file_operations.py +0 -0
  228. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/subagent_context.py +0 -0
  229. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/tools_content.py +0 -0
  230. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/tools/universal_constructor.py +0 -0
  231. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/uvx_detection.py +0 -0
  232. {code_puppy-0.0.374 → code_puppy-0.0.375}/code_puppy/version_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-puppy
3
- Version: 0.0.374
3
+ Version: 0.0.375
4
4
  Summary: Code generation agent
5
5
  Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
6
6
  Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
@@ -13,7 +13,7 @@ from pydantic_ai.messages import ModelMessage
13
13
 
14
14
  from code_puppy.agents.base_agent import BaseAgent
15
15
  from code_puppy.agents.json_agent import JSONAgent, discover_json_agents
16
- from code_puppy.callbacks import on_agent_reload
16
+ from code_puppy.callbacks import on_agent_reload, on_register_agents
17
17
  from code_puppy.messaging import emit_success, emit_warning
18
18
 
19
19
  # Registry of available agents (Python classes and JSON file paths)
@@ -289,6 +289,38 @@ def _discover_agents(message_group_id: Optional[str] = None):
289
289
  message_group=message_group_id,
290
290
  )
291
291
 
292
+ # 3. Discover agents registered by plugins
293
+ try:
294
+ results = on_register_agents()
295
+ for result in results:
296
+ if result is None:
297
+ continue
298
+ # Each result should be a list of agent definitions
299
+ agents_list = result if isinstance(result, list) else [result]
300
+ for agent_def in agents_list:
301
+ if not isinstance(agent_def, dict) or "name" not in agent_def:
302
+ continue
303
+
304
+ agent_name = agent_def["name"]
305
+
306
+ # Support both class-based and JSON path-based registration
307
+ if "class" in agent_def:
308
+ agent_class = agent_def["class"]
309
+ if isinstance(agent_class, type) and issubclass(
310
+ agent_class, BaseAgent
311
+ ):
312
+ _AGENT_REGISTRY[agent_name] = agent_class
313
+ elif "json_path" in agent_def:
314
+ json_path = agent_def["json_path"]
315
+ if isinstance(json_path, str):
316
+ _AGENT_REGISTRY[agent_name] = json_path
317
+
318
+ except Exception as e:
319
+ emit_warning(
320
+ f"Warning: Could not load plugin agents: {e}",
321
+ message_group=message_group_id,
322
+ )
323
+
292
324
 
293
325
  def get_available_agents() -> Dict[str, str]:
294
326
  """Get a dictionary of available agents with their display names.
@@ -612,7 +644,7 @@ def clone_agent(agent_name: str) -> Optional[str]:
612
644
  agent_instance.display_name, clone_index
613
645
  ),
614
646
  "description": agent_instance.description,
615
- "system_prompt": agent_instance.get_system_prompt(),
647
+ "system_prompt": agent_instance.get_full_system_prompt(),
616
648
  "tools": _filter_available_tools(agent_instance.get_available_tools()),
617
649
  }
618
650
 
@@ -47,6 +47,7 @@ from pydantic_ai.messages import (
47
47
  from rich.text import Text
48
48
 
49
49
  from code_puppy.agents.event_stream_handler import event_stream_handler
50
+ from code_puppy.callbacks import on_agent_response_complete
50
51
 
51
52
  # Consolidated relative imports
52
53
  from code_puppy.config import (
@@ -101,6 +102,37 @@ class BaseAgent(ABC):
101
102
  # This is populated after the first successful run when MCP tools are retrieved
102
103
  self._mcp_tool_definitions_cache: List[Dict[str, Any]] = []
103
104
 
105
+ def get_identity(self) -> str:
106
+ """Get a unique identity for this agent instance.
107
+
108
+ Returns:
109
+ A string like 'python-programmer-a3f2b1' combining name + short UUID.
110
+ """
111
+ return f"{self.name}-{self.id[:6]}"
112
+
113
+ def get_identity_prompt(self) -> str:
114
+ """Get the identity prompt suffix to embed in system prompts.
115
+
116
+ Returns:
117
+ A string instructing the agent about its identity for task ownership.
118
+ """
119
+ return (
120
+ f"\n\nYour ID is `{self.get_identity()}`. "
121
+ "Use this for any tasks which require identifying yourself "
122
+ "such as claiming task ownership or coordination with other agents."
123
+ )
124
+
125
+ def get_full_system_prompt(self) -> str:
126
+ """Get the complete system prompt with identity automatically appended.
127
+
128
+ This wraps get_system_prompt() and appends the agent's identity,
129
+ so subclasses don't need to worry about it.
130
+
131
+ Returns:
132
+ The full system prompt including identity information.
133
+ """
134
+ return self.get_system_prompt() + self.get_identity_prompt()
135
+
104
136
  @property
105
137
  @abstractmethod
106
138
  def name(self) -> str:
@@ -398,7 +430,7 @@ class BaseAgent(ABC):
398
430
  total_tokens += self.estimate_token_count(instructions)
399
431
  else:
400
432
  # For other models, count the full system prompt
401
- system_prompt = self.get_system_prompt()
433
+ system_prompt = self.get_full_system_prompt()
402
434
  if system_prompt:
403
435
  total_tokens += self.estimate_token_count(system_prompt)
404
436
  except Exception:
@@ -1122,7 +1154,7 @@ class BaseAgent(ABC):
1122
1154
  message_group,
1123
1155
  )
1124
1156
 
1125
- instructions = self.get_system_prompt()
1157
+ instructions = self.get_full_system_prompt()
1126
1158
  puppy_rules = self.load_puppy_rules()
1127
1159
  if puppy_rules:
1128
1160
  instructions += f"\n{puppy_rules}"
@@ -1286,7 +1318,7 @@ class BaseAgent(ABC):
1286
1318
  model_name, models_config, str(uuid.uuid4())
1287
1319
  )
1288
1320
 
1289
- instructions = self.get_system_prompt()
1321
+ instructions = self.get_full_system_prompt()
1290
1322
  puppy_rules = self.load_puppy_rules()
1291
1323
  if puppy_rules:
1292
1324
  instructions += f"\n{puppy_rules}"
@@ -1568,7 +1600,7 @@ class BaseAgent(ABC):
1568
1600
  self.get_model_name()
1569
1601
  ):
1570
1602
  if len(self.get_message_history()) == 0:
1571
- system_prompt = self.get_system_prompt()
1603
+ system_prompt = self.get_full_system_prompt()
1572
1604
  puppy_rules = self.load_puppy_rules()
1573
1605
  if puppy_rules:
1574
1606
  system_prompt += f"\n{puppy_rules}"
@@ -1800,6 +1832,31 @@ class BaseAgent(ABC):
1800
1832
  except Exception:
1801
1833
  pass # Don't fail the run if cache update fails
1802
1834
 
1835
+ # Trigger agent_response_complete callback for workflow orchestration
1836
+ try:
1837
+ # Extract the response text from the result
1838
+ response_text = ""
1839
+ if result is not None:
1840
+ if hasattr(result, "data"):
1841
+ response_text = str(result.data) if result.data else ""
1842
+ elif hasattr(result, "output"):
1843
+ response_text = str(result.output) if result.output else ""
1844
+ else:
1845
+ response_text = str(result)
1846
+
1847
+ # Fire the callback - don't await to avoid blocking return
1848
+ # Use asyncio.create_task to run it in background
1849
+ asyncio.create_task(
1850
+ on_agent_response_complete(
1851
+ agent_name=self.name,
1852
+ response_text=response_text,
1853
+ session_id=group_id,
1854
+ metadata={"model": self.get_model_name()},
1855
+ )
1856
+ )
1857
+ except Exception:
1858
+ pass # Don't fail the run if callback fails
1859
+
1803
1860
  return result
1804
1861
  except asyncio.CancelledError:
1805
1862
  agent_task.cancel()
@@ -21,6 +21,11 @@ PhaseType = Literal[
21
21
  "pre_tool_call",
22
22
  "post_tool_call",
23
23
  "stream_event",
24
+ "register_tools",
25
+ "register_agents",
26
+ "register_model_type",
27
+ "get_model_system_prompt",
28
+ "agent_response_complete",
24
29
  ]
25
30
  CallbackFunc = Callable[..., Any]
26
31
 
@@ -42,6 +47,11 @@ _callbacks: Dict[PhaseType, List[CallbackFunc]] = {
42
47
  "pre_tool_call": [],
43
48
  "post_tool_call": [],
44
49
  "stream_event": [],
50
+ "register_tools": [],
51
+ "register_agents": [],
52
+ "register_model_type": [],
53
+ "get_model_system_prompt": [],
54
+ "agent_response_complete": [],
45
55
  }
46
56
 
47
57
  logger = logging.getLogger(__name__)
@@ -344,3 +354,118 @@ async def on_stream_event(
344
354
  return await _trigger_callbacks(
345
355
  "stream_event", event_type, event_data, agent_session_id
346
356
  )
357
+
358
+
359
+ def on_register_tools() -> List[Dict[str, Any]]:
360
+ """Collect custom tool registrations from plugins.
361
+
362
+ Each callback should return a list of dicts with:
363
+ - "name": str - the tool name
364
+ - "register_func": callable - function that takes an agent and registers the tool
365
+
366
+ Example return: [{"name": "my_tool", "register_func": register_my_tool}]
367
+ """
368
+ return _trigger_callbacks_sync("register_tools")
369
+
370
+
371
+ def on_register_agents() -> List[Dict[str, Any]]:
372
+ """Collect custom agent registrations from plugins.
373
+
374
+ Each callback should return a list of dicts with either:
375
+ - "name": str, "class": Type[BaseAgent] - for Python agent classes
376
+ - "name": str, "json_path": str - for JSON agent files
377
+
378
+ Example return: [{"name": "my-agent", "class": MyAgentClass}]
379
+ """
380
+ return _trigger_callbacks_sync("register_agents")
381
+
382
+
383
+ def on_register_model_types() -> List[Dict[str, Any]]:
384
+ """Collect custom model type registrations from plugins.
385
+
386
+ This hook allows plugins to register custom model types that can be used
387
+ in model configurations. Each callback should return a list of dicts with:
388
+ - "type": str - the model type name (e.g., "antigravity", "claude_code")
389
+ - "handler": callable - function(model_name, model_config, config) -> model instance
390
+
391
+ The handler function receives:
392
+ - model_name: str - the name of the model being created
393
+ - model_config: dict - the model's configuration from models.json
394
+ - config: dict - the full models configuration
395
+
396
+ The handler should return a model instance or None if creation fails.
397
+
398
+ Example callback:
399
+ def register_my_model_types():
400
+ return [{
401
+ "type": "my_custom_type",
402
+ "handler": create_my_custom_model,
403
+ }]
404
+
405
+ Example return: [{"type": "antigravity", "handler": create_antigravity_model}]
406
+ """
407
+ return _trigger_callbacks_sync("register_model_type")
408
+
409
+
410
+ def on_get_model_system_prompt(
411
+ model_name: str, default_system_prompt: str, user_prompt: str
412
+ ) -> List[Dict[str, Any]]:
413
+ """Allow plugins to provide custom system prompts for specific model types.
414
+
415
+ This hook allows plugins to override the system prompt handling for custom
416
+ model types (like claude_code or antigravity models). Each callback receives
417
+ the model name and should return a dict if it handles that model type, or None.
418
+
419
+ Args:
420
+ model_name: The name of the model being used (e.g., "claude-code-sonnet")
421
+ default_system_prompt: The default system prompt from the agent
422
+ user_prompt: The user's prompt/message
423
+
424
+ Each callback should return a dict with:
425
+ - "instructions": str - the system prompt/instructions to use
426
+ - "user_prompt": str - the (possibly modified) user prompt
427
+ - "handled": bool - True if this callback handled the model
428
+
429
+ Or return None if the callback doesn't handle this model type.
430
+
431
+ Example callback:
432
+ def get_my_model_system_prompt(model_name, default_system_prompt, user_prompt):
433
+ if model_name.startswith("my-custom-"):
434
+ return {
435
+ "instructions": "You are MyCustomBot.",
436
+ "user_prompt": f"{default_system_prompt}\n\n{user_prompt}",
437
+ "handled": True,
438
+ }
439
+ return None # Not handled by this callback
440
+
441
+ Returns:
442
+ List of results from registered callbacks (dicts or None values).
443
+ """
444
+ return _trigger_callbacks_sync(
445
+ "get_model_system_prompt", model_name, default_system_prompt, user_prompt
446
+ )
447
+
448
+
449
+ async def on_agent_response_complete(
450
+ agent_name: str,
451
+ response_text: str,
452
+ session_id: str | None = None,
453
+ metadata: dict | None = None,
454
+ ) -> List[Any]:
455
+ """Trigger callbacks after an agent completes its full response.
456
+
457
+ This fires after all tool calls are resolved and the agent has finished.
458
+ Useful for:
459
+ - Workflow orchestration (like Ralph's autonomous loop)
460
+ - Logging/analytics
461
+ - Detecting completion signals in responses
462
+
463
+ Args:
464
+ agent_name: Name of the agent that completed
465
+ response_text: The final text response from the agent
466
+ session_id: Optional session identifier
467
+ metadata: Optional dict with additional context (tokens used, etc.)
468
+ """
469
+ return await _trigger_callbacks(
470
+ "agent_response_complete", agent_name, response_text, session_id, metadata
471
+ )
@@ -675,15 +675,21 @@ class RichConsoleRenderer:
675
675
  self._console.print(f"[dim]⏱ Timeout: {msg.timeout}s[/dim]")
676
676
 
677
677
  def _render_shell_line(self, msg: ShellLineMessage) -> None:
678
- """Render shell output line preserving ANSI codes."""
679
- from rich.text import Text
678
+ """Render shell output line preserving ANSI codes and carriage returns."""
679
+ import sys
680
680
 
681
- # Use Text.from_ansi() to parse ANSI codes into Rich styling
682
- # This preserves colors while still being safe
683
- text = Text.from_ansi(msg.line)
681
+ from rich.text import Text
684
682
 
685
- # Make all shell output dim to reduce visual noise
686
- self._console.print(text, style="dim")
683
+ # Check if line contains carriage return (progress bar style output)
684
+ if "\r" in msg.line:
685
+ # Bypass Rich entirely - write directly to stdout so terminal interprets \r
686
+ # Apply dim styling manually via ANSI codes
687
+ sys.stdout.write(f"\033[2m{msg.line}\033[0m")
688
+ sys.stdout.flush()
689
+ else:
690
+ # Normal line: use Rich for nice formatting
691
+ text = Text.from_ansi(msg.line)
692
+ self._console.print(text, style="dim")
687
693
 
688
694
  def _render_shell_output(self, msg: ShellOutputMessage) -> None:
689
695
  """Render shell command output - just a trailing newline for spinner separation.