codepp 0.0.437__py3-none-any.whl

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 (288) hide show
  1. code_puppy/__init__.py +10 -0
  2. code_puppy/__main__.py +10 -0
  3. code_puppy/agents/__init__.py +31 -0
  4. code_puppy/agents/agent_c_reviewer.py +155 -0
  5. code_puppy/agents/agent_code_puppy.py +117 -0
  6. code_puppy/agents/agent_code_reviewer.py +90 -0
  7. code_puppy/agents/agent_cpp_reviewer.py +132 -0
  8. code_puppy/agents/agent_creator_agent.py +638 -0
  9. code_puppy/agents/agent_golang_reviewer.py +151 -0
  10. code_puppy/agents/agent_helios.py +124 -0
  11. code_puppy/agents/agent_javascript_reviewer.py +160 -0
  12. code_puppy/agents/agent_manager.py +742 -0
  13. code_puppy/agents/agent_pack_leader.py +385 -0
  14. code_puppy/agents/agent_planning.py +165 -0
  15. code_puppy/agents/agent_python_programmer.py +169 -0
  16. code_puppy/agents/agent_python_reviewer.py +90 -0
  17. code_puppy/agents/agent_qa_expert.py +163 -0
  18. code_puppy/agents/agent_qa_kitten.py +208 -0
  19. code_puppy/agents/agent_scheduler.py +121 -0
  20. code_puppy/agents/agent_security_auditor.py +181 -0
  21. code_puppy/agents/agent_terminal_qa.py +323 -0
  22. code_puppy/agents/agent_typescript_reviewer.py +166 -0
  23. code_puppy/agents/base_agent.py +2156 -0
  24. code_puppy/agents/event_stream_handler.py +348 -0
  25. code_puppy/agents/json_agent.py +202 -0
  26. code_puppy/agents/pack/__init__.py +34 -0
  27. code_puppy/agents/pack/bloodhound.py +304 -0
  28. code_puppy/agents/pack/husky.py +327 -0
  29. code_puppy/agents/pack/retriever.py +393 -0
  30. code_puppy/agents/pack/shepherd.py +348 -0
  31. code_puppy/agents/pack/terrier.py +287 -0
  32. code_puppy/agents/pack/watchdog.py +367 -0
  33. code_puppy/agents/prompt_reviewer.py +145 -0
  34. code_puppy/agents/subagent_stream_handler.py +276 -0
  35. code_puppy/api/__init__.py +13 -0
  36. code_puppy/api/app.py +169 -0
  37. code_puppy/api/main.py +21 -0
  38. code_puppy/api/pty_manager.py +453 -0
  39. code_puppy/api/routers/__init__.py +12 -0
  40. code_puppy/api/routers/agents.py +36 -0
  41. code_puppy/api/routers/commands.py +217 -0
  42. code_puppy/api/routers/config.py +75 -0
  43. code_puppy/api/routers/sessions.py +234 -0
  44. code_puppy/api/templates/terminal.html +361 -0
  45. code_puppy/api/websocket.py +154 -0
  46. code_puppy/callbacks.py +692 -0
  47. code_puppy/chatgpt_codex_client.py +338 -0
  48. code_puppy/claude_cache_client.py +672 -0
  49. code_puppy/cli_runner.py +1073 -0
  50. code_puppy/command_line/__init__.py +1 -0
  51. code_puppy/command_line/add_model_menu.py +1092 -0
  52. code_puppy/command_line/agent_menu.py +662 -0
  53. code_puppy/command_line/attachments.py +395 -0
  54. code_puppy/command_line/autosave_menu.py +704 -0
  55. code_puppy/command_line/clipboard.py +527 -0
  56. code_puppy/command_line/colors_menu.py +532 -0
  57. code_puppy/command_line/command_handler.py +293 -0
  58. code_puppy/command_line/command_registry.py +150 -0
  59. code_puppy/command_line/config_commands.py +719 -0
  60. code_puppy/command_line/core_commands.py +867 -0
  61. code_puppy/command_line/diff_menu.py +865 -0
  62. code_puppy/command_line/file_path_completion.py +73 -0
  63. code_puppy/command_line/load_context_completion.py +52 -0
  64. code_puppy/command_line/mcp/__init__.py +10 -0
  65. code_puppy/command_line/mcp/base.py +32 -0
  66. code_puppy/command_line/mcp/catalog_server_installer.py +175 -0
  67. code_puppy/command_line/mcp/custom_server_form.py +688 -0
  68. code_puppy/command_line/mcp/custom_server_installer.py +195 -0
  69. code_puppy/command_line/mcp/edit_command.py +148 -0
  70. code_puppy/command_line/mcp/handler.py +138 -0
  71. code_puppy/command_line/mcp/help_command.py +147 -0
  72. code_puppy/command_line/mcp/install_command.py +214 -0
  73. code_puppy/command_line/mcp/install_menu.py +705 -0
  74. code_puppy/command_line/mcp/list_command.py +94 -0
  75. code_puppy/command_line/mcp/logs_command.py +235 -0
  76. code_puppy/command_line/mcp/remove_command.py +82 -0
  77. code_puppy/command_line/mcp/restart_command.py +100 -0
  78. code_puppy/command_line/mcp/search_command.py +123 -0
  79. code_puppy/command_line/mcp/start_all_command.py +135 -0
  80. code_puppy/command_line/mcp/start_command.py +117 -0
  81. code_puppy/command_line/mcp/status_command.py +184 -0
  82. code_puppy/command_line/mcp/stop_all_command.py +112 -0
  83. code_puppy/command_line/mcp/stop_command.py +80 -0
  84. code_puppy/command_line/mcp/test_command.py +107 -0
  85. code_puppy/command_line/mcp/utils.py +129 -0
  86. code_puppy/command_line/mcp/wizard_utils.py +334 -0
  87. code_puppy/command_line/mcp_completion.py +174 -0
  88. code_puppy/command_line/model_picker_completion.py +197 -0
  89. code_puppy/command_line/model_settings_menu.py +932 -0
  90. code_puppy/command_line/motd.py +96 -0
  91. code_puppy/command_line/onboarding_slides.py +179 -0
  92. code_puppy/command_line/onboarding_wizard.py +342 -0
  93. code_puppy/command_line/pin_command_completion.py +329 -0
  94. code_puppy/command_line/prompt_toolkit_completion.py +846 -0
  95. code_puppy/command_line/session_commands.py +302 -0
  96. code_puppy/command_line/shell_passthrough.py +145 -0
  97. code_puppy/command_line/skills_completion.py +160 -0
  98. code_puppy/command_line/uc_menu.py +893 -0
  99. code_puppy/command_line/utils.py +93 -0
  100. code_puppy/command_line/wiggum_state.py +78 -0
  101. code_puppy/config.py +1770 -0
  102. code_puppy/error_logging.py +134 -0
  103. code_puppy/gemini_code_assist.py +385 -0
  104. code_puppy/gemini_model.py +754 -0
  105. code_puppy/hook_engine/README.md +105 -0
  106. code_puppy/hook_engine/__init__.py +21 -0
  107. code_puppy/hook_engine/aliases.py +155 -0
  108. code_puppy/hook_engine/engine.py +221 -0
  109. code_puppy/hook_engine/executor.py +296 -0
  110. code_puppy/hook_engine/matcher.py +156 -0
  111. code_puppy/hook_engine/models.py +240 -0
  112. code_puppy/hook_engine/registry.py +106 -0
  113. code_puppy/hook_engine/validator.py +144 -0
  114. code_puppy/http_utils.py +361 -0
  115. code_puppy/keymap.py +128 -0
  116. code_puppy/main.py +10 -0
  117. code_puppy/mcp_/__init__.py +66 -0
  118. code_puppy/mcp_/async_lifecycle.py +286 -0
  119. code_puppy/mcp_/blocking_startup.py +469 -0
  120. code_puppy/mcp_/captured_stdio_server.py +275 -0
  121. code_puppy/mcp_/circuit_breaker.py +290 -0
  122. code_puppy/mcp_/config_wizard.py +507 -0
  123. code_puppy/mcp_/dashboard.py +308 -0
  124. code_puppy/mcp_/error_isolation.py +407 -0
  125. code_puppy/mcp_/examples/retry_example.py +226 -0
  126. code_puppy/mcp_/health_monitor.py +589 -0
  127. code_puppy/mcp_/managed_server.py +428 -0
  128. code_puppy/mcp_/manager.py +807 -0
  129. code_puppy/mcp_/mcp_logs.py +224 -0
  130. code_puppy/mcp_/registry.py +451 -0
  131. code_puppy/mcp_/retry_manager.py +337 -0
  132. code_puppy/mcp_/server_registry_catalog.py +1126 -0
  133. code_puppy/mcp_/status_tracker.py +355 -0
  134. code_puppy/mcp_/system_tools.py +209 -0
  135. code_puppy/mcp_prompts/__init__.py +1 -0
  136. code_puppy/mcp_prompts/hook_creator.py +103 -0
  137. code_puppy/messaging/__init__.py +255 -0
  138. code_puppy/messaging/bus.py +613 -0
  139. code_puppy/messaging/commands.py +167 -0
  140. code_puppy/messaging/markdown_patches.py +57 -0
  141. code_puppy/messaging/message_queue.py +361 -0
  142. code_puppy/messaging/messages.py +569 -0
  143. code_puppy/messaging/queue_console.py +271 -0
  144. code_puppy/messaging/renderers.py +311 -0
  145. code_puppy/messaging/rich_renderer.py +1158 -0
  146. code_puppy/messaging/spinner/__init__.py +83 -0
  147. code_puppy/messaging/spinner/console_spinner.py +240 -0
  148. code_puppy/messaging/spinner/spinner_base.py +95 -0
  149. code_puppy/messaging/subagent_console.py +460 -0
  150. code_puppy/model_factory.py +848 -0
  151. code_puppy/model_switching.py +63 -0
  152. code_puppy/model_utils.py +168 -0
  153. code_puppy/models.json +174 -0
  154. code_puppy/models_dev_api.json +1 -0
  155. code_puppy/models_dev_parser.py +592 -0
  156. code_puppy/plugins/__init__.py +186 -0
  157. code_puppy/plugins/agent_skills/__init__.py +22 -0
  158. code_puppy/plugins/agent_skills/config.py +175 -0
  159. code_puppy/plugins/agent_skills/discovery.py +136 -0
  160. code_puppy/plugins/agent_skills/downloader.py +392 -0
  161. code_puppy/plugins/agent_skills/installer.py +22 -0
  162. code_puppy/plugins/agent_skills/metadata.py +219 -0
  163. code_puppy/plugins/agent_skills/prompt_builder.py +60 -0
  164. code_puppy/plugins/agent_skills/register_callbacks.py +241 -0
  165. code_puppy/plugins/agent_skills/remote_catalog.py +322 -0
  166. code_puppy/plugins/agent_skills/skill_catalog.py +257 -0
  167. code_puppy/plugins/agent_skills/skills_install_menu.py +664 -0
  168. code_puppy/plugins/agent_skills/skills_menu.py +781 -0
  169. code_puppy/plugins/antigravity_oauth/__init__.py +10 -0
  170. code_puppy/plugins/antigravity_oauth/accounts.py +406 -0
  171. code_puppy/plugins/antigravity_oauth/antigravity_model.py +706 -0
  172. code_puppy/plugins/antigravity_oauth/config.py +42 -0
  173. code_puppy/plugins/antigravity_oauth/constants.py +133 -0
  174. code_puppy/plugins/antigravity_oauth/oauth.py +478 -0
  175. code_puppy/plugins/antigravity_oauth/register_callbacks.py +518 -0
  176. code_puppy/plugins/antigravity_oauth/storage.py +288 -0
  177. code_puppy/plugins/antigravity_oauth/test_plugin.py +319 -0
  178. code_puppy/plugins/antigravity_oauth/token.py +167 -0
  179. code_puppy/plugins/antigravity_oauth/transport.py +863 -0
  180. code_puppy/plugins/antigravity_oauth/utils.py +168 -0
  181. code_puppy/plugins/chatgpt_oauth/__init__.py +8 -0
  182. code_puppy/plugins/chatgpt_oauth/config.py +52 -0
  183. code_puppy/plugins/chatgpt_oauth/oauth_flow.py +329 -0
  184. code_puppy/plugins/chatgpt_oauth/register_callbacks.py +176 -0
  185. code_puppy/plugins/chatgpt_oauth/test_plugin.py +301 -0
  186. code_puppy/plugins/chatgpt_oauth/utils.py +523 -0
  187. code_puppy/plugins/claude_code_hooks/__init__.py +1 -0
  188. code_puppy/plugins/claude_code_hooks/config.py +137 -0
  189. code_puppy/plugins/claude_code_hooks/register_callbacks.py +175 -0
  190. code_puppy/plugins/claude_code_oauth/README.md +167 -0
  191. code_puppy/plugins/claude_code_oauth/SETUP.md +93 -0
  192. code_puppy/plugins/claude_code_oauth/__init__.py +25 -0
  193. code_puppy/plugins/claude_code_oauth/config.py +52 -0
  194. code_puppy/plugins/claude_code_oauth/register_callbacks.py +453 -0
  195. code_puppy/plugins/claude_code_oauth/test_plugin.py +283 -0
  196. code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +241 -0
  197. code_puppy/plugins/claude_code_oauth/utils.py +640 -0
  198. code_puppy/plugins/customizable_commands/__init__.py +0 -0
  199. code_puppy/plugins/customizable_commands/register_callbacks.py +152 -0
  200. code_puppy/plugins/example_custom_command/README.md +280 -0
  201. code_puppy/plugins/example_custom_command/register_callbacks.py +51 -0
  202. code_puppy/plugins/file_permission_handler/__init__.py +4 -0
  203. code_puppy/plugins/file_permission_handler/register_callbacks.py +470 -0
  204. code_puppy/plugins/frontend_emitter/__init__.py +25 -0
  205. code_puppy/plugins/frontend_emitter/emitter.py +121 -0
  206. code_puppy/plugins/frontend_emitter/register_callbacks.py +261 -0
  207. code_puppy/plugins/hook_creator/__init__.py +1 -0
  208. code_puppy/plugins/hook_creator/register_callbacks.py +33 -0
  209. code_puppy/plugins/hook_manager/__init__.py +1 -0
  210. code_puppy/plugins/hook_manager/config.py +290 -0
  211. code_puppy/plugins/hook_manager/hooks_menu.py +564 -0
  212. code_puppy/plugins/hook_manager/register_callbacks.py +227 -0
  213. code_puppy/plugins/oauth_puppy_html.py +228 -0
  214. code_puppy/plugins/scheduler/__init__.py +1 -0
  215. code_puppy/plugins/scheduler/register_callbacks.py +88 -0
  216. code_puppy/plugins/scheduler/scheduler_menu.py +522 -0
  217. code_puppy/plugins/scheduler/scheduler_wizard.py +341 -0
  218. code_puppy/plugins/shell_safety/__init__.py +6 -0
  219. code_puppy/plugins/shell_safety/agent_shell_safety.py +69 -0
  220. code_puppy/plugins/shell_safety/command_cache.py +156 -0
  221. code_puppy/plugins/shell_safety/register_callbacks.py +202 -0
  222. code_puppy/plugins/synthetic_status/__init__.py +1 -0
  223. code_puppy/plugins/synthetic_status/register_callbacks.py +132 -0
  224. code_puppy/plugins/synthetic_status/status_api.py +147 -0
  225. code_puppy/plugins/universal_constructor/__init__.py +13 -0
  226. code_puppy/plugins/universal_constructor/models.py +138 -0
  227. code_puppy/plugins/universal_constructor/register_callbacks.py +47 -0
  228. code_puppy/plugins/universal_constructor/registry.py +302 -0
  229. code_puppy/plugins/universal_constructor/sandbox.py +584 -0
  230. code_puppy/prompts/antigravity_system_prompt.md +1 -0
  231. code_puppy/pydantic_patches.py +356 -0
  232. code_puppy/reopenable_async_client.py +232 -0
  233. code_puppy/round_robin_model.py +150 -0
  234. code_puppy/scheduler/__init__.py +41 -0
  235. code_puppy/scheduler/__main__.py +9 -0
  236. code_puppy/scheduler/cli.py +118 -0
  237. code_puppy/scheduler/config.py +126 -0
  238. code_puppy/scheduler/daemon.py +280 -0
  239. code_puppy/scheduler/executor.py +155 -0
  240. code_puppy/scheduler/platform.py +19 -0
  241. code_puppy/scheduler/platform_unix.py +22 -0
  242. code_puppy/scheduler/platform_win.py +32 -0
  243. code_puppy/session_storage.py +338 -0
  244. code_puppy/status_display.py +257 -0
  245. code_puppy/summarization_agent.py +176 -0
  246. code_puppy/terminal_utils.py +418 -0
  247. code_puppy/tools/__init__.py +501 -0
  248. code_puppy/tools/agent_tools.py +603 -0
  249. code_puppy/tools/ask_user_question/__init__.py +26 -0
  250. code_puppy/tools/ask_user_question/constants.py +73 -0
  251. code_puppy/tools/ask_user_question/demo_tui.py +55 -0
  252. code_puppy/tools/ask_user_question/handler.py +232 -0
  253. code_puppy/tools/ask_user_question/models.py +304 -0
  254. code_puppy/tools/ask_user_question/registration.py +26 -0
  255. code_puppy/tools/ask_user_question/renderers.py +309 -0
  256. code_puppy/tools/ask_user_question/terminal_ui.py +329 -0
  257. code_puppy/tools/ask_user_question/theme.py +155 -0
  258. code_puppy/tools/ask_user_question/tui_loop.py +423 -0
  259. code_puppy/tools/browser/__init__.py +37 -0
  260. code_puppy/tools/browser/browser_control.py +289 -0
  261. code_puppy/tools/browser/browser_interactions.py +545 -0
  262. code_puppy/tools/browser/browser_locators.py +640 -0
  263. code_puppy/tools/browser/browser_manager.py +378 -0
  264. code_puppy/tools/browser/browser_navigation.py +251 -0
  265. code_puppy/tools/browser/browser_screenshot.py +179 -0
  266. code_puppy/tools/browser/browser_scripts.py +462 -0
  267. code_puppy/tools/browser/browser_workflows.py +221 -0
  268. code_puppy/tools/browser/chromium_terminal_manager.py +259 -0
  269. code_puppy/tools/browser/terminal_command_tools.py +534 -0
  270. code_puppy/tools/browser/terminal_screenshot_tools.py +552 -0
  271. code_puppy/tools/browser/terminal_tools.py +525 -0
  272. code_puppy/tools/command_runner.py +1346 -0
  273. code_puppy/tools/common.py +1409 -0
  274. code_puppy/tools/display.py +84 -0
  275. code_puppy/tools/file_modifications.py +886 -0
  276. code_puppy/tools/file_operations.py +802 -0
  277. code_puppy/tools/scheduler_tools.py +412 -0
  278. code_puppy/tools/skills_tools.py +244 -0
  279. code_puppy/tools/subagent_context.py +158 -0
  280. code_puppy/tools/tools_content.py +51 -0
  281. code_puppy/tools/universal_constructor.py +889 -0
  282. code_puppy/uvx_detection.py +242 -0
  283. code_puppy/version_checker.py +82 -0
  284. codepp-0.0.437.dist-info/METADATA +766 -0
  285. codepp-0.0.437.dist-info/RECORD +288 -0
  286. codepp-0.0.437.dist-info/WHEEL +4 -0
  287. codepp-0.0.437.dist-info/entry_points.txt +3 -0
  288. codepp-0.0.437.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,501 @@
1
+ from code_puppy.callbacks import on_register_tools
2
+ from code_puppy.messaging import emit_warning
3
+ from code_puppy.tools.agent_tools import register_invoke_agent, register_list_agents
4
+ from code_puppy.tools.ask_user_question import register_ask_user_question
5
+
6
+ # Browser automation tools
7
+ from code_puppy.tools.browser.browser_control import (
8
+ register_close_browser,
9
+ register_create_new_page,
10
+ register_get_browser_status,
11
+ register_initialize_browser,
12
+ register_list_pages,
13
+ )
14
+ from code_puppy.tools.browser.browser_interactions import (
15
+ register_browser_check,
16
+ register_browser_uncheck,
17
+ register_click_element,
18
+ register_double_click_element,
19
+ register_get_element_text,
20
+ register_get_element_value,
21
+ register_hover_element,
22
+ register_select_option,
23
+ register_set_element_text,
24
+ )
25
+ from code_puppy.tools.browser.browser_locators import (
26
+ register_find_buttons,
27
+ register_find_by_label,
28
+ register_find_by_placeholder,
29
+ register_find_by_role,
30
+ register_find_by_test_id,
31
+ register_find_by_text,
32
+ register_find_links,
33
+ register_run_xpath_query,
34
+ )
35
+ from code_puppy.tools.browser.browser_navigation import (
36
+ register_browser_go_back,
37
+ register_browser_go_forward,
38
+ register_get_page_info,
39
+ register_navigate_to_url,
40
+ register_reload_page,
41
+ register_wait_for_load_state,
42
+ )
43
+ from code_puppy.tools.browser.browser_screenshot import (
44
+ register_take_screenshot_and_analyze,
45
+ )
46
+ from code_puppy.tools.browser.browser_scripts import (
47
+ register_browser_clear_highlights,
48
+ register_browser_highlight_element,
49
+ register_execute_javascript,
50
+ register_scroll_page,
51
+ register_scroll_to_element,
52
+ register_set_viewport_size,
53
+ register_wait_for_element,
54
+ )
55
+ from code_puppy.tools.browser.browser_workflows import (
56
+ register_list_workflows,
57
+ register_read_workflow,
58
+ register_save_workflow,
59
+ )
60
+ from code_puppy.tools.browser.terminal_command_tools import (
61
+ register_run_terminal_command,
62
+ register_send_terminal_keys,
63
+ register_wait_terminal_output,
64
+ )
65
+ from code_puppy.tools.browser.terminal_screenshot_tools import (
66
+ register_load_image,
67
+ register_terminal_compare_mockup,
68
+ register_terminal_read_output,
69
+ register_terminal_screenshot,
70
+ )
71
+
72
+ # Terminal automation tools
73
+ from code_puppy.tools.browser.terminal_tools import (
74
+ register_check_terminal_server,
75
+ register_close_terminal,
76
+ register_open_terminal,
77
+ register_start_api_server,
78
+ )
79
+ from code_puppy.tools.command_runner import (
80
+ register_agent_run_shell_command,
81
+ register_agent_share_your_reasoning,
82
+ )
83
+ from code_puppy.tools.display import (
84
+ display_non_streamed_result as display_non_streamed_result,
85
+ )
86
+ from code_puppy.tools.file_modifications import (
87
+ register_create_file,
88
+ register_delete_file,
89
+ register_delete_snippet,
90
+ register_edit_file,
91
+ register_replace_in_file,
92
+ )
93
+ from code_puppy.tools.file_operations import (
94
+ register_grep,
95
+ register_list_files,
96
+ register_read_file,
97
+ )
98
+
99
+ # Scheduler tools
100
+ from code_puppy.tools.scheduler_tools import (
101
+ register_scheduler_create_task,
102
+ register_scheduler_daemon_status,
103
+ register_scheduler_delete_task,
104
+ register_scheduler_list_tasks,
105
+ register_scheduler_run_task,
106
+ register_scheduler_start_daemon,
107
+ register_scheduler_stop_daemon,
108
+ register_scheduler_toggle_task,
109
+ register_scheduler_view_log,
110
+ )
111
+ from code_puppy.tools.skills_tools import (
112
+ register_activate_skill,
113
+ register_list_or_search_skills,
114
+ )
115
+ from code_puppy.tools.universal_constructor import register_universal_constructor
116
+
117
+ # Map of tool names to their individual registration functions
118
+ TOOL_REGISTRY = {
119
+ # Agent Tools
120
+ "list_agents": register_list_agents,
121
+ "invoke_agent": register_invoke_agent,
122
+ # File Operations
123
+ "list_files": register_list_files,
124
+ "read_file": register_read_file,
125
+ "grep": register_grep,
126
+ # File Modifications
127
+ "edit_file": register_edit_file, # DEPRECATED: auto-expanded to create_file, replace_in_file, delete_snippet
128
+ "create_file": register_create_file,
129
+ "replace_in_file": register_replace_in_file,
130
+ "delete_snippet": register_delete_snippet,
131
+ "delete_file": register_delete_file,
132
+ # Command Runner
133
+ "agent_run_shell_command": register_agent_run_shell_command,
134
+ "agent_share_your_reasoning": register_agent_share_your_reasoning,
135
+ # User Interaction
136
+ "ask_user_question": register_ask_user_question,
137
+ # Browser Control
138
+ "browser_initialize": register_initialize_browser,
139
+ "browser_close": register_close_browser,
140
+ "browser_status": register_get_browser_status,
141
+ "browser_new_page": register_create_new_page,
142
+ "browser_list_pages": register_list_pages,
143
+ # Browser Navigation
144
+ "browser_navigate": register_navigate_to_url,
145
+ "browser_get_page_info": register_get_page_info,
146
+ "browser_go_back": register_browser_go_back,
147
+ "browser_go_forward": register_browser_go_forward,
148
+ "browser_reload": register_reload_page,
149
+ "browser_wait_for_load": register_wait_for_load_state,
150
+ # Browser Element Discovery
151
+ "browser_find_by_role": register_find_by_role,
152
+ "browser_find_by_text": register_find_by_text,
153
+ "browser_find_by_label": register_find_by_label,
154
+ "browser_find_by_placeholder": register_find_by_placeholder,
155
+ "browser_find_by_test_id": register_find_by_test_id,
156
+ "browser_xpath_query": register_run_xpath_query,
157
+ "browser_find_buttons": register_find_buttons,
158
+ "browser_find_links": register_find_links,
159
+ # Browser Element Interactions
160
+ "browser_click": register_click_element,
161
+ "browser_double_click": register_double_click_element,
162
+ "browser_hover": register_hover_element,
163
+ "browser_set_text": register_set_element_text,
164
+ "browser_get_text": register_get_element_text,
165
+ "browser_get_value": register_get_element_value,
166
+ "browser_select_option": register_select_option,
167
+ "browser_check": register_browser_check,
168
+ "browser_uncheck": register_browser_uncheck,
169
+ # Browser Scripts and Advanced Features
170
+ "browser_execute_js": register_execute_javascript,
171
+ "browser_scroll": register_scroll_page,
172
+ "browser_scroll_to_element": register_scroll_to_element,
173
+ "browser_set_viewport": register_set_viewport_size,
174
+ "browser_wait_for_element": register_wait_for_element,
175
+ "browser_highlight_element": register_browser_highlight_element,
176
+ "browser_clear_highlights": register_browser_clear_highlights,
177
+ # Browser Screenshots
178
+ "browser_screenshot_analyze": register_take_screenshot_and_analyze,
179
+ # Browser Workflows
180
+ "browser_save_workflow": register_save_workflow,
181
+ "browser_list_workflows": register_list_workflows,
182
+ "browser_read_workflow": register_read_workflow,
183
+ # Terminal Connection Tools
184
+ "terminal_check_server": register_check_terminal_server,
185
+ "terminal_open": register_open_terminal,
186
+ "terminal_close": register_close_terminal,
187
+ "start_api_server": register_start_api_server,
188
+ # Terminal Command Execution Tools
189
+ "terminal_run_command": register_run_terminal_command,
190
+ "terminal_send_keys": register_send_terminal_keys,
191
+ "terminal_wait_output": register_wait_terminal_output,
192
+ # Terminal Screenshot Tools
193
+ "terminal_screenshot_analyze": register_terminal_screenshot,
194
+ "terminal_read_output": register_terminal_read_output,
195
+ "terminal_compare_mockup": register_terminal_compare_mockup,
196
+ "load_image_for_analysis": register_load_image,
197
+ # Skills Tools
198
+ "activate_skill": register_activate_skill,
199
+ "list_or_search_skills": register_list_or_search_skills,
200
+ # Universal Constructor
201
+ "universal_constructor": register_universal_constructor,
202
+ # Scheduler Tools
203
+ "scheduler_list_tasks": register_scheduler_list_tasks,
204
+ "scheduler_create_task": register_scheduler_create_task,
205
+ "scheduler_delete_task": register_scheduler_delete_task,
206
+ "scheduler_toggle_task": register_scheduler_toggle_task,
207
+ "scheduler_daemon_status": register_scheduler_daemon_status,
208
+ "scheduler_start_daemon": register_scheduler_start_daemon,
209
+ "scheduler_stop_daemon": register_scheduler_stop_daemon,
210
+ "scheduler_run_task": register_scheduler_run_task,
211
+ "scheduler_view_log": register_scheduler_view_log,
212
+ }
213
+
214
+ # Tools that expand into multiple tools for backward compatibility.
215
+ # When an agent requests a tool listed here, all the expansion tools
216
+ # are registered instead (the original tool is NOT registered).
217
+ TOOL_EXPANSIONS: dict[str, list[str]] = {
218
+ "edit_file": ["create_file", "replace_in_file", "delete_snippet"],
219
+ }
220
+
221
+
222
+ def _load_plugin_tools() -> None:
223
+ """Load tools registered by plugins via the register_tools callback.
224
+
225
+ This merges plugin-provided tools into the TOOL_REGISTRY.
226
+ Called lazily when tools are first accessed.
227
+ """
228
+ try:
229
+ results = on_register_tools()
230
+ for result in results:
231
+ if result is None:
232
+ continue
233
+ # Each result should be a list of tool definitions
234
+ tools_list = result if isinstance(result, list) else [result]
235
+ for tool_def in tools_list:
236
+ if (
237
+ isinstance(tool_def, dict)
238
+ and "name" in tool_def
239
+ and "register_func" in tool_def
240
+ ):
241
+ tool_name = tool_def["name"]
242
+ register_func = tool_def["register_func"]
243
+ if callable(register_func):
244
+ TOOL_REGISTRY[tool_name] = register_func
245
+ except Exception:
246
+ # Don't let plugin failures break core functionality
247
+ pass
248
+
249
+
250
+ # Appended to the system prompt when extended thinking is active and
251
+ # the share_your_reasoning tool is removed. Encourages the model to
252
+ # use its native thinking blocks between tool calls instead.
253
+ EXTENDED_THINKING_PROMPT_NOTE = (
254
+ "\n\nIMPORTANT: You have extended thinking enabled. "
255
+ "Always think between tool calls or waves of tool calls "
256
+ "(if running parallel tools). Use your thinking blocks to reason "
257
+ "about the results before deciding on next steps."
258
+ )
259
+
260
+
261
+ def has_extended_thinking_active(model_name: str | None = None) -> bool:
262
+ """Check if an Anthropic model has extended thinking enabled or adaptive.
263
+
264
+ When extended thinking is active, the model already exposes its reasoning
265
+ via thinking blocks, making the share_your_reasoning tool redundant.
266
+
267
+ Args:
268
+ model_name: The model name to check. If None, uses the current global model.
269
+
270
+ Returns:
271
+ True if the model is an Anthropic model with extended_thinking set to
272
+ "enabled" or "adaptive".
273
+ """
274
+ from code_puppy.config import get_effective_model_settings, get_global_model_name
275
+
276
+ if model_name is None:
277
+ model_name = get_global_model_name()
278
+
279
+ if model_name is None:
280
+ return False
281
+
282
+ # Only applies to Anthropic/Claude models
283
+ if not (model_name.startswith("claude-") or model_name.startswith("anthropic-")):
284
+ return False
285
+
286
+ from code_puppy.model_utils import get_default_extended_thinking
287
+
288
+ settings = get_effective_model_settings(model_name)
289
+ default_thinking = get_default_extended_thinking(model_name)
290
+ extended_thinking = settings.get("extended_thinking", default_thinking)
291
+
292
+ # Handle legacy boolean values
293
+ if extended_thinking is True:
294
+ extended_thinking = "enabled"
295
+ elif extended_thinking is False:
296
+ return False
297
+
298
+ return extended_thinking in ("enabled", "adaptive")
299
+
300
+
301
+ def register_tools_for_agent(
302
+ agent, tool_names: list[str], model_name: str | None = None
303
+ ):
304
+ """Register specific tools for an agent based on tool names.
305
+
306
+ Args:
307
+ agent: The agent to register tools to.
308
+ tool_names: List of tool names to register. UC tools are prefixed with "uc:".
309
+ model_name: Optional model name. Used to determine if certain tools
310
+ (like agent_share_your_reasoning) should be skipped. If None,
311
+ falls back to the current global model.
312
+ """
313
+ from code_puppy.config import get_universal_constructor_enabled
314
+
315
+ _load_plugin_tools()
316
+
317
+ # Pre-compute whether extended thinking is active to avoid repeated checks
318
+ skip_reasoning_tool = has_extended_thinking_active(model_name)
319
+
320
+ # Expand compound tools (e.g. "edit_file" → three individual tools)
321
+ expanded_tools: list[str] = []
322
+ seen: set[str] = set()
323
+ for tool_name in tool_names:
324
+ if tool_name in TOOL_EXPANSIONS:
325
+ for expanded in TOOL_EXPANSIONS[tool_name]:
326
+ if expanded not in seen:
327
+ expanded_tools.append(expanded)
328
+ seen.add(expanded)
329
+ else:
330
+ if tool_name not in seen:
331
+ expanded_tools.append(tool_name)
332
+ seen.add(tool_name)
333
+ tool_names = expanded_tools
334
+
335
+ for tool_name in tool_names:
336
+ # Handle UC tools (prefixed with "uc:")
337
+ if tool_name.startswith("uc:"):
338
+ # Skip UC tools if UC is disabled
339
+ if not get_universal_constructor_enabled():
340
+ continue
341
+ uc_tool_name = tool_name[3:] # Remove "uc:" prefix
342
+ _register_uc_tool_wrapper(agent, uc_tool_name)
343
+ continue
344
+
345
+ if tool_name not in TOOL_REGISTRY:
346
+ # Skip unknown tools with a warning instead of failing
347
+ emit_warning(f"Warning: Unknown tool '{tool_name}' requested, skipping...")
348
+ continue
349
+
350
+ # Check if Universal Constructor is disabled
351
+ if (
352
+ tool_name == "universal_constructor"
353
+ and not get_universal_constructor_enabled()
354
+ ):
355
+ continue # Skip UC if disabled in config
356
+
357
+ # Skip reasoning tool when extended thinking is active — the model
358
+ # already exposes its chain-of-thought via thinking blocks.
359
+ if tool_name == "agent_share_your_reasoning" and skip_reasoning_tool:
360
+ continue
361
+
362
+ # Register the individual tool
363
+ register_func = TOOL_REGISTRY[tool_name]
364
+ register_func(agent)
365
+
366
+
367
+ def _register_uc_tool_wrapper(agent, uc_tool_name: str):
368
+ """Register a wrapper for a UC tool that calls it via the UC registry.
369
+
370
+ This creates a dynamic tool that wraps the UC tool, preserving its
371
+ parameter signature so pydantic-ai can generate proper JSON schema.
372
+
373
+ Args:
374
+ agent: The agent to register the tool wrapper to.
375
+ uc_tool_name: The full name of the UC tool (e.g., "api.weather").
376
+ """
377
+ import inspect
378
+ from typing import Any
379
+
380
+ from pydantic_ai import RunContext
381
+
382
+ # Get tool info and function from registry
383
+ try:
384
+ from code_puppy.plugins.universal_constructor.registry import get_registry
385
+
386
+ registry = get_registry()
387
+ tool_info = registry.get_tool(uc_tool_name)
388
+ if not tool_info:
389
+ emit_warning(f"Warning: UC tool '{uc_tool_name}' not found, skipping...")
390
+ return
391
+
392
+ func = registry.get_tool_function(uc_tool_name)
393
+ if not func:
394
+ emit_warning(
395
+ f"Warning: UC tool '{uc_tool_name}' function not found, skipping..."
396
+ )
397
+ return
398
+
399
+ description = tool_info.meta.description
400
+ docstring = tool_info.docstring or description
401
+ except Exception as e:
402
+ emit_warning(f"Warning: Failed to get UC tool '{uc_tool_name}' info: {e}")
403
+ return
404
+
405
+ # Get the original function's signature
406
+ try:
407
+ sig = inspect.signature(func)
408
+ # Get annotations from the original function
409
+ annotations = getattr(func, "__annotations__", {}).copy()
410
+ except (ValueError, TypeError):
411
+ sig = None
412
+ annotations = {}
413
+
414
+ # Create wrapper that preserves the signature
415
+ def make_uc_wrapper(
416
+ tool_name: str, original_func, original_sig, original_annotations
417
+ ):
418
+ # Build the wrapper function
419
+ async def uc_tool_wrapper(context: RunContext, **kwargs: Any) -> Any:
420
+ """Dynamically generated wrapper for a UC tool."""
421
+ try:
422
+ result = original_func(**kwargs)
423
+ # Await async tool implementations
424
+ if inspect.isawaitable(result):
425
+ result = await result
426
+ return result
427
+ except Exception as e:
428
+ return {"error": f"UC tool '{tool_name}' failed: {e}"}
429
+
430
+ # Copy signature info from original function
431
+ uc_tool_wrapper.__name__ = tool_name.replace(".", "_")
432
+ uc_tool_wrapper.__doc__ = (
433
+ f"{docstring}\n\nThis is a Universal Constructor tool."
434
+ )
435
+
436
+ # Preserve annotations for pydantic-ai schema generation
437
+ if original_annotations:
438
+ # Add 'context' param and copy original params (excluding 'return')
439
+ new_annotations = {"context": RunContext}
440
+ for param_name, param_type in original_annotations.items():
441
+ if param_name != "return":
442
+ new_annotations[param_name] = param_type
443
+ if "return" in original_annotations:
444
+ new_annotations["return"] = original_annotations["return"]
445
+ else:
446
+ new_annotations["return"] = Any
447
+ uc_tool_wrapper.__annotations__ = new_annotations
448
+
449
+ # Try to set __signature__ for better introspection
450
+ if original_sig:
451
+ try:
452
+ # Build new parameters list: context first, then original params
453
+ new_params = [
454
+ inspect.Parameter(
455
+ "context",
456
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
457
+ annotation=RunContext,
458
+ )
459
+ ]
460
+ for param in original_sig.parameters.values():
461
+ new_params.append(param)
462
+
463
+ # Create new signature with return annotation
464
+ return_annotation = original_annotations.get("return", Any)
465
+ new_sig = original_sig.replace(
466
+ parameters=new_params, return_annotation=return_annotation
467
+ )
468
+ uc_tool_wrapper.__signature__ = new_sig
469
+ except (ValueError, TypeError):
470
+ pass # Signature manipulation failed, continue without it
471
+
472
+ return uc_tool_wrapper
473
+
474
+ wrapper = make_uc_wrapper(uc_tool_name, func, sig, annotations)
475
+
476
+ # Register the wrapper as a tool
477
+ try:
478
+ agent.tool(wrapper)
479
+ except Exception as e:
480
+ emit_warning(f"Warning: Failed to register UC tool '{uc_tool_name}': {e}")
481
+
482
+
483
+ def register_all_tools(agent, model_name: str | None = None):
484
+ """Register all available tools to the provided agent.
485
+
486
+ Args:
487
+ agent: The agent to register tools to.
488
+ model_name: Optional model name for conditional tool filtering.
489
+ """
490
+ all_tools = list(TOOL_REGISTRY.keys())
491
+ register_tools_for_agent(agent, all_tools, model_name=model_name)
492
+
493
+
494
+ def get_available_tool_names() -> list[str]:
495
+ """Get list of all available tool names.
496
+
497
+ Returns:
498
+ List of all tool names that can be registered.
499
+ """
500
+ _load_plugin_tools()
501
+ return list(TOOL_REGISTRY.keys())