Skip to main content

Sanityops Agent

PyPI version Python versions License

A modular, extensible AI Agent framework with OOP design, multi-provider support, and a plugin architecture for tools, hooks, and multi-agent workflows.

Features

  • Unified Message Model: Subclassed content blocks (TextBlock, ToolUseBlock, ThinkingBlock, etc.) with type-safe access and FinishReason enums.
  • LLM Provider Abstraction: Swap between OpenAI, Anthropic, or any custom provider via the LLMProvider interface. Adapters handle protocol differences.
  • Plugin Tools: Register custom tools by subclassing Tool with JSON Schema parameters. Tools support tags (e.g., parent_only) for access control.
  • Multi-Agent: Parent agent can spawn sub-agents with filtered tool access and tighter limits (max_loops=10, timeout=120s).
  • Hook System: Intercept tool calls, LLM responses, and agent lifecycle events for approval workflows, logging, or blocking.
  • State Persistence: Save/restore conversation context as JSON.
  • Streaming: Token-by-token streaming with StreamChunk dataclass.
  • Retry Logic: Exponential backoff for transient LLM errors.

Installation

# Install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment and install dependencies
cd new_agent
uv sync

# Install with dev dependencies (pytest, etc.)
uv sync --all-extras

Manual pip install

pip install -e ".[dev]"

Quick Start

Minimal Example

import asyncio
from sanityops_agent.llm.providers.openai import OpenAIProvider
from sanityops_agent.agents.factory import AgentFactory
from sanityops_agent.tools.registry import ToolRegistry

async def main():
    provider = OpenAIProvider(
        api_key="your-key",  # or set OPENAI_API_KEY env var
        model="gpt-4o-mini",
    )

    factory = AgentFactory(
        provider=provider,
        tool_registry=ToolRegistry(),
    )
    agent = factory.create_parent_agent(
        system_prompt="You are a helpful assistant.",
    )

    result = await agent.run("What is the capital of France?")
    print(result.text)
    print(f"Tokens: {result.tokens_used}, Loops: {result.loops_used}")

    await provider.close()

asyncio.run(main())

Custom Tool

from sanityops_agent.tools.base import Tool, ToolResult

class WeatherTool(Tool):
    name = "get_weather"
    description = "Get weather for a city."
    parameters = {
        "type": "object",
        "properties": {
            "city": {"type": "string"},
        },
        "required": ["city"],
    }

    async def execute(self, city: str, **kwargs) -> ToolResult:
        # Call weather API here
        return ToolResult(content=f"Sunny, 25°C in {city}")

# Register it
registry = ToolRegistry()
registry.register(WeatherTool())

factory = AgentFactory(provider=provider, tool_registry=registry)
agent = factory.create_parent_agent()
result = await agent.run("What's the weather in Tokyo?")

State Persistence

from sanityops_agent.managers.state import StateManager

state = StateManager(state_path="session.json")

# Save
await state.save(agent.context)

# Resume
context = await state.load()
agent.context = context

Sub-Agent Creation

# Sub-agents have filtered tools (no parent_only) and tighter limits
sub = factory.create_sub_agent(
    system_prompt="You are a code reviewer.",
)
result = await sub.run("Review this function: def foo(x): return x + 1")

Project Structure

sanityops_agent/
├── core/          # Message model, Agent base class, Context
├── llm/           # Provider abstraction, adapters, exceptions
│   └── providers/ # OpenAI, Anthropic implementations
├── tools/         # Tool base class, registry, context
│   └── builtins/  # Built-in tools (bash, file_ops, todo, etc.)
├── agents/        # Parent agent, Sub-agent, Factory
├── hooks/         # Hook system (before/after tool, LLM, etc.)
├── managers/      # State, skill, todo, history persistence
└── legacy/        # Backward compatibility adapter

tests/
├── unit/          # Isolated component tests
├── integration/   # Multi-component workflow tests
├── mocks/         # MockLLMProvider, mock tools
└── conftest.py    # Pytest fixtures

examples/
├── basic_usage.py           # Interactive examples (6 scenarios)
└── streaming_react_agent.py # Streaming ReAct agent with .env config

Configuration

Using .env File

Copy .env.example to .env and fill in your credentials:

cp .env.example .env

Supported environment variables:

Variable Default Description
LLM_PROVIDER openai Provider name: openai or anthropic
API_KEY (required) Your API key
BASE_URL (empty) Custom endpoint (vLLM, Azure, etc.)
MODEL gpt-4o-mini Model name
MAX_LOOPS 30 Max agent loops per run
MAX_TOKENS 8000 Max tokens per LLM call
TOTAL_TIMEOUT 300 Total timeout in seconds
TEMPERATURE 0.7 Sampling temperature
SYSTEM_PROMPT (see .env) System prompt for the agent

Running Examples

# 1. Set up your .env first
cp .env.example .env
# Edit .env with your API key

# 2. Streaming ReAct Agent (reads .env, streams output)
uv run python examples/streaming_react_agent.py "What's 25 * 13?"

# 3. Interactive basic examples menu
uv run python examples/basic_usage.py

Key Design Decisions

Decision Rationale
Subclassed content blocks Type safety, static analysis catches wrong field access
FinishReason enum over strings No magic strings, IDE autocomplete
content: list[...] always Simplifies adapter logic, no str/list branching
Provider is pure call, no retry Single responsibility, retry belongs in Agent layer
Tools use JSON Schema params Compatible with OpenAI/Anthropic tool calling APIs
Sequential tool execution Simpler error handling, predictable ordering
AgentFactory owns config Factory config propagates to created agents

License

Apache 2.0 - See LICENSE for details.

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Release files for sanityops-agent 0.0.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sanityops-agent 0.0.6
File Size Uploaded
sanityops_agent-0.0.6.tar.gz 164.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sanityops-agent 0.0.6
File Interpreter ABI Platform
sanityops_agent-0.0.6-py3-none-any.whl Python 3 none any Details

Total release size: 231.0 kB

Release files / sanityops_agent-0.0.6.tar.gz

Download URL sanityops_agent-0.0.6.tar.gz
Size 164.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0139c6e42794bdb5cf8091a1184498e2571ab56c924408e2390cd7c51ba8511f
BLAKE2b-256 checksum
How to use checksums
ba774adf00157de9b4565884c1cd27305f30535ea22c8eb36371a26edf302457
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / sanityops_agent-0.0.6-py3-none-any.whl

Download URL sanityops_agent-0.0.6-py3-none-any.whl
Size 66.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e08bc15f9704a472042dee0ec3bf3532eac215845dc796132ceeca8ec1cee36d
BLAKE2b-256 checksum
How to use checksums
02fa49d83e932a8f69735d2057a32045382245e10d979b249fb4c349c7999fbc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.0

2 release files

This release

0.0.6 This release

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page