Skip to main content

A minimalistic 'anti-agentic' framework for building reliable AI puppies

Project description

SmartPup Logo

SmartPup

A minimalistic "anti-agentic" framework for building reliable AI puppies that do exactly what you tell them to do, without extra magic. Give them some instructions, a response schema and a bunch of tools - and they will run off and do it. Or at least they will try and will bail clearly if they can't.

Why?

The existing agent frameworks feel too complex and bloated. Maybe they are right for some use cases, but my feeble brain needed something simpler. All this talk of "agents" is tricky because you can't really rely on an LLM to do what you want it to do. Not yet anyway. So I really want is not smart agents that will figure things out, but simply smart functions - that I can call with a system prompt and a bunch of tools and they will reliably do the one thing they are supposed to do. And if they can't - they will fail, ideally explaining why.

So less like superintelligent "agents" and more like well trained puppies. You tell them what to do and they do it, bringing back exactly what you needed in the form you needed. Maybe in the future there is some pavlovian conditioning and training. But for now they are just like your average well trained dog: excitable, reliable, and not very smart.

Features

  • Simple, predictable agents that do run off and do one thing at a time and if they can't - they don't invent shit. They fail clearly and explain why.
  • Uses OpenRouter to support multiple LLM providers (OpenAI, Anthropic, Google, etc.)
  • Built-in tool system with auto-discovery
  • No conversation history - each request is independent
  • Optional memory system for persistence when needed (built as a tool)
  • Uses Pydantic for type safety

Installation

pip install smartpup

Quick Start

import asyncio
from smartpup import Pup, ToolRegistry

async def main():
    # Initialize tools
    registry = ToolRegistry()
    registry.discover_tools()
    
    # Create a weather pup
    weather_pup = Pup(
        instructions="You are a weather assistant. Check the weather and report it as a short poem.",
        tools=registry.get_tools(["get_current_weather"])
    )

    # Get weather
    response = await weather_pup.run("What's the weather in Amsterdam?")
    print(response)

if __name__ == "__main__":
    asyncio.run(main())

Environment Setup

Create a .env file:

OPENROUTER_API_KEY=your-api-key
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1

Built-in Tools

  • get_current_weather: Get current weather for any location
  • get_datetime: Get current date/time in various formats
  • memory: Simple key-value storage for persistence
  • translate: Text translation between languages

You can list all available tools and their parameters programmatically:

from smartpup import ToolRegistry

# Initialize registry and discover tools
registry = ToolRegistry()
registry.discover_tools()

# Get list of all available tools with their descriptions and parameters
tools = registry.list_tools()
for tool in tools:
    print(f"\n{tool['name']}: {tool['description']}")
    print("Parameters:")
    for param_name, param_info in tool['parameters'].items():
        default = f" (default: {param_info['default']})" if param_info['default'] != 'None' else ''
        print(f"  - {param_name}: {param_info['type']}{default}")

Creating Custom Tools

from smartpup import BaseTool

class CalculatorTool(BaseTool):
    name = "calculator"
    description = "Perform basic arithmetic operations"
    
    async def execute(
        self,
        operation: str,
        a: float,
        b: float
    ) -> str:
        """
        Perform basic arithmetic
        
        Args:
            operation: One of 'add', 'subtract', 'multiply', 'divide'
            a: First number
            b: Second number
        """
        if operation == "add":
            return f"Result: {a + b}"
        # ... other operations ...

# Register and use the tool
registry = ToolRegistry()
registry.register_tool(CalculatorTool)


# Now you can use this tool in a pup
pup = Pup(
    instructions="You are a calculator. Use the calculator tool to perform calculations and return back the result, spelled out in letters.",
    tools=registry.get_tools(["calculator"])
)

response = await pup.run("What is 15 plus 10?")
print(response)

Examples

Check the examples directory for more usage examples:

  • Basic weather reporting
  • Translation service
  • Memory usage
  • Custom calculator tool

Configuration

Optional global configuration:

from smartpup import configure

configure(
    default_model="openai/gpt-4o-mini",  # Default LLM to use
    max_iterations=10,                    # Max tool call iterations
    memory_file="memory.json"            # For memory tools. alternatively you can set the environment variable MEMORY_FILE
)

Development

For development:

git clone https://github.com/georgestrakhov/smartpup.git
cd smartpup
pip install -e ".[dev]"
pytest  # Run tests

Philosophy

SmartPup is built on these principles:

  1. One Task at a Time: Each pup does one specific thing
  2. No Magic: Clear, predictable behavior without hidden complexity
  3. Tool-First: Tools provide clear interfaces for agent capabilities
  4. Independent Requests: No conversation history or context bleeding

License

MIT License - see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smartpup-0.1.11.tar.gz (275.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smartpup-0.1.11-py3-none-any.whl (21.5 kB view details)

Uploaded Python 3

File details

Details for the file smartpup-0.1.11.tar.gz.

File metadata

  • Download URL: smartpup-0.1.11.tar.gz
  • Upload date:
  • Size: 275.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for smartpup-0.1.11.tar.gz
Algorithm Hash digest
SHA256 aabd9aa1a2a01fb9788d6d1c035b95d423368f3fc22da03740df373af814dbda
MD5 60c29fa1b3f9e4474aeff7b5e77f9ebc
BLAKE2b-256 8bf9fc68cd3b381fcbf8adaaea203645948c81a7adcf65d16beef6c957477f6c

See more details on using hashes here.

File details

Details for the file smartpup-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: smartpup-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 21.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for smartpup-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 15f7f04c589aa4d64311d122ee7c38a5a0e7456a679268a84a1be8fe3a468d5f
MD5 790ba8618aa6d98cc70fbac4087d9787
BLAKE2b-256 3f523f45b9b118f5cd0c882b407c411091abc13e21b1862f1b1c205dba6a6cb4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page