3.0 KiB
Skill Resolution
The SkillResolver flattens a skill's tool set by recursively resolving
includes, collecting tool references, inline tools, and external sources
into a deterministic ordered list.
Resolution Algorithm
-
Cycle detection -- Before descending into includes, check if the current skill has already been visited in this resolution path. If so, raise a
ValueErrorwith the full cycle path trace. -
Depth-first include resolution -- Process each
SkillIncludeby recursively resolving the included skill first. This ensures that tools from deeper includes appear earlier in the final order. -
Tool ref collection -- Add tool_refs from the current skill. If a tool name already exists (from an include), it is replaced (last-wins semantics for overrides).
-
Inline tool collection -- Anonymous tools are keyed as
{skill_name}/_anon_{index}and added in definition order. -
MCP source collection -- For MCP servers with explicit tool lists, each tool is added as
mcp:{server}/{tool_name}. -
Agent skill collection -- Each agent skill path is added as
agent_skill:{path}.
De-duplication
When the same tool name appears multiple times (e.g., from overlapping includes), the last occurrence wins. The tool's position in the ordered list is preserved from its first appearance, but the entry metadata is updated.
Override Application
Overrides defined in the skill's overrides dict are applied to matching
tool refs during resolution. The overrides dict is keyed by tool name and
contains arbitrary metadata that is attached to the ResolvedToolEntry.
Cycle Detection
The resolver tracks the current resolution path (stack of skill names).
If a skill is encountered that is already on the path, a ValueError is
raised with a human-readable path trace:
Cycle detected in skill includes: local/a -> local/b -> local/a
CapabilitySummary
After resolution, SkillResolver.compute_capability_summary() aggregates
capability metadata from inline tools to produce a SkillCapabilitySummary:
- Counts read-only, write, and checkpointable tools
- Detects side effects across all inline tools
- Counts MCP and agent skill sources
API
resolver = SkillResolver()
# Resolve tools
entries = resolver.resolve_tools(skill, skill_lookup_dict)
# Compute summary
summary = resolver.compute_capability_summary(skill, entries)
ResolvedToolEntry
Each entry in the resolved list contains:
| Field | Type | Description |
|---|---|---|
name |
str |
Tool name or generated key |
source_skill |
str |
Skill that contributed this tool |
is_inline |
bool |
Whether this is an inline tool |
inline_tool |
SkillInlineTool | None |
Inline definition (if applicable) |
overrides |
dict[str, Any] |
Applied overrides |