code-puppy 0.0.358__tar.gz → 0.0.360__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 (215) hide show
  1. {code_puppy-0.0.358 → code_puppy-0.0.360}/PKG-INFO +1 -1
  2. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_qa_kitten.py +13 -13
  3. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/event_stream_handler.py +27 -7
  4. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/config.py +1 -63
  5. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/__init__.py +1 -5
  6. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/__init__.py +0 -4
  7. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_screenshot.py +41 -28
  8. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/terminal_screenshot_tools.py +113 -77
  9. {code_puppy-0.0.358 → code_puppy-0.0.360}/pyproject.toml +1 -1
  10. code_puppy-0.0.358/code_puppy/tools/browser/browser_screenshot_vqa.py +0 -195
  11. code_puppy-0.0.358/code_puppy/tools/browser/vqa_agent.py +0 -194
  12. {code_puppy-0.0.358 → code_puppy-0.0.360}/.gitignore +0 -0
  13. {code_puppy-0.0.358 → code_puppy-0.0.360}/LICENSE +0 -0
  14. {code_puppy-0.0.358 → code_puppy-0.0.360}/README.md +0 -0
  15. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/__init__.py +0 -0
  16. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/__main__.py +0 -0
  17. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/__init__.py +0 -0
  18. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_c_reviewer.py +0 -0
  19. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_code_puppy.py +0 -0
  20. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_code_reviewer.py +0 -0
  21. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_cpp_reviewer.py +0 -0
  22. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_creator_agent.py +0 -0
  23. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_golang_reviewer.py +0 -0
  24. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_javascript_reviewer.py +0 -0
  25. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_manager.py +0 -0
  26. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_pack_leader.py +0 -0
  27. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_planning.py +0 -0
  28. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_python_programmer.py +0 -0
  29. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_python_reviewer.py +0 -0
  30. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_qa_expert.py +0 -0
  31. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_security_auditor.py +0 -0
  32. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_terminal_qa.py +0 -0
  33. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/agent_typescript_reviewer.py +0 -0
  34. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/base_agent.py +0 -0
  35. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/json_agent.py +0 -0
  36. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/__init__.py +0 -0
  37. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/bloodhound.py +0 -0
  38. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/husky.py +0 -0
  39. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/retriever.py +0 -0
  40. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/shepherd.py +0 -0
  41. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/terrier.py +0 -0
  42. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/pack/watchdog.py +0 -0
  43. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/prompt_reviewer.py +0 -0
  44. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/agents/subagent_stream_handler.py +0 -0
  45. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/__init__.py +0 -0
  46. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/app.py +0 -0
  47. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/main.py +0 -0
  48. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/pty_manager.py +0 -0
  49. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/routers/__init__.py +0 -0
  50. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/routers/agents.py +0 -0
  51. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/routers/commands.py +0 -0
  52. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/routers/config.py +0 -0
  53. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/routers/sessions.py +0 -0
  54. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/templates/terminal.html +0 -0
  55. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/api/websocket.py +0 -0
  56. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/callbacks.py +0 -0
  57. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/chatgpt_codex_client.py +0 -0
  58. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/claude_cache_client.py +0 -0
  59. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/cli_runner.py +0 -0
  60. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/__init__.py +0 -0
  61. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/add_model_menu.py +0 -0
  62. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/attachments.py +0 -0
  63. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/autosave_menu.py +0 -0
  64. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/clipboard.py +0 -0
  65. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/colors_menu.py +0 -0
  66. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/command_handler.py +0 -0
  67. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/command_registry.py +0 -0
  68. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/config_commands.py +0 -0
  69. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/core_commands.py +0 -0
  70. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/diff_menu.py +0 -0
  71. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/file_path_completion.py +0 -0
  72. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/load_context_completion.py +0 -0
  73. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/__init__.py +0 -0
  74. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/base.py +0 -0
  75. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
  76. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
  77. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
  78. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/edit_command.py +0 -0
  79. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/handler.py +0 -0
  80. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/help_command.py +0 -0
  81. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/install_command.py +0 -0
  82. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/install_menu.py +0 -0
  83. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/list_command.py +0 -0
  84. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/logs_command.py +0 -0
  85. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/remove_command.py +0 -0
  86. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/restart_command.py +0 -0
  87. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/search_command.py +0 -0
  88. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/start_all_command.py +0 -0
  89. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/start_command.py +0 -0
  90. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/status_command.py +0 -0
  91. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
  92. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/stop_command.py +0 -0
  93. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/test_command.py +0 -0
  94. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/utils.py +0 -0
  95. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
  96. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/mcp_completion.py +0 -0
  97. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/model_picker_completion.py +0 -0
  98. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/model_settings_menu.py +0 -0
  99. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/motd.py +0 -0
  100. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/onboarding_slides.py +0 -0
  101. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/onboarding_wizard.py +0 -0
  102. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/pin_command_completion.py +0 -0
  103. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
  104. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/session_commands.py +0 -0
  105. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/command_line/utils.py +0 -0
  106. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/error_logging.py +0 -0
  107. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/gemini_code_assist.py +0 -0
  108. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/http_utils.py +0 -0
  109. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/keymap.py +0 -0
  110. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/main.py +0 -0
  111. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/__init__.py +0 -0
  112. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/async_lifecycle.py +0 -0
  113. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/blocking_startup.py +0 -0
  114. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/captured_stdio_server.py +0 -0
  115. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/circuit_breaker.py +0 -0
  116. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/config_wizard.py +0 -0
  117. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/dashboard.py +0 -0
  118. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/error_isolation.py +0 -0
  119. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/examples/retry_example.py +0 -0
  120. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/health_monitor.py +0 -0
  121. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/managed_server.py +0 -0
  122. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/manager.py +0 -0
  123. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/mcp_logs.py +0 -0
  124. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/registry.py +0 -0
  125. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/retry_manager.py +0 -0
  126. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/server_registry_catalog.py +0 -0
  127. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/status_tracker.py +0 -0
  128. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/mcp_/system_tools.py +0 -0
  129. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/__init__.py +0 -0
  130. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/bus.py +0 -0
  131. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/commands.py +0 -0
  132. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/markdown_patches.py +0 -0
  133. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/message_queue.py +0 -0
  134. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/messages.py +0 -0
  135. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/queue_console.py +0 -0
  136. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/renderers.py +0 -0
  137. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/rich_renderer.py +0 -0
  138. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/spinner/__init__.py +0 -0
  139. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/spinner/console_spinner.py +0 -0
  140. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/spinner/spinner_base.py +0 -0
  141. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/messaging/subagent_console.py +0 -0
  142. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/model_factory.py +0 -0
  143. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/model_utils.py +0 -0
  144. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/models.json +0 -0
  145. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/models_dev_api.json +0 -0
  146. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/models_dev_parser.py +0 -0
  147. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/__init__.py +0 -0
  148. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/__init__.py +0 -0
  149. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/accounts.py +0 -0
  150. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/antigravity_model.py +0 -0
  151. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/config.py +0 -0
  152. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/constants.py +0 -0
  153. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/oauth.py +0 -0
  154. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/register_callbacks.py +0 -0
  155. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/storage.py +0 -0
  156. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/test_plugin.py +0 -0
  157. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/token.py +0 -0
  158. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/transport.py +0 -0
  159. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/antigravity_oauth/utils.py +0 -0
  160. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
  161. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
  162. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
  163. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
  164. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
  165. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
  166. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
  167. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
  168. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
  169. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
  170. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
  171. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
  172. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
  173. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
  174. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
  175. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/example_custom_command/README.md +0 -0
  176. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
  177. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
  178. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
  179. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
  180. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
  181. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
  182. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/oauth_puppy_html.py +0 -0
  183. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/shell_safety/__init__.py +0 -0
  184. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
  185. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
  186. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
  187. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/prompts/antigravity_system_prompt.md +0 -0
  188. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/prompts/codex_system_prompt.md +0 -0
  189. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/pydantic_patches.py +0 -0
  190. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/reopenable_async_client.py +0 -0
  191. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/round_robin_model.py +0 -0
  192. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/session_storage.py +0 -0
  193. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/status_display.py +0 -0
  194. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/summarization_agent.py +0 -0
  195. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/terminal_utils.py +0 -0
  196. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/agent_tools.py +0 -0
  197. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_control.py +0 -0
  198. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_interactions.py +0 -0
  199. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_locators.py +0 -0
  200. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_navigation.py +0 -0
  201. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_scripts.py +0 -0
  202. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/browser_workflows.py +0 -0
  203. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/camoufox_manager.py +0 -0
  204. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/chromium_terminal_manager.py +0 -0
  205. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/terminal_command_tools.py +0 -0
  206. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/browser/terminal_tools.py +0 -0
  207. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/command_runner.py +0 -0
  208. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/common.py +0 -0
  209. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/display.py +0 -0
  210. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/file_modifications.py +0 -0
  211. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/file_operations.py +0 -0
  212. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/subagent_context.py +0 -0
  213. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/tools/tools_content.py +0 -0
  214. {code_puppy-0.0.358 → code_puppy-0.0.360}/code_puppy/uvx_detection.py +0 -0
  215. {code_puppy-0.0.358 → code_puppy-0.0.360}/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.358
3
+ Version: 0.0.360
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
@@ -16,7 +16,7 @@ class QualityAssuranceKittenAgent(BaseAgent):
16
16
 
17
17
  @property
18
18
  def description(self) -> str:
19
- return "Advanced web browser automation and quality assurance testing using Playwright with VQA capabilities"
19
+ return "Advanced web browser automation and quality assurance testing using Playwright with visual analysis capabilities"
20
20
 
21
21
  def get_available_tools(self) -> list[str]:
22
22
  """Get the list of tools available to Web Browser Puppy."""
@@ -63,8 +63,9 @@ class QualityAssuranceKittenAgent(BaseAgent):
63
63
  "browser_wait_for_element",
64
64
  "browser_highlight_element",
65
65
  "browser_clear_highlights",
66
- # Screenshots and VQA (uses dedicated VQA agent for context management)
67
- "browser_screenshot_vqa",
66
+ # Screenshots (returns BinaryContent for direct visual analysis)
67
+ "browser_screenshot_analyze",
68
+ "load_image_for_analysis",
68
69
  # Workflow management
69
70
  "browser_save_workflow",
70
71
  "browser_list_workflows",
@@ -78,7 +79,7 @@ You are Quality Assurance Kitten 🐱, an advanced autonomous browser automation
78
79
 
79
80
  You specialize in:
80
81
  🎯 **Quality Assurance Testing** - automated testing of web applications and user workflows
81
- 👁️ **Visual verification** - taking screenshots and analyzing page content for bugs
82
+ 👁️ **Visual verification** - taking screenshots you can directly see and analyze for bugs
82
83
  🔍 **Element discovery** - finding elements using semantic locators and accessibility best practices
83
84
  📝 **Data extraction** - scraping content and gathering information from web pages
84
85
  🧪 **Web automation** - filling forms, clicking buttons, navigating sites with precision
@@ -117,12 +118,10 @@ For any browser task, follow this approach:
117
118
 
118
119
  ### Visual Verification Workflow
119
120
  - **Before critical actions**: Use browser_highlight_element to visually confirm
120
- - **After interactions**: Use browser_screenshot_vqa to verify results
121
- - **Ask specific questions**: The VQA tool requires a question like:
122
- - "Is the login button visible?"
123
- - "What error message is displayed?"
124
- - "Is the form filled out correctly?"
125
- - "What is the main heading text?"
121
+ - **After interactions**: Use browser_screenshot_analyze to verify results
122
+ - The screenshot is returned directly as an image you can see and analyze
123
+ - No need to ask questions - just analyze what you see in the returned image
124
+ - Use load_image_for_analysis to load mockups or reference images for comparison
126
125
 
127
126
  ### Form Input Best Practices
128
127
  - **ALWAYS check current values** with browser_get_value before typing
@@ -135,14 +134,15 @@ For any browser task, follow this approach:
135
134
  **When Element Discovery Fails:**
136
135
  1. Try different semantic locators first
137
136
  2. Use browser_find_buttons or browser_find_links to see available elements
138
- 3. Take a screenshot with browser_screenshot_analyze to understand the page layout
137
+ 3. Take a screenshot with browser_screenshot_analyze to see and understand the page layout
139
138
  4. Only use XPath as absolute last resort
140
139
 
141
140
  **When Page Interactions Fail:**
142
141
  1. Check if element is visible with browser_wait_for_element
143
142
  2. Scroll element into view with browser_scroll_to_element
144
143
  3. Use browser_highlight_element to confirm element location
145
- 4. Try browser_execute_js for complex interactions
144
+ 4. Take a screenshot with browser_screenshot_analyze to see the actual page state
145
+ 5. Try browser_execute_js for complex interactions
146
146
 
147
147
  ### JavaScript Execution
148
148
  - Use browser_execute_js for:
@@ -187,7 +187,7 @@ For any browser task, follow this approach:
187
187
  ## Specialized Capabilities
188
188
 
189
189
  🌐 **WCAG 2.2 Level AA Compliance**: Always prioritize accessibility in element discovery
190
- 📸 **Visual Question Answering**: Use browser_screenshot_vqa for intelligent page analysis (uses dedicated VQA agent)
190
+ 📸 **Direct Visual Analysis**: Use browser_screenshot_analyze to see and analyze page content directly
191
191
  🚀 **Semantic Web Navigation**: Prefer role-based and label-based element discovery
192
192
  ⚡ **Playwright Power**: Full access to modern browser automation capabilities
193
193
  📋 **Workflow Management**: Save, load, and reuse automation patterns for consistency
@@ -119,6 +119,7 @@ async def event_stream_handler(
119
119
  tool_parts: set[int] = set() # Track which parts are tool calls
120
120
  banner_printed: set[int] = set() # Track if banner was already printed
121
121
  token_count: dict[int, int] = {} # Track token count per text/tool part
122
+ tool_names: dict[int, str] = {} # Track tool name per tool part index
122
123
  did_stream_anything = False # Track if we streamed any content
123
124
 
124
125
  # Termflow streaming state for text parts
@@ -203,6 +204,8 @@ async def event_stream_handler(
203
204
  streaming_parts.add(event.index)
204
205
  tool_parts.add(event.index)
205
206
  token_count[event.index] = 0 # Initialize token counter
207
+ # Capture tool name from the start event
208
+ tool_names[event.index] = part.tool_name or ""
206
209
  # Track tool name for display
207
210
  banner_printed.add(
208
211
  event.index
@@ -253,20 +256,36 @@ async def event_stream_handler(
253
256
  escaped = escape(delta.content_delta)
254
257
  console.print(f"[dim]{escaped}[/dim]", end="")
255
258
  elif isinstance(delta, ToolCallPartDelta):
256
- # For tool calls, count chunks received
257
- token_count[event.index] += 1
258
- # Get tool name if available
259
- tool_name = getattr(delta, "tool_name_delta", "")
259
+ # For tool calls, estimate tokens from args_delta content
260
+ # args_delta contains the streaming JSON arguments
261
+ args_delta = getattr(delta, "args_delta", "") or ""
262
+ if args_delta:
263
+ # Rough estimate: 4 chars ≈ 1 token (same heuristic as subagent_stream_handler)
264
+ estimated_tokens = max(1, len(args_delta) // 4)
265
+ token_count[event.index] += estimated_tokens
266
+ else:
267
+ # Even empty deltas count as activity
268
+ token_count[event.index] += 1
269
+
270
+ # Update tool name if delta provides more of it
271
+ tool_name_delta = getattr(delta, "tool_name_delta", "") or ""
272
+ if tool_name_delta:
273
+ tool_names[event.index] = (
274
+ tool_names.get(event.index, "") + tool_name_delta
275
+ )
276
+
277
+ # Use stored tool name for display
278
+ tool_name = tool_names.get(event.index, "")
260
279
  count = token_count[event.index]
261
280
  # Display with tool wrench icon and tool name
262
281
  if tool_name:
263
282
  console.print(
264
- f" \U0001f527 Calling {tool_name}... {count} chunks ",
283
+ f" \U0001f527 Calling {tool_name}... {count} token(s) ",
265
284
  end="\r",
266
285
  )
267
286
  else:
268
287
  console.print(
269
- f" \U0001f527 Calling tool... {count} chunks ",
288
+ f" \U0001f527 Calling tool... {count} token(s) ",
270
289
  end="\r",
271
290
  )
272
291
 
@@ -311,8 +330,9 @@ async def event_stream_handler(
311
330
  elif event.index in banner_printed:
312
331
  console.print() # Final newline after streaming
313
332
 
314
- # Clean up token count
333
+ # Clean up token count and tool names
315
334
  token_count.pop(event.index, None)
335
+ tool_names.pop(event.index, None)
316
336
  # Clean up all tracking sets
317
337
  streaming_parts.discard(event.index)
318
338
  thinking_parts.discard(event.index)
@@ -98,7 +98,6 @@ _CURRENT_AUTOSAVE_ID: Optional[str] = None
98
98
  _model_validation_cache = {}
99
99
  _default_model_cache = None
100
100
  _default_vision_model_cache = None
101
- _default_vqa_model_cache = None
102
101
 
103
102
 
104
103
  def ensure_config_exists():
@@ -358,47 +357,6 @@ def _default_vision_model_from_models_json() -> str:
358
357
  return "gpt-4.1"
359
358
 
360
359
 
361
- def _default_vqa_model_from_models_json() -> str:
362
- """Select a default VQA-capable model, preferring vision-ready options."""
363
- global _default_vqa_model_cache
364
-
365
- if _default_vqa_model_cache is not None:
366
- return _default_vqa_model_cache
367
-
368
- try:
369
- from code_puppy.model_factory import ModelFactory
370
-
371
- models_config = ModelFactory.load_config()
372
- if models_config:
373
- # Allow explicit VQA hints if present
374
- for name, config in models_config.items():
375
- if config.get("supports_vqa"):
376
- _default_vqa_model_cache = name
377
- return name
378
-
379
- # Reuse multimodal heuristics before falling back to generic default
380
- preferred_candidates = (
381
- "gpt-4.1",
382
- "gpt-4.1-mini",
383
- "claude-4-0-sonnet",
384
- "gemini-2.5-flash-preview-05-20",
385
- "gpt-4.1-nano",
386
- )
387
- for candidate in preferred_candidates:
388
- if candidate in models_config:
389
- _default_vqa_model_cache = candidate
390
- return candidate
391
-
392
- _default_vqa_model_cache = _default_model_from_models_json()
393
- return _default_vqa_model_cache
394
-
395
- _default_vqa_model_cache = "gpt-4.1"
396
- return "gpt-4.1"
397
- except Exception:
398
- _default_vqa_model_cache = "gpt-4.1"
399
- return "gpt-4.1"
400
-
401
-
402
360
  def _validate_model_exists(model_name: str) -> bool:
403
361
  """Check if a model exists in models.json with caching to avoid redundant calls."""
404
362
  global _model_validation_cache
@@ -424,15 +382,10 @@ def _validate_model_exists(model_name: str) -> bool:
424
382
 
425
383
  def clear_model_cache():
426
384
  """Clear the model validation cache. Call this when models.json changes."""
427
- global \
428
- _model_validation_cache, \
429
- _default_model_cache, \
430
- _default_vision_model_cache, \
431
- _default_vqa_model_cache
385
+ global _model_validation_cache, _default_model_cache, _default_vision_model_cache
432
386
  _model_validation_cache.clear()
433
387
  _default_model_cache = None
434
388
  _default_vision_model_cache = None
435
- _default_vqa_model_cache = None
436
389
 
437
390
 
438
391
  def model_supports_setting(model_name: str, setting: str) -> bool:
@@ -503,21 +456,6 @@ def set_model_name(model: str):
503
456
  clear_model_cache()
504
457
 
505
458
 
506
- def get_vqa_model_name() -> str:
507
- """Return the configured VQA model, falling back to the global model."""
508
- stored_model = get_value("vqa_model_name")
509
- if stored_model and _validate_model_exists(stored_model):
510
- return stored_model
511
- # Fall back to the global model if no specific VQA model is set
512
- return get_global_model_name()
513
-
514
-
515
- def set_vqa_model_name(model: str):
516
- """Persist the configured VQA model name and refresh caches."""
517
- set_config_value("vqa_model_name", model or "")
518
- clear_model_cache()
519
-
520
-
521
459
  def get_puppy_token():
522
460
  """Returns the puppy_token from config, or None if not set."""
523
461
  return get_value("puppy_token")
@@ -41,9 +41,6 @@ from code_puppy.tools.browser.browser_navigation import (
41
41
  from code_puppy.tools.browser.browser_screenshot import (
42
42
  register_take_screenshot_and_analyze,
43
43
  )
44
- from code_puppy.tools.browser.browser_screenshot_vqa import (
45
- register_take_screenshot_and_analyze_vqa,
46
- )
47
44
  from code_puppy.tools.browser.browser_scripts import (
48
45
  register_browser_clear_highlights,
49
46
  register_browser_highlight_element,
@@ -146,9 +143,8 @@ TOOL_REGISTRY = {
146
143
  "browser_wait_for_element": register_wait_for_element,
147
144
  "browser_highlight_element": register_browser_highlight_element,
148
145
  "browser_clear_highlights": register_browser_clear_highlights,
149
- # Browser Screenshots and VQA
146
+ # Browser Screenshots
150
147
  "browser_screenshot_analyze": register_take_screenshot_and_analyze,
151
- "browser_screenshot_vqa": register_take_screenshot_and_analyze_vqa,
152
148
  # Browser Workflows
153
149
  "browser_save_workflow": register_save_workflow,
154
150
  "browser_list_workflows": register_list_workflows,
@@ -11,7 +11,6 @@ from .camoufox_manager import (
11
11
  get_session_browser_manager,
12
12
  set_browser_session,
13
13
  )
14
- from .vqa_agent import VisualAnalysisResult, run_vqa_analysis, run_vqa_analysis_stream
15
14
 
16
15
 
17
16
  def format_terminal_banner(text: str) -> str:
@@ -35,7 +34,4 @@ __all__ = [
35
34
  "get_browser_session",
36
35
  "get_session_browser_manager",
37
36
  "set_browser_session",
38
- "VisualAnalysisResult",
39
- "run_vqa_analysis",
40
- "run_vqa_analysis_stream",
41
37
  ]
@@ -1,16 +1,16 @@
1
1
  """Screenshot tool for browser automation.
2
2
 
3
- Captures screenshots and returns them as base64 data that multimodal
4
- models can directly see and analyze - no separate VQA agent needed.
3
+ Captures screenshots and returns them via ToolReturn with BinaryContent
4
+ so multimodal models can directly see and analyze - no separate VQA agent needed.
5
5
  """
6
6
 
7
- import base64
7
+ import time
8
8
  from datetime import datetime
9
9
  from pathlib import Path
10
10
  from tempfile import gettempdir, mkdtemp
11
- from typing import Any, Dict, Optional
11
+ from typing import Any, Dict, Optional, Union
12
12
 
13
- from pydantic_ai import RunContext
13
+ from pydantic_ai import BinaryContent, RunContext, ToolReturn
14
14
 
15
15
  from code_puppy.messaging import emit_error, emit_info, emit_success
16
16
  from code_puppy.tools.common import generate_group_id
@@ -54,7 +54,6 @@ async def _capture_screenshot(
54
54
  result: Dict[str, Any] = {
55
55
  "success": True,
56
56
  "screenshot_bytes": screenshot_bytes,
57
- "base64_data": base64.b64encode(screenshot_bytes).decode("utf-8"),
58
57
  "timestamp": timestamp,
59
58
  }
60
59
 
@@ -80,11 +79,11 @@ async def take_screenshot(
80
79
  full_page: bool = False,
81
80
  element_selector: Optional[str] = None,
82
81
  save_screenshot: bool = True,
83
- ) -> Dict[str, Any]:
82
+ ) -> Union[ToolReturn, Dict[str, Any]]:
84
83
  """Take a screenshot of the browser page.
85
84
 
86
- Returns the screenshot as base64-encoded PNG data that multimodal
87
- models can directly see and analyze.
85
+ Returns a ToolReturn with BinaryContent so multimodal models can
86
+ directly see and analyze the screenshot.
88
87
 
89
88
  Args:
90
89
  full_page: Whether to capture full page or just viewport.
@@ -92,12 +91,11 @@ async def take_screenshot(
92
91
  save_screenshot: Whether to save the screenshot to disk.
93
92
 
94
93
  Returns:
95
- Dict containing:
96
- - success (bool): True if screenshot was captured.
97
- - base64_image (str): Base64-encoded PNG image data.
98
- - media_type (str): Always "image/png".
99
- - screenshot_path (str): Path to saved file (if saved).
100
- - error (str): Error message if unsuccessful.
94
+ ToolReturn containing:
95
+ - return_value: Success message with screenshot path
96
+ - content: List with description and BinaryContent image
97
+ - metadata: Screenshot details (path, target, timestamp)
98
+ Or Dict with error info if failed.
101
99
  """
102
100
  target = element_selector or ("full_page" if full_page else "viewport")
103
101
  group_id = generate_group_id("browser_screenshot", target)
@@ -122,15 +120,30 @@ async def take_screenshot(
122
120
 
123
121
  if not result["success"]:
124
122
  emit_error(result.get("error", "Screenshot failed"), message_group=group_id)
125
- return result
126
-
127
- return {
128
- "success": True,
129
- "base64_image": result["base64_data"],
130
- "media_type": "image/png",
131
- "screenshot_path": result.get("screenshot_path"),
132
- "message": "Screenshot captured. The base64_image contains the browser view.",
133
- }
123
+ return {"success": False, "error": result.get("error")}
124
+
125
+ screenshot_path = result.get("screenshot_path", "(not saved)")
126
+
127
+ # Return as ToolReturn with BinaryContent so the model can SEE the image!
128
+ return ToolReturn(
129
+ return_value=f"Screenshot captured successfully. Saved to: {screenshot_path}",
130
+ content=[
131
+ f"Here's the browser screenshot ({target}):",
132
+ BinaryContent(
133
+ data=result["screenshot_bytes"],
134
+ media_type="image/png",
135
+ ),
136
+ "Please analyze what you see and describe any relevant details.",
137
+ ],
138
+ metadata={
139
+ "success": True,
140
+ "screenshot_path": screenshot_path,
141
+ "target": target,
142
+ "full_page": full_page,
143
+ "element_selector": element_selector,
144
+ "timestamp": time.time(),
145
+ },
146
+ )
134
147
 
135
148
  except Exception as e:
136
149
  error_msg = f"Screenshot failed: {str(e)}"
@@ -146,19 +159,19 @@ def register_take_screenshot_and_analyze(agent):
146
159
  context: RunContext,
147
160
  full_page: bool = False,
148
161
  element_selector: Optional[str] = None,
149
- ) -> Dict[str, Any]:
162
+ ) -> Union[ToolReturn, Dict[str, Any]]:
150
163
  """
151
164
  Take a screenshot of the browser page.
152
165
 
153
- Returns the screenshot as base64 image data that you can see directly.
154
- Use this to see what's displayed in the browser.
166
+ Returns the screenshot via ToolReturn with BinaryContent that you can
167
+ see directly. Use this to see what's displayed in the browser.
155
168
 
156
169
  Args:
157
170
  full_page: Capture full page (True) or just viewport (False).
158
171
  element_selector: Optional CSS selector to screenshot specific element.
159
172
 
160
173
  Returns:
161
- Dict with base64_image (PNG data you can see), screenshot_path, etc.
174
+ ToolReturn with the screenshot image you can analyze, or error dict.
162
175
  """
163
176
  return await take_screenshot(
164
177
  full_page=full_page,