Files
cleveragents-core/docs/reference/skill_resolution.md
T
Jeff 20321f21ee
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / security (push) Waiting to run
CI / quality (push) Waiting to run
CI / unit_tests (push) Waiting to run
CI / integration_tests (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
feat(skill): add skill domain model and resolver
2026-02-14 03:54:14 +00:00

85 lines
3.0 KiB
Markdown

# 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
1. **Cycle detection** -- Before descending into includes, check if the
current skill has already been visited in this resolution path. If so,
raise a `ValueError` with the full cycle path trace.
2. **Depth-first include resolution** -- Process each `SkillInclude` by
recursively resolving the included skill first. This ensures that
tools from deeper includes appear earlier in the final order.
3. **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).
4. **Inline tool collection** -- Anonymous tools are keyed as
`{skill_name}/_anon_{index}` and added in definition order.
5. **MCP source collection** -- For MCP servers with explicit tool lists,
each tool is added as `mcp:{server}/{tool_name}`.
6. **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
```python
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 |