Types API Reference
Type definitions for pydantic-ai-skills.
Overview
The package uses dataclasses for type-safe skill representation:
Skill- Complete skill with metadata, resources, and scriptsSkillResource- Resource file (content) or callable resource within a skillSkillScript- Executable script (file or callable function) within a skillSkillWrapper- Generic decorator return type for@toolset.skill()supporting attachment of resources and scripts
File-Based vs Programmatic
These types support both file-based skills (loaded from directories) and programmatic skills (created in Python code). For file-based skills, see Creating Skills. For programmatic skills, see Programmatic Skills. For advanced patterns, see Advanced Features.
Skill Class
A skill instance with metadata, content, resources, and scripts.
Can be created programmatically or loaded from filesystem directories.
Example - Programmatic skill with decorators
from pydantic_ai import RunContext
from pydantic_ai.toolsets.skills import Skill, SkillResource
# Create a skill (uri is optional and only for file-based skills)
my_skill = Skill(
name='hr-analytics-skill',
description='Skill for HR analytics',
content='Use this skill for HR data analysis...',
resources=[
SkillResource(name='table-schemas', content='Schema definitions...')
]
)
# Add callable resources
@my_skill.resource
def get_db_context() -> str:
return "Dynamic database context."
@my_skill.resource
async def get_samples(ctx: RunContext[MyDeps]) -> str:
return await ctx.deps.get_samples()
# Add callable scripts
@my_skill.script
async def load_dataset(ctx: RunContext[MyDeps]) -> str:
await ctx.deps.load_data()
return 'Dataset loaded.'
@my_skill.script
async def run_query(ctx: RunContext[MyDeps], query: str) -> str:
result = await ctx.deps.db.execute(query)
return str(result)
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Skill name. |
description |
str
|
Brief description of what the skill does. |
content |
str
|
Main instructional content. |
license |
str | None
|
Optional license information. |
compatibility |
str | None
|
Optional environment requirements (max 500 chars). |
resources |
list[SkillResource]
|
List of resources (files or callables). |
scripts |
list[SkillScript]
|
List of scripts (functions or file-based). |
uri |
str | None
|
URI for the skill's base location. When not provided, a |
metadata |
dict[str, Any] | None
|
Additional metadata fields. |
Source code in pydantic_ai_skills/types.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
__post_init__
__post_init__() -> None
Auto-assign a skill:// URI for any Skill instantiated with no URI.
This fires for any Skill where uri=None at construction time, including
programmatic skills. Filesystem-based skills have their uri set explicitly
by the filesystem discovery/loading utilities (overwriting this default), so the
auto-assigned value is effectively a transient default for those cases.
The resulting URI follows the convention: skill://{name}.
Source code in pydantic_ai_skills/types.py
251 252 253 254 255 256 257 258 259 260 261 | |
resource
resource(func: Callable[..., Any] | None = None, *, name: str | None = None, description: str | None = None, takes_ctx: bool | None = None, docstring_format: DocstringFormat = 'auto', schema_generator: type[GenerateJsonSchema] | None = None) -> Callable[..., Any] | Callable[[Callable[..., Any]], Callable[..., Any]]
Decorator to register a callable as a skill resource.
The decorated function can optionally take RunContext as its first argument for accessing dependencies. This is auto-detected if not specified.
Example
@my_skill.resource
def get_context() -> str:
return "Static context"
@my_skill.resource
async def get_data(ctx: RunContext[MyDeps]) -> str:
return await ctx.deps.fetch_data()
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any] | None
|
The function to register as a resource. |
None
|
name
|
str | None
|
Resource name (defaults to function name). |
None
|
description
|
str | None
|
Resource description (inferred from docstring if not provided). |
None
|
takes_ctx
|
bool | None
|
Whether function takes RunContext (auto-detected if None). |
None
|
docstring_format
|
DocstringFormat
|
Format of the docstring ('auto', 'google', 'numpy', 'sphinx'). |
'auto'
|
schema_generator
|
type[GenerateJsonSchema] | None
|
Custom JSON schema generator class. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any] | Callable[[Callable[..., Any]], Callable[..., Any]]
|
The original function (allows use as decorator). |
Source code in pydantic_ai_skills/types.py
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | |
script
script(func: Callable[..., Any] | None = None, *, name: str | None = None, description: str | None = None, takes_ctx: bool | None = None, docstring_format: DocstringFormat = 'auto', schema_generator: type[GenerateJsonSchema] | None = None) -> Callable[..., Any]
Decorator to register a callable as a skill script.
The decorated function can optionally take RunContext as its first argument for accessing dependencies. This is auto-detected if not specified.
Scripts accept named arguments (kwargs) matching their function signature.
Example
@my_skill.script
async def load_data(ctx: RunContext[MyDeps]) -> str:
await ctx.deps.load()
return 'Loaded'
@my_skill.script
async def run_query(ctx: RunContext[MyDeps], query: str, limit: int = 10) -> str:
result = await ctx.deps.db.execute(query, limit)
return str(result)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
Callable[..., Any] | None
|
The function to register as a script. |
None
|
name
|
str | None
|
Script name (defaults to function name). |
None
|
description
|
str | None
|
Script description (inferred from docstring if not provided). |
None
|
takes_ctx
|
bool | None
|
Whether function takes RunContext (auto-detected if None). |
None
|
docstring_format
|
DocstringFormat
|
Format of the docstring ('auto', 'google', 'numpy', 'sphinx'). |
'auto'
|
schema_generator
|
type[GenerateJsonSchema] | None
|
Custom JSON schema generator class. |
None
|
Returns:
| Type | Description |
|---|---|
Callable[..., Any]
|
The original function (allows use as decorator). |
Source code in pydantic_ai_skills/types.py
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
Key Attributes
| Attribute | Type | Description |
|---|---|---|
name |
str |
Unique skill identifier. Pattern: ^[a-z0-9]+(-[a-z0-9]+)*$, max 64 chars. |
description |
str |
Brief description of the skill. Max 1024 characters. |
content |
str |
Main skill instructions in markdown format. |
resources |
list[SkillResource] \| None |
Additional resources (documentation, schemas, data). |
scripts |
list[SkillScript] \| None |
Executable scripts (file-based or callable functions). |
uri |
str \| None |
Base URI/path. Set for file-based skills, None for programmatic. |
metadata |
dict[str, Any] \| None |
Custom metadata (version, author, license, compatibility, etc.). |
Methods
| Method | Description |
|---|---|
@resource |
Decorator to attach a callable resource to the skill. |
@script |
Decorator to attach a callable script to the skill. |
SkillResource Class
A skill resource: static content or callable that generates content.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Resource name (e.g., "FORMS.md" or "get_samples"). |
description |
str | None
|
Description of what the resource provides. |
content |
str | None
|
Static content string. |
function |
Callable[..., Any | Awaitable[Any]] | None
|
Callable that generates content dynamically. |
takes_ctx |
bool
|
Whether the function takes RunContext as first argument. |
function_schema |
FunctionSchema | None
|
Function schema for callable resources (auto-generated). |
uri |
str | None
|
Optional URI string for file-based resources (internal use). |
Source code in pydantic_ai_skills/types.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
__post_init__
__post_init__() -> None
Validate that resource has either content, function, or uri.
For programmatic resources, content or function is required. For file-based resources (subclasses), uri is sufficient.
Source code in pydantic_ai_skills/types.py
94 95 96 97 98 99 100 101 102 103 | |
load
async
load(ctx: Any, args: dict[str, Any] | None = None) -> Any
Load resource content.
File-based subclasses override to load from disk.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
Any
|
RunContext for accessing dependencies. |
required |
args
|
dict[str, Any] | None
|
Named arguments for callable resources. |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Resource content (any type). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If resource has no content or function. |
Source code in pydantic_ai_skills/types.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | |
Key Attributes
| Attribute | Type | Description |
|---|---|---|
name |
str |
Resource identifier within the skill. |
description |
str \| None |
Optional description of the resource. |
content |
str \| None |
Static content (for static resources or file-based). |
function |
Callable \| None |
Callable function (for programmatic dynamic resources). |
takes_ctx |
bool |
Whether function accepts RunContext as first parameter. Auto-detected. |
function_schema |
FunctionSchema \| None |
JSON schema for function parameters (Pydantic AI generated). |
uri |
str \| None |
File URI for file-based resources. |
File-Based Variants
FileSkillResource - Loads resource content from file:
- Auto-detects file type by extension
- Supports: .md, .json, .yaml, .yml, .csv, .xml, .txt
- JSON/YAML files are parsed; others returned as text
- Automatically validates path traversal safety
SkillScript Class
An executable script within a skill.
Can be programmatic (function) or file-based (executed via subprocess).
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Script name (includes .py extension for file-based). |
description |
str | None
|
Description of what the script does. |
function |
Callable[..., Any] | None
|
Callable that implements the script (programmatic). |
takes_ctx |
bool
|
Whether the function takes RunContext as first argument. |
function_schema |
FunctionSchema | None
|
Function schema for callable scripts (auto-generated). |
uri |
str | None
|
Optional URI for file-based scripts (internal use). |
skill_name |
str | None
|
Optional parent skill name (internal use). |
Source code in pydantic_ai_skills/types.py
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
__post_init__
__post_init__() -> None
Validate that script has either function or uri.
For programmatic scripts, function is required. For file-based scripts (subclasses), uri is sufficient.
Source code in pydantic_ai_skills/types.py
152 153 154 155 156 157 158 159 160 161 | |
run
async
run(ctx: Any, args: dict[str, Any] | None = None) -> Any
Execute the script.
File-based subclasses override to execute via subprocess.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
Any
|
RunContext for accessing dependencies. |
required |
args
|
dict[str, Any] | None
|
Named arguments for the script. |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Script output (any type). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If script has no function. |
Source code in pydantic_ai_skills/types.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
Key Attributes
| Attribute | Type | Description |
|---|---|---|
name |
str |
Script identifier within the skill. |
description |
str \| None |
Optional description of what the script does. |
function |
Callable \| None |
Callable Python function (for programmatic scripts). |
takes_ctx |
bool |
Whether function accepts RunContext as first parameter. Auto-detected. |
function_schema |
FunctionSchema \| None |
JSON schema for function parameters. |
uri |
str \| None |
File URI for file-based scripts. |
skill_name |
str \| None |
Parent skill name (auto-set for file-based scripts). |
File-Based Variants
LocalSkillScriptExecutor - Executes file-based scripts:
- Runs Python scripts via subprocess
- Converts dict arguments to CLI flags: {"query": "test"} → --query test
- Combines stdout/stderr
- Default timeout: 30 seconds
- Execution directory: script's parent folder
CallableSkillScriptExecutor - Executes callable functions:
- Runs Python functions directly
- Passes dict arguments as function kwargs
- Supports async functions
- Receives RunContext for dependency access
SkillWrapper[T] Class
Generic type returned by @toolset.skill() decorator that enables type-safe dependency injection and attachment of resources/scripts.
Generic Parameter: T - The dependency type available in RunContext[T]
Decorators
@skill.resource
def my_resource() -> str:
"""Attach a callable resource."""
return "..."
@skill.resource
async def context_resource(ctx: RunContext[MyDeps]) -> str:
"""Resource with access to dependencies."""
return str(ctx.deps)
@skill.script
def my_script() -> str:
"""Attach a callable script."""
return "..."
@skill.script
async def context_script(ctx: RunContext[MyDeps], param: str) -> str:
"""Script with dependencies and parameters."""
return f"Executed with {param}"
Utility Functions
normalize_skill_name()
def normalize_skill_name(name: str) -> str:
"""Convert a name to valid skill name format.
Rules:
- Convert underscores to hyphens
- Convert to lowercase
- Ensure matches ^[a-z0-9]+(-[a-z0-9]+)*$
Args:
name: Input string (e.g., "MySkillName", "my_skill_name")
Returns:
Normalized skill name (e.g., "my-skill-name")
"""
Type Structures
Skill Structure
Skill
├── name: str # Unique identifier (lowercase, hyphens only)
├── description: str # Brief description (max 1024 chars)
├── content: str # Main instructions (markdown)
├── resources: list[SkillResource] | None # Additional resources
├── scripts: list[SkillScript] | None # Executable scripts
├── uri: str | None # Base path (file-based: set, programmatic: None)
└── metadata: dict[str, Any] | None # Custom fields (version, author, license, etc.)
SkillResource Structure
SkillResource
├── name: str # Resource identifier
├── description: str | None # Optional description
├── content: str | None # Static content
├── function: Callable | None # Callable (for dynamic resources)
├── takes_ctx: bool # Requires RunContext
├── function_schema: FunctionSchema| None
└── uri: str | None # File path (file-based only)
SkillScript Structure
SkillScript
├── name: str # Script identifier
├── description: str | None # Optional description
├── function: Callable | None # Callable (for programmatic)
├── takes_ctx: bool # Requires RunContext
├── function_schema: FunctionSchema| None
├── uri: str | None # File path (file-based only)
└── skill_name: str | None # Parent skill (file-based only)
Common Metadata Fields
When creating skills, these metadata fields are commonly used:
| Field | Type | Purpose |
|---|---|---|
version |
str |
Semantic version (e.g., "1.0.0") |
author |
str |
Creator/maintainer |
license |
str |
License identifier (e.g., "Apache-2.0") |
compatibility |
str |
Environment requirements |
tags |
list[str] |
Categorization tags |
requires |
dict[str, str] |
External dependencies |
deprecated |
bool |
Whether skill is deprecated |
deprecation_message |
str |
Explanation if deprecated |
Usage Examples
Creating Programmatic Skills
from pydantic_ai import RunContext
from pydantic_ai.toolsets.skills import Skill, SkillResource
# Create a skill with static resources
my_skill = Skill(
name='my-skill',
description='A programmatic skill',
content='Instructions for using this skill...',
resources=[
SkillResource(
name='reference',
content='## Reference\n\nStatic documentation here...'
)
]
)
# Add dynamic resources
@my_skill.resource
def get_info() -> str:
"""Get dynamic information."""
return "Dynamic content generated at runtime"
@my_skill.resource
async def get_data(ctx: RunContext[MyDeps]) -> str:
"""Get data from dependencies."""
return await ctx.deps.fetch_data()
# Add scripts
@my_skill.script
async def process(ctx: RunContext[MyDeps], query: str) -> str:
"""Process a query.
Args:
query: The query to process
"""
result = await ctx.deps.process(query)
return f"Processed: {result}"
Working with File-Based Skills
from pydantic_ai_skills import SkillsToolset
toolset = SkillsToolset(directories=["./skills"])
# Access skills
for name, skill in toolset.skills.items():
print(f"\nSkill: {name}")
print(f" Description: {skill.description}")
if skill.uri: # File-based skill
print(f" URI: {skill.uri}")
# Access metadata
if skill.metadata and "version" in skill.metadata:
print(f" Version: {skill.metadata['version']}")
# List resources
if skill.resources:
print(f" Resources:")
for resource in skill.resources:
print(f" - {resource.name}")
# List scripts
if skill.scripts:
print(f" Scripts:")
for script in skill.scripts:
print(f" - {script.name}")
Mixing Programmatic and File-Based Skills
from pydantic_ai import RunContext
from pydantic_ai.toolsets.skills import Skill, SkillsToolset
# Create programmatic skill
custom_skill = Skill(
name='custom-skill',
description='Programmatic skill',
content='Custom instructions...'
)
@custom_skill.script
async def custom_action(ctx: RunContext[MyDeps]) -> str:
"""Perform custom action."""
return 'Action completed'
# Combine with file-based skills
toolset = SkillsToolset(
directories=["./skills"], # File-based skills
skills=[custom_skill] # Programmatic skills
)
print(f"Total skills: {len(toolset.skills)}")
Type Structures
Skill Structure
Skill
├── name: str # Unique skill identifier
├── description: str # Brief description
├── content: str # Main instructions (markdown)
├── resources: list[SkillResource] # Additional resources
├── scripts: list[SkillScript] # Executable scripts
├── uri: str | None # Base URI (file-based only)
└── metadata: dict[str, Any] | None # Additional metadata
SkillResource Structure
SkillResource
├── name: str # Resource identifier
├── description: str | None # Optional description
├── content: str | None # Static content (for file-based or inline)
├── function: Callable | None # Callable function (programmatic)
├── takes_ctx: bool # Whether function takes RunContext
├── function_schema: FunctionSchema | None # Schema for callable
└── uri: str | None # File URI (file-based only)
SkillScript Structure
SkillScript
├── name: str # Script identifier
├── description: str | None # Optional description
├── function: Callable | None # Callable function (programmatic)
├── takes_ctx: bool # Whether function takes RunContext
├── function_schema: FunctionSchema | None # Schema for callable
├── uri: str | None # File URI (file-based only)
└── skill_name: str | None # Parent skill name
Programmatic vs File-Based
File-Based Skills
Loaded from filesystem directories:
uripoints to file/directory locationcontentis loaded fromSKILL.md- Resources loaded from additional
.mdfiles - Scripts loaded from
scripts/directory and executed via subprocess
Programmatic Skills
Created in Python code:
- No
uri(no filesystem location) contentprovided directly as string- Resources can be static content or callable functions
- Scripts are Python functions with RunContext support
- Supports dependency injection via
RunContext
See Also
- SkillsToolset - Main toolset API and initialization
- Exceptions - Exception classes and error handling
- Advanced Features - Decorator patterns and custom executors
- Creating Skills - File-based skill creation guide
- Programmatic Skills - Programmatic skill creation guide