feat: structured skill packages with config overrides, chaining, and TUI integration
Add a skill package system where each skill is a directory with a skill.yaml manifest and prompt markdown files. Skills support /command triggers, scoped config overrides (temperature, max_tokens, tool filtering), chain dependencies with cycle-safe resolution, and a finish_skill completion signal. Includes four built-in skills: explore, brainstorm, write-document, and plan. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,7 @@ from app.utils.logging import get_logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.services.debug_log import DebugLogger
|
||||
from app.services.skill_runner import SkillRunner
|
||||
from app.services.skills import SkillsManager
|
||||
|
||||
logger = get_logger(__name__)
|
||||
@@ -45,6 +46,7 @@ class AgentLoop:
|
||||
display: DisplayAdapter | None = None,
|
||||
debug_logger: DebugLogger | None = None,
|
||||
skills_manager: SkillsManager | None = None,
|
||||
skill_runner: SkillRunner | None = None,
|
||||
) -> None:
|
||||
self._config = config
|
||||
self._ctx = ctx
|
||||
@@ -55,6 +57,7 @@ class AgentLoop:
|
||||
self._display = display
|
||||
self._debug = debug_logger
|
||||
self._skills = skills_manager
|
||||
self._skill_runner = skill_runner
|
||||
self._tools_schema = registry.get_openai_tools_schema()
|
||||
self._system_prompt = self._build_system_prompt()
|
||||
self._cancelled = False
|
||||
@@ -81,6 +84,11 @@ class AgentLoop:
|
||||
)
|
||||
if self._skills:
|
||||
prompt += self._skills.get_system_prompt_snippet()
|
||||
if self._skill_runner and self._skill_runner.is_active:
|
||||
prompt += (
|
||||
f"\n\nCurrently active skill: {self._skill_runner.active_skill_name}. "
|
||||
"When the skill's objective is complete, call the `finish_skill` tool."
|
||||
)
|
||||
return prompt
|
||||
|
||||
def _get_messages_with_system_prompt(self) -> list[Message]:
|
||||
@@ -199,7 +207,12 @@ class AgentLoop:
|
||||
name=result.tool_name,
|
||||
)
|
||||
|
||||
# Check if finish tool was called
|
||||
# Rebuild tools schema and system prompt if skill state may have changed
|
||||
if any(r.tool_name in ("load_skill", "finish_skill") for r in results):
|
||||
self._tools_schema = self._registry.get_openai_tools_schema()
|
||||
self._system_prompt = self._build_system_prompt()
|
||||
|
||||
# Check if finish tool was called (finish_skill does NOT break the loop)
|
||||
if any(r.tool_name == "finish" for r in results):
|
||||
break
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user