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,179 @@
|
|
|
1
|
+
"""Session model selection + config options exposed to the ACP client.
|
|
2
|
+
|
|
3
|
+
Everything is delivered as ACP **config options** (``session/set_config_option``)
|
|
4
|
+
-- clients (Zed, opencode, oh-my-pi) bind each bottom-bar dropdown to a config
|
|
5
|
+
option by its ``category``, so this is the shape that actually populates them:
|
|
6
|
+
|
|
7
|
+
* **Model picker** — a ``select`` option tagged ``category="model"``:
|
|
8
|
+
``{id: "model", category: "model", type: "select", ...}``. Backed by
|
|
9
|
+
``model_picker_completion.load_model_names`` + ``config.get_global_model_name``
|
|
10
|
+
/ ``set_model_name``. Changing it rebinds the live session's model.
|
|
11
|
+
* **Mode picker** — a ``select`` option tagged ``category="mode"``. Code Puppy
|
|
12
|
+
has exactly one operating mode, so this is a single "Default" entry; we still
|
|
13
|
+
send it so the client's mode dropdown reads "Default" instead of an empty
|
|
14
|
+
"Unknown" control. (ACP's top-level ``SessionModeState`` is a *different*
|
|
15
|
+
mechanism that Zed 1.7.2 does not bind that dropdown to -- config options are
|
|
16
|
+
what work across clients.)
|
|
17
|
+
* **Streaming toggle** — an On/Off ``select`` option. (A boolean option would
|
|
18
|
+
be more natural, but Zed 1.7.2 renders only ``select`` options in its bottom
|
|
19
|
+
bar -- a boolean shows as "Unknown" -- so every control here is a select.) We
|
|
20
|
+
deliberately expose only this safe setting; we do **not** expose a
|
|
21
|
+
yolo/approval-bypass toggle (permissions must stay client-driven).
|
|
22
|
+
|
|
23
|
+
All accessors are best-effort and degrade to "nothing to offer" on error.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import logging
|
|
29
|
+
from typing import Any, List, Optional, Tuple
|
|
30
|
+
|
|
31
|
+
from acp.schema import (
|
|
32
|
+
SessionConfigOptionSelect,
|
|
33
|
+
SessionConfigSelectOption,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
logger = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
# Config-option ids. ``MODEL_OPTION_ID`` is public because ``agent.py`` keys
|
|
39
|
+
# its "rebind the live model" behaviour off it.
|
|
40
|
+
MODEL_OPTION_ID = "model"
|
|
41
|
+
MODE_OPTION_ID = "mode"
|
|
42
|
+
_STREAMING_ID = "enable_streaming"
|
|
43
|
+
_STREAMING_ON = "on"
|
|
44
|
+
_STREAMING_OFF = "off"
|
|
45
|
+
|
|
46
|
+
# Exactly one operating mode, but advertised as a category="mode" select so the
|
|
47
|
+
# client's dropdown shows "Default" rather than an empty "Unknown" control.
|
|
48
|
+
# (Model selection is the separate category="model" option.)
|
|
49
|
+
_DEFAULT_MODE_ID = "default"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _mode_option() -> SessionConfigOptionSelect:
|
|
53
|
+
"""Advertise Code Puppy's single "Default" mode as a category=mode select.
|
|
54
|
+
|
|
55
|
+
There is nothing to switch between, but a one-item option keeps the
|
|
56
|
+
client's mode dropdown meaningful instead of blank.
|
|
57
|
+
"""
|
|
58
|
+
return SessionConfigOptionSelect(
|
|
59
|
+
id=MODE_OPTION_ID,
|
|
60
|
+
name="Mode",
|
|
61
|
+
category="mode",
|
|
62
|
+
type="select",
|
|
63
|
+
current_value=_DEFAULT_MODE_ID,
|
|
64
|
+
options=[
|
|
65
|
+
SessionConfigSelectOption(
|
|
66
|
+
value=_DEFAULT_MODE_ID,
|
|
67
|
+
name="Default",
|
|
68
|
+
description="Standard Code Puppy session",
|
|
69
|
+
)
|
|
70
|
+
],
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _model_choices() -> Tuple[List[str], Optional[str]]:
|
|
75
|
+
"""Return ``(available_model_names, current_selection)`` from config.
|
|
76
|
+
|
|
77
|
+
``current`` is coerced into the available list so a picker always has a
|
|
78
|
+
valid selection. Returns ``([], None)`` when there are no models to offer.
|
|
79
|
+
"""
|
|
80
|
+
from code_puppy.command_line.model_picker_completion import load_model_names
|
|
81
|
+
from code_puppy.config import get_global_model_name
|
|
82
|
+
|
|
83
|
+
names = list(load_model_names() or [])
|
|
84
|
+
if not names:
|
|
85
|
+
return [], None
|
|
86
|
+
current = get_global_model_name()
|
|
87
|
+
return names, (current if current in names else names[0])
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _model_option() -> Optional[SessionConfigOptionSelect]:
|
|
91
|
+
"""Build the model picker as a ``category="model"`` select option.
|
|
92
|
+
|
|
93
|
+
Returns ``None`` when there are no models to offer.
|
|
94
|
+
"""
|
|
95
|
+
names, current = _model_choices()
|
|
96
|
+
if not names or current is None:
|
|
97
|
+
return None
|
|
98
|
+
return SessionConfigOptionSelect(
|
|
99
|
+
id=MODEL_OPTION_ID,
|
|
100
|
+
name="Model",
|
|
101
|
+
category="model",
|
|
102
|
+
type="select",
|
|
103
|
+
current_value=current,
|
|
104
|
+
options=[SessionConfigSelectOption(value=n, name=n) for n in names],
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def set_model(model_id: str) -> bool:
|
|
109
|
+
"""Switch the active model. Returns ``True`` on success."""
|
|
110
|
+
try:
|
|
111
|
+
from code_puppy.config import set_model_name
|
|
112
|
+
|
|
113
|
+
set_model_name(model_id)
|
|
114
|
+
return True
|
|
115
|
+
except Exception: # noqa: BLE001
|
|
116
|
+
logger.debug("ACP: set_model failed", exc_info=True)
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def config_options() -> List[Any]:
|
|
121
|
+
"""Build the config-option list for a session (model picker + streaming).
|
|
122
|
+
|
|
123
|
+
Order matters for presentation: the model picker leads. Either entry is
|
|
124
|
+
omitted if it can't be built, so a config hiccup never sinks the session.
|
|
125
|
+
"""
|
|
126
|
+
opts: List[Any] = []
|
|
127
|
+
try:
|
|
128
|
+
model_opt = _model_option()
|
|
129
|
+
if model_opt is not None:
|
|
130
|
+
opts.append(model_opt)
|
|
131
|
+
except Exception: # noqa: BLE001
|
|
132
|
+
logger.debug("ACP: could not build model option", exc_info=True)
|
|
133
|
+
try:
|
|
134
|
+
opts.append(_mode_option())
|
|
135
|
+
except Exception: # noqa: BLE001
|
|
136
|
+
logger.debug("ACP: could not build mode option", exc_info=True)
|
|
137
|
+
try:
|
|
138
|
+
from code_puppy.config import get_enable_streaming
|
|
139
|
+
|
|
140
|
+
# A select (On/Off), not a boolean: Zed 1.7.2 only renders select-type
|
|
141
|
+
# config options in its bottom bar; a boolean shows as "Unknown".
|
|
142
|
+
opts.append(
|
|
143
|
+
SessionConfigOptionSelect(
|
|
144
|
+
id=_STREAMING_ID,
|
|
145
|
+
name="Streaming responses",
|
|
146
|
+
type="select",
|
|
147
|
+
current_value=_STREAMING_ON
|
|
148
|
+
if get_enable_streaming()
|
|
149
|
+
else _STREAMING_OFF,
|
|
150
|
+
options=[
|
|
151
|
+
SessionConfigSelectOption(value=_STREAMING_ON, name="On"),
|
|
152
|
+
SessionConfigSelectOption(value=_STREAMING_OFF, name="Off"),
|
|
153
|
+
],
|
|
154
|
+
description="Stream model output token-by-token.",
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
except Exception: # noqa: BLE001
|
|
158
|
+
logger.debug("ACP: could not build streaming option", exc_info=True)
|
|
159
|
+
return opts
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def apply_config_option(config_id: str, value: Any) -> List[Any]:
|
|
163
|
+
"""Apply a config-option change and return the refreshed option list."""
|
|
164
|
+
try:
|
|
165
|
+
if config_id == MODEL_OPTION_ID:
|
|
166
|
+
set_model(str(value))
|
|
167
|
+
elif config_id == _STREAMING_ID:
|
|
168
|
+
from code_puppy.config import set_config_value
|
|
169
|
+
|
|
170
|
+
set_config_value("enable_streaming", "true" if _as_bool(value) else "false")
|
|
171
|
+
except Exception: # noqa: BLE001
|
|
172
|
+
logger.debug("ACP: apply_config_option failed", exc_info=True)
|
|
173
|
+
return config_options()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _as_bool(value: Any) -> bool:
|
|
177
|
+
if isinstance(value, bool):
|
|
178
|
+
return value
|
|
179
|
+
return str(value).strip().lower() in ("1", "true", "yes", "on")
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"""Run context for the active ACP connection.
|
|
2
|
+
|
|
3
|
+
Code Puppy's approval and I/O seams live at its *edges* (the
|
|
4
|
+
``run_shell_command`` hook, the ``tools.common`` approval backend, and the
|
|
5
|
+
``tools.io_backends`` filesystem/command backends). Those are plain module
|
|
6
|
+
functions with no reference to the live ACP connection, so this module is the
|
|
7
|
+
small, explicit bridge between them and the running agent.
|
|
8
|
+
|
|
9
|
+
Two kinds of state live here:
|
|
10
|
+
|
|
11
|
+
* **Connection-scoped** — the ``AgentSideConnection`` handle + its event loop.
|
|
12
|
+
There is exactly one connection per process (set once, on connect), so these
|
|
13
|
+
are plain module globals.
|
|
14
|
+
* **Run-scoped** — the id of the session whose prompt is currently running, the
|
|
15
|
+
stack of in-flight tool calls (so permission dialogs and updates correlate to
|
|
16
|
+
the tool that triggered them), and whether any assistant text has streamed.
|
|
17
|
+
A single ACP connection multiplexes *multiple* sessions, and the SDK
|
|
18
|
+
dispatches each ``session/prompt`` as its own task, so two prompts can be in
|
|
19
|
+
flight at once. Run-scoped state therefore lives in a **``ContextVar``** — set
|
|
20
|
+
in ``begin_run`` before the run task is spawned, so each prompt task (and the
|
|
21
|
+
tool coroutines/threads it copies its context into) sees its *own* run, never
|
|
22
|
+
a sibling's. The var holds a shared mutable dict so a mutation made deep in
|
|
23
|
+
the run (e.g. ``note_streamed_text`` from a streamed delta) is visible back in
|
|
24
|
+
the prompt coroutine's ``finally`` that reads it.
|
|
25
|
+
|
|
26
|
+
Keeping this here — rather than smuggled through globals or reached via the
|
|
27
|
+
agent object — keeps the coupling visible and testable.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import asyncio
|
|
33
|
+
import contextvars
|
|
34
|
+
import uuid
|
|
35
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
36
|
+
|
|
37
|
+
_CONNECTION: Any = None
|
|
38
|
+
_LOOP: Optional[asyncio.AbstractEventLoop] = None
|
|
39
|
+
|
|
40
|
+
# Per-run state isolated per prompt task via a ContextVar (None = no active run).
|
|
41
|
+
# A mutable dict {"session_id", "streamed", "tool_stack"} so child tasks/threads
|
|
42
|
+
# (which copy this context) see writes made by the creating prompt coroutine.
|
|
43
|
+
_RUN: contextvars.ContextVar[Optional[Dict[str, Any]]] = contextvars.ContextVar(
|
|
44
|
+
"acp_run", default=None
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ---- Connection lifecycle -------------------------------------------------
|
|
49
|
+
def set_connection(connection: Any, loop: Optional[asyncio.AbstractEventLoop]) -> None:
|
|
50
|
+
"""Register (or clear, with ``None``) the live connection + its loop."""
|
|
51
|
+
global _CONNECTION, _LOOP
|
|
52
|
+
_CONNECTION = connection
|
|
53
|
+
_LOOP = loop
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_connection() -> Any:
|
|
57
|
+
"""Return the ``AgentSideConnection``, or ``None`` when not in ACP mode."""
|
|
58
|
+
return _CONNECTION
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_loop() -> Optional[asyncio.AbstractEventLoop]:
|
|
62
|
+
"""Return the ACP event loop, or ``None`` when not in ACP mode."""
|
|
63
|
+
return _LOOP
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ---- Per-run context ------------------------------------------------------
|
|
67
|
+
def begin_run(session_id: str) -> None:
|
|
68
|
+
"""Mark ``session_id`` as the run whose events/permissions we handle.
|
|
69
|
+
|
|
70
|
+
Sets a fresh run-state dict in the current context. Call this in the prompt
|
|
71
|
+
coroutine *before* spawning the run task, so the task (and every tool
|
|
72
|
+
coroutine/thread that copies the context) shares this exact dict.
|
|
73
|
+
"""
|
|
74
|
+
_RUN.set(
|
|
75
|
+
{
|
|
76
|
+
"session_id": session_id,
|
|
77
|
+
"streamed": False,
|
|
78
|
+
"tool_stack": [],
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def end_run() -> None:
|
|
84
|
+
"""Detach after a run; late events/permissions in this context are dropped."""
|
|
85
|
+
_RUN.set(None)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def get_active_session_id() -> Optional[str]:
|
|
89
|
+
"""The session id of the in-flight run in this context, or ``None``."""
|
|
90
|
+
run = _RUN.get()
|
|
91
|
+
return run["session_id"] if run else None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ---- Streamed-text tracking (final-result fallback) -----------------------
|
|
95
|
+
def note_streamed_text() -> None:
|
|
96
|
+
"""Record that at least one assistant text delta streamed this run."""
|
|
97
|
+
run = _RUN.get()
|
|
98
|
+
if run is not None:
|
|
99
|
+
run["streamed"] = True
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def streamed_text() -> bool:
|
|
103
|
+
"""Whether any assistant text streamed during the active run."""
|
|
104
|
+
run = _RUN.get()
|
|
105
|
+
return bool(run and run["streamed"])
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
# ---- Tool-call correlation ------------------------------------------------
|
|
109
|
+
def push_tool_call(tool_name: str) -> str:
|
|
110
|
+
"""Open a tool call, returning a fresh id to report to the client."""
|
|
111
|
+
tool_call_id = f"tc_{uuid.uuid4().hex[:12]}"
|
|
112
|
+
run = _RUN.get()
|
|
113
|
+
if run is not None:
|
|
114
|
+
run["tool_stack"].append((tool_name, tool_call_id))
|
|
115
|
+
return tool_call_id
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def pop_tool_call(tool_name: str) -> Optional[str]:
|
|
119
|
+
"""Close the most recent open call for ``tool_name`` and return its id."""
|
|
120
|
+
run = _RUN.get()
|
|
121
|
+
if run is None:
|
|
122
|
+
return None
|
|
123
|
+
stack: List[Tuple[str, str]] = run["tool_stack"]
|
|
124
|
+
for i in range(len(stack) - 1, -1, -1):
|
|
125
|
+
if stack[i][0] == tool_name:
|
|
126
|
+
return stack.pop(i)[1]
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def current_tool_call() -> Optional[Tuple[str, str]]:
|
|
131
|
+
"""Return the most recent open ``(tool_name, tool_call_id)``, or ``None``."""
|
|
132
|
+
run = _RUN.get()
|
|
133
|
+
if not run or not run["tool_stack"]:
|
|
134
|
+
return None
|
|
135
|
+
return run["tool_stack"][-1]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Agent Skills plugin - dynamic skill loading and discovery.
|
|
2
|
+
|
|
3
|
+
This plugin enables code_puppy to discover, load, and use custom skills
|
|
4
|
+
defined in SKILL.md files. Skills can be placed in user-specific or
|
|
5
|
+
project-specific directories for easy sharing and organization.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .metadata import (
|
|
9
|
+
SkillMetadata,
|
|
10
|
+
get_skill_resources,
|
|
11
|
+
load_full_skill_content,
|
|
12
|
+
parse_skill_metadata,
|
|
13
|
+
parse_yaml_frontmatter,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"SkillMetadata",
|
|
18
|
+
"parse_yaml_frontmatter",
|
|
19
|
+
"parse_skill_metadata",
|
|
20
|
+
"load_full_skill_content",
|
|
21
|
+
"get_skill_resources",
|
|
22
|
+
]
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"""Plugin-level config helpers for agent_skills."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import List, Set
|
|
7
|
+
|
|
8
|
+
from code_puppy.config import get_value, set_value
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_skill_directories() -> List[str]:
|
|
14
|
+
"""Get configured skill directories.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
List of skill directory paths from configuration, normalized to
|
|
18
|
+
POSIX-style forward-slash separators for cross-platform display
|
|
19
|
+
consistency (see the ``display-paths-as-posix`` convention adopted
|
|
20
|
+
by ``plugin_list``). Consumers that need a native ``Path`` wrap the
|
|
21
|
+
string in ``Path(...)``, which accepts either separator on Windows.
|
|
22
|
+
Reads from puppy.cfg [puppy] section under 'skill_directories' key.
|
|
23
|
+
Default: ['~/.code_puppy/skills', './.code_puppy/skills', './skills']
|
|
24
|
+
|
|
25
|
+
The directories are stored as a JSON list in the config.
|
|
26
|
+
"""
|
|
27
|
+
# Try to read from config first
|
|
28
|
+
config_value = get_value("skill_directories")
|
|
29
|
+
|
|
30
|
+
if config_value:
|
|
31
|
+
try:
|
|
32
|
+
# Parse as JSON
|
|
33
|
+
directories = json.loads(config_value)
|
|
34
|
+
# Ensure it's a list
|
|
35
|
+
if isinstance(directories, list):
|
|
36
|
+
return [Path(d).as_posix() for d in directories]
|
|
37
|
+
except json.JSONDecodeError as e:
|
|
38
|
+
logger.error(f"Failed to parse skill_directories config: {e}")
|
|
39
|
+
|
|
40
|
+
# Fallback to defaults
|
|
41
|
+
home_skills = (Path.home() / ".code_puppy" / "skills").as_posix()
|
|
42
|
+
project_config_skills = (Path.cwd() / ".code_puppy" / "skills").as_posix()
|
|
43
|
+
local_skills = (Path.cwd() / "skills").as_posix()
|
|
44
|
+
return [
|
|
45
|
+
home_skills,
|
|
46
|
+
project_config_skills,
|
|
47
|
+
local_skills,
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def add_skill_directory(path: str) -> bool:
|
|
52
|
+
"""Add a directory to the skills search path.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
path: Path to add to the skill directories list.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
True if the directory was added successfully, False otherwise.
|
|
59
|
+
"""
|
|
60
|
+
directories = get_skill_directories()
|
|
61
|
+
|
|
62
|
+
# Check if already exists
|
|
63
|
+
if path in directories:
|
|
64
|
+
logger.info(f"Skill directory already exists: {path}")
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
# Add the new directory
|
|
68
|
+
directories.append(path)
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
# Save back to config as JSON
|
|
72
|
+
set_value("skill_directories", json.dumps(directories))
|
|
73
|
+
logger.info(f"Added skill directory: {path}")
|
|
74
|
+
return True
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.error(f"Failed to add skill directory: {e}")
|
|
77
|
+
return False
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def remove_skill_directory(path: str) -> bool:
|
|
81
|
+
"""Remove a directory from the skills search path.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
path: Path to remove from the skill directories list.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
True if the directory was removed successfully, False otherwise.
|
|
88
|
+
"""
|
|
89
|
+
directories = get_skill_directories()
|
|
90
|
+
|
|
91
|
+
# Check if exists
|
|
92
|
+
if path not in directories:
|
|
93
|
+
logger.info(f"Skill directory not found: {path}")
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
# Remove the directory
|
|
97
|
+
directories.remove(path)
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
# Save back to config as JSON
|
|
101
|
+
set_value("skill_directories", json.dumps(directories))
|
|
102
|
+
logger.info(f"Removed skill directory: {path}")
|
|
103
|
+
return True
|
|
104
|
+
except Exception as e:
|
|
105
|
+
logger.error(f"Failed to remove skill directory: {e}")
|
|
106
|
+
return False
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def get_skills_enabled() -> bool:
|
|
110
|
+
"""Check if skills integration is globally enabled.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
True if skills are globally enabled, False otherwise.
|
|
114
|
+
Reads from 'skills_enabled' config key (default: True).
|
|
115
|
+
"""
|
|
116
|
+
cfg_val = get_value("skills_enabled")
|
|
117
|
+
if cfg_val is None:
|
|
118
|
+
return True # Enabled by default
|
|
119
|
+
return str(cfg_val).strip().lower() in {"1", "true", "yes", "on"}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def set_skills_enabled(enabled: bool) -> None:
|
|
123
|
+
"""Enable or disable skills integration globally.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
enabled: True to enable, False to disable.
|
|
127
|
+
"""
|
|
128
|
+
set_value("skills_enabled", "true" if enabled else "false")
|
|
129
|
+
logger.info(f"Skills integration {'enabled' if enabled else 'disabled'}")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def get_frontmatter_in_system_prompt() -> bool:
|
|
133
|
+
"""Check if skill frontmatter is injected into the system prompt.
|
|
134
|
+
|
|
135
|
+
When enabled (default), each enabled skill's ``name`` + ``description``
|
|
136
|
+
(parsed from the SKILL.md frontmatter) is appended to the system prompt
|
|
137
|
+
so the model can see what skills are available. When disabled, the model
|
|
138
|
+
has no built-in awareness of skills but can still discover / activate
|
|
139
|
+
them via the ``list_or_search_skills`` and ``activate_skill`` tools.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if frontmatter is loaded into the system prompt, False otherwise.
|
|
143
|
+
Reads from ``frontmatter_in_system_prompt`` config key (default: True).
|
|
144
|
+
"""
|
|
145
|
+
cfg_val = get_value("frontmatter_in_system_prompt")
|
|
146
|
+
if cfg_val is None:
|
|
147
|
+
return True # Enabled by default
|
|
148
|
+
return str(cfg_val).strip().lower() in {"1", "true", "yes", "on"}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def set_frontmatter_in_system_prompt(enabled: bool) -> None:
|
|
152
|
+
"""Enable or disable loading frontmatter into the system prompt.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
enabled: True to inject frontmatter, False to skip it.
|
|
156
|
+
"""
|
|
157
|
+
set_value("frontmatter_in_system_prompt", "true" if enabled else "false")
|
|
158
|
+
logger.info(f"Frontmatter in system prompt {'enabled' if enabled else 'disabled'}")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def get_disabled_skills() -> Set[str]:
|
|
162
|
+
"""Get set of explicitly disabled skill names.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Set of skill names that are disabled.
|
|
166
|
+
Reads from 'disabled_skills' config key as a JSON list.
|
|
167
|
+
"""
|
|
168
|
+
config_value = get_value("disabled_skills")
|
|
169
|
+
|
|
170
|
+
if config_value:
|
|
171
|
+
try:
|
|
172
|
+
# Parse as JSON
|
|
173
|
+
disabled_list = json.loads(config_value)
|
|
174
|
+
# Ensure it's a list and convert to set
|
|
175
|
+
if isinstance(disabled_list, list):
|
|
176
|
+
return set(disabled_list)
|
|
177
|
+
except json.JSONDecodeError as e:
|
|
178
|
+
logger.error(f"Failed to parse disabled_skills config: {e}")
|
|
179
|
+
|
|
180
|
+
return set()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def set_skill_disabled(skill_name: str, disabled: bool) -> None:
|
|
184
|
+
"""Disable or re-enable a specific skill.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
skill_name: Name of the skill to disable/enable.
|
|
188
|
+
disabled: True to disable, False to enable.
|
|
189
|
+
"""
|
|
190
|
+
disabled_skills = get_disabled_skills()
|
|
191
|
+
|
|
192
|
+
if disabled:
|
|
193
|
+
# Add to disabled set
|
|
194
|
+
if skill_name in disabled_skills:
|
|
195
|
+
logger.info(f"Skill already disabled: {skill_name}")
|
|
196
|
+
return
|
|
197
|
+
disabled_skills.add(skill_name)
|
|
198
|
+
logger.info(f"Disabled skill: {skill_name}")
|
|
199
|
+
else:
|
|
200
|
+
# Remove from disabled set
|
|
201
|
+
if skill_name not in disabled_skills:
|
|
202
|
+
logger.info(f"Skill already enabled: {skill_name}")
|
|
203
|
+
return
|
|
204
|
+
disabled_skills.remove(skill_name)
|
|
205
|
+
logger.info(f"Enabled skill: {skill_name}")
|
|
206
|
+
|
|
207
|
+
# Save back to config as JSON
|
|
208
|
+
set_value("disabled_skills", json.dumps(list(disabled_skills)))
|