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.
- code_puppy_core_plugins/__init__.py +5 -0
- code_puppy_core_plugins/acp/README.md +266 -0
- code_puppy_core_plugins/acp/__init__.py +8 -0
- code_puppy_core_plugins/acp/agent.py +494 -0
- code_puppy_core_plugins/acp/bridge.py +309 -0
- code_puppy_core_plugins/acp/capabilities.py +73 -0
- code_puppy_core_plugins/acp/commands.py +116 -0
- code_puppy_core_plugins/acp/content.py +115 -0
- code_puppy_core_plugins/acp/io_delegation.py +231 -0
- code_puppy_core_plugins/acp/mcp_config.py +66 -0
- code_puppy_core_plugins/acp/permissions.py +159 -0
- code_puppy_core_plugins/acp/persistence.py +197 -0
- code_puppy_core_plugins/acp/register_callbacks.py +110 -0
- code_puppy_core_plugins/acp/replay.py +114 -0
- code_puppy_core_plugins/acp/session.py +329 -0
- code_puppy_core_plugins/acp/session_config.py +179 -0
- code_puppy_core_plugins/acp/state.py +135 -0
- code_puppy_core_plugins/agent_skills/__init__.py +22 -0
- code_puppy_core_plugins/agent_skills/config.py +208 -0
- code_puppy_core_plugins/agent_skills/discovery.py +337 -0
- code_puppy_core_plugins/agent_skills/downloader.py +392 -0
- code_puppy_core_plugins/agent_skills/enabled_skills.py +82 -0
- code_puppy_core_plugins/agent_skills/installer.py +22 -0
- code_puppy_core_plugins/agent_skills/metadata.py +219 -0
- code_puppy_core_plugins/agent_skills/prompt_builder.py +49 -0
- code_puppy_core_plugins/agent_skills/provider.py +52 -0
- code_puppy_core_plugins/agent_skills/register_callbacks.py +309 -0
- code_puppy_core_plugins/agent_skills/remote_catalog.py +322 -0
- code_puppy_core_plugins/agent_skills/skill_catalog.py +257 -0
- code_puppy_core_plugins/agent_skills/skill_commands.py +102 -0
- code_puppy_core_plugins/agent_skills/skills_install_menu.py +698 -0
- code_puppy_core_plugins/agent_skills/skills_menu.py +794 -0
- code_puppy_core_plugins/aws_bedrock/__init__.py +14 -0
- code_puppy_core_plugins/aws_bedrock/config.py +101 -0
- code_puppy_core_plugins/aws_bedrock/register_callbacks.py +243 -0
- code_puppy_core_plugins/aws_bedrock/utils.py +186 -0
- code_puppy_core_plugins/azure_foundry/README.md +238 -0
- code_puppy_core_plugins/azure_foundry/__init__.py +15 -0
- code_puppy_core_plugins/azure_foundry/config.py +126 -0
- code_puppy_core_plugins/azure_foundry/discovery.py +189 -0
- code_puppy_core_plugins/azure_foundry/register_callbacks.py +506 -0
- code_puppy_core_plugins/azure_foundry/token.py +182 -0
- code_puppy_core_plugins/azure_foundry/utils.py +375 -0
- code_puppy_core_plugins/btw/__init__.py +1 -0
- code_puppy_core_plugins/btw/inline_view.py +135 -0
- code_puppy_core_plugins/btw/register_callbacks.py +106 -0
- code_puppy_core_plugins/btw/side_query.py +91 -0
- code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +83 -0
- code_puppy_core_plugins/chatgpt_oauth/__init__.py +8 -0
- code_puppy_core_plugins/chatgpt_oauth/config.py +52 -0
- code_puppy_core_plugins/chatgpt_oauth/image_generation.py +253 -0
- code_puppy_core_plugins/chatgpt_oauth/image_tool.py +70 -0
- code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +461 -0
- code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +288 -0
- code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +663 -0
- code_puppy_core_plugins/chatgpt_oauth/usage.py +113 -0
- code_puppy_core_plugins/chatgpt_oauth/utils.py +534 -0
- code_puppy_core_plugins/claude_code_hooks/__init__.py +1 -0
- code_puppy_core_plugins/claude_code_hooks/config.py +137 -0
- code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +383 -0
- code_puppy_core_plugins/claude_code_oauth/README.md +167 -0
- code_puppy_core_plugins/claude_code_oauth/SETUP.md +93 -0
- code_puppy_core_plugins/claude_code_oauth/__init__.py +25 -0
- code_puppy_core_plugins/claude_code_oauth/config.py +59 -0
- code_puppy_core_plugins/claude_code_oauth/fast_mode.py +122 -0
- code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +64 -0
- code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +719 -0
- code_puppy_core_plugins/claude_code_oauth/test_plugin.py +285 -0
- code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +240 -0
- code_puppy_core_plugins/claude_code_oauth/utils.py +663 -0
- code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +155 -0
- code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +104 -0
- code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +147 -0
- code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +39 -0
- code_puppy_core_plugins/code_puppy_agent/SKILL.md +180 -0
- code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +136 -0
- code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +160 -0
- code_puppy_core_plugins/code_puppy_agent/__init__.py +5 -0
- code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +46 -0
- code_puppy_core_plugins/computer_use/NativeCapture.swift +123 -0
- code_puppy_core_plugins/computer_use/README.md +109 -0
- code_puppy_core_plugins/computer_use/__init__.py +1 -0
- code_puppy_core_plugins/computer_use/accessibility.py +163 -0
- code_puppy_core_plugins/computer_use/activation.py +75 -0
- code_puppy_core_plugins/computer_use/backend.py +584 -0
- code_puppy_core_plugins/computer_use/backend_types.py +5 -0
- code_puppy_core_plugins/computer_use/capture.py +110 -0
- code_puppy_core_plugins/computer_use/commands.py +62 -0
- code_puppy_core_plugins/computer_use/geometry.py +81 -0
- code_puppy_core_plugins/computer_use/inline_image.py +56 -0
- code_puppy_core_plugins/computer_use/keycodes.py +47 -0
- code_puppy_core_plugins/computer_use/policy.py +144 -0
- code_puppy_core_plugins/computer_use/register_callbacks.py +96 -0
- code_puppy_core_plugins/computer_use/safety.py +18 -0
- code_puppy_core_plugins/computer_use/settle.py +64 -0
- code_puppy_core_plugins/computer_use/state.py +86 -0
- code_puppy_core_plugins/computer_use/tools.py +469 -0
- code_puppy_core_plugins/context_indicator/__init__.py +14 -0
- code_puppy_core_plugins/context_indicator/register_callbacks.py +249 -0
- code_puppy_core_plugins/context_indicator/usage.py +40 -0
- code_puppy_core_plugins/copilot_auth/__init__.py +11 -0
- code_puppy_core_plugins/copilot_auth/config.py +93 -0
- code_puppy_core_plugins/copilot_auth/reasoning_client.py +409 -0
- code_puppy_core_plugins/copilot_auth/register_callbacks.py +460 -0
- code_puppy_core_plugins/copilot_auth/utils.py +587 -0
- code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
- code_puppy_core_plugins/customizable_commands/register_callbacks.py +464 -0
- code_puppy_core_plugins/dbos_durable_exec/__init__.py +1 -0
- code_puppy_core_plugins/dbos_durable_exec/cancel.py +15 -0
- code_puppy_core_plugins/dbos_durable_exec/commands.py +31 -0
- code_puppy_core_plugins/dbos_durable_exec/config.py +31 -0
- code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +83 -0
- code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +45 -0
- code_puppy_core_plugins/dbos_durable_exec/runtime.py +65 -0
- code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +155 -0
- code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +16 -0
- code_puppy_core_plugins/dbos_durable_exec/wrapper.py +58 -0
- code_puppy_core_plugins/destructive_command_guard/AGENTS.md +79 -0
- code_puppy_core_plugins/destructive_command_guard/__init__.py +14 -0
- code_puppy_core_plugins/destructive_command_guard/detector.py +374 -0
- code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +165 -0
- code_puppy_core_plugins/emoji_filter/__init__.py +12 -0
- code_puppy_core_plugins/emoji_filter/config.py +26 -0
- code_puppy_core_plugins/emoji_filter/register_callbacks.py +238 -0
- code_puppy_core_plugins/emoji_filter/stripper.py +45 -0
- code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +116 -0
- code_puppy_core_plugins/example_custom_command/README.md +328 -0
- code_puppy_core_plugins/example_custom_command/register_callbacks.py +66 -0
- code_puppy_core_plugins/file_permission_handler/__init__.py +4 -0
- code_puppy_core_plugins/file_permission_handler/register_callbacks.py +575 -0
- code_puppy_core_plugins/flux_bootstrap/__init__.py +5 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +173 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +86 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +167 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +392 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +51 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +129 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +211 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +181 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +71 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +16 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +103 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +108 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +195 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +221 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +151 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +208 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +180 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +304 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +120 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +179 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +46 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +155 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +154 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +248 -0
- code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +345 -0
- code_puppy_core_plugins/flux_bootstrap/installer.py +256 -0
- code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +71 -0
- code_puppy_core_plugins/force_push_guard/__init__.py +5 -0
- code_puppy_core_plugins/force_push_guard/detector.py +96 -0
- code_puppy_core_plugins/force_push_guard/register_callbacks.py +161 -0
- code_puppy_core_plugins/fork/__init__.py +7 -0
- code_puppy_core_plugins/fork/register_callbacks.py +445 -0
- code_puppy_core_plugins/frontend_emitter/__init__.py +25 -0
- code_puppy_core_plugins/frontend_emitter/emitter.py +249 -0
- code_puppy_core_plugins/frontend_emitter/register_callbacks.py +412 -0
- code_puppy_core_plugins/frontend_emitter/session_context.py +50 -0
- code_puppy_core_plugins/grok_oauth/__init__.py +6 -0
- code_puppy_core_plugins/grok_oauth/config.py +49 -0
- code_puppy_core_plugins/grok_oauth/oauth_flow.py +213 -0
- code_puppy_core_plugins/grok_oauth/register_callbacks.py +132 -0
- code_puppy_core_plugins/grok_oauth/utils.py +195 -0
- code_puppy_core_plugins/herdr/README.md +168 -0
- code_puppy_core_plugins/herdr/__init__.py +9 -0
- code_puppy_core_plugins/herdr/client.py +339 -0
- code_puppy_core_plugins/herdr/register_callbacks.py +140 -0
- code_puppy_core_plugins/herdr/reporter.py +212 -0
- code_puppy_core_plugins/herdr/smoke.py +143 -0
- code_puppy_core_plugins/herdr/sources.py +133 -0
- code_puppy_core_plugins/hook_creator/__init__.py +1 -0
- code_puppy_core_plugins/hook_creator/register_callbacks.py +33 -0
- code_puppy_core_plugins/hook_manager/__init__.py +1 -0
- code_puppy_core_plugins/hook_manager/config.py +290 -0
- code_puppy_core_plugins/hook_manager/hooks_menu.py +571 -0
- code_puppy_core_plugins/hook_manager/register_callbacks.py +227 -0
- code_puppy_core_plugins/meta_oauth/__init__.py +1 -0
- code_puppy_core_plugins/meta_oauth/config.py +55 -0
- code_puppy_core_plugins/meta_oauth/oauth_flow.py +109 -0
- code_puppy_core_plugins/meta_oauth/register_callbacks.py +154 -0
- code_puppy_core_plugins/meta_oauth/utils.py +252 -0
- code_puppy_core_plugins/namespace_skill_search/README.md +118 -0
- code_puppy_core_plugins/namespace_skill_search/__init__.py +15 -0
- code_puppy_core_plugins/namespace_skill_search/namespaces.py +125 -0
- code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +99 -0
- code_puppy_core_plugins/namespace_skill_search/search_tool.py +158 -0
- code_puppy_core_plugins/no_tools/__init__.py +0 -0
- code_puppy_core_plugins/no_tools/register_callbacks.py +42 -0
- code_puppy_core_plugins/oauth_pasteback.py +110 -0
- code_puppy_core_plugins/oauth_puppy_html.py +194 -0
- code_puppy_core_plugins/obsidian_agent/README.md +52 -0
- code_puppy_core_plugins/obsidian_agent/__init__.py +8 -0
- code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +147 -0
- code_puppy_core_plugins/obsidian_agent/register_callbacks.py +13 -0
- code_puppy_core_plugins/ollama/__init__.py +1 -0
- code_puppy_core_plugins/ollama/register_callbacks.py +127 -0
- code_puppy_core_plugins/ollama_setup/__init__.py +5 -0
- code_puppy_core_plugins/ollama_setup/completer.py +38 -0
- code_puppy_core_plugins/ollama_setup/register_callbacks.py +419 -0
- code_puppy_core_plugins/plugin_list/__init__.py +0 -0
- code_puppy_core_plugins/plugin_list/plugin_contributions.py +348 -0
- code_puppy_core_plugins/plugin_list/plugin_meta.py +67 -0
- code_puppy_core_plugins/plugin_list/plugin_text_utils.py +173 -0
- code_puppy_core_plugins/plugin_list/plugins_menu.py +455 -0
- code_puppy_core_plugins/plugin_list/plugins_menu_layout.py +194 -0
- code_puppy_core_plugins/plugin_list/plugins_menu_render.py +431 -0
- code_puppy_core_plugins/plugin_list/project_trust_flow.py +162 -0
- code_puppy_core_plugins/plugin_list/register_callbacks.py +281 -0
- code_puppy_core_plugins/pop_command/__init__.py +1 -0
- code_puppy_core_plugins/pop_command/register_callbacks.py +191 -0
- code_puppy_core_plugins/prompt_newline/__init__.py +13 -0
- code_puppy_core_plugins/prompt_newline/config.py +21 -0
- code_puppy_core_plugins/prompt_newline/register_callbacks.py +163 -0
- code_puppy_core_plugins/prune/__init__.py +1 -0
- code_puppy_core_plugins/prune/prune_menu.py +308 -0
- code_puppy_core_plugins/prune/prune_model.py +517 -0
- code_puppy_core_plugins/prune/prune_render.py +354 -0
- code_puppy_core_plugins/prune/register_callbacks.py +388 -0
- code_puppy_core_plugins/puppy_kennel/README.md +203 -0
- code_puppy_core_plugins/puppy_kennel/__init__.py +6 -0
- code_puppy_core_plugins/puppy_kennel/commands.py +206 -0
- code_puppy_core_plugins/puppy_kennel/config.py +36 -0
- code_puppy_core_plugins/puppy_kennel/kennel.py +368 -0
- code_puppy_core_plugins/puppy_kennel/packer.py +152 -0
- code_puppy_core_plugins/puppy_kennel/recorder.py +83 -0
- code_puppy_core_plugins/puppy_kennel/register_callbacks.py +109 -0
- code_puppy_core_plugins/puppy_kennel/retriever.py +28 -0
- code_puppy_core_plugins/puppy_kennel/schema.py +78 -0
- code_puppy_core_plugins/puppy_kennel/state.py +68 -0
- code_puppy_core_plugins/puppy_kennel/tools.py +449 -0
- code_puppy_core_plugins/puppy_kennel/wings.py +110 -0
- code_puppy_core_plugins/puppy_spinner/README.md +93 -0
- code_puppy_core_plugins/puppy_spinner/__init__.py +11 -0
- code_puppy_core_plugins/puppy_spinner/builtin_frames.py +172 -0
- code_puppy_core_plugins/puppy_spinner/commands.py +116 -0
- code_puppy_core_plugins/puppy_spinner/picker.py +379 -0
- code_puppy_core_plugins/puppy_spinner/register_callbacks.py +193 -0
- code_puppy_core_plugins/puppy_spinner/spinners.py +444 -0
- code_puppy_core_plugins/quick_resume/__init__.py +0 -0
- code_puppy_core_plugins/quick_resume/register_callbacks.py +77 -0
- code_puppy_core_plugins/review_pr/__init__.py +1 -0
- code_puppy_core_plugins/review_pr/register_callbacks.py +162 -0
- code_puppy_core_plugins/shell_safety/__init__.py +6 -0
- code_puppy_core_plugins/shell_safety/agent_shell_safety.py +69 -0
- code_puppy_core_plugins/shell_safety/command_cache.py +156 -0
- code_puppy_core_plugins/shell_safety/register_callbacks.py +203 -0
- code_puppy_core_plugins/stack_dump/__init__.py +1 -0
- code_puppy_core_plugins/stack_dump/register_callbacks.py +79 -0
- code_puppy_core_plugins/statusline/__init__.py +14 -0
- code_puppy_core_plugins/statusline/config.py +68 -0
- code_puppy_core_plugins/statusline/payload.py +138 -0
- code_puppy_core_plugins/statusline/prompt_patch.py +76 -0
- code_puppy_core_plugins/statusline/register_callbacks.py +45 -0
- code_puppy_core_plugins/statusline/runner.py +122 -0
- code_puppy_core_plugins/statusline/statusline_command.py +197 -0
- code_puppy_core_plugins/steer_queue/__init__.py +10 -0
- code_puppy_core_plugins/steer_queue/queue_menu.py +444 -0
- code_puppy_core_plugins/steer_queue/register_callbacks.py +138 -0
- code_puppy_core_plugins/subagent_panel/README.md +102 -0
- code_puppy_core_plugins/subagent_panel/__init__.py +24 -0
- code_puppy_core_plugins/subagent_panel/coalesce_patch.py +242 -0
- code_puppy_core_plugins/subagent_panel/panel_render.py +145 -0
- code_puppy_core_plugins/subagent_panel/register_callbacks.py +535 -0
- code_puppy_core_plugins/subagent_panel/resume_repaint.py +112 -0
- code_puppy_core_plugins/subagent_panel/state.py +231 -0
- code_puppy_core_plugins/switch_agent_resume/__init__.py +5 -0
- code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +314 -0
- code_puppy_core_plugins/theme/README.md +86 -0
- code_puppy_core_plugins/theme/__init__.py +14 -0
- code_puppy_core_plugins/theme/bundled_palettes.py +346 -0
- code_puppy_core_plugins/theme/content_styles.py +146 -0
- code_puppy_core_plugins/theme/osc_palette.py +178 -0
- code_puppy_core_plugins/theme/picker.py +358 -0
- code_puppy_core_plugins/theme/prompt_toolkit_theme.py +113 -0
- code_puppy_core_plugins/theme/register_callbacks.py +348 -0
- code_puppy_core_plugins/theme/rich_themes.py +202 -0
- code_puppy_core_plugins/theme/themes.py +720 -0
- code_puppy_core_plugins/timestamp_heartbeat/__init__.py +1 -0
- code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +114 -0
- code_puppy_core_plugins/token_ratio_learner/__init__.py +5 -0
- code_puppy_core_plugins/token_ratio_learner/ratios.py +208 -0
- code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +213 -0
- code_puppy_core_plugins/universal_constructor/__init__.py +13 -0
- code_puppy_core_plugins/universal_constructor/models.py +138 -0
- code_puppy_core_plugins/universal_constructor/provider.py +62 -0
- code_puppy_core_plugins/universal_constructor/register_callbacks.py +75 -0
- code_puppy_core_plugins/universal_constructor/registry.py +302 -0
- code_puppy_core_plugins/universal_constructor/sandbox.py +584 -0
- code_puppy_core_plugins/wide_completion_menu/__init__.py +6 -0
- code_puppy_core_plugins/wide_completion_menu/register_callbacks.py +165 -0
- code_puppy_core_plugins/wiggum/__init__.py +1 -0
- code_puppy_core_plugins/wiggum/goal_runs.py +91 -0
- code_puppy_core_plugins/wiggum/judge.py +299 -0
- code_puppy_core_plugins/wiggum/judge_config.py +249 -0
- code_puppy_core_plugins/wiggum/judges_menu.py +814 -0
- code_puppy_core_plugins/wiggum/register_callbacks.py +569 -0
- code_puppy_core_plugins/wiggum/state.py +89 -0
- code_puppy_core_plugins/yolo_cli/__init__.py +1 -0
- code_puppy_core_plugins/yolo_cli/register_callbacks.py +41 -0
- code_puppy_core_plugins-0.0.2.dist-info/METADATA +64 -0
- code_puppy_core_plugins-0.0.2.dist-info/RECORD +313 -0
- code_puppy_core_plugins-0.0.2.dist-info/WHEEL +4 -0
- code_puppy_core_plugins-0.0.2.dist-info/entry_points.txt +55 -0
- code_puppy_core_plugins-0.0.2.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Agent & Tool System
|
|
2
|
+
|
|
3
|
+
> Part of the `code-puppy-agent` skill. Read this when you need to
|
|
4
|
+
> understand how agents are structured/discovered, or how tools get
|
|
5
|
+
> registered and wired to an agent. See `SKILL.md` for the overview and
|
|
6
|
+
> the full reference map.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Agent System
|
|
11
|
+
|
|
12
|
+
### BaseAgent (`agents/base_agent.py`)
|
|
13
|
+
|
|
14
|
+
All agents inherit from `BaseAgent` (ABC). Key interface:
|
|
15
|
+
|
|
16
|
+
| Member | Purpose |
|
|
17
|
+
|--------|---------|
|
|
18
|
+
| `name` (abstract property) | Stable machine identifier, e.g. `"code-puppy"` |
|
|
19
|
+
| `display_name` (abstract property) | Human name with emoji |
|
|
20
|
+
| `description` (abstract property) | One-line summary |
|
|
21
|
+
| `get_system_prompt()` (abstract) | The authored system prompt (identity is appended separately at runtime) |
|
|
22
|
+
| `get_available_tools()` (abstract) | List of tool-name strings from `TOOL_REGISTRY` |
|
|
23
|
+
| `get_model_name()` | Effective model: runtime override > pinned > global |
|
|
24
|
+
| `get_full_system_prompt()` | Authored prompt + `load_prompt` plugin fragments + identity ID |
|
|
25
|
+
|
|
26
|
+
`BaseAgent` is a **thin conductor**. Real logic lives in sibling modules:
|
|
27
|
+
- `_builder.py` — builds the pydantic-ai `Agent`, wires MCP toolsets
|
|
28
|
+
- `_runtime.py` — `run_with_mcp()` orchestration, cancellation, retries
|
|
29
|
+
- `_history.py` — token estimation, hashing, orphan pruning
|
|
30
|
+
- `_compaction.py` — summarization/truncation when context overflows
|
|
31
|
+
|
|
32
|
+
### Agent Types
|
|
33
|
+
|
|
34
|
+
**Python agents** — classes in `agents/` discovered automatically by
|
|
35
|
+
`agent_manager._discover_agents()` via `pkgutil.iter_modules`. Any
|
|
36
|
+
`BaseAgent` subclass (excluding `JSONAgent` itself) in a non-underscore
|
|
37
|
+
module gets registered.
|
|
38
|
+
|
|
39
|
+
**JSON agents** — `JSONAgent` loads from `~/.code_puppy/agents/*.json`
|
|
40
|
+
(user) and `<CWD>/.code_puppy/agents/*.json` (project). Project overrides
|
|
41
|
+
user on name collision. Required fields: `name`, `description`,
|
|
42
|
+
`system_prompt`, `tools`. Optional: `display_name`, `user_prompt`,
|
|
43
|
+
`tools_config`, `model`, `mcp_servers`.
|
|
44
|
+
|
|
45
|
+
**Plugin agents** — registered via the `register_agents` callback, which
|
|
46
|
+
returns `[{"name": "...", "class": SomeAgentClass}]` (or
|
|
47
|
+
`{"name": ..., "json_path": ".../agent.json"}`).
|
|
48
|
+
|
|
49
|
+
**Discovery & precedence** — `_discover_agents()` runs three phases:
|
|
50
|
+
|
|
51
|
+
1. Builtin Python classes (`pkgutil` scan of `agents/`).
|
|
52
|
+
2. JSON agents via `discover_json_agents()`: the **user** dir is scanned
|
|
53
|
+
first, then the **project** dir overwrites it on collision, so **project
|
|
54
|
+
wins over user**. Both are skipped if a builtin Python agent already owns
|
|
55
|
+
the name (builtin beats JSON).
|
|
56
|
+
3. Plugin-registered agents via `on_register_agents()` — these overwrite
|
|
57
|
+
`_AGENT_REGISTRY` **unconditionally**, so a plugin agent can shadow a
|
|
58
|
+
builtin. Register under a unique name.
|
|
59
|
+
|
|
60
|
+
Net precedence: **builtin Python > JSON project > JSON user**; plugin
|
|
61
|
+
agents are last-writer-wins (handled after the others, no collision guard).
|
|
62
|
+
|
|
63
|
+
### Agent Manager (`agents/agent_manager.py`)
|
|
64
|
+
|
|
65
|
+
- `get_current_agent()` — returns the active `BaseAgent` instance
|
|
66
|
+
- `set_current_agent(name)` — switches agent, preserves history
|
|
67
|
+
- `get_available_agents()` — dict of `name → display_name`
|
|
68
|
+
- `clone_agent()` — creates a copy of the current agent
|
|
69
|
+
|
|
70
|
+
Agent selection persists per **terminal session** (keyed by PPID) in
|
|
71
|
+
`terminal_sessions.json` so different terminals can run different agents.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Tool System
|
|
76
|
+
|
|
77
|
+
### TOOL_REGISTRY (`tools/__init__.py`)
|
|
78
|
+
|
|
79
|
+
A flat dict mapping tool-name strings to registration functions:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
TOOL_REGISTRY = {
|
|
83
|
+
"read_file": register_read_file,
|
|
84
|
+
"create_file": register_create_file,
|
|
85
|
+
"replace_in_file": register_replace_in_file,
|
|
86
|
+
# ... 60+ tools
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Each `register_*` function takes a pydantic-ai `agent` and calls
|
|
91
|
+
`@agent.tool` to wire the tool's JSON schema.
|
|
92
|
+
|
|
93
|
+
### How tools are assigned
|
|
94
|
+
|
|
95
|
+
`register_tools_for_agent(agent, tool_names, agent_name=...)` is called
|
|
96
|
+
during agent build. It:
|
|
97
|
+
|
|
98
|
+
1. Loads plugin-registered tools via `on_register_tools()` → merges into `TOOL_REGISTRY`
|
|
99
|
+
2. Merges plugin-advertised tools via `on_register_agent_tools(agent_name)` → unions into the requested list
|
|
100
|
+
3. Expands compound tools (e.g. `"edit_file"` → `["create_file", "replace_in_file", "delete_snippet"]`)
|
|
101
|
+
4. Registers each tool by calling its `register_func(agent)`
|
|
102
|
+
|
|
103
|
+
### Built-in tool categories
|
|
104
|
+
|
|
105
|
+
| Category | Tools |
|
|
106
|
+
|----------|-------|
|
|
107
|
+
| **File ops** | `list_files`, `read_file`, `grep` |
|
|
108
|
+
| **File mods** | `create_file`, `replace_in_file`, `delete_snippet`, `delete_file` |
|
|
109
|
+
| **Shell** | `agent_run_shell_command`, `agent_share_your_reasoning` |
|
|
110
|
+
| **Sub-agents** | `list_agents`, `invoke_agent`, `invoke_agent_with_model` |
|
|
111
|
+
| **Skills** | `activate_skill`, `list_or_search_skills` |
|
|
112
|
+
| **User** | `ask_user_question`, `load_image_for_analysis` |
|
|
113
|
+
| **Browser** | 30+ `browser_*` tools (Playwright-backed) |
|
|
114
|
+
| **Models** | `list_available_models` |
|
|
115
|
+
| **UC** | `universal_constructor` (dynamic tool factory) |
|
|
116
|
+
|
|
117
|
+
### Plugin tools: two hooks, both required
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# 1. Define the tool (adds to TOOL_REGISTRY)
|
|
121
|
+
def _register_tools():
|
|
122
|
+
return [{"name": "my_tool", "register_func": register_my_tool}]
|
|
123
|
+
register_callback("register_tools", _register_tools)
|
|
124
|
+
|
|
125
|
+
# 2. Advertise it to agents (adds to agent's tool list)
|
|
126
|
+
def _advertise(agent_name=None):
|
|
127
|
+
return ["my_tool"]
|
|
128
|
+
register_callback("register_agent_tools", _advertise)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Step 1 makes the tool *exist*; step 2 makes agents *see* it. Both are
|
|
132
|
+
needed. `namespace_skill_search` (`code_puppy/plugins/namespace_skill_search/`)
|
|
133
|
+
is a small, complete example of this pattern for a single tool
|
|
134
|
+
(`browse_skill_namespace`) — see `SKILLS_SYSTEM.md` for what it does and
|
|
135
|
+
`PLUGINS_AND_CALLBACKS.md` for the callback-safety reasoning behind how
|
|
136
|
+
it's wired.
|
|
137
|
+
|
|
138
|
+
### Async tool functions and blocking I/O
|
|
139
|
+
|
|
140
|
+
Tool functions taking a `RunContext` (`activate_skill`,
|
|
141
|
+
`list_or_search_skills`, `browse_skill_namespace`) are conventionally
|
|
142
|
+
`async def` in this codebase. That matters for one non-obvious reason:
|
|
143
|
+
pydantic-ai only auto-offloads **synchronous** tool functions to a worker
|
|
144
|
+
thread (via `anyio.to_thread`); an `async def` tool runs directly on the
|
|
145
|
+
event loop. If your async tool does blocking filesystem/network I/O
|
|
146
|
+
(e.g. scanning a large directory tree), wrap the blocking call
|
|
147
|
+
explicitly:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
result = await asyncio.to_thread(blocking_function, *args)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`namespace_skill_search/search_tool.py` does exactly this around its
|
|
154
|
+
`build_namespaces()` call — a good reference implementation if you're
|
|
155
|
+
writing a new async tool with real I/O in it.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Model System & MCP Integration
|
|
2
|
+
|
|
3
|
+
> Part of the `code-puppy-agent` skill. Read this when working with model
|
|
4
|
+
> selection/config, or external MCP tool servers. See `SKILL.md` for the
|
|
5
|
+
> overview and the full reference map.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Model System
|
|
10
|
+
|
|
11
|
+
### ModelFactory (`model_factory.py`)
|
|
12
|
+
|
|
13
|
+
Resolves a model-name string into a pydantic-ai `Model` object.
|
|
14
|
+
Supports providers: OpenAI, Anthropic, Gemini, Cerebras, OpenRouter,
|
|
15
|
+
Azure, and custom OpenAI/Anthropic/Gemini-compatible endpoints.
|
|
16
|
+
|
|
17
|
+
### Model configuration
|
|
18
|
+
|
|
19
|
+
Models are defined in three places (merged at runtime):
|
|
20
|
+
|
|
21
|
+
1. **Built-in defaults** — hardcoded in the factory
|
|
22
|
+
2. **`~/.code_puppy/extra_models.json`** — user-defined custom models
|
|
23
|
+
3. **Plugin injection** — `load_models_config` callback returns a dict
|
|
24
|
+
|
|
25
|
+
Example `extra_models.json`:
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"my-model": {
|
|
29
|
+
"type": "custom_openai",
|
|
30
|
+
"name": "gpt-4o",
|
|
31
|
+
"custom_endpoint": {
|
|
32
|
+
"url": "https://api.example.com/v1",
|
|
33
|
+
"api_key": "$MY_API_KEY"
|
|
34
|
+
},
|
|
35
|
+
"context_length": 128000
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Model types
|
|
41
|
+
|
|
42
|
+
| Type | Provider |
|
|
43
|
+
|------|----------|
|
|
44
|
+
| `openai` / `openai_responses` | OpenAI |
|
|
45
|
+
| `anthropic` | Anthropic (Claude) |
|
|
46
|
+
| `gemini` | Google Gemini |
|
|
47
|
+
| `cerebras` | Cerebras (via CerebrasProvider) |
|
|
48
|
+
| `custom_openai` | Any OpenAI-compatible endpoint |
|
|
49
|
+
| `custom_anthropic` | Anthropic-compatible endpoint |
|
|
50
|
+
| `round_robin` | Cycle through N models (rate-limit mitigation) |
|
|
51
|
+
| Plugin types | Registered via `register_model_type` callback |
|
|
52
|
+
|
|
53
|
+
### Model selection precedence
|
|
54
|
+
|
|
55
|
+
For any agent: **runtime override > agent-pinned model > agent's `model`
|
|
56
|
+
field (JSON agents) > global model name**.
|
|
57
|
+
|
|
58
|
+
The global model is set via `/model` and stored in config.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## MCP Integration
|
|
63
|
+
|
|
64
|
+
### MCP Manager (`mcp_/manager.py`)
|
|
65
|
+
|
|
66
|
+
Code Puppy manages external MCP (Model Context Protocol) servers that
|
|
67
|
+
provide additional tools to agents. Key components:
|
|
68
|
+
|
|
69
|
+
- **Registry** (`mcp_/registry.py`) — server definitions (stdio/SSE/streamable-http)
|
|
70
|
+
- **Manager** (`mcp_/manager.py`) — lifecycle: start, stop, health checks
|
|
71
|
+
- **Agent bindings** (`mcp_/agent_bindings.py`) — which agents get which servers
|
|
72
|
+
- **Circuit breaker** (`mcp_/circuit_breaker.py`) — auto-disables flaky servers
|
|
73
|
+
|
|
74
|
+
### How MCP servers attach to agents
|
|
75
|
+
|
|
76
|
+
Servers can be:
|
|
77
|
+
1. **Globally started** — available to all agents
|
|
78
|
+
2. **Agent-bound** — declared in a JSON agent's `mcp_servers` field, or
|
|
79
|
+
bound via the `/mcp bind` menu
|
|
80
|
+
3. **Auto-started** — bound servers with `auto_start: true` start when the
|
|
81
|
+
agent runs
|
|
82
|
+
|
|
83
|
+
The `pre_mcp_autostart` hook fires before auto-start, letting plugins
|
|
84
|
+
refresh tokens or mint credentials.
|
|
85
|
+
|
|
86
|
+
### Managing MCP servers
|
|
87
|
+
|
|
88
|
+
Use `/mcp` in the TUI:
|
|
89
|
+
- `/mcp list` — show configured servers
|
|
90
|
+
- `/mcp start <name>` / `/mcp stop <name>`
|
|
91
|
+
- `/mcp status` — health dashboard
|
|
92
|
+
- `/mcp bind` — attach servers to agents
|
|
93
|
+
|
|
94
|
+
### MCP servers as skill providers — a known gap, not yet implemented
|
|
95
|
+
|
|
96
|
+
Skills today are discovered only by filesystem scan (see
|
|
97
|
+
`SKILLS_SYSTEM.md`) or via the `register_skills` callback. There is
|
|
98
|
+
currently **no** mechanism for a bound MCP server to advertise skills of
|
|
99
|
+
its own (e.g. a hypothetical `skill_provider` capability exposing
|
|
100
|
+
`list_skills`/`get_skill`/`search_skills`) — skills served that way would
|
|
101
|
+
just look like ordinary tool results, not first-class skills appearing in
|
|
102
|
+
`/skills list` or `activate_skill`-able. If you're evaluating whether to
|
|
103
|
+
build this, that's new platform work, not something `namespace_skill_search`
|
|
104
|
+
or the existing skill-discovery code already covers.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Plugin & Callback System
|
|
2
|
+
|
|
3
|
+
> Part of the `code-puppy-agent` skill. Read this before writing a new
|
|
4
|
+
> plugin, or when debugging why a hook isn't firing / is being
|
|
5
|
+
> overwritten. See `SKILL.md` for the overview and the full reference map.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Plugin discovery (three tiers)
|
|
10
|
+
|
|
11
|
+
| Tier | Location | Load order |
|
|
12
|
+
|------|----------|------------|
|
|
13
|
+
| **Builtin** | `code_puppy/plugins/<name>/register_callbacks.py` | 1st |
|
|
14
|
+
| **User** | `~/.code_puppy/plugins/<name>/register_callbacks.py` | 2nd |
|
|
15
|
+
| **Project** | `<CWD>/.code_puppy/plugins/<name>/register_callbacks.py` | 3rd (highest precedence) |
|
|
16
|
+
|
|
17
|
+
Each plugin is a directory containing `register_callbacks.py`. The loader
|
|
18
|
+
auto-discovers it. Project plugins shadow user plugins on name collision.
|
|
19
|
+
|
|
20
|
+
## The callback hook system
|
|
21
|
+
|
|
22
|
+
`register_callback(phase, func)` at module scope. The callback engine
|
|
23
|
+
(`callbacks.py`) stores functions per phase and fires them at the right
|
|
24
|
+
time. All hooks accept sync or async functions.
|
|
25
|
+
|
|
26
|
+
**Most important hooks for extending Code Puppy:**
|
|
27
|
+
|
|
28
|
+
| Hook | When | Return value |
|
|
29
|
+
|------|------|-------------|
|
|
30
|
+
| `startup` | Once, at process start | (no return value used) — do one-time setup/migrations here, NOT at module import time (see below) |
|
|
31
|
+
| `register_tools` | Tool registration | `list[dict]` with `name`, `register_func` |
|
|
32
|
+
| `register_agent_tools` | Per-agent tool advertisement | `list[str]` of tool names |
|
|
33
|
+
| `register_skills` | Skill catalogue | `list[dict]` with `name` + `skill_md`/`skill_md_path`/`frontmatter`+`body` |
|
|
34
|
+
| `register_agents` | Agent catalogue | `list[dict]` with `name`, `class` |
|
|
35
|
+
| `load_prompt` | System prompt assembly | `str` fragment or `None` |
|
|
36
|
+
| `get_model_system_prompt` | Per-model prompt patch | `dict` with `instructions`/`handled` or `None` |
|
|
37
|
+
| `custom_command` | Unknown `/slash` command | `True` (handled), `str` (message), or `None` (not mine) |
|
|
38
|
+
| `pre_tool_call` | Before tool executes | Can modify args |
|
|
39
|
+
| `post_tool_call` | After tool finishes | Observes result + duration |
|
|
40
|
+
| `run_shell_command` | Before shell exec | Return `{"blocked": True}` to block |
|
|
41
|
+
| `file_permission` | Before file op | `bool` — allow/deny |
|
|
42
|
+
| `agent_run_start` / `agent_run_end` | Agent lifecycle | Observes name, model, session |
|
|
43
|
+
|
|
44
|
+
The full list is in `callbacks.py` — `PhaseType` has ~45 phases.
|
|
45
|
+
|
|
46
|
+
## Minimal plugin example
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
my_plugin/
|
|
50
|
+
__init__.py # (can be empty)
|
|
51
|
+
register_callbacks.py
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
from code_puppy.callbacks import register_callback
|
|
56
|
+
|
|
57
|
+
def _on_load_prompt():
|
|
58
|
+
return "\n## Project Rules\nAlways use type hints."
|
|
59
|
+
|
|
60
|
+
register_callback("load_prompt", _on_load_prompt)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
That's it. The loader handles discovery, import, and registration.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Two gotchas that will bite you, both discovered building `namespace_skill_search`
|
|
68
|
+
|
|
69
|
+
`namespace_skill_search` (`code_puppy/plugins/namespace_skill_search/`)
|
|
70
|
+
groups skills into namespaces and replaces the flat per-skill list in the
|
|
71
|
+
system prompt with a compact directory + a `browse_skill_namespace` tool
|
|
72
|
+
(see `SKILLS_SYSTEM.md` for what it does from a user's perspective). It's
|
|
73
|
+
also a good reference implementation for two hook-system pitfalls that
|
|
74
|
+
are easy to hit and don't fail loudly when you do:
|
|
75
|
+
|
|
76
|
+
### 1. `get_model_system_prompt` is last-write-wins, not additive
|
|
77
|
+
|
|
78
|
+
If two plugins register a `get_model_system_prompt` callback, the second
|
|
79
|
+
one processed can silently overwrite the first one's `instructions` —
|
|
80
|
+
`model_utils.prepare_prompt_for_model` threads augmenter results through
|
|
81
|
+
sequentially, and whichever callback runs last on a given key wins. This
|
|
82
|
+
is *not* a merge; the built-in `agent_skills` plugin's own contribution
|
|
83
|
+
(the flat skill list) can be clobbered by a badly-timed second callback
|
|
84
|
+
on the same phase.
|
|
85
|
+
|
|
86
|
+
**If you need to add content to the system prompt, use `load_prompt`
|
|
87
|
+
instead whenever possible.** `load_prompt` fragments from every plugin
|
|
88
|
+
are simply newline-joined by `base_agent.py::get_full_system_prompt` —
|
|
89
|
+
there's no merge conflict possible, by construction. This is exactly why
|
|
90
|
+
`namespace_skill_search` injects its namespace directory via
|
|
91
|
+
`load_prompt` and explicitly avoids `get_model_system_prompt`, even
|
|
92
|
+
though the content it's replacing (the flat skill list) is itself
|
|
93
|
+
injected through `get_model_system_prompt`.
|
|
94
|
+
|
|
95
|
+
### 2. Don't mutate config (or do any other real work) at import time
|
|
96
|
+
|
|
97
|
+
A plugin's `register_callbacks.py` module body runs once, at import —
|
|
98
|
+
which happens during every plugin scan, including in test collection.
|
|
99
|
+
Anything at module scope that does real work (writes to
|
|
100
|
+
`~/.code_puppy/puppy.cfg`, hits the filesystem, calls out to a network)
|
|
101
|
+
is:
|
|
102
|
+
|
|
103
|
+
- **Hard to test** — you'd need `importlib.reload()` gymnastics to
|
|
104
|
+
exercise it in isolation, and reloading re-runs *every* top-level
|
|
105
|
+
statement in the module, not just the one you wanted to test.
|
|
106
|
+
- **Not observable** — it just happens silently whenever the module
|
|
107
|
+
happens to get imported, with no log line tied to a specific lifecycle
|
|
108
|
+
event.
|
|
109
|
+
- **A pattern already solved by the `startup` callback.** See
|
|
110
|
+
`code_puppy/plugins/theme/register_callbacks.py`'s
|
|
111
|
+
`_apply_default_theme_on_first_run`, registered via
|
|
112
|
+
`register_callback("startup", _apply_default_theme_on_first_run)`.
|
|
113
|
+
|
|
114
|
+
`namespace_skill_search` follows this pattern for its one piece of real
|
|
115
|
+
setup work (turning off the built-in flat skill list the first time it
|
|
116
|
+
ever runs): the config mutation lives in a plain function,
|
|
117
|
+
`_maybe_disable_frontmatter()`, registered on `startup` — not executed
|
|
118
|
+
as a bare statement in the module body. That function is directly
|
|
119
|
+
callable and testable with mocked config, exactly like the theme
|
|
120
|
+
plugin's equivalent.
|
|
121
|
+
|
|
122
|
+
If you're doing a **one-time migration** (config flip, cache rebuild,
|
|
123
|
+
etc.), also consider a dedicated marker config key to record "this
|
|
124
|
+
plugin already ran its migration," independent of whatever value the
|
|
125
|
+
thing you migrated currently holds — otherwise you can't distinguish
|
|
126
|
+
"never ran yet" from "user changed it back after we ran." See
|
|
127
|
+
`_MIGRATION_MARKER_KEY` in `namespace_skill_search/register_callbacks.py`
|
|
128
|
+
for a worked example.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Plugin structure convention
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
my_plugin/
|
|
136
|
+
├── __init__.py # docstring (can be minimal)
|
|
137
|
+
├── register_callbacks.py # entry point: register_callback() calls
|
|
138
|
+
├── helpers.py # optional: logic split out
|
|
139
|
+
└── README.md # optional: documentation
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
For a plugin that also ships a builtin skill via `register_skills`
|
|
143
|
+
(rather than, or in addition to, tools/prompt fragments), see
|
|
144
|
+
`code_puppy/plugins/code_puppy_agent/` (this skill's own plugin) or
|
|
145
|
+
`namespace_skill_search`'s README for a fuller worked example of
|
|
146
|
+
justifying design decisions in-repo rather than only in a PR
|
|
147
|
+
description.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Session & History System
|
|
2
|
+
|
|
3
|
+
> Part of the `code-puppy-agent` skill. Read this when debugging context
|
|
4
|
+
> window / compaction issues, or working with session save/load. See
|
|
5
|
+
> `SKILL.md` for the overview and the full reference map.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Message history
|
|
10
|
+
|
|
11
|
+
Each `BaseAgent` maintains `_message_history` — a list of pydantic-ai
|
|
12
|
+
`ModelMessage` objects (alternating `ModelRequest`/`ModelResponse`).
|
|
13
|
+
History is the conversation context sent to the LLM on each turn.
|
|
14
|
+
|
|
15
|
+
## Context window management
|
|
16
|
+
|
|
17
|
+
When the conversation grows too large:
|
|
18
|
+
1. **Token estimation** (`_history.py`) — estimates tokens per message
|
|
19
|
+
2. **Compaction** (`_compaction.py`) — summarizes older messages using a
|
|
20
|
+
dedicated summarization agent, preserving recent messages
|
|
21
|
+
3. **Protected tokens** — the most recent N tokens are never compacted
|
|
22
|
+
(configurable via `protected_token_count`)
|
|
23
|
+
|
|
24
|
+
## Session persistence
|
|
25
|
+
|
|
26
|
+
Sessions are saved as pickle files in the state directory:
|
|
27
|
+
- `session_storage.py` handles serialization
|
|
28
|
+
- `/save <name>` and `/load <name>` commands
|
|
29
|
+
- Auto-save on exit
|
|
30
|
+
|
|
31
|
+
## Useful history commands
|
|
32
|
+
|
|
33
|
+
| Command | Effect |
|
|
34
|
+
|---------|--------|
|
|
35
|
+
| `/save <name>` | Save current session |
|
|
36
|
+
| `/load <name>` | Load a saved session |
|
|
37
|
+
| `/pop [N]` | Remove N most recent messages |
|
|
38
|
+
| `/truncate <N>` | Keep only N most recent messages |
|
|
39
|
+
| `/prune` | Interactive context pruning UI |
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-puppy-agent
|
|
3
|
+
description: How Code Puppy itself is built — its internal architecture, structure, codebase layout, and source modules. Explains agents, tools, the plugin/callback hook system, models, MCP, sessions and history/context windows, skills (including skill namespaces for large catalogs), slash commands, config, messaging/UI, system-prompt assembly, and i18n. Activate for ANY question about how Code Puppy works internally, why it behaves a certain way, where something lives in the code, how a feature is implemented, or how to navigate, debug, or extend the codebase (add a tool, agent, plugin, command, skill, model, or MCP server).
|
|
4
|
+
version: "2.0"
|
|
5
|
+
author: code-puppy
|
|
6
|
+
tags:
|
|
7
|
+
- code-puppy
|
|
8
|
+
- architecture
|
|
9
|
+
- structure
|
|
10
|
+
- internals
|
|
11
|
+
- codebase
|
|
12
|
+
- source
|
|
13
|
+
- how-it-works
|
|
14
|
+
- self-awareness
|
|
15
|
+
- agents
|
|
16
|
+
- tools
|
|
17
|
+
- plugins
|
|
18
|
+
- hooks
|
|
19
|
+
- callbacks
|
|
20
|
+
- models
|
|
21
|
+
- mcp
|
|
22
|
+
- sessions
|
|
23
|
+
- history
|
|
24
|
+
- skills
|
|
25
|
+
- namespaces
|
|
26
|
+
- commands
|
|
27
|
+
- config
|
|
28
|
+
- messaging
|
|
29
|
+
- i18n
|
|
30
|
+
- extend
|
|
31
|
+
- debug
|
|
32
|
+
- reference
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
# Code Puppy — Architecture & Internals
|
|
36
|
+
|
|
37
|
+
This skill is a **self-awareness document**. When activated it teaches the
|
|
38
|
+
LLM how Code Puppy is structured under the hood so it can navigate the
|
|
39
|
+
codebase, debug issues, and extend the product without guessing.
|
|
40
|
+
|
|
41
|
+
> **Philosophy:** Code Puppy is plugin-first. Nearly all new functionality
|
|
42
|
+
> should be a plugin under `code_puppy/plugins/` that hooks into core via
|
|
43
|
+
> `code_puppy/callbacks.py`. Don't edit `code_puppy/command_line/` or core
|
|
44
|
+
> agent files unless a hook genuinely doesn't exist.
|
|
45
|
+
|
|
46
|
+
This skill is split across multiple files so activating it doesn't force
|
|
47
|
+
the full ~30KB of internals into context on every use — this SKILL.md is
|
|
48
|
+
the index. **Read the reference file for the topic you actually need**;
|
|
49
|
+
each one is self-contained and cites real file paths so you can jump
|
|
50
|
+
straight to source. All reference files are plain repo paths under
|
|
51
|
+
`code_puppy/plugins/code_puppy_agent/` — read them with `read_file`.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Layered Architecture
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
┌──────────────────────────────────────────────────┐
|
|
59
|
+
│ TUI / CLI (command_line/, tui/) │
|
|
60
|
+
│ user input → slash commands → agent dispatch │
|
|
61
|
+
├──────────────────────────────────────────────────┤
|
|
62
|
+
│ Agent Layer (agents/) │
|
|
63
|
+
│ BaseAgent → system prompt, tools, history │
|
|
64
|
+
│ _builder, _runtime, _compaction, _history │
|
|
65
|
+
├──────────────────────────────────────────────────┤
|
|
66
|
+
│ Tool Layer (tools/) │
|
|
67
|
+
│ TOOL_REGISTRY → register_tools_for_agent() │
|
|
68
|
+
├──────────────────────────────────────────────────┤
|
|
69
|
+
│ Plugin Layer (plugins/, callbacks.py) │
|
|
70
|
+
│ register_callback("hook", fn) at import time │
|
|
71
|
+
├──────────────────────────────────────────────────┤
|
|
72
|
+
│ Model Layer (model_factory.py, config.py) │
|
|
73
|
+
│ ModelFactory → pydantic-ai Model objects │
|
|
74
|
+
├──────────────────────────────────────────────────┤
|
|
75
|
+
│ pydantic-ai (external) │
|
|
76
|
+
│ Agent.run(), streaming, tool schemas │
|
|
77
|
+
└──────────────────────────────────────────────────┘
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The TUI collects user input. It delegates to the **agent manager** which
|
|
81
|
+
loads the current agent. The agent builds a pydantic-ai `Agent` with a
|
|
82
|
+
system prompt + tool set, then `run_with_mcp()` streams the LLM response.
|
|
83
|
+
Plugins hook into every stage via callbacks.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Reference Map
|
|
88
|
+
|
|
89
|
+
| File | Read this for |
|
|
90
|
+
|------|----------------|
|
|
91
|
+
| `AGENTS_AND_TOOLS.md` | How agents are structured/discovered (Python, JSON, plugin agents, precedence). How tools get registered and wired to an agent. Async-tool blocking-I/O gotcha. |
|
|
92
|
+
| `PLUGINS_AND_CALLBACKS.md` | Plugin discovery tiers, the full callback hook table, a minimal plugin example, and **two hook-system gotchas** (`get_model_system_prompt` last-write-wins; don't do real work at import time) worth reading before writing any new plugin. |
|
|
93
|
+
| `MODELS_AND_MCP.md` | ModelFactory, model config precedence, model types. MCP server lifecycle, agent bindings, and a known gap (MCP servers can't yet provide skills). |
|
|
94
|
+
| `SESSIONS_AND_HISTORY.md` | Message history, context-window compaction, session save/load commands. |
|
|
95
|
+
| `SKILLS_SYSTEM.md` | Skill discovery/activation, bundled-resource-file gotcha for plugin-registered skills, and **skill namespaces** — how `namespace_skill_search` groups large skill catalogs and replaces the flat prompt list. |
|
|
96
|
+
| `SYSTEM_PROMPT_CONFIG_AND_I18N.md` | Exact system-prompt assembly order (which layer skills/rules/patches land in), `puppy.cfg` + key directories, the messaging bus, and an i18n quick-reference (full guide: `docs/I18N.md`). |
|
|
97
|
+
|
|
98
|
+
Don't guess which file has what you need — the table above is exhaustive
|
|
99
|
+
for this skill's scope. If a question doesn't map cleanly to one row, it's
|
|
100
|
+
probably answered by combining two (e.g. "why did my plugin's prompt
|
|
101
|
+
addition get silently dropped" is a `PLUGINS_AND_CALLBACKS.md` +
|
|
102
|
+
`SYSTEM_PROMPT_CONFIG_AND_I18N.md` question).
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Development Conventions
|
|
107
|
+
|
|
108
|
+
### Golden rules
|
|
109
|
+
|
|
110
|
+
1. **Plugins over core** — if a callback hook exists, use it. Don't edit
|
|
111
|
+
`command_line/` or core agent files.
|
|
112
|
+
2. **One `register_callbacks.py` per plugin** — register at module scope.
|
|
113
|
+
3. **600-line hard cap** per file — split into submodules. (This very
|
|
114
|
+
skill was split for exactly this reason — it was 632 lines as one file.)
|
|
115
|
+
4. **Fail gracefully** — plugins must never crash the app. Wrap external
|
|
116
|
+
calls in try/except.
|
|
117
|
+
5. **Return `None`** from hooks/commands you don't own.
|
|
118
|
+
6. **Always run linters** — `ruff check --fix`, `ruff format .`
|
|
119
|
+
7. **Wrap user-facing strings** in `t()`/`ngettext` (see
|
|
120
|
+
`SYSTEM_PROMPT_CONFIG_AND_I18N.md`) — don't hardcode English display
|
|
121
|
+
text. Model-facing system prompt content is explicitly exempt.
|
|
122
|
+
8. **Never allow a Claude co-author commit.**
|
|
123
|
+
|
|
124
|
+
### Plugin structure
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
my_plugin/
|
|
128
|
+
├── __init__.py # docstring (can be minimal)
|
|
129
|
+
├── register_callbacks.py # entry point: register_callback() calls
|
|
130
|
+
├── helpers.py # optional: logic split out
|
|
131
|
+
└── README.md # optional: documentation
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Zen of Code Puppy
|
|
135
|
+
|
|
136
|
+
- Simple is better than complex.
|
|
137
|
+
- Flat is better than nested.
|
|
138
|
+
- If a hook exists for it, use it.
|
|
139
|
+
- Files should be readable in one sitting.
|
|
140
|
+
- The plugin system is the API surface; the core is the engine.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Quick Reference: Key File Map
|
|
145
|
+
|
|
146
|
+
| File | Responsibility |
|
|
147
|
+
|------|---------------|
|
|
148
|
+
| `agents/base_agent.py` | Abstract agent base — thin conductor |
|
|
149
|
+
| `agents/_builder.py` | Builds pydantic-ai Agent + MCP wiring |
|
|
150
|
+
| `agents/_runtime.py` | `run_with_mcp()` — streaming, retries, cancellation |
|
|
151
|
+
| `agents/_compaction.py` | Context summarization |
|
|
152
|
+
| `agents/agent_manager.py` | Agent registry, switching, discovery |
|
|
153
|
+
| `agents/json_agent.py` | JSON-config agent loader |
|
|
154
|
+
| `tools/__init__.py` | `TOOL_REGISTRY`, `register_tools_for_agent()` |
|
|
155
|
+
| `plugins/__init__.py` | Plugin loader (builtin → user → project) |
|
|
156
|
+
| `callbacks.py` | Hook engine — 45+ phases |
|
|
157
|
+
| `config.py` | Config read/write, directories, model settings |
|
|
158
|
+
| `model_factory.py` | Model-name → pydantic-ai Model |
|
|
159
|
+
| `mcp_/manager.py` | MCP server lifecycle |
|
|
160
|
+
| `session_storage.py` | Session pickle save/load |
|
|
161
|
+
| `plugins/agent_skills/` | Skills discovery, activation, UI |
|
|
162
|
+
| `plugins/namespace_skill_search/` | Namespace grouping + on-demand browse tool for large skill catalogs |
|
|
163
|
+
| `i18n/` | Internationalization: catalogs, `t()`/`ngettext`, locale detection, formatting |
|
|
164
|
+
| `i18n/locales/*.json` | Message catalogs (source of truth: `en-US.json`) |
|
|
165
|
+
| `pydantic_patches.py` | Startup monkey-patches (clipboard fix, etc.) |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## When to use this skill
|
|
170
|
+
|
|
171
|
+
Activate this skill when you need to:
|
|
172
|
+
- Understand **how a feature works internally** before modifying it
|
|
173
|
+
- **Create a new plugin** and need to know which hooks to use
|
|
174
|
+
- **Debug** an agent, tool, model, skill, or MCP issue
|
|
175
|
+
- **Navigate the codebase** and need to find the right file
|
|
176
|
+
- **Extend Code Puppy** with custom tools, agents, skills, or commands
|
|
177
|
+
|
|
178
|
+
Then read the specific reference file(s) from the map above — don't try
|
|
179
|
+
to hold all six in context at once unless the question is genuinely
|
|
180
|
+
that broad.
|