Skip to content
Back to skills

2515 Toolsets B0785398

ASecurity

Toolsets are collections of tools that extend agent capabilities. pydantic-deep includes four built-in toolsets.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
ai-agentspythonshellcode-reviewgitapibackendsecuritydocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2515-toolsets_b0785398 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2515 Toolsets B0785398?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2515 Toolsets B0785398
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2515-toolsets-b0785398/badge)](https://www.skillsdirectory.com/skills/tools-only-2515-toolsets-b0785398)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Toolsets

Toolsets are collections of tools that extend agent capabilities. pydantic-deep includes four built-in toolsets.

## Built-in Toolsets

### TodoToolset

Task planning and tracking. Powered by [pydantic-ai-todo](https://github.com/vstorm-co/pydantic-ai-todo).

| Tool | Description |
|------|-------------|
| `read_todos` | Read the current todo list state |
| `write_todos` | Update the todo list with tasks and statuses |

```python
# Agent can call:
write_todos(todos=[
    {"content": "Create module", "status": "in_progress", "active_form": "Creating module"},
    {"content": "Write tests", "status": "pending", "active_form": "Writing tests"},
])
```

**Todo Status Values:**

- `pending` - Not started
- `in_progress` - Currently working
- `completed` - Done

!!! tip "Standalone Usage"
    The todo toolset can also be used independently with any pydantic-ai agent:

    ```python
    from pydantic_ai import Agent
    from pydantic_ai_todo import create_todo_toolset, TodoStorage

    storage = TodoStorage()
    agent = Agent("openai:gpt-4.1", toolsets=[create_todo_toolset(storage)])
    ```

### Console Toolset (from pydantic-ai-backend)

File operations using the configured backend. Provided by [pydantic-ai-backend](https://vstorm-co.github.io/pydantic-ai-backend/concepts/console-toolset/).

| Tool | Description |
|------|-------------|
| `ls` | List directory contents |
| `read_file` | Read file with line numbers |
| `write_file` | Create or overwrite file |
| `edit_file` | Replace strings in file |
| `glob` | Find files by pattern |
| `grep` | Search file contents |
| `execute` | Run shell command (when enabled) |

```python
# Agent can call:
ls(path="/src")
read_file(path="/src/app.py")
write_file(path="/src/new.py", content="print('hello')")
edit_file(path="/src/app.py", old_string="old", new_string="new")
glob(pattern="**/*.py", path="/src")
grep(pattern="def main", path="/src")
execute(command="python test.py", timeout=30)
```

**Reading Large Files with Pagination:**

The `read_file` tool supports `offset` and `limit` parameters for handling large files:

```python
# Read first 100 lines
read_file(path="/logs/large.log", limit=100)

# Read lines 500-600 (offset is 0-indexed)
read_file(path="/logs/large.log", offset=500, limit=100)

# Read from line 1000 to end
read_file(path="/logs/large.log", offset=1000)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `path` | `str` | required | File path to read |
| `offset` | `int` | `0` | Starting line number (0-indexed) |
| `limit` | `int` | `None` | Maximum lines to return (None = all remaining) |

!!! tip "Best Practices for Large Files"
    - Use `grep` first to find relevant sections
    - Use `glob` to locate files, then paginate through them
    - Read in chunks of 100-500 lines for context
    - The agent will see line numbers to track position

See [Console Toolset docs](https://vstorm-co.github.io/pydantic-ai-backend/concepts/console-toolset/) for full details.

### SubAgentToolset

Delegate tasks to specialized subagents. Powered by [subagents-pydantic-ai](https://github.com/vstorm-co/subagents-pydantic-ai).

| Tool | Description |
|------|-------------|
| `task` | Spawn a subagent for a task (sync or async) |
| `check_task` | Check status of a background task |
| `list_active_tasks` | List all running/pending tasks |
| `soft_cancel_task` | Request graceful task cancellation |
| `hard_cancel_task` | Force immediate task cancellation |

```python
# Agent can call:
task(
    description="Review the authentication module for security issues",
    subagent_type="code-reviewer",
    mode="sync",  # or "async" or "auto"
)
```

**Built-in Subagent Types:**

- `general-purpose` - Default agent for any task (if enabled)
- Custom types from `subagents` configuration

### SkillsToolset

Modular capability packages.

| Tool | Description |
|------|-------------|
| `list_skills` | List available skills with metadata |
| `load_skill` | Load full instructions for a skill |
| `read_skill_resource` | Read additional files from a skill |

```python
# Agent can call:
list_skills()
load_skill(skill_name="code-review")
read_skill_resource(skill_name="code-review", resource_name="template.md")
```

## Enabling/Disabling Toolsets

```python
agent = create_deep_agent(
    include_todo=True,        # TodoToolset
    include_filesystem=True,  # Console Toolset (file operations)
    include_subagents=True,   # SubAgentToolset
    include_skills=True,      # SkillsToolset
)
```

## Custom Toolsets

Create custom toolsets using `FunctionToolset`:

```python
from pydantic_ai import RunContext
from pydantic_ai.toolsets import FunctionToolset
from pydantic_deep import DeepAgentDeps

# Create toolset
my_toolset = FunctionToolset[DeepAgentDeps](id="my-tools")

@my_toolset.tool
async def fetch_data(
    ctx: RunContext[DeepAgentDeps],
    url: str,
) -> str:
    """Fetch data from a URL.

    Args:
        url: The URL to fetch.

    Returns:
        The response content.
    """
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.text

@my_toolset.tool
async def analyze_sentiment(
    ctx: RunContext[DeepAgentDeps],
    text: str,
) -> str:
    """Analyze sentiment of text.

    Args:
        text: Text to analyze.

    Returns:
        Sentiment analysis result.
    """
    # Your sentiment analysis logic
    return "Positive"

# Add to agent
agent = create_deep_agent(toolsets=[my_toolset])
```

## Tool Documentation

Tools use docstrings for LLM understanding:

```python
@my_toolset.tool
async def process_data(
    ctx: RunContext[DeepAgentDeps],
    data: str,
    format: str = "json",
) -> str:
    """Process and transform data.

    This tool takes raw data and processes it according to the
    specified format. Supports JSON, CSV, and XML formats.

    Args:
        data: The raw data to process.
        format: Output format - 'json', 'csv', or 'xml'. Defaults to 'json'.

    Returns:
        Processed data in the requested format.

    Example:
        >>> process_data(data="name,age\\nAlice,30", format="json")
        '[{"name": "Alice", "age": "30"}]'
    """
    ...
```

## Approval Requirements

Require human approval for sensitive tools:

```python
from pydantic_ai.common_tools.dangerous import DangerousCapability

@my_toolset.tool
async def delete_files(
    ctx: RunContext[DeepAgentDeps],
    pattern: str,
) -> str:
    """Delete files matching pattern."""
    ...

# Mark as dangerous
delete_files.dangerous = DangerousCapability.FILESYSTEM
```

Or configure via `interrupt_on`:

```python
agent = create_deep_agent(
    interrupt_on={
        "delete_files": True,
        "execute": True,
    }
)
```

## Dynamic System Prompts

Toolsets can contribute dynamic system prompts:

```python
def get_my_system_prompt(deps: DeepAgentDeps) -> str:
    """Generate system prompt based on current state."""
    if deps.some_condition:
        return "## Additional Context\nSome relevant information..."
    return ""
```

The agent factory uses these to build dynamic instructions.

## Tool Return Types

Tools can return various types:

```python
# String - most common
async def my_tool(ctx: RunContext[DeepAgentDeps]) -> str:
    return "Result text"

# Structured data (converted to string)
async def my_tool(ctx: RunContext[DeepAgentDeps]) -> dict:
    return {"status": "success", "count": 42}

# Lists
async def my_tool(ctx: RunContext[DeepAgentDeps]) -> list[str]:
    return ["item1", "item2", "item3"]
```

## Best Practices

### 1. Clear Docstrings

Write detailed docstrings - they're the LLM's documentation.

### 2. Type Hints

Use type hints for all parameters:

```python
async def process(
    ctx: RunContext[DeepAgentDeps],
    items: list[str],          # List of strings
    count: int = 10,           # Integer with default
    enabled: bool = True,      # Boolean
) -> str:
    ...
```

### 3. Error Handling

Return informative errors:

```python
async def read_config(
    ctx: RunContext[DeepAgentDeps],
    name: str,
) -> str:
    try:
        return load_config(name)
    except FileNotFoundError:
        return f"Error: Config '{name}' not found. Available: {list_configs()}"
```

### 4. Idempotent Operations

When possible, make tools idempotent:

```python
async def ensure_directory(
    ctx: RunContext[DeepAgentDeps],
    path: str,
) -> str:
    """Ensure directory exists (creates if needed)."""
    if directory_exists(path):
        return f"Directory {path} already exists"
    create_directory(path)
    return f"Created directory {path}"
```

## Next Steps

- [Skills](skills.md) - Modular capability packages
- [API Reference](../api/toolsets.md) - Complete toolset API
- [Custom Tools Example](../examples/basic-usage.md) - More examples

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.