let skills run agentic + gate on integrations via requires:#20
Merged
Conversation
skills are no longer tool-less single-shot turns. claude tiers get the full claude_code preset (agent/task still denied); ollama tier routes through the same runToolLoop the regular ollama turn uses when integrations are wired. budget is per-skill max_turns frontmatter (1-10, default 1), bounded by the existing cost cap + loop detector + three-tier policy. self-tool entry filtered from the catalog the body sees (direct recursion impossible); indirect cycles bounded by max_turns and the shared loop detector. new requires: frontmatter gates a skill on named integrations being loaded at boot. bare string or array. missing deps -> skill skipped with skills.load_error, absent from /help and telegram autocomplete. loadSkillsSync gains a 4th arg loadedIntegrationNames, sourced from integration result.sources filtered to toolCount > 0 (probe-failed integrations do not satisfy the gate). docs (features, usage, architecture, glossary, roadmap) updated to match. stale scheduler PLAN.md at repo root deleted (shipped in bff8ca4; canonical story now lives in usage + architecture).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Two related changes that take operator-defined skills from "templated single-shot prompts" to a real workflow primitive, while making the boot-time honesty story tighter.
1. Skills run with the full tool surface (skills-as-agents)
The v1 design treated a
SKILL.mdas a one-shot text transform:maxTurns: 1,disallowedToolsdeny-list of everything useful,canUseTool: deny-all. That ruled out the whole class of skills the operator actually wants — "append this entry to my Notion Journal," "draft a Gmail reply about X," "look this up in the projects DB." Those need tool calls.This PR lifts the constraint without weakening the safety story:
primary/secondary).runSkillnow passes the sameclaude_codetool preset a normal turn uses. OnlyAgentandTaskstay denied (sub-agents off at the SDK + policy layers, belt-and-suspenders). The interactivecanUseToolfactory plus thePreToolUse/PostToolUse/PostToolUseFailurehooks come from the same factoryrunAgentuses, so cost cap, loop detector, and the Telegram-confirm UX behave identically inside a skill. Integrations MCP server attached when present.runSkillBareWithToolsroutes the body through the samerunToolLoopdriver as a regular Ollama turn whenOllamaSkillDeps.tools + toolTiers + brokerare wired. Self-tool entry (skills__<self>) filtered out of the catalog the body sees — direct recursion impossible. Pure text-transform skills (no integrations / tools wired) still fall through to the one-shot/api/chatpath; back-compat preserved.max_turns(integer 1–10, default 1). Doubles as the SDKmaxTurnson Claude tiers andrunToolLoop.maxIterationson Ollama — one knob constrains both paths. Indirect cycles (A →skills__B→skills__A) bounded bymax_turnsplus the shared loop detector (third identical(tool, input)per turn → deny).2.
requires:frontmatter gates skills on integration depsToday a
/logskill that callsnotion_searchappears in/help+ autocomplete regardless of whetherNOTION_API_KEYis set. Operator types/log foo→❌ Failed to log: notion_search not available. Gate is invisible until use-time.New
requires:field (bare string or string array, entries match[a-z][a-z0-9_-]{0,31}) names integrations the skill depends on. Missing at boot → skill skipped with a non-fatalskills.load_errorand absent from the registry,/help, andsetMyCommandsautocomplete.loadSkillsSyncgains a 4th argloadedIntegrationNames, sourced fromintegration result.sources.filter(s => s.toolCount > 0)(probe-failed integrations do NOT satisfy the gate — a skill that callsnotion_searchneeds the tool to actually exist).Omitting
requires:preserves back-compat —tldrand friends still load unconditionally.Verification
npm run typecheckcleanbun test740/740 green (10 new tests forrequires:inskills.test.ts, fixture updates inskill-tools.test.ts)NOTION_API_KEYabsent →/logabsent from/help+ Telegram autocomplete; key set + Journal database shared with the Solrac integration →/log <text>chainsnotion_search→notion_create_pageand returns the page URL. Confirmed end-to-end in this session.Docs
Updated in this PR (same logical change, easier to review together):
docs/USAGE.md—SKILL.mdschema example now includesmax_turns; rewrote "What skills can do," Ollama-tier cost paragraph, recursion-safety bullet, latency note.docs/ARCHITECTURE.md— frontmatter schema (2 required + 4 optional), Claude + Ollama execution paragraphs, "Skills as tools" header now disambiguates the two axes (skills using tools vs skills callable as tools by the agent), recursion-safety mechanism (self-filter + max_turns + loop detector, not zero-tools).docs/FEATURES.md— skills bullet updated.docs/GLOSSARY.md— Solrac-skill entry updated.docs/ROADMAP.md— OQ#16 restructured into the two axes; Phase 2 reframed as axis-2 expansion only.Stale
solrac/PLAN.md(the shipped scheduler plan frombff8ca4) deleted — canonical story now lives indocs/USAGE.md+docs/ARCHITECTURE.md.Anti-goal check
No anti-goal reversal. Pure additive feature work. SDK pin (
0.2.119) untouched.Deferred (non-blocking)
requires: not implemented. Integration granularity only. Avoids ordering games./helphint for skipped skills: silent. Boot log is the audit trail.SOLRAC_SKILL_<NAME>_DISABLED): separate axis from dep gating.requires_tools: integration granularity sufficient at v1.Test plan
runSkill(src/commands.ts) and confirms the hook trio mirrorsrunAgent's pattern (agent.ts)runSkillBareWithToolsfilters the self-tool entry before passing the catalog torunToolLooploadedIntegrationNamesis built fromresult.sources.filter(s => s.toolCount > 0)(notresult.tools, which would let a probe-failed integration with cached metadata satisfy the gate)USAGE/ARCHITECTURE/GLOSSARY/ROADMAP