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,238 @@
|
|
|
1
|
+
"""Wire emoji_filter into the runtime.
|
|
2
|
+
|
|
3
|
+
Three points of contact, all gated by ``config.is_enabled()``:
|
|
4
|
+
|
|
5
|
+
1. ``pre_tool_call`` callback — mutates the *args dict in-place* for file-write
|
|
6
|
+
and shell tools before the tool actually runs. We only touch text destined
|
|
7
|
+
for disk (new_str, content, payload) and the shell command string. Search
|
|
8
|
+
strings (old_str / snippet) are left alone so matching doesn't silently
|
|
9
|
+
break.
|
|
10
|
+
|
|
11
|
+
2. ``startup`` callback — installs a one-time monkey-patch on
|
|
12
|
+
``pydantic_ai.messages.TextPart`` / ``TextPartDelta`` to strip emojis from
|
|
13
|
+
streamed text content. ``ThinkingPart`` / ``ThinkingPartDelta`` are
|
|
14
|
+
deliberately untouched.
|
|
15
|
+
|
|
16
|
+
3. ``custom_command`` / ``custom_command_help`` — a tiny ``/emoji-filter``
|
|
17
|
+
slash command so the user can flip the switch without editing puppy.cfg.
|
|
18
|
+
|
|
19
|
+
Failures here must never crash the app: every patch site is wrapped.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import logging
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
27
|
+
from code_puppy.callbacks import register_callback
|
|
28
|
+
|
|
29
|
+
from .config import is_enabled, set_enabled
|
|
30
|
+
from .stripper import strip_emojis
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
# Tool name → handler. Keeps the dispatch table flat and inspectable (no
|
|
35
|
+
# nested if/elif soup). All handlers mutate ``args`` in place and return None.
|
|
36
|
+
_FILE_WRITE_TOOLS = {"create_file", "edit_file", "replace_in_file"}
|
|
37
|
+
_SHELL_TOOLS = {"agent_run_shell_command"}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _strip_field(container: dict, key: str) -> bool:
|
|
41
|
+
"""Strip emojis from ``container[key]`` in place. Return True if it changed.
|
|
42
|
+
|
|
43
|
+
One helper, one job. Used by every other strip-site so the
|
|
44
|
+
"did anything actually change?" signal is honest and DRY.
|
|
45
|
+
"""
|
|
46
|
+
val = container.get(key)
|
|
47
|
+
if not isinstance(val, str) or not val:
|
|
48
|
+
return False
|
|
49
|
+
stripped = strip_emojis(val)
|
|
50
|
+
if stripped == val:
|
|
51
|
+
return False
|
|
52
|
+
container[key] = stripped
|
|
53
|
+
return True
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _filter_replacements(replacements: Any) -> int:
|
|
57
|
+
"""Strip emojis from each ``new_str`` in a replacements list (in place).
|
|
58
|
+
|
|
59
|
+
Returns the number of items whose ``new_str`` was modified.
|
|
60
|
+
"""
|
|
61
|
+
if not isinstance(replacements, list):
|
|
62
|
+
return 0
|
|
63
|
+
count = 0
|
|
64
|
+
for item in replacements:
|
|
65
|
+
if isinstance(item, dict) and _strip_field(item, "new_str"):
|
|
66
|
+
count += 1
|
|
67
|
+
return count
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _filter_edit_payload(payload: Any) -> list[str]:
|
|
71
|
+
"""Mutate an edit_file payload dict in place.
|
|
72
|
+
|
|
73
|
+
edit_file accepts three payload shapes:
|
|
74
|
+
* ContentPayload → strip ``content``
|
|
75
|
+
* ReplacementsPayload → strip each ``new_str``
|
|
76
|
+
* DeleteSnippetPayload → leave alone (it's a search string)
|
|
77
|
+
|
|
78
|
+
Returns a list of human-readable labels describing what was stripped
|
|
79
|
+
(empty list = nothing changed).
|
|
80
|
+
"""
|
|
81
|
+
if not isinstance(payload, dict):
|
|
82
|
+
return []
|
|
83
|
+
stripped: list[str] = []
|
|
84
|
+
if _strip_field(payload, "content"):
|
|
85
|
+
stripped.append("payload.content")
|
|
86
|
+
if "replacements" in payload:
|
|
87
|
+
n = _filter_replacements(payload["replacements"])
|
|
88
|
+
if n:
|
|
89
|
+
stripped.append(f"payload.replacements ({n} item{'s' if n != 1 else ''})")
|
|
90
|
+
return stripped
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Notify the model when we tamper with its tool call so it stops emitting emojis.
|
|
94
|
+
# The framework (pydantic_patches._patched_call_tool) prepends the ``context_message``
|
|
95
|
+
# to the tool result as ``[hook context]\n{msg}``, which the model then reads.
|
|
96
|
+
_CONTEXT_MESSAGE_TEMPLATE = (
|
|
97
|
+
"emoji_filter is ENABLED. Emojis were detected and stripped from "
|
|
98
|
+
"`{tool_name}` arg(s): {fields}. This project does not allow emojis "
|
|
99
|
+
"in file writes, shell commands, or assistant output \u2014 please "
|
|
100
|
+
"omit them in future tool calls and responses."
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _on_pre_tool_call(
|
|
105
|
+
tool_name: str, tool_args: dict, context: Any = None
|
|
106
|
+
) -> dict | None:
|
|
107
|
+
"""Strip emojis from file-write and shell tool args, and notify the model.
|
|
108
|
+
|
|
109
|
+
Returns ``{"context_message": ...}`` when any emojis were detected so the
|
|
110
|
+
framework can surface that fact to the model via the tool result. Returns
|
|
111
|
+
``None`` otherwise (no-op for the framework).
|
|
112
|
+
"""
|
|
113
|
+
if not is_enabled() or not isinstance(tool_args, dict):
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
stripped_fields: list[str] = []
|
|
117
|
+
try:
|
|
118
|
+
if tool_name == "create_file":
|
|
119
|
+
if _strip_field(tool_args, "content"):
|
|
120
|
+
stripped_fields.append("content")
|
|
121
|
+
|
|
122
|
+
elif tool_name == "replace_in_file":
|
|
123
|
+
n = _filter_replacements(tool_args.get("replacements"))
|
|
124
|
+
if n:
|
|
125
|
+
stripped_fields.append(
|
|
126
|
+
f"replacements ({n} item{'s' if n != 1 else ''})"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
elif tool_name == "edit_file":
|
|
130
|
+
stripped_fields.extend(_filter_edit_payload(tool_args.get("payload")))
|
|
131
|
+
|
|
132
|
+
elif tool_name in _SHELL_TOOLS:
|
|
133
|
+
if _strip_field(tool_args, "command"):
|
|
134
|
+
stripped_fields.append("command")
|
|
135
|
+
except Exception as exc: # never block tool execution
|
|
136
|
+
logger.debug("emoji_filter pre_tool_call failed: %s", exc)
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
if not stripped_fields:
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
"context_message": _CONTEXT_MESSAGE_TEMPLATE.format(
|
|
144
|
+
tool_name=tool_name, fields=", ".join(stripped_fields)
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# Streaming patch: patch TextPart/TextPartDelta __init__ exactly once; the patched
|
|
150
|
+
# init checks ``is_enabled()`` at call time so the user can toggle without restart.
|
|
151
|
+
|
|
152
|
+
_STREAM_PATCH_FLAG = "_emoji_filter_patched"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _install_streaming_patch() -> None:
|
|
156
|
+
try:
|
|
157
|
+
from pydantic_ai.messages import TextPart, TextPartDelta
|
|
158
|
+
except Exception as exc:
|
|
159
|
+
logger.debug("emoji_filter: pydantic_ai.messages unavailable: %s", exc)
|
|
160
|
+
return
|
|
161
|
+
|
|
162
|
+
for cls, attr in ((TextPartDelta, "content_delta"), (TextPart, "content")):
|
|
163
|
+
if getattr(cls, _STREAM_PATCH_FLAG, False):
|
|
164
|
+
continue
|
|
165
|
+
_wrap_init(cls, attr)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _wrap_init(cls: type, content_attr: str) -> None:
|
|
169
|
+
original_init = cls.__init__
|
|
170
|
+
|
|
171
|
+
def patched_init(self, *args, **kwargs): # noqa: ANN001 - dataclass-y
|
|
172
|
+
original_init(self, *args, **kwargs)
|
|
173
|
+
if not is_enabled():
|
|
174
|
+
return
|
|
175
|
+
try:
|
|
176
|
+
current = getattr(self, content_attr, None)
|
|
177
|
+
if isinstance(current, str) and current:
|
|
178
|
+
stripped = strip_emojis(current)
|
|
179
|
+
if stripped != current:
|
|
180
|
+
setattr(self, content_attr, stripped)
|
|
181
|
+
except Exception as exc: # defensive: never break message construction
|
|
182
|
+
logger.debug(
|
|
183
|
+
"emoji_filter stream patch failed on %s: %s", cls.__name__, exc
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
cls.__init__ = patched_init # type: ignore[method-assign]
|
|
187
|
+
setattr(cls, _STREAM_PATCH_FLAG, True)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _on_startup() -> None:
|
|
191
|
+
_install_streaming_patch()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
# --- /emoji-filter slash command --------------------------------------------
|
|
195
|
+
|
|
196
|
+
_COMMAND_NAMES = {"emoji-filter", "emojifilter"}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _custom_help():
|
|
200
|
+
return [
|
|
201
|
+
("emoji-filter", "Show / toggle the emoji filter (on|off|status)"),
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _handle_command(command: str, name: str):
|
|
206
|
+
if name not in _COMMAND_NAMES:
|
|
207
|
+
return None
|
|
208
|
+
|
|
209
|
+
from code_puppy.messaging import emit_info
|
|
210
|
+
|
|
211
|
+
parts = command.split(maxsplit=1)
|
|
212
|
+
arg = parts[1].strip().lower() if len(parts) == 2 else "status"
|
|
213
|
+
|
|
214
|
+
if arg in ("on", "enable", "enabled", "true", "1"):
|
|
215
|
+
set_enabled(True)
|
|
216
|
+
emit_info(
|
|
217
|
+
"emoji_filter: ON (emojis will be stripped from outputs/file writes/shell)"
|
|
218
|
+
)
|
|
219
|
+
return True
|
|
220
|
+
if arg in ("off", "disable", "disabled", "false", "0"):
|
|
221
|
+
set_enabled(False)
|
|
222
|
+
emit_info("emoji_filter: OFF (emojis pass through untouched)")
|
|
223
|
+
return True
|
|
224
|
+
if arg in ("status", ""):
|
|
225
|
+
state = "ON" if is_enabled() else "OFF"
|
|
226
|
+
emit_info(f"emoji_filter: {state}")
|
|
227
|
+
return True
|
|
228
|
+
|
|
229
|
+
emit_info("Usage: /emoji-filter [on|off|status]")
|
|
230
|
+
return True
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# --- Registration ------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
register_callback("startup", _on_startup)
|
|
236
|
+
register_callback("pre_tool_call", _on_pre_tool_call)
|
|
237
|
+
register_callback("custom_command_help", _custom_help)
|
|
238
|
+
register_callback("custom_command", _handle_command)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Emoji stripping utilities.
|
|
2
|
+
|
|
3
|
+
One regex, one entrypoint. Beautiful is better than ugly.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
|
|
10
|
+
# Common pictographic/emoji ranges + zero-width joiner & variation selector-16
|
|
11
|
+
# (multi-codepoint composition). Conservative: no punctuation/math/arrows/letters.
|
|
12
|
+
_EMOJI_RE = re.compile(
|
|
13
|
+
"["
|
|
14
|
+
"\U0001f300-\U0001f5ff" # misc symbols & pictographs
|
|
15
|
+
"\U0001f600-\U0001f64f" # emoticons
|
|
16
|
+
"\U0001f680-\U0001f6ff" # transport & map
|
|
17
|
+
"\U0001f700-\U0001f77f" # alchemical
|
|
18
|
+
"\U0001f780-\U0001f7ff" # geometric shapes extended
|
|
19
|
+
"\U0001f800-\U0001f8ff" # supplemental arrows-C
|
|
20
|
+
"\U0001f900-\U0001f9ff" # supplemental symbols and pictographs
|
|
21
|
+
"\U0001fa00-\U0001fa6f" # chess symbols
|
|
22
|
+
"\U0001fa70-\U0001faff" # symbols & pictographs extended-A
|
|
23
|
+
"\U0001fb00-\U0001fbff" # symbols for legacy computing
|
|
24
|
+
"\U00002600-\U000026ff" # misc symbols (includes ☂ ☀ ♻ etc.)
|
|
25
|
+
"\U00002700-\U000027bf" # dingbats (✂ ✈ ✅ ❌ ❤ etc.)
|
|
26
|
+
"\U0001f1e6-\U0001f1ff" # regional indicator symbols (flags)
|
|
27
|
+
"\U0000fe0f" # variation selector-16
|
|
28
|
+
"\U0000200d" # zero width joiner
|
|
29
|
+
"]+",
|
|
30
|
+
flags=re.UNICODE,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def strip_emojis(text: str) -> str:
|
|
35
|
+
"""Return ``text`` with emoji codepoints removed. None-safe on non-strings."""
|
|
36
|
+
if not isinstance(text, str) or not text:
|
|
37
|
+
return text
|
|
38
|
+
return _EMOJI_RE.sub("", text)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def contains_emoji(text: str) -> bool:
|
|
42
|
+
"""Quick check used mostly by tests."""
|
|
43
|
+
if not isinstance(text, str) or not text:
|
|
44
|
+
return False
|
|
45
|
+
return _EMOJI_RE.search(text) is not None
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Hide whitespace-only HTML comments from streamed thinking display.
|
|
2
|
+
|
|
3
|
+
The filter is stateful because model deltas may split ``<!-- -->`` at any
|
|
4
|
+
character boundary. It changes presentation only; model history and response
|
|
5
|
+
content remain untouched.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from threading import Lock
|
|
11
|
+
|
|
12
|
+
from code_puppy.callbacks import register_callback
|
|
13
|
+
|
|
14
|
+
_OPEN = "<!--"
|
|
15
|
+
_CLOSE = "-->"
|
|
16
|
+
_pending: dict[tuple[object, int], str] = {}
|
|
17
|
+
_lock = Lock()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _prefix_suffix_length(text: str, marker: str) -> int:
|
|
21
|
+
"""Return the longest suffix of ``text`` that prefixes ``marker``."""
|
|
22
|
+
limit = min(len(text), len(marker) - 1)
|
|
23
|
+
for length in range(limit, 0, -1):
|
|
24
|
+
if text.endswith(marker[:length]):
|
|
25
|
+
return length
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _could_complete_empty_comment(body: str) -> bool:
|
|
30
|
+
"""Whether an unfinished body is whitespace plus a closing-prefix."""
|
|
31
|
+
return body.lstrip() in ("", "-", "--")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _pop_trailing_newline(parts: list[str]) -> str:
|
|
35
|
+
"""Remove and return one trailing newline from accumulated output."""
|
|
36
|
+
for index in range(len(parts) - 1, -1, -1):
|
|
37
|
+
part = parts[index]
|
|
38
|
+
if not part:
|
|
39
|
+
continue
|
|
40
|
+
if part.endswith("\r\n"):
|
|
41
|
+
parts[index] = part[:-2]
|
|
42
|
+
return "\r\n"
|
|
43
|
+
if part.endswith("\n"):
|
|
44
|
+
parts[index] = part[:-1]
|
|
45
|
+
return "\n"
|
|
46
|
+
break
|
|
47
|
+
return ""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _held_suffix_length(text: str) -> int:
|
|
51
|
+
"""Retain a possible opener and its immediately preceding newline."""
|
|
52
|
+
length = _prefix_suffix_length(text, _OPEN)
|
|
53
|
+
start = len(text) - length
|
|
54
|
+
if start > 0 and text[start - 1] == "\n":
|
|
55
|
+
length += 1
|
|
56
|
+
if start > 1 and text[start - 2] == "\r":
|
|
57
|
+
length += 1
|
|
58
|
+
return length
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _filter_chunk(buffered: str, text: str, *, final: bool) -> tuple[str, str]:
|
|
62
|
+
"""Return display-safe output and an incomplete candidate to retain."""
|
|
63
|
+
data = buffered + text
|
|
64
|
+
output: list[str] = []
|
|
65
|
+
position = 0
|
|
66
|
+
|
|
67
|
+
while position < len(data):
|
|
68
|
+
opening = data.find(_OPEN, position)
|
|
69
|
+
if opening < 0:
|
|
70
|
+
remainder = data[position:]
|
|
71
|
+
held_length = 0 if final else _held_suffix_length(remainder)
|
|
72
|
+
if held_length:
|
|
73
|
+
output.append(remainder[:-held_length])
|
|
74
|
+
return "".join(output), remainder[-held_length:]
|
|
75
|
+
output.append(remainder)
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
output.append(data[position:opening])
|
|
79
|
+
closing = data.find(_CLOSE, opening + len(_OPEN))
|
|
80
|
+
if closing < 0:
|
|
81
|
+
candidate = data[opening:]
|
|
82
|
+
body = candidate[len(_OPEN) :]
|
|
83
|
+
if not final and _could_complete_empty_comment(body):
|
|
84
|
+
newline = _pop_trailing_newline(output)
|
|
85
|
+
return "".join(output), newline + candidate
|
|
86
|
+
output.append(candidate)
|
|
87
|
+
return "".join(output), ""
|
|
88
|
+
|
|
89
|
+
body = data[opening + len(_OPEN) : closing]
|
|
90
|
+
if body.strip():
|
|
91
|
+
output.append(data[opening : closing + len(_CLOSE)])
|
|
92
|
+
else:
|
|
93
|
+
_pop_trailing_newline(output)
|
|
94
|
+
position = closing + len(_CLOSE)
|
|
95
|
+
|
|
96
|
+
return "".join(output), ""
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _filter_thinking_display(
|
|
100
|
+
text: str,
|
|
101
|
+
*,
|
|
102
|
+
stream_id: object,
|
|
103
|
+
part_index: int,
|
|
104
|
+
final: bool = False,
|
|
105
|
+
) -> str:
|
|
106
|
+
"""Remove empty comments while retaining incomplete markers across deltas."""
|
|
107
|
+
key = (stream_id, part_index)
|
|
108
|
+
with _lock:
|
|
109
|
+
buffered = _pending.pop(key, "")
|
|
110
|
+
output, remainder = _filter_chunk(buffered, text, final=final)
|
|
111
|
+
if remainder and not final:
|
|
112
|
+
_pending[key] = remainder
|
|
113
|
+
return output
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
register_callback("thinking_display_filter", _filter_thinking_display)
|