feat(chat-workflow): port skill discovery + skillTool (PR 6, slim)

Merged
SW
5mo ago
+1071-19

Summary

Ports the `skill` composite tool from open-agents along with the skill discovery layer it depends on. The handler now scans `${workingDirectory}/skills/` before workflow start and threads the catalog into `AgentContext.skills`. The `skill` tool registers in `buildAgentTools` only when the catalog is non-empty.

New

Skills layer (`lib/skills/`):

  • `skillTypes.ts` (types + Zod schema), `parseSkillFrontmatter.ts`, `extractSkillBody.ts`, `substituteArguments.ts`, `injectSkillDirectory.ts`, `discoverSkills.ts`, `getSandboxSkillDirectories.ts`

Tool: `lib/agent/tools/skillTool.ts` — case-insensitive name match, respects `disable-model-invocation`, surfaces available-skills hint on unknown names. Loads SKILL.md → extractSkillBody → injectSkillDirectory → substituteArguments → returns to model.

Wire-up: AgentContext gains `skills?`; buildAgentTools conditional registration; handler connects sandbox + discoverSkills before `start(workflow)`.

Slim choices (follow-ups)

  • Project skills only — global `~/.skills/` scan comes later, alongside short-lived token minting (the highest-value global skill, `recoup-api`, needs that token to be useful)
  • No token minting — `skill` tool returns SKILL.md to the model; the recoup-api skill's curl examples wouldn't authenticate without ad-hoc credentials. Token design lands as a focused PR

Verification

  • 35 new tests; full suite 3049/3049 pass
  • Lint clean, production build succeeds
  • E2E preview verification running now against `recoupable/org-rostrum-pacific-...`

🤖 Generated with Claude Code


Summary by cubic

Adds global skill discovery and a new skill tool to the chat workflow. The handler scans $HOME/.agents/skills before start and registers skill only when skills exist, enabling slash-command-style execution without noise.

  • New Features

    • Skill discovery: reads SKILL.md/skill.md, validates frontmatter, dedupes by name, and skips names that shadow built-ins (model, resume, new).
    • skill tool: case-insensitive name match; blocks skills with disable-model-invocation; loads file, strips frontmatter, injects Skill directory: <path>, and substitutes $ARGUMENTS.
    • Wire-up: AgentContext.skills added; buildAgentTools({ skills }) conditionally includes skill; runAgentStep passes skills; handleChatWorkflowStream connects sandbox, discovers skills (best-effort), and threads the catalog.
  • Refactors

    • Simplified discovery to global-only: getSandboxSkillDirectories now returns ${HOME}/.agents/skills.
    • Extracted helpers for clarity and reuse: getSkills (context accessor), findSkillFile (SKILL.md resolution), getGlobalSkillsDirectory (global path resolver).

Summary by CodeRabbit

  • New Features
    • AI agent now discovers and invokes custom project skills from workspace directories
    • Model can dynamically call skills with optional arguments for flexible execution
    • Skills are automatically scanned from project-level and designated global directories at workflow start
    • Skill invocation includes metadata about available skills and error handling for invalid requests

Review Change Stack