### Run a Basic Usage Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md Execute the basic_usage.py example script from the repository root. This will start a Pydantic AI agent accessible at http://127.0.0.1:7932. ```bash # from the repo root python -m examples.basic_usage ``` -------------------------------- ### Install Examples Dependency Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md Install the 'examples' optional dependency group for pydantic-ai-skills. This command ensures all necessary packages for running the examples are available. ```bash pip install -e ".[examples]" # or with uv uv sync --extra examples ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md Install the project with documentation support. This is necessary for building or serving the project's documentation locally. ```bash pip install -e ".[docs]" ``` -------------------------------- ### Skills Toolset Initialization Examples Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Provides code examples for initializing the SkillsToolset with different configurations. ```APIDOC ## Usage Examples ### Initialize with File-Based Skills ```python from pydantic_ai_skills import SkillsToolset # Basic initialization - defaults to ./skills directory toolset = SkillsToolset() # Explicit single directory toolset = SkillsToolset(directories=["./skills"]) # Multiple directories toolset = SkillsToolset( directories=["./skills", "./shared", "./custom"], validate=True, max_depth=3, id="my-skills" ) # Using SkillsDirectory instances directly from pydantic_ai.toolsets.skills import SkillsDirectory skills_dir = SkillsDirectory( path="./skills", validate=True, max_depth=3 ) toolset = SkillsToolset(directories=[skills_dir]) ``` ### Initialize with Git Registry ```python from pydantic_ai_skills import SkillsToolset from pydantic_ai_skills.registries import GitSkillsRegistry, GitCloneOptions # Clone a remote Git repository and load its skills registry = GitSkillsRegistry( repo_url='https://github.com/anthropics/skills', path='skills', target_dir='./anthropics-skills', clone_options=GitCloneOptions(depth=1, single_branch=True), ) toolset = SkillsToolset(registries=[registry]) # Combine with local skills toolset = SkillsToolset( directories=['./skills'], registries=[registry], ) ``` ### Initialize with Programmatic Skills ```python from pydantic_ai import RunContext from pydantic_ai.toolsets.skills import Skill, SkillsToolset # Create a simple programmatic skill my_skill = Skill( name='custom-skill', description='Custom programmatic skill', content='Instructions for this skill...' ) # Initialize toolset with programmatic skill toolset = SkillsToolset(skills=[my_skill]) # Use the @skill() decorator to define skills inline skills = SkillsToolset() @skills.skill() def data_analyzer() -> str: """Analyze data from various sources.""" return "Provide data analysis capabilities..." @data_analyzer.resource def get_schema() -> str: """Get available schema information.""" return "## Schema\n\nAvailable columns..." @data_analyzer.script async def analyze(ctx: RunContext[MyDeps], query: str) -> str: """Run analysis query.""" return await ctx.deps.database.execute(query) ``` ### Mix File-Based and Programmatic Skills ```python from pydantic_ai.toolsets.skills import Skill, SkillsToolset ``` ``` -------------------------------- ### Install Git-backed Registry Support Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md Install the necessary package for Git-backed registries. This requires GitPython. ```bash pip install pydantic-ai-skills[git] ``` -------------------------------- ### Environment Variable Configuration Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Provides an example of how to configure secrets using environment variables, avoiding hardcoding. ```bash export XYZ_API_KEY="your-key-here" ``` -------------------------------- ### Install S3-backed Registry Support Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md Install the necessary package for S3-backed registries. This requires boto3. ```bash pip install pydantic-ai-skills[s3] ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/CLAUDE.md Starts a local web server to preview the project documentation. Changes to the documentation files will be reflected live. ```bash mkdocs serve ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md Install the project in editable mode with testing and Git support. This command is used for setting up the development environment. ```bash pip install -e ".[test]" pip install -e ".[git]" ``` -------------------------------- ### SkillsCapability Integration Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/concepts.md Demonstrates how to integrate skills into an Agent using the SkillsCapability, specifying directories where skills are located. ```python from pydantic_ai import Agent from pydantic_ai_skills import SkillsCapability agent = Agent( model='openai:gpt-5.2', capabilities=[SkillsCapability(directories=['./skills'])] ) ``` -------------------------------- ### Basic Agent Initialization and Execution Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/AGENT.md Demonstrates how to initialize an Agent with a specific model and system prompt, and then perform both synchronous and asynchronous runs to get output. ```python from pydantic_ai import Agent agent = Agent( 'openai:gpt-4o', system_prompt='You are a helpful assistant.', retries=2, ) # Sync run result = agent.run_sync('What is the capital of France?') print(result.output) # Async run import asyncio async def main(): result = await agent.run('What is 2 + 2?') print(result.output) asyncio.run(main()) ``` -------------------------------- ### Basic Skill Structure Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md Illustrates the minimal directory structure for a basic skill, requiring only the SKILL.md file. ```markdown my-skill/ └── SKILL.md # Required: Main instructions and metadata ``` -------------------------------- ### Example .env File Configuration Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/README.md Configure environment variables for running pydantic-ai-skills examples. This includes the required Pydantic AI Gateway API key and optional Logfire token for observability. ```dotenv # Pydantic AI Gateway (required) PYDANTIC_AI_GATEWAY_API_KEY="your-gateway-api-key" # Logfire observability (optional) LOGFIRE_TOKEN="your-logfire-token" ``` -------------------------------- ### Example: arXiv Search Skill Instructions Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Demonstrates how to write clear instructions for an arXiv search skill, including when to use it, how to call the script, and expected output format. ```markdown --- name: arxiv-search description: Search arXiv for research papers --- # arXiv Search Skill ## When to Use Use this skill when you need to: - Find recent preprints in physics, math, or computer science - Search for papers not yet published in journals - Access cutting-edge research ## Instructions To search arXiv, use the `run_skill_script` tool with: 1. **skill_name**: "arxiv-search" 2. **script_name**: "scripts/arxiv_search.py" 3. **args**: - `query`: Required search query (e.g., "neural networks") - `max-papers`: Optional, defaults to 10 ## Examples Search for 5 papers on machine learning: ```python run_skill_script( skill_name="arxiv-search", script_name="scripts/arxiv_search.py", args={"query": "machine learning", "max-papers": 5} ) ``` ## Output Format The script returns a formatted list with: - Paper title - Authors - arXiv ID - Abstract ## Adding Scripts Scripts enable skills to perform custom operations that aren't available as standard agent tools. ### Script Location Place scripts in either: - `scripts/` subdirectory (recommended) - Directly in the skill folder ```markdown my-skill/ ├── SKILL.md └── scripts/ ├── process_data.py └── fetch_info.py ``` ### Writing Scripts Scripts should: - Accept named command-line arguments (for example, using `argparse` in Python or an equivalent option parser in your runtime) - Print output to stdout - Exit with code 0 on success, non-zero on error - Handle errors gracefully #### Example Script ```python #!/usr/bin/env python3 """Example skill script.""" import sys import json def main(): if len(sys.argv) < 2: print("Usage: process_data.py ") sys.exit(1) input_data = sys.argv[1] try: # Process the input result = process(input_data) # Output results print(json.dumps(result, indent=2)) except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) def process(data): # Your processing logic here return {"processed": data.upper()} if __name__ == "__main__": main() ``` ### Script Best Practices **✅ Do:** - Validate input arguments - Return structured output (JSON preferred) - Handle errors gracefully - Document expected inputs/outputs in SKILL.md - Use timeouts for external calls - Add a shebang line for interpreter portability (for example `#!/usr/bin/env python3`) **❌ Don't:** - Make network calls without timeouts - Write to files outside the skill directory - Require interactive input - Use environment-specific paths ### Script Interpreter Selection When filesystem scripts are executed, interpreter selection follows this order: 1. Shebang line, when present and resolvable 2. Extension-based fallback for compatibility (`.py`, `.sh`, `.bash`, `.zsh`, `.fish`, `.ps1`, `.bat`, `.cmd`) 3. Direct executable invocation fallback This allows extensionless and custom-extension executable scripts to run while preserving compatibility with existing script names and extensions. ### Script Argument Handling When agents call scripts via `run_skill_script()`, arguments are converted to command-line flags: ```python ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md Install pre-commit hooks to automatically check code quality and style before committing. ```bash pre-commit install ``` -------------------------------- ### Reading Skill Resource Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Demonstrates how to read a resource file associated with a skill. Use for accessing API references or example data within a skill. ```python read_skill_resource( skill_name="api-integration", resource_name="API_REFERENCE.md" ) ``` ```python read_skill_resource( skill_name="api-integration", resource_name="resources/examples.json" ) ``` -------------------------------- ### Load Skill Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md An agent calls `load_skill` to retrieve the full instructions for a specific skill, such as 'arxiv-search'. ```python # Agent calls this when a skill is relevant result = await load_skill(ctx, "arxiv-search") ``` -------------------------------- ### Dynamic Skill Refresh Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/quick-start.md Demonstrates how to reload skills by recreating the SkillsToolset and Agent instances after filesystem changes. ```python import asyncio from pydantic_ai import Agent from pydantic_ai_skills import SkillsToolset async def main(): toolset = SkillsToolset(directories=["./skills"]) agent = Agent( model='openai:gpt-5.2', instructions="You are a helpful assistant.", toolsets=[toolset] ) # Use agent result = await agent.run("What skills are available?") print(result.output) # ... User adds new skill to ./skills/ ... # To pick up new skills, recreate the toolset and agent toolset = SkillsToolset(directories=["./skills"]) agent = Agent( model='openai:gpt-5.2', instructions="You are a helpful assistant.", toolsets=[toolset] ) print(f"\nReloaded. Now have {len(toolset.skills)} skills") result = await agent.run("What skills are available now?") print(result.output) if __name__ == "__main__": asyncio.run(main()) ``` -------------------------------- ### Install pydantic-ai-skills Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md Install the package using pip. For development, include test dependencies. ```bash pip install pydantic-ai-skills ``` ```bash pip install pydantic-ai-skills[test] # Includes pytest and coverage tools ``` -------------------------------- ### run_skill_script() Tool Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Illustrates how an agent might call the `run_skill_script` tool to execute a specific script within a skill, passing arguments for the script. The example shows the agent's call and the internal toolset invocation. ```python # Agent calls the tool agent.run_sync('Run the arxiv search script with query "machine learning"') # Internally calls: # result = await toolset.run_skill_script( # 'arxiv-search', # 'arxiv_search', # {'query': 'machine learning'} # ) ``` -------------------------------- ### Run Skill Script Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md An agent executes a skill script, providing the skill name, script path, and a dictionary of arguments. ```python # Agent executes scripts with arguments result = await run_skill_script( ctx, "arxiv-search", "scripts/arxiv_search.py", {"query": "machine learning", "max-papers": 5} ) ``` -------------------------------- ### Plain Text Output Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Shows how to generate output as plain text for human-readable reports or logs. ```python output = """Analysis Results ================ Total records: 42 Average value: 123.45 Range: [10, 456] Top 3 results: 1. Item A - 456 2. Item B - 234 3. Item C - 189 """ print(output) ``` -------------------------------- ### list_skills() Tool Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md An example of the markdown output returned by the `list_skills()` tool, which provides a formatted list of all available skills and their associated scripts. ```markdown # Available Skills ## arxiv-search Search arXiv for research papers (scripts: arxiv_search) ## web-research Structured approach to web research ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md Install the project's development dependencies, including the package itself in editable mode. ```bash pip install -e ".[dev]" ``` -------------------------------- ### File-Based Skill Loading Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/types.md Shows how to load skills from a directory using `SkillsToolset`. It iterates through the loaded skills, printing their names, descriptions, URIs, metadata, and lists of resources and scripts. ```python 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}") ``` -------------------------------- ### Minimal SKILL.md Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md A minimal SKILL.md file demonstrating the required YAML frontmatter for name and description, followed by Markdown instructions. ```markdown --- name: my-skill description: Brief description of what this skill does and when to use it --- # My Skill ## When to Use This Skill Use this skill when you need to: - Do specific task A - Handle scenario B - Process data type C ## Instructions 1. Step 1 2. Step 2 3. Step 3 ``` -------------------------------- ### Example Docstring for discover_skills Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md Illustrates the expected docstring format for Python functions, including arguments, return values, exceptions, and an example usage. ```python def discover_skills( directories: list[str | Path], validate: bool = True, ) -> list[Skill]: """Discover skills from filesystem directories. Searches for SKILL.md files in the given directories and loads skill metadata and structure. Args: directories: List of directory paths to search for skills. validate: Whether to validate skill structure. Returns: List of discovered Skill objects. Raises: ValueError: If validation enabled and skill is invalid. Example: ```python skills = discover_skills( directories=["./skills"], validate=True ) for skill in skills: print(f"{skill.name}: {skill.metadata.description}") ``` """ ``` -------------------------------- ### Running Skill Script Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Shows how to execute a script within a skill, passing arguments. Use for automating tasks like data analysis or visualization. ```python run_skill_script( skill_name="data-analyzer", script_name="scripts/analyze.py", args={"input": "data.csv", "output": "json"} ) ``` ```python run_skill_script( skill_name="data-analyzer", script_name="scripts/visualize.py", args={"input": "data.csv", "type": "histogram"} ) ``` -------------------------------- ### Example CHANGELOG Entry Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md Shows the format for adding release notes to the CHANGELOG file, including sections for Added and Fixed changes. ```markdown ## [Unreleased] ### Added - New feature description (#PR_NUMBER) ### Fixed - Bug fix description (#PR_NUMBER) ``` -------------------------------- ### CSV Output Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Illustrates generating output in CSV format, suitable for tabular data exchange. ```python import csv import sys data = [ {"id": 1, "name": "Alice", "score": 95}, {"id": 2, "name": "Bob", "score": 87} ] writer = csv.DictWriter(sys.stdout, fieldnames=['id', 'name', 'score']) writer.writeheader() writer.writerows(data) ``` -------------------------------- ### JSON Output Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Demonstrates how to format results as JSON, which is the recommended output format for structured data. ```python import json result = { "success": True, "data": [ {"id": 1, "value": 100}, {"id": 2, "value": 200} ], "count": 2, "metadata": {"query": "user_data", "timestamp": "2025-01-23"} } print(json.dumps(result, indent=2)) ``` -------------------------------- ### Dynamically Register a New Skill Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md This example shows how to programmatically register a new skill after a toolset has been created. It uses the Skill model and an internal method for registration, which is not recommended for production. ```python from pydantic_ai.toolsets.skills import Skill # Create toolset toolset = SkillsToolset() # Register a new programmatic skill new_skill = Skill( name='dynamically-added', description='Added after initialization', content='This skill was registered dynamically' ) toolset._register_skill(new_skill) # Internal method, use with caution ``` -------------------------------- ### SKILL.md Frontmatter Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Shows how to use YAML frontmatter in a SKILL.md file to define metadata for a skill, such as its name and description. ```markdown --- name: api-client description: Work with the XYZ API --- ``` -------------------------------- ### Custom In-Process Script Executor Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md Provides a minimal example of setting up a custom script executor for in-process execution, suitable for local debugging. This executor uses `CallableSkillScriptExecutor` with a custom function. ```python from pydantic_ai_skills import CallableSkillScriptExecutor, SkillsDirectory async def in_process_executor(*, script, args=None): # Development-only path for breakpoint debugging. ... executor = CallableSkillScriptExecutor(func=in_process_executor) skills_dir = SkillsDirectory(path='./skills', script_executor=executor) ``` -------------------------------- ### Read Skill Resource Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md An agent uses `read_skill_resource` to access additional documentation files like FORMS.md for a given skill. ```python # Agent loads resources only when needed result = await read_skill_resource(ctx, "pdf-processing", "FORMS.md") ``` -------------------------------- ### Programmatic Skill Creation Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/types.md Demonstrates creating a programmatic skill using the `Skill` class and adding dynamic resources and scripts using decorators. This approach is suitable when skills are defined entirely in code. ```python from pydantic_ai import RunContext from pydantic_ai.toolsets.skills import Skill, SkillResource # Assuming MyDeps is defined elsewhere # class MyDeps: # async def fetch_data(self) -> str: # return "data" # async def process(self, query: str) -> str: # return f"processed {query}" # 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}" ``` -------------------------------- ### Extended Skill Structure Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md Shows an extended skill directory structure including optional files like FORMS.md, REFERENCE.md, scripts, and resources. ```markdown my-skill/ ├── SKILL.md # Required: Main instructions and metadata ├── FORMS.md # Optional: Form-filling guides ├── REFERENCE.md # Optional: Detailed API reference ├── scripts/ # Optional: executable scripts │ ├── script1.py │ └── script2.sh └── resources/ # Optional: Additional files ├── templates/ └── data.json ``` -------------------------------- ### Example Skill Script Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md A Python script demonstrating how to accept command-line arguments, process data, and output results as JSON. Includes basic error handling and argument validation. ```python #!/usr/bin/env python3 """Example skill script.""" import sys import json def main(): if len(sys.argv) < 2: print("Usage: process_data.py ") sys.exit(1) input_data = sys.argv[1] try: # Process the input result = process(input_data) # Output results print(json.dumps(result, indent=2)) except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) def process(data): # Your processing logic here return {"processed": data.upper()} if __name__ == "__main__": main() ``` -------------------------------- ### Custom Instruction Template with Skills Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Shows how to use a custom instruction template that includes a list of available skills for an agent. This template guides the agent on how to utilize specialized skills. ```python from pydantic_ai import Agent from pydantic_ai.toolsets.skills import SkillsToolset custom_instructions = """ You have specialized skills available for specific domains. Each skill includes instructions, resources, and executable scripts. Available skills: {skills_list} Use `load_skill` to explore any skill that's relevant to the user's request. """ toolset = SkillsToolset( directories=["./skills"], instruction_template=custom_instructions ) agent = Agent( model='openai:gpt-4o', toolsets=[toolset] ) ``` -------------------------------- ### Chaining Registry Operations Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md Wrappers like `filtered` and `prefixed` can be chained for complex skill selection and naming. This example starts with a Git registry, filters for document-related skills, and then prefixes their names. ```python registry = GitSkillsRegistry( repo_url='https://github.com/anthropics/skills', path='skills', target_dir='./cached-skills', ) doc_skills = ( registry .filtered(lambda s: s.name in ('pdf', 'docx', 'pptx')) .prefixed('docs-') ) # doc_skills now has: 'docs-pdf', 'docs-docx', 'docs-pptx' ``` -------------------------------- ### Serve and Build Documentation Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/AGENTS.md Serve the project documentation locally for preview or build it for deployment. These commands use MkDocs to manage documentation. ```bash mkdocs serve mkdocs build ``` -------------------------------- ### Install arxiv Python Package Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/README.md Installs the 'arxiv' Python package using pip. This is a required dependency for the arxiv-search skill and should be installed if not already present. ```bash pip install arxiv ``` -------------------------------- ### Agent Instantiation and Basic Run Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/SKILL.md Instantiate an agent with a model string and system prompt, then run a synchronous query. ```python from pydantic_ai import Agent agent = Agent( 'openai:gpt-4o', # model string: provider:model-name system_prompt='Be helpful.', ) result = agent.run_sync('What is the capital of France?') print(result.output) ``` -------------------------------- ### Initialize Agent with SkillsCapability Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/capability.md Demonstrates how to initialize an Agent with SkillsCapability, specifying local skill directories and enabling auto-reloading. ```python from pydantic_ai import Agent from pydantic_ai_skills import SkillsCapability agent = Agent( model='openai:gpt-5.2', capabilities=[ SkillsCapability( directories=['./skills'], auto_reload=True, ) ], ) ``` -------------------------------- ### Install Pydantic AI MCP Package Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MCP.md Install the pydantic-ai-slim package with MCP support using pip. ```bash pip install "pydantic-ai-slim[mcp]" ``` -------------------------------- ### Build Documentation Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/CLAUDE.md Builds the static documentation files for the project. The output will be in the `site` directory. ```bash mkdocs build ``` -------------------------------- ### Agent Initialization with Dependencies Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md Shows how to initialize an Agent with custom dependencies, which are then accessible via RunContext in skills and scripts. Ensure all required dependencies are provided. ```python from pydantic_ai import Agent agent = Agent( model='openai:gpt-4o', deps=MyDeps( database=my_database, cache=my_cache, logger=my_logger ), toolsets=[skills] ) result = agent.run_sync('Query the user database', deps=agent.deps) ``` -------------------------------- ### Agent Initialization with SkillsCapability Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/quick-start.md Initializes an agent using SkillsCapability, pointing to a directory containing skills. This is the preferred method for integrating skills. ```python from pydantic_ai import Agent from pydantic_ai_skills import SkillsCapability agent = Agent( model='openai:gpt-5.2', instructions='You are a helpful assistant.', capabilities=[SkillsCapability(directories=['./skills'])] ) result = agent.run_sync('How do I create a Pydantic AI agent with tools?') print(result.output) ``` -------------------------------- ### Circular Dependency Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Demonstrates a circular dependency anti-pattern where skills explicitly depend on each other. ```markdown # skill-a/SKILL.md To use this skill, first load skill-b... # skill-b/SKILL.md This skill requires skill-a to be loaded... ``` -------------------------------- ### Hardcoded Secret Anti-Pattern Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Shows an example of hardcoding sensitive information like API keys directly in the code. ```plaintext API_KEY = "sk-1234567890abcdef" ``` -------------------------------- ### Defining and Using Function Tools Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/FUNCTION_TOOLS.md Demonstrates defining plain tools, context-aware tools, and unreliable tools with retries using Pydantic AI decorators. Shows how to run the agent with dependencies. ```python import random from pydantic_ai import Agent, RunContext, ModelRetry agent = Agent('openai:gpt-4o', deps_type=str) @agent.tool_plain def roll_die() -> str: """Roll a six-sided die and return the result.""" return str(random.randint(1, 6)) @agent.tool def get_player_name(ctx: RunContext[str]) -> str: """Return the current player's name.""" return ctx.deps @agent.tool(retries=3) def unreliable_api(ctx: RunContext[str], query: str) -> str: """Call an API that might fail.""" if not query: raise ModelRetry('Please provide a non-empty query') return f'Result for {query}' result = agent.run_sync('Roll the die for me!', deps='Alice') ``` -------------------------------- ### Initialize SkillsToolset with SkillsDirectory Instances Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Initializes the SkillsToolset using SkillsDirectory instances for more granular control over skill discovery. ```python from pydantic_ai_skills import SkillsToolset from pydantic_ai.toolsets.skills import SkillsDirectory skills_dir = SkillsDirectory( path="./skills", validate=True, max_depth=3 ) toolset = SkillsToolset(directories=[skills_dir]) ``` -------------------------------- ### Implement Sandboxed Execution Executor Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md Example of a custom executor that runs Python scripts in isolated sandboxes using subprocess. ```python import subprocess from pathlib import Path import os class SandboxedExecutor: """Execute Python scripts in isolated sandboxes.""" def __init__(self, timeout: int = 30): self.timeout = timeout async def execute(self, script: SkillScript, args: dict | None = None) -> str: """Execute script in sandbox.""" # Convert args to environment variables env = {f"ARG_{k.upper()}": str(v) for k, v in (args or {}).items()} try: result = subprocess.run( ["sandbox", "--timeout", str(self.timeout), script.name], capture_output=True, text=True, env={**os.environ, **env}, timeout=self.timeout + 5 ) return result.stdout or result.stderr except subprocess.TimeoutExpired: return f"ERROR: Script execution timed out after {self.timeout}s" ``` -------------------------------- ### Initialize SkillsToolset with Multiple Directories and Options Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Initializes the SkillsToolset with multiple directories and custom validation and depth settings. ```python from pydantic_ai_skills import SkillsToolset # Multiple directories toolset = SkillsToolset( directories=["./skills", "./shared", "./custom"], validate=True, max_depth=3, id="my-skills" ) ``` -------------------------------- ### Markdown for Exit Code Documentation Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Example of documenting script exit codes in a SKILL.md file, explaining the meaning of each code for users. ```markdown ## Script: analyze Executes data analysis with exit codes: - **0**: Success - **1**: Validation error (bad input) - **2**: Timeout (operation too slow) - **3**: System error (unexpected failure) ### Examples ```python # Successful analysis run_skill_script('data-skill', 'analyze', {'query': 'SELECT count(*) FROM users'}) # Returns: {"count": 42, "time_ms": 123} # Invalid input (exits with code 1) run_skill_script('data-skill', 'analyze', {'query': 'INVALID SQL'}) # Returns: ERROR: Syntax error in SQL query ``` ``` -------------------------------- ### Pull Request Template Example Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md A template for creating pull requests, including sections for description, type of change, and a checklist of requirements. ```markdown ## Description Brief description of changes ## Type of Change - [ ] Bug fix - [ ] New feature - [ ] Breaking change - [ ] Documentation update ## Checklist - [ ] Tests added/updated - [ ] Documentation updated - [ ] CHANGELOG updated - [ ] All tests pass - [ ] Pre-commit checks pass ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/contributing.md Create a Python virtual environment and activate it to manage project dependencies. ```bash python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate ``` -------------------------------- ### Skills Toolset Initialization Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Demonstrates various ways to initialize the SkillsToolset, including using local directories, Git registries, and programmatic skills. ```APIDOC ## Constructor: SkillsToolset ### Description Initializes the SkillsToolset, which manages and discovers skills for AI agents. It can load skills from local directories, remote Git repositories via registries, or directly defined programmatic skills. ### Parameters * **`skills`** (`list[Skill] | None`): Pre-loaded Skill objects. Defaults to `None`. * **`directories`** (`list[str | Path | SkillsDirectory] | None`): Directories or SkillsDirectory instances to discover skills from. Defaults to `["./skills"]` if neither `skills` nor `directories` are provided. * **`registries`** (`list[SkillRegistry] | None`): List of SkillRegistry instances (e.g., `GitSkillsRegistry`) to load skills from. Registries have the lowest priority. * **`validate`** (`bool`): Validate skill structure during discovery. Defaults to `True`. * **`max_depth`** (`int | None`): Maximum depth for skill discovery. Defaults to `3`. * **`id`** (`str | None`): Unique identifier for this toolset. Defaults to `None`. * **`instruction_template`** (`str | None`): Custom instruction template for skills system prompt. Must include `{skills_list}` placeholder. Defaults to `None` (uses default template). * **`max_retries`** (`int`): Maximum number of retries for tool calls that raise `ModelRetry`. Defaults to `1`. ### Properties * **`skills`** (`dict[str, Skill]`): Dictionary of all available skills, keyed by skill name. ### Methods * **`get_skill(skill_name: str) -> Skill`**: Retrieve a specific skill by name. Raises `KeyError` if not found. * **`get_instructions(ctx: RunContext[Any]) -> str | None`**: Returns formatted system prompt with skills instructions, or `None` if no skills are loaded. Called automatically by the agent. ``` -------------------------------- ### Get a Skill from Combined Registries Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md When multiple registries provide a skill with the same name, the first registry in the order passed to `CombinedRegistry` wins. ```python skill = await combined.get('pdf') ``` -------------------------------- ### Agent Integration with Skills Toolset Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Demonstrates setting up an agent with a SkillsToolset, where skill instructions are automatically injected into the agent's system prompt. The agent can then be used to run tasks that leverage these skills. ```python from pydantic_ai import Agent from pydantic_ai_skills import SkillsToolset toolset = SkillsToolset(directories=["./skills"]) agent = Agent( model='openai:gpt-4o', instructions="You are a helpful assistant.", toolsets=[toolset] ) # Skill instructions are injected into the agent's system prompt automatically. result = agent.run_sync('Analyze the quarterly data') ``` -------------------------------- ### Initialize S3SkillsRegistry with MinIO Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md Configure and initialize S3SkillsRegistry to connect to an S3-compatible store like MinIO. This requires building a custom boto3 client with the correct endpoint URL, credentials, and path-style addressing configuration. ```python import boto3 from botocore.config import Config from pydantic_ai_skills.registries import S3SkillsRegistry client = boto3.client( "s3", endpoint_url="http://localhost:9000", aws_access_key_id="minioadmin", aws_secret_access_key="minioadmin", config=Config(s3={"addressing_style": "path"}), ) registry = S3SkillsRegistry(bucket="skills", boto3_client=client) ``` -------------------------------- ### Initialize Skills Toolset with Directories Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Initializes a SkillsToolset by specifying directories to load skills from. Useful for organizing skills in a categorized structure. ```python toolset = SkillsToolset(directories=[ "./skills/research", "./skills/data-processing", "./skills/communication" ]) ``` -------------------------------- ### Implement Remote Execution Executor Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/advanced.md Example of a custom executor that sends script execution requests to a remote server via HTTP POST. ```python from pydantic_ai.toolsets.skills import SkillScript, CallableSkillScriptExecutor import httpx class RemoteExecutor: """Execute scripts on a remote server.""" def __init__(self, server_url: str): self.server_url = server_url async def execute(self, script: SkillScript, args: dict | None = None) -> str: """Send script execution request to remote server.""" async with httpx.AsyncClient() as client: response = await client.post( f"{self.server_url}/execute", json={ "script_name": script.name, "args": args or {} } ) return response.text # Use in custom script definitions from pydantic_ai.toolsets.skills import SkillScript remote_executor = RemoteExecutor("https://api.example.com") script = SkillScript( name='remote-analysis', description='Run analysis on remote server', function=None, executor=remote_executor # Custom executor ) ``` -------------------------------- ### SkillRegistry Methods Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/registries.md Provides documentation for the core methods available in the SkillRegistry class, including searching, retrieving, installing, updating, and listing skills. ```APIDOC ## SkillRegistry ### Description Manages a collection of AI skills, allowing for searching, retrieval, installation, and updates. ### Methods #### `search(query: str)` Searches for skills matching the given query. #### `get(skill_id: str)` Retrieves a specific skill by its ID. #### `install(skill_data: dict)` Installs a new skill into the registry. #### `update(skill_id: str, skill_data: dict)` Updates an existing skill in the registry. #### `get_skills()` Returns a list of all skills available in the registry. #### `filtered(filter_func: callable)` Returns a filtered list of skills based on the provided filter function. #### `prefixed(prefix: str)` Returns skills that have a specific prefix. #### `renamed(rename_map: dict)` Returns skills with renamed identifiers based on the provided map. ``` -------------------------------- ### Instantiate Agent with Model Settings Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MODELS.md Instantiate an Agent with specific model inference parameters like temperature and max_tokens using ModelSettings. ```python from pydantic_ai import Agent from pydantic_ai.settings import ModelSettings agent = Agent( 'openai:gpt-4o', model_settings=ModelSettings(temperature=0.2, max_tokens=1024), ) ``` -------------------------------- ### Optional SKILL.md Frontmatter Fields Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/concepts.md Provides an example of a SKILL.md file's YAML frontmatter with optional fields like version, author, and category. ```yaml --- name: arxiv-search description: Search arXiv for research papers version: 1.0.0 author: Your Name category: research --- ``` -------------------------------- ### Skill Structure with API Reference (Version 2) Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/creating-skills.md Illustrates a skill directory structure including a separate API reference file. ```markdown api-client/ ├── SKILL.md └── API_REFERENCE.md ``` -------------------------------- ### Create and Combine Skills in Toolset Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Demonstrates creating a programmatic skill and combining it with file-based skills in a SkillsToolset. The total number of loaded skills is then printed. ```python programmatic_skill = Skill( name='runtime-skill', description='Created at runtime', content='Dynamic skill content...' ) toolset = SkillsToolset( directories=["./skills"], # File-based skills from directory skills=[programmatic_skill], # Programmatic skills max_depth=3 # Limit directory discovery depth ) @toolset.skill() def extra_skill() -> str: return "Additional dynamically-defined skill..." print(f"Total skills loaded: {len(toolset.skills)}") ``` -------------------------------- ### Lazy Initialization of Expensive Resources Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/patterns.md Defer the initialization of expensive resources until they are actually needed. This improves startup performance by avoiding upfront setup costs. ```python from pydantic_ai.toolsets.skills import SkillsToolset from pydantic_ai import RunContext class MyDeps: # Assume database, cache, logger, config are defined here or elsewhere pass async def initialize_expensive_resource(): # Placeholder for expensive resource initialization print("Initializing expensive resource...") await asyncio.sleep(2) # Simulate initialization time return "Expensive Resource Instance" skills = SkillsToolset() @skills.skill() def expensive_skill() -> str: return "Use expensive resources" @expensive_skill.resource async def get_expensive_resource(ctx: RunContext[MyDeps]) -> str: """Lazy-load expensive resource only when needed.""" # First call initializes, subsequent calls reuse if not hasattr(ctx.deps, '_expensive_resource'): ctx.deps._expensive_resource = await initialize_expensive_resource() return str(ctx.deps._expensive_resource) ``` -------------------------------- ### Creating a Custom Wrapper Registry Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/registries.md Extend `WrapperRegistry` to create custom composition wrappers. This example defines a `LoggingRegistry` that logs search operations performed on the wrapped registry. ```python from pydantic_ai_skills.registries import WrapperRegistry from pydantic_ai_skills.types import Skill class LoggingRegistry(WrapperRegistry): """Registry that logs all operations.""" async def search(self, query: str, limit: int = 10) -> list[Skill]: print(f'Searching for: {query}') results = await self.wrapped.search(query, limit) print(f'Found {len(results)} results') return results ``` -------------------------------- ### Initialize SkillsToolset with Git Registry Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/docs/api/toolset.md Initializes the SkillsToolset by cloning a remote Git repository and loading skills from it. ```python from pydantic_ai_skills import SkillsToolset from pydantic_ai_skills.registries import GitSkillsRegistry, GitCloneOptions # Clone a remote Git repository and load its skills registry = GitSkillsRegistry( repo_url='https://github.com/anthropics/skills', path='skills', target_dir='./anthropics-skills', clone_options=GitCloneOptions(depth=1, single_branch=True), ) toolset = SkillsToolset(registries=[registry]) ``` -------------------------------- ### Load MCP Servers from Configuration File Source: https://github.com/dougtrajano/pydantic-ai-skills/blob/main/examples/skills/pydanticai-docs/references/MCP.md Load multiple MCP servers from a JSON configuration file. This simplifies the setup when dealing with numerous MCP server integrations. ```python from pydantic_ai.mcp import load_mcp_servers servers = load_mcp_servers('mcp_config.json') agent = Agent('openai:gpt-4o', toolsets=servers) # Config supports ${VAR} and ${VAR:-default} env var expansion. ```