Files
cleveragents-core/docs/reference/skills_protocol.md
T

183 lines
5.5 KiB
Markdown

# Skill Protocol Reference
The **Skill Protocol** defines the type contracts used for skill discovery,
composition, execution, and error reporting within CleverAgents v3.
All protocol types are frozen Pydantic `BaseModel` instances, ensuring
immutability after construction.
---
## Overview
| Type | Purpose |
|------|---------|
| `SkillErrorType` | `StrEnum` of all skill error categories |
| `SkillError` | Structured error payload |
| `SkillMetadata` | Lightweight discovery descriptor |
| `SkillDefinition` | Full skill + resolved tools + metadata |
| `SkillResult` | Outcome of a skill-tool invocation |
---
## SkillErrorType
A `StrEnum` with the following members:
| Value | Description |
|-------|-------------|
| `skill_not_found` | The requested skill does not exist |
| `resolution_failure` | Skill resolution failed (missing include, etc.) |
| `cycle_detected` | Circular dependency in skill includes |
| `tool_activation_failure` | Tool could not be activated |
| `tool_execution_failure` | Tool execution failed at runtime |
| `validation_error` | Input/output schema validation failed |
| `permission_denied` | Operation not permitted |
---
## SkillError
Structured error payload for skill operations.
### Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `error_type` | `SkillErrorType` | Yes | Error category |
| `message` | `str` | Yes | Human-readable description |
| `details` | `dict[str, Any]` | No | Diagnostic context |
| `skill_name` | `str` | Yes | Originating skill |
| `tool_name` | `str \| None` | No | Originating tool |
---
## SkillMetadata
Lightweight metadata for skill discovery and catalogue listings.
### Fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `name` | `str` | — | Namespaced skill name |
| `description` | `str` | — | Skill description |
| `version` | `str` | `"0.0.0"` | Semantic version |
| `tool_count` | `int` | `0` | Number of resolved tools |
| `capability_summary` | `SkillCapabilitySummary` | empty | Aggregated capabilities |
| `source_types` | `list[str]` | `[]` | Distinct source type labels |
| `writes` | `bool` | `False` | Any tool can write |
| `read_only` | `bool` | `True` | Entire skill is read-only |
### Factory: `from_skill()`
```python
meta = SkillMetadata.from_skill(skill, resolved=resolved_entries, version="1.0.0")
```
Derives `writes` and `read_only` from the `SkillCapabilitySummary`:
- `writes = True` when `write_tools > 0` or `has_side_effects` is true
- `read_only = True` when `write_tools == 0` and no side effects
### Writes / Read-Only Gating
The `writes` and `read_only` flags are propagated to the ToolRuntime
gating layer. A skill marked `read_only=True` will never be allowed
to trigger a write-capable tool at runtime.
---
## SkillDefinition
Full skill definition combining the domain `Skill` model, resolved tools,
and pre-computed metadata.
### Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `skill` | `Skill` | Yes | Domain-level Skill model |
| `resolved_tools` | `list[ResolvedToolEntry]` | No | Flattened tool set |
| `metadata` | `SkillMetadata` | Yes | Pre-computed metadata |
| `input_schema` | `dict \| None` | No | JSON Schema for inputs |
| `output_schema` | `dict \| None` | No | JSON Schema for outputs |
### JSON Schema Validation
When `input_schema` or `output_schema` is provided, it **must** include a
`"type"` key to be considered a valid JSON Schema object. The validator
rejects schemas missing this key at construction time.
```json
{
"type": "object",
"properties": {
"query": {"type": "string"}
}
}
```
### Writes Consistency
The model validator checks that if `metadata.read_only` is `True`, none
of the resolved inline tools declare `writes=True`. A mismatch raises
a `ValidationError`.
---
## SkillResult
Outcome of a single skill-tool invocation.
### Fields
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `skill_name` | `str` | — | Invoked skill |
| `tool_name` | `str` | — | Invoked tool |
| `success` | `bool` | — | Whether invocation succeeded |
| `output_data` | `Any` | `None` | Tool output |
| `error` | `SkillError \| None` | `None` | Error on failure |
| `duration_ms` | `float` | `0.0` | Execution time in ms |
| `resource_changes` | `list[dict]` | `[]` | Resource change descriptors |
---
## Error Mapping
The `map_tool_error()` helper normalises arbitrary exceptions into
`SkillError` payloads:
```python
from cleveragents.skills.protocol import map_tool_error
try:
run_tool(...)
except Exception as exc:
error = map_tool_error(exc, skill_name="local/my-skill", tool_name="local/my-tool")
```
### Mapping Rules
| Exception Type | Message Contains | Mapped To |
|----------------|------------------|-----------|
| `ValueError` | `"cycle"` | `CYCLE_DETECTED` |
| `ValueError` | `"not found"` | `SKILL_NOT_FOUND` |
| `ValueError` | (other) | `RESOLUTION_FAILURE` |
| `PermissionError` | — | `PERMISSION_DENIED` |
| `ValidationError` | — | `VALIDATION_ERROR` |
| Any | `"activation"` | `TOOL_ACTIVATION_FAILURE` |
| Any | (other) | `TOOL_EXECUTION_FAILURE` |
---
## JSON Schema Rules Summary
1. **Input/output schemas** on `SkillDefinition` must include `"type"`.
2. **Writes/read_only metadata** on `SkillMetadata` must be consistent
with the resolved tool capabilities.
3. **Error payloads** always include `skill_name`; `tool_name` is
optional but recommended.
4. All protocol types are **frozen** (immutable after construction).