code-puppy-core-plugins 0.0.2__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 (313) hide show
  1. code_puppy_core_plugins/__init__.py +5 -0
  2. code_puppy_core_plugins/acp/README.md +266 -0
  3. code_puppy_core_plugins/acp/__init__.py +8 -0
  4. code_puppy_core_plugins/acp/agent.py +494 -0
  5. code_puppy_core_plugins/acp/bridge.py +309 -0
  6. code_puppy_core_plugins/acp/capabilities.py +73 -0
  7. code_puppy_core_plugins/acp/commands.py +116 -0
  8. code_puppy_core_plugins/acp/content.py +115 -0
  9. code_puppy_core_plugins/acp/io_delegation.py +231 -0
  10. code_puppy_core_plugins/acp/mcp_config.py +66 -0
  11. code_puppy_core_plugins/acp/permissions.py +159 -0
  12. code_puppy_core_plugins/acp/persistence.py +197 -0
  13. code_puppy_core_plugins/acp/register_callbacks.py +110 -0
  14. code_puppy_core_plugins/acp/replay.py +114 -0
  15. code_puppy_core_plugins/acp/session.py +329 -0
  16. code_puppy_core_plugins/acp/session_config.py +179 -0
  17. code_puppy_core_plugins/acp/state.py +135 -0
  18. code_puppy_core_plugins/agent_skills/__init__.py +22 -0
  19. code_puppy_core_plugins/agent_skills/config.py +208 -0
  20. code_puppy_core_plugins/agent_skills/discovery.py +337 -0
  21. code_puppy_core_plugins/agent_skills/downloader.py +392 -0
  22. code_puppy_core_plugins/agent_skills/enabled_skills.py +82 -0
  23. code_puppy_core_plugins/agent_skills/installer.py +22 -0
  24. code_puppy_core_plugins/agent_skills/metadata.py +219 -0
  25. code_puppy_core_plugins/agent_skills/prompt_builder.py +49 -0
  26. code_puppy_core_plugins/agent_skills/provider.py +52 -0
  27. code_puppy_core_plugins/agent_skills/register_callbacks.py +309 -0
  28. code_puppy_core_plugins/agent_skills/remote_catalog.py +322 -0
  29. code_puppy_core_plugins/agent_skills/skill_catalog.py +257 -0
  30. code_puppy_core_plugins/agent_skills/skill_commands.py +102 -0
  31. code_puppy_core_plugins/agent_skills/skills_install_menu.py +698 -0
  32. code_puppy_core_plugins/agent_skills/skills_menu.py +794 -0
  33. code_puppy_core_plugins/aws_bedrock/__init__.py +14 -0
  34. code_puppy_core_plugins/aws_bedrock/config.py +101 -0
  35. code_puppy_core_plugins/aws_bedrock/register_callbacks.py +243 -0
  36. code_puppy_core_plugins/aws_bedrock/utils.py +186 -0
  37. code_puppy_core_plugins/azure_foundry/README.md +238 -0
  38. code_puppy_core_plugins/azure_foundry/__init__.py +15 -0
  39. code_puppy_core_plugins/azure_foundry/config.py +126 -0
  40. code_puppy_core_plugins/azure_foundry/discovery.py +189 -0
  41. code_puppy_core_plugins/azure_foundry/register_callbacks.py +506 -0
  42. code_puppy_core_plugins/azure_foundry/token.py +182 -0
  43. code_puppy_core_plugins/azure_foundry/utils.py +375 -0
  44. code_puppy_core_plugins/btw/__init__.py +1 -0
  45. code_puppy_core_plugins/btw/inline_view.py +135 -0
  46. code_puppy_core_plugins/btw/register_callbacks.py +106 -0
  47. code_puppy_core_plugins/btw/side_query.py +91 -0
  48. code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +83 -0
  49. code_puppy_core_plugins/chatgpt_oauth/__init__.py +8 -0
  50. code_puppy_core_plugins/chatgpt_oauth/config.py +52 -0
  51. code_puppy_core_plugins/chatgpt_oauth/image_generation.py +253 -0
  52. code_puppy_core_plugins/chatgpt_oauth/image_tool.py +70 -0
  53. code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +461 -0
  54. code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +288 -0
  55. code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +663 -0
  56. code_puppy_core_plugins/chatgpt_oauth/usage.py +113 -0
  57. code_puppy_core_plugins/chatgpt_oauth/utils.py +534 -0
  58. code_puppy_core_plugins/claude_code_hooks/__init__.py +1 -0
  59. code_puppy_core_plugins/claude_code_hooks/config.py +137 -0
  60. code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +383 -0
  61. code_puppy_core_plugins/claude_code_oauth/README.md +167 -0
  62. code_puppy_core_plugins/claude_code_oauth/SETUP.md +93 -0
  63. code_puppy_core_plugins/claude_code_oauth/__init__.py +25 -0
  64. code_puppy_core_plugins/claude_code_oauth/config.py +59 -0
  65. code_puppy_core_plugins/claude_code_oauth/fast_mode.py +122 -0
  66. code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +64 -0
  67. code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +719 -0
  68. code_puppy_core_plugins/claude_code_oauth/test_plugin.py +285 -0
  69. code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +240 -0
  70. code_puppy_core_plugins/claude_code_oauth/utils.py +663 -0
  71. code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +155 -0
  72. code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +104 -0
  73. code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +147 -0
  74. code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +39 -0
  75. code_puppy_core_plugins/code_puppy_agent/SKILL.md +180 -0
  76. code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +136 -0
  77. code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +160 -0
  78. code_puppy_core_plugins/code_puppy_agent/__init__.py +5 -0
  79. code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +46 -0
  80. code_puppy_core_plugins/computer_use/NativeCapture.swift +123 -0
  81. code_puppy_core_plugins/computer_use/README.md +109 -0
  82. code_puppy_core_plugins/computer_use/__init__.py +1 -0
  83. code_puppy_core_plugins/computer_use/accessibility.py +163 -0
  84. code_puppy_core_plugins/computer_use/activation.py +75 -0
  85. code_puppy_core_plugins/computer_use/backend.py +584 -0
  86. code_puppy_core_plugins/computer_use/backend_types.py +5 -0
  87. code_puppy_core_plugins/computer_use/capture.py +110 -0
  88. code_puppy_core_plugins/computer_use/commands.py +62 -0
  89. code_puppy_core_plugins/computer_use/geometry.py +81 -0
  90. code_puppy_core_plugins/computer_use/inline_image.py +56 -0
  91. code_puppy_core_plugins/computer_use/keycodes.py +47 -0
  92. code_puppy_core_plugins/computer_use/policy.py +144 -0
  93. code_puppy_core_plugins/computer_use/register_callbacks.py +96 -0
  94. code_puppy_core_plugins/computer_use/safety.py +18 -0
  95. code_puppy_core_plugins/computer_use/settle.py +64 -0
  96. code_puppy_core_plugins/computer_use/state.py +86 -0
  97. code_puppy_core_plugins/computer_use/tools.py +469 -0
  98. code_puppy_core_plugins/context_indicator/__init__.py +14 -0
  99. code_puppy_core_plugins/context_indicator/register_callbacks.py +249 -0
  100. code_puppy_core_plugins/context_indicator/usage.py +40 -0
  101. code_puppy_core_plugins/copilot_auth/__init__.py +11 -0
  102. code_puppy_core_plugins/copilot_auth/config.py +93 -0
  103. code_puppy_core_plugins/copilot_auth/reasoning_client.py +409 -0
  104. code_puppy_core_plugins/copilot_auth/register_callbacks.py +460 -0
  105. code_puppy_core_plugins/copilot_auth/utils.py +587 -0
  106. code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  107. code_puppy_core_plugins/customizable_commands/register_callbacks.py +464 -0
  108. code_puppy_core_plugins/dbos_durable_exec/__init__.py +1 -0
  109. code_puppy_core_plugins/dbos_durable_exec/cancel.py +15 -0
  110. code_puppy_core_plugins/dbos_durable_exec/commands.py +31 -0
  111. code_puppy_core_plugins/dbos_durable_exec/config.py +31 -0
  112. code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +83 -0
  113. code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +45 -0
  114. code_puppy_core_plugins/dbos_durable_exec/runtime.py +65 -0
  115. code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +155 -0
  116. code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +16 -0
  117. code_puppy_core_plugins/dbos_durable_exec/wrapper.py +58 -0
  118. code_puppy_core_plugins/destructive_command_guard/AGENTS.md +79 -0
  119. code_puppy_core_plugins/destructive_command_guard/__init__.py +14 -0
  120. code_puppy_core_plugins/destructive_command_guard/detector.py +374 -0
  121. code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +165 -0
  122. code_puppy_core_plugins/emoji_filter/__init__.py +12 -0
  123. code_puppy_core_plugins/emoji_filter/config.py +26 -0
  124. code_puppy_core_plugins/emoji_filter/register_callbacks.py +238 -0
  125. code_puppy_core_plugins/emoji_filter/stripper.py +45 -0
  126. code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +116 -0
  127. code_puppy_core_plugins/example_custom_command/README.md +328 -0
  128. code_puppy_core_plugins/example_custom_command/register_callbacks.py +66 -0
  129. code_puppy_core_plugins/file_permission_handler/__init__.py +4 -0
  130. code_puppy_core_plugins/file_permission_handler/register_callbacks.py +575 -0
  131. code_puppy_core_plugins/flux_bootstrap/__init__.py +5 -0
  132. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +173 -0
  133. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +86 -0
  134. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +167 -0
  135. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +392 -0
  136. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +51 -0
  137. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +129 -0
  138. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +211 -0
  139. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +181 -0
  140. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +71 -0
  141. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +16 -0
  142. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +103 -0
  143. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +108 -0
  144. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +195 -0
  145. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +221 -0
  146. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +151 -0
  147. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +208 -0
  148. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +180 -0
  149. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +304 -0
  150. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +120 -0
  151. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +179 -0
  152. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +46 -0
  153. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +155 -0
  154. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +154 -0
  155. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +248 -0
  156. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +345 -0
  157. code_puppy_core_plugins/flux_bootstrap/installer.py +256 -0
  158. code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +71 -0
  159. code_puppy_core_plugins/force_push_guard/__init__.py +5 -0
  160. code_puppy_core_plugins/force_push_guard/detector.py +96 -0
  161. code_puppy_core_plugins/force_push_guard/register_callbacks.py +161 -0
  162. code_puppy_core_plugins/fork/__init__.py +7 -0
  163. code_puppy_core_plugins/fork/register_callbacks.py +445 -0
  164. code_puppy_core_plugins/frontend_emitter/__init__.py +25 -0
  165. code_puppy_core_plugins/frontend_emitter/emitter.py +249 -0
  166. code_puppy_core_plugins/frontend_emitter/register_callbacks.py +412 -0
  167. code_puppy_core_plugins/frontend_emitter/session_context.py +50 -0
  168. code_puppy_core_plugins/grok_oauth/__init__.py +6 -0
  169. code_puppy_core_plugins/grok_oauth/config.py +49 -0
  170. code_puppy_core_plugins/grok_oauth/oauth_flow.py +213 -0
  171. code_puppy_core_plugins/grok_oauth/register_callbacks.py +132 -0
  172. code_puppy_core_plugins/grok_oauth/utils.py +195 -0
  173. code_puppy_core_plugins/herdr/README.md +168 -0
  174. code_puppy_core_plugins/herdr/__init__.py +9 -0
  175. code_puppy_core_plugins/herdr/client.py +339 -0
  176. code_puppy_core_plugins/herdr/register_callbacks.py +140 -0
  177. code_puppy_core_plugins/herdr/reporter.py +212 -0
  178. code_puppy_core_plugins/herdr/smoke.py +143 -0
  179. code_puppy_core_plugins/herdr/sources.py +133 -0
  180. code_puppy_core_plugins/hook_creator/__init__.py +1 -0
  181. code_puppy_core_plugins/hook_creator/register_callbacks.py +33 -0
  182. code_puppy_core_plugins/hook_manager/__init__.py +1 -0
  183. code_puppy_core_plugins/hook_manager/config.py +290 -0
  184. code_puppy_core_plugins/hook_manager/hooks_menu.py +571 -0
  185. code_puppy_core_plugins/hook_manager/register_callbacks.py +227 -0
  186. code_puppy_core_plugins/meta_oauth/__init__.py +1 -0
  187. code_puppy_core_plugins/meta_oauth/config.py +55 -0
  188. code_puppy_core_plugins/meta_oauth/oauth_flow.py +109 -0
  189. code_puppy_core_plugins/meta_oauth/register_callbacks.py +154 -0
  190. code_puppy_core_plugins/meta_oauth/utils.py +252 -0
  191. code_puppy_core_plugins/namespace_skill_search/README.md +118 -0
  192. code_puppy_core_plugins/namespace_skill_search/__init__.py +15 -0
  193. code_puppy_core_plugins/namespace_skill_search/namespaces.py +125 -0
  194. code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +99 -0
  195. code_puppy_core_plugins/namespace_skill_search/search_tool.py +158 -0
  196. code_puppy_core_plugins/no_tools/__init__.py +0 -0
  197. code_puppy_core_plugins/no_tools/register_callbacks.py +42 -0
  198. code_puppy_core_plugins/oauth_pasteback.py +110 -0
  199. code_puppy_core_plugins/oauth_puppy_html.py +194 -0
  200. code_puppy_core_plugins/obsidian_agent/README.md +52 -0
  201. code_puppy_core_plugins/obsidian_agent/__init__.py +8 -0
  202. code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +147 -0
  203. code_puppy_core_plugins/obsidian_agent/register_callbacks.py +13 -0
  204. code_puppy_core_plugins/ollama/__init__.py +1 -0
  205. code_puppy_core_plugins/ollama/register_callbacks.py +127 -0
  206. code_puppy_core_plugins/ollama_setup/__init__.py +5 -0
  207. code_puppy_core_plugins/ollama_setup/completer.py +38 -0
  208. code_puppy_core_plugins/ollama_setup/register_callbacks.py +419 -0
  209. code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  210. code_puppy_core_plugins/plugin_list/plugin_contributions.py +348 -0
  211. code_puppy_core_plugins/plugin_list/plugin_meta.py +67 -0
  212. code_puppy_core_plugins/plugin_list/plugin_text_utils.py +173 -0
  213. code_puppy_core_plugins/plugin_list/plugins_menu.py +455 -0
  214. code_puppy_core_plugins/plugin_list/plugins_menu_layout.py +194 -0
  215. code_puppy_core_plugins/plugin_list/plugins_menu_render.py +431 -0
  216. code_puppy_core_plugins/plugin_list/project_trust_flow.py +162 -0
  217. code_puppy_core_plugins/plugin_list/register_callbacks.py +281 -0
  218. code_puppy_core_plugins/pop_command/__init__.py +1 -0
  219. code_puppy_core_plugins/pop_command/register_callbacks.py +191 -0
  220. code_puppy_core_plugins/prompt_newline/__init__.py +13 -0
  221. code_puppy_core_plugins/prompt_newline/config.py +21 -0
  222. code_puppy_core_plugins/prompt_newline/register_callbacks.py +163 -0
  223. code_puppy_core_plugins/prune/__init__.py +1 -0
  224. code_puppy_core_plugins/prune/prune_menu.py +308 -0
  225. code_puppy_core_plugins/prune/prune_model.py +517 -0
  226. code_puppy_core_plugins/prune/prune_render.py +354 -0
  227. code_puppy_core_plugins/prune/register_callbacks.py +388 -0
  228. code_puppy_core_plugins/puppy_kennel/README.md +203 -0
  229. code_puppy_core_plugins/puppy_kennel/__init__.py +6 -0
  230. code_puppy_core_plugins/puppy_kennel/commands.py +206 -0
  231. code_puppy_core_plugins/puppy_kennel/config.py +36 -0
  232. code_puppy_core_plugins/puppy_kennel/kennel.py +368 -0
  233. code_puppy_core_plugins/puppy_kennel/packer.py +152 -0
  234. code_puppy_core_plugins/puppy_kennel/recorder.py +83 -0
  235. code_puppy_core_plugins/puppy_kennel/register_callbacks.py +109 -0
  236. code_puppy_core_plugins/puppy_kennel/retriever.py +28 -0
  237. code_puppy_core_plugins/puppy_kennel/schema.py +78 -0
  238. code_puppy_core_plugins/puppy_kennel/state.py +68 -0
  239. code_puppy_core_plugins/puppy_kennel/tools.py +449 -0
  240. code_puppy_core_plugins/puppy_kennel/wings.py +110 -0
  241. code_puppy_core_plugins/puppy_spinner/README.md +93 -0
  242. code_puppy_core_plugins/puppy_spinner/__init__.py +11 -0
  243. code_puppy_core_plugins/puppy_spinner/builtin_frames.py +172 -0
  244. code_puppy_core_plugins/puppy_spinner/commands.py +116 -0
  245. code_puppy_core_plugins/puppy_spinner/picker.py +379 -0
  246. code_puppy_core_plugins/puppy_spinner/register_callbacks.py +193 -0
  247. code_puppy_core_plugins/puppy_spinner/spinners.py +444 -0
  248. code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  249. code_puppy_core_plugins/quick_resume/register_callbacks.py +77 -0
  250. code_puppy_core_plugins/review_pr/__init__.py +1 -0
  251. code_puppy_core_plugins/review_pr/register_callbacks.py +162 -0
  252. code_puppy_core_plugins/shell_safety/__init__.py +6 -0
  253. code_puppy_core_plugins/shell_safety/agent_shell_safety.py +69 -0
  254. code_puppy_core_plugins/shell_safety/command_cache.py +156 -0
  255. code_puppy_core_plugins/shell_safety/register_callbacks.py +203 -0
  256. code_puppy_core_plugins/stack_dump/__init__.py +1 -0
  257. code_puppy_core_plugins/stack_dump/register_callbacks.py +79 -0
  258. code_puppy_core_plugins/statusline/__init__.py +14 -0
  259. code_puppy_core_plugins/statusline/config.py +68 -0
  260. code_puppy_core_plugins/statusline/payload.py +138 -0
  261. code_puppy_core_plugins/statusline/prompt_patch.py +76 -0
  262. code_puppy_core_plugins/statusline/register_callbacks.py +45 -0
  263. code_puppy_core_plugins/statusline/runner.py +122 -0
  264. code_puppy_core_plugins/statusline/statusline_command.py +197 -0
  265. code_puppy_core_plugins/steer_queue/__init__.py +10 -0
  266. code_puppy_core_plugins/steer_queue/queue_menu.py +444 -0
  267. code_puppy_core_plugins/steer_queue/register_callbacks.py +138 -0
  268. code_puppy_core_plugins/subagent_panel/README.md +102 -0
  269. code_puppy_core_plugins/subagent_panel/__init__.py +24 -0
  270. code_puppy_core_plugins/subagent_panel/coalesce_patch.py +242 -0
  271. code_puppy_core_plugins/subagent_panel/panel_render.py +145 -0
  272. code_puppy_core_plugins/subagent_panel/register_callbacks.py +535 -0
  273. code_puppy_core_plugins/subagent_panel/resume_repaint.py +112 -0
  274. code_puppy_core_plugins/subagent_panel/state.py +231 -0
  275. code_puppy_core_plugins/switch_agent_resume/__init__.py +5 -0
  276. code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +314 -0
  277. code_puppy_core_plugins/theme/README.md +86 -0
  278. code_puppy_core_plugins/theme/__init__.py +14 -0
  279. code_puppy_core_plugins/theme/bundled_palettes.py +346 -0
  280. code_puppy_core_plugins/theme/content_styles.py +146 -0
  281. code_puppy_core_plugins/theme/osc_palette.py +178 -0
  282. code_puppy_core_plugins/theme/picker.py +358 -0
  283. code_puppy_core_plugins/theme/prompt_toolkit_theme.py +113 -0
  284. code_puppy_core_plugins/theme/register_callbacks.py +348 -0
  285. code_puppy_core_plugins/theme/rich_themes.py +202 -0
  286. code_puppy_core_plugins/theme/themes.py +720 -0
  287. code_puppy_core_plugins/timestamp_heartbeat/__init__.py +1 -0
  288. code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +114 -0
  289. code_puppy_core_plugins/token_ratio_learner/__init__.py +5 -0
  290. code_puppy_core_plugins/token_ratio_learner/ratios.py +208 -0
  291. code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +213 -0
  292. code_puppy_core_plugins/universal_constructor/__init__.py +13 -0
  293. code_puppy_core_plugins/universal_constructor/models.py +138 -0
  294. code_puppy_core_plugins/universal_constructor/provider.py +62 -0
  295. code_puppy_core_plugins/universal_constructor/register_callbacks.py +75 -0
  296. code_puppy_core_plugins/universal_constructor/registry.py +302 -0
  297. code_puppy_core_plugins/universal_constructor/sandbox.py +584 -0
  298. code_puppy_core_plugins/wide_completion_menu/__init__.py +6 -0
  299. code_puppy_core_plugins/wide_completion_menu/register_callbacks.py +165 -0
  300. code_puppy_core_plugins/wiggum/__init__.py +1 -0
  301. code_puppy_core_plugins/wiggum/goal_runs.py +91 -0
  302. code_puppy_core_plugins/wiggum/judge.py +299 -0
  303. code_puppy_core_plugins/wiggum/judge_config.py +249 -0
  304. code_puppy_core_plugins/wiggum/judges_menu.py +814 -0
  305. code_puppy_core_plugins/wiggum/register_callbacks.py +569 -0
  306. code_puppy_core_plugins/wiggum/state.py +89 -0
  307. code_puppy_core_plugins/yolo_cli/__init__.py +1 -0
  308. code_puppy_core_plugins/yolo_cli/register_callbacks.py +41 -0
  309. code_puppy_core_plugins-0.0.2.dist-info/METADATA +64 -0
  310. code_puppy_core_plugins-0.0.2.dist-info/RECORD +313 -0
  311. code_puppy_core_plugins-0.0.2.dist-info/WHEEL +4 -0
  312. code_puppy_core_plugins-0.0.2.dist-info/entry_points.txt +55 -0
  313. code_puppy_core_plugins-0.0.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,409 @@
1
+ """Reasoning-opaque round-trip interceptor for Copilot Claude models.
2
+
3
+ The Copilot API returns two fields on Claude assistant messages:
4
+
5
+ - ``reasoning_text``: the model's chain-of-thought (human-readable)
6
+ - ``reasoning_opaque``: encrypted round-trip blob (**must** be echoed back)
7
+
8
+ pydantic-ai's ``openai_chat_send_back_thinking_parts="field"`` mode preserves
9
+ ``reasoning_text`` across tool calls, but it doesn't know about
10
+ ``reasoning_opaque``. The Copilot API returns **400 Bad Request** if
11
+ ``reasoning_text`` is sent without the accompanying ``reasoning_opaque``.
12
+
13
+ This module monkey-patches the httpx client to transparently:
14
+
15
+ 1. Capture ``reasoning_opaque`` (keyed by ``reasoning_text``) from responses
16
+ 2. Inject the matching ``reasoning_opaque`` into outgoing request messages
17
+
18
+ The approach mirrors the ``ChatGPTCodexAsyncClient`` pattern already in the codebase.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import hashlib
24
+ import json
25
+ import logging
26
+ from typing import Any, Dict
27
+
28
+ import httpx
29
+ from httpx import AsyncByteStream
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+ # Cap the cache so it can't grow forever across long sessions.
34
+ _MAX_CACHE_ENTRIES = 256
35
+
36
+
37
+ # ---------------------------------------------------------------------------
38
+ # Helpers
39
+ # ---------------------------------------------------------------------------
40
+
41
+
42
+ def _text_key(text: str) -> str:
43
+ """Short SHA-256 prefix — enough to avoid collisions in practice."""
44
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()[:32]
45
+
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Stream wrapper — captures opaque data as SSE events flow through
49
+ # ---------------------------------------------------------------------------
50
+
51
+
52
+ class _OpaqueCapturingStream(AsyncByteStream):
53
+ """Async byte-stream wrapper that taps ``reasoning_opaque`` from SSE.
54
+
55
+ Yields every byte unchanged so downstream consumers (the OpenAI SDK)
56
+ see the exact same data. Internally it buffers bytes, splits SSE
57
+ lines, parses JSON, and pairs ``reasoning_text`` chunks with
58
+ ``reasoning_opaque`` chunks for storage in *opaque_cache*.
59
+
60
+ Inherits from ``httpx.AsyncByteStream`` so that
61
+ ``httpx.Response.aclose()`` recognises us as an async stream and
62
+ doesn't blow up with *"Attempted to call an async close on an sync
63
+ stream"*. Ask me how I know.
64
+ """
65
+
66
+ def __init__(
67
+ self,
68
+ inner_stream: Any,
69
+ opaque_cache: Dict[str, str],
70
+ thinking_field: str,
71
+ ):
72
+ self._inner = inner_stream
73
+ self._opaque_cache = opaque_cache
74
+ self._thinking_field = thinking_field
75
+ self._buffer = ""
76
+ self._text_parts: list[str] = []
77
+ self._opaque_parts: list[str] = []
78
+
79
+ # -- async-iterator protocol ------------------------------------------
80
+
81
+ def __aiter__(self):
82
+ return self._iter_impl()
83
+
84
+ async def _iter_impl(self):
85
+ try:
86
+ async for chunk in self._inner:
87
+ self._feed(chunk)
88
+ yield chunk
89
+ finally:
90
+ self._flush()
91
+
92
+ async def aclose(self):
93
+ self._flush()
94
+ if hasattr(self._inner, "aclose"):
95
+ await self._inner.aclose()
96
+
97
+ # Fallback for any attributes we don't explicitly handle.
98
+ def __getattr__(self, name: str):
99
+ return getattr(self._inner, name)
100
+
101
+ # -- SSE parsing -------------------------------------------------------
102
+
103
+ def _feed(self, chunk: bytes) -> None:
104
+ self._buffer += chunk.decode("utf-8", errors="replace")
105
+ self._process_buffer()
106
+
107
+ def _process_buffer(self) -> None:
108
+ while "\n" in self._buffer:
109
+ line, self._buffer = self._buffer.split("\n", 1)
110
+ line = line.strip()
111
+ if not line.startswith("data: "):
112
+ continue
113
+ data_str = line[6:]
114
+ if data_str == "[DONE]":
115
+ self._flush()
116
+ continue
117
+ try:
118
+ event = json.loads(data_str)
119
+ self._extract_from_event(event)
120
+ except (json.JSONDecodeError, TypeError):
121
+ pass
122
+
123
+ def _extract_from_event(self, event: dict) -> None:
124
+ for choice in event.get("choices", []):
125
+ # Streaming deltas
126
+ delta = choice.get("delta") or {}
127
+ self._collect(delta)
128
+ # Non-streaming message (fallback)
129
+ message = choice.get("message") or {}
130
+ self._collect(message)
131
+ # Flush when the model signals it's done with this turn
132
+ if choice.get("finish_reason"):
133
+ self._flush()
134
+
135
+ def _collect(self, obj: dict) -> None:
136
+ text_chunk = obj.get(self._thinking_field)
137
+ if text_chunk:
138
+ self._text_parts.append(text_chunk)
139
+ opaque_chunk = obj.get("reasoning_opaque")
140
+ if opaque_chunk:
141
+ self._opaque_parts.append(opaque_chunk)
142
+
143
+ def _flush(self) -> None:
144
+ if self._opaque_parts and self._text_parts:
145
+ text = "".join(self._text_parts)
146
+ opaque = "".join(self._opaque_parts)
147
+ key = _text_key(text)
148
+ self._opaque_cache[key] = opaque
149
+ logger.debug(
150
+ "Captured reasoning_opaque (%d chars) for key %.8s…",
151
+ len(opaque),
152
+ key,
153
+ )
154
+ # Evict oldest entry if we exceed the cap.
155
+ while len(self._opaque_cache) > _MAX_CACHE_ENTRIES:
156
+ first_key = next(iter(self._opaque_cache))
157
+ del self._opaque_cache[first_key]
158
+ self._text_parts = []
159
+ self._opaque_parts = []
160
+
161
+
162
+ # ---------------------------------------------------------------------------
163
+ # Non-streaming capture (safety net)
164
+ # ---------------------------------------------------------------------------
165
+
166
+
167
+ def _capture_from_content(
168
+ content: bytes,
169
+ opaque_cache: Dict[str, str],
170
+ thinking_field: str,
171
+ ) -> None:
172
+ """Extract ``reasoning_opaque`` from an already-read response body."""
173
+ try:
174
+ data = json.loads(content)
175
+ for choice in data.get("choices", []):
176
+ msg = choice.get("message") or {}
177
+ text = msg.get(thinking_field)
178
+ opaque = msg.get("reasoning_opaque")
179
+ if text and opaque:
180
+ opaque_cache[_text_key(text)] = opaque
181
+ except (json.JSONDecodeError, TypeError, AttributeError):
182
+ pass
183
+
184
+
185
+ # ---------------------------------------------------------------------------
186
+ # Request-side injection
187
+ # ---------------------------------------------------------------------------
188
+
189
+
190
+ def _rebuild_request_body(
191
+ request: httpx.Request,
192
+ body: dict,
193
+ client: httpx.AsyncClient,
194
+ ) -> None:
195
+ """Replace the request body in-place (mirrors ChatGPTCodexAsyncClient)."""
196
+ new_body = json.dumps(body).encode("utf-8")
197
+ rebuilt = client.build_request(
198
+ method=request.method,
199
+ url=request.url,
200
+ headers=request.headers,
201
+ content=new_body,
202
+ )
203
+ if hasattr(rebuilt, "_content"):
204
+ request._content = rebuilt._content # type: ignore[attr-defined]
205
+ if hasattr(rebuilt, "stream"):
206
+ request.stream = rebuilt.stream
207
+ if hasattr(rebuilt, "extensions"):
208
+ request.extensions = rebuilt.extensions
209
+ request.headers["Content-Length"] = str(len(new_body))
210
+
211
+
212
+ def _inject_opaque_into_request(
213
+ request: httpx.Request,
214
+ opaque_cache: Dict[str, str],
215
+ client: httpx.AsyncClient,
216
+ thinking_field: str,
217
+ ) -> None:
218
+ """Add stored ``reasoning_opaque`` to assistant messages that need it.
219
+
220
+ **Prevention layer**: if we can't find a matching opaque for a
221
+ ``reasoning_text``, we strip that field entirely rather than sending
222
+ it bare (which would trigger a 400).
223
+ """
224
+ try:
225
+ body_bytes = request.content
226
+ if not body_bytes:
227
+ return
228
+
229
+ body = json.loads(body_bytes)
230
+ if not isinstance(body, dict):
231
+ return
232
+
233
+ messages = body.get("messages")
234
+ if not messages:
235
+ return
236
+
237
+ modified = False
238
+ injected = 0
239
+ stripped = 0
240
+
241
+ for msg in messages:
242
+ if not isinstance(msg, dict):
243
+ continue
244
+ if msg.get("role") != "assistant":
245
+ continue
246
+ if thinking_field not in msg:
247
+ continue
248
+ if "reasoning_opaque" in msg:
249
+ # Already has opaque — don't touch.
250
+ continue
251
+
252
+ key = _text_key(msg[thinking_field])
253
+ opaque = opaque_cache.get(key)
254
+ if opaque:
255
+ msg["reasoning_opaque"] = opaque
256
+ modified = True
257
+ injected += 1
258
+ else:
259
+ # SAFETY: no matching opaque → strip reasoning_text to avoid the 400;
260
+ # losing thinking context beats crashing the conversation.
261
+ del msg[thinking_field]
262
+ modified = True
263
+ stripped += 1
264
+ logger.debug(
265
+ "Stripped orphaned %s (no opaque in cache)",
266
+ thinking_field,
267
+ )
268
+
269
+ if not modified:
270
+ return
271
+
272
+ _rebuild_request_body(request, body, client)
273
+
274
+ if injected:
275
+ logger.debug(
276
+ "Injected reasoning_opaque into %d assistant message(s)",
277
+ injected,
278
+ )
279
+ if stripped:
280
+ logger.debug(
281
+ "Stripped %d orphaned %s field(s) (cache miss)",
282
+ stripped,
283
+ thinking_field,
284
+ )
285
+ except Exception as exc:
286
+ # Never crash the real request.
287
+ logger.debug("Failed to inject reasoning_opaque: %s", exc)
288
+
289
+
290
+ def _strip_all_reasoning_fields(
291
+ request: httpx.Request,
292
+ client: httpx.AsyncClient,
293
+ thinking_field: str,
294
+ ) -> bool:
295
+ """Remove ALL reasoning fields from the request body.
296
+
297
+ **Recovery layer**: called after a 400 to retry without any reasoning
298
+ context. Degrades gracefully to the old ``send_back_thinking_parts=False``
299
+ behaviour — thinking disappears after tool calls, but the conversation
300
+ keeps working.
301
+
302
+ Returns True if the body was modified.
303
+ """
304
+ try:
305
+ body_bytes = request.content
306
+ if not body_bytes:
307
+ return False
308
+
309
+ body = json.loads(body_bytes)
310
+ if not isinstance(body, dict):
311
+ return False
312
+
313
+ messages = body.get("messages")
314
+ if not messages:
315
+ return False
316
+
317
+ modified = False
318
+ for msg in messages:
319
+ if not isinstance(msg, dict):
320
+ continue
321
+ if msg.get("role") != "assistant":
322
+ continue
323
+ for field in (thinking_field, "reasoning_opaque"):
324
+ if field in msg:
325
+ del msg[field]
326
+ modified = True
327
+
328
+ if modified:
329
+ _rebuild_request_body(request, body, client)
330
+
331
+ return modified
332
+ except Exception as exc:
333
+ logger.debug("Failed to strip reasoning fields: %s", exc)
334
+ return False
335
+
336
+
337
+ # ---------------------------------------------------------------------------
338
+ # Public API — single entry-point
339
+ # ---------------------------------------------------------------------------
340
+
341
+
342
+ def patch_client_for_reasoning_opaque(
343
+ client: httpx.AsyncClient,
344
+ thinking_field: str = "reasoning_text",
345
+ ) -> None:
346
+ """Monkey-patch *client* to round-trip ``reasoning_opaque`` transparently.
347
+
348
+ Call **after** creating the client but **before** handing it to
349
+ ``OpenAIProvider``. Works with plain ``httpx.AsyncClient`` and the
350
+ ``RetryingAsyncClient`` subclass returned by ``create_async_client``.
351
+
352
+ Args:
353
+ client: The httpx async client to patch.
354
+ thinking_field: JSON field name that carries the thinking content
355
+ (default ``"reasoning_text"`` — the Copilot Claude convention).
356
+ """
357
+ opaque_cache: Dict[str, str] = {}
358
+ original_send = client.send
359
+
360
+ async def _patched_send(
361
+ request: httpx.Request, *args: Any, **kwargs: Any
362
+ ) -> httpx.Response:
363
+ # 1) Inject reasoning_opaque into outgoing POST bodies.
364
+ # Also strips orphaned reasoning_text with no cached opaque.
365
+ if request.method == "POST":
366
+ _inject_opaque_into_request(request, opaque_cache, client, thinking_field)
367
+
368
+ # 2) Let the real send (incl. auth + retries) run.
369
+ response = await original_send(request, *args, **kwargs)
370
+
371
+ # 3) RECOVERY: still 400 → reasoning fields likely stale; strip them all and
372
+ # retry once (degrades to "no thinking after tool calls" but keeps the convo
373
+ # alive).
374
+ if response.status_code == 400 and request.method == "POST":
375
+ # Read the error body for diagnostics before retrying.
376
+ try:
377
+ err_body = response.content.decode("utf-8", errors="replace")
378
+ except Exception:
379
+ err_body = "<unreadable>"
380
+ logger.warning(
381
+ "Copilot 400 — attempting recovery by stripping reasoning "
382
+ "fields and retrying. Error: %.300s",
383
+ err_body,
384
+ )
385
+ if _strip_all_reasoning_fields(request, client, thinking_field):
386
+ response = await original_send(request, *args, **kwargs)
387
+ if response.status_code == 200:
388
+ logger.info(
389
+ "Recovery succeeded — reasoning stripped, "
390
+ "conversation continues without thinking context."
391
+ )
392
+ else:
393
+ logger.warning(
394
+ "Recovery retry also failed (%d) — returning retry response.",
395
+ response.status_code,
396
+ )
397
+
398
+ # 4) Capture reasoning_opaque from successful responses.
399
+ if response.status_code == 200:
400
+ if response.is_stream_consumed:
401
+ _capture_from_content(response.content, opaque_cache, thinking_field)
402
+ elif hasattr(response, "stream") and response.stream is not None:
403
+ response.stream = _OpaqueCapturingStream(
404
+ response.stream, opaque_cache, thinking_field
405
+ )
406
+
407
+ return response
408
+
409
+ client.send = _patched_send # type: ignore[method-assign]