Skip to main content

A minimal DSPy-inspired library with native OpenAI tool calling

Project description

udspy

PyPI version Python versions Tests Documentation codecov License: MIT

A lightweight DSPy-inspired library optimized for resource-constrained environments, with native OpenAI tool calling, human-in-the-loop workflows, and conversation history.

Topics: python openai llm dspy pydantic async ai-framework function-calling tool-calling streaming conversational-ai prompt-engineering type-hints pytest chatbot agent human-in-the-loop

About This Project

This project is inspired by DSPy's elegant design and core abstractions (Signatures, Modules, Predictions).

udspy addresses a specific use case: resource-constrained environments. DSPy's dependency on LiteLLM (which requires ~200MB of memory when loaded) makes it challenging to use in contexts with limited resources, such as:

  • Serverless functions with memory limits
  • Edge deployments
  • Embedded systems
  • Cost-sensitive cloud environments

udspy provides:

  • Minimal footprint: Uses the OpenAI library directly (~10MB vs ~200MB)
  • OpenAI-compatible providers: Works with any provider compatible with OpenAI's API (OpenAI, Azure OpenAI, Together AI, Groq, etc.)
  • Additional features for common patterns:
    • Human-in-the-loop workflows with state management
    • Automatic tool calling with multi-turn conversations
    • Built-in conversation history management
    • Confirmation system for user approval of critical operations

If resource constraints aren't a concern for your use case, consider DSPy for a more feature-complete solution.

Features

  • Pydantic-based Signatures: Define inputs, outputs, and tools using Pydantic models
  • Human-in-the-Loop Workflows: Built-in confirmation system for user approval, clarification, and feedback
    • @confirm_first decorator for requiring confirmation before execution
    • Thread-safe and asyncio task-safe state management
    • Support for approval, rejection, argument modification, and feedback
  • Automatic Tool Calling: Use @tool decorator for automatic tool execution with multi-turn conversations
  • ReAct Agent: Reasoning and acting agent with tool calling and self-reflection
  • Conversation History: Built-in History class for managing multi-turn conversations
  • Optional Tool Execution: Control whether tools execute automatically or return for manual handling
  • Module Abstraction: Compose LLM calls with reusable modules (Predict, ChainOfThought, ReAct)
  • Streaming Support: Stream reasoning and output fields incrementally with async generators
  • Minimal Dependencies: Only requires openai and pydantic (~10MB total footprint)

Installation

For Development

# Clone the repository
git clone https://github.com/silvestrid/udspy
cd udspy

# Install dependencies and package in editable mode
uv sync
uv pip install -e .

# Or with pip
pip install -e .

For Users

# When published to PyPI
pip install udspy

# Or with uv
uv pip install udspy

Quick Start

Basic Usage

import udspy
from udspy import Signature, InputField, OutputField, Predict, LM

# Configure with LM instance
lm = LM(model="gpt-4o-mini", api_key="your-api-key")
udspy.settings.configure(lm=lm)

# Define a signature
class QA(Signature):
    """Answer questions concisely."""
    question: str = InputField()
    answer: str = OutputField()

# Create and use a predictor
predictor = Predict(QA)
result = predictor(question="What is the capital of France?")
print(result.answer)

With Conversation History

from udspy import History

predictor = Predict(QA)
history = History()

# Multi-turn conversation
result = predictor(question="What is Python?", history=history)
print(result.answer)

result = predictor(question="What are its main features?", history=history)
print(result.answer)  # Context from previous turn is maintained

With Automatic Tool Calling

from udspy import tool
from pydantic import Field

@tool(name="Calculator", description="Perform arithmetic operations")
def calculator(
    operation: str = Field(description="add, subtract, multiply, divide"),
    a: float = Field(description="First number"),
    b: float = Field(description="Second number"),
) -> float:
    ops = {"add": a + b, "subtract": a - b, "multiply": a * b, "divide": a / b}
    return ops[operation]

predictor = Predict(QA, tools=[calculator])
result = predictor(question="What is 157 times 234?")
print(result.answer)  # Tools are automatically executed

With Human-in-the-Loop

from udspy import ReAct, HumanInTheLoopRequired, tool
from pydantic import Field
import os

@tool(
    name="delete_file",
    description="Delete a file",
    require_confirmation=True  # Requires user confirmation
)
def delete_file(path: str = Field(description="File path")) -> str:
    os.remove(path)
    return f"Deleted {path}"

class FileTask(Signature):
    """Perform file operations safely."""
    request: str = InputField()
    result: str = OutputField()

agent = ReAct(FileTask, tools=[delete_file])

try:
    result = agent(request="Delete /tmp/old_data.txt")
except HumanInTheLoopRequired as e:
    print(f"Agent asks: {e.question}")
    # User confirms: "yes", "no", or provides feedback
    result = agent.resume("yes", e)
    print(result.result)

Development

# Install dependencies and package in editable mode
just install
uv pip install -e .

# Run tests
just test

# Run linter
just lint

# Format code
just fmt

# Type check
just typecheck

# Run all checks
just check

# Build docs
just docs-serve

Documentation

Full documentation is available at silvestrid.github.io/udspy

Or browse locally:

Building Documentation

# Install mkdocs dependencies
pip install mkdocs-material mkdocstrings[python]

# Serve docs locally
mkdocs serve

# Build static site
mkdocs build

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Releases

Releases are automated via GitHub Actions:

  1. Update version in pyproject.toml and src/udspy/__init__.py
  2. Commit and tag: git tag v0.x.x && git push --tags
  3. GitHub Actions will build, test, and publish to PyPI
  4. Documentation will be deployed to GitHub Pages

See CONTRIBUTING.md for detailed release instructions.

License

MIT

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

udspy-0.1.5.tar.gz (267.6 kB view details)

Uploaded Source

Built Distribution

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

udspy-0.1.5-py3-none-any.whl (60.4 kB view details)

Uploaded Python 3

File details

Details for the file udspy-0.1.5.tar.gz.

File metadata

  • Download URL: udspy-0.1.5.tar.gz
  • Upload date:
  • Size: 267.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for udspy-0.1.5.tar.gz
Algorithm Hash digest
SHA256 d9cdbc9980d23449903d5b6ab86c93f3bd8b7847a4d2b9407b81857690d7d8fb
MD5 dbbed251df166868a34f448473da6f44
BLAKE2b-256 eb8e7a3ebaf3702fe60763cfe5727548ee27661ecc89b1f9bb11d5ca8c1727f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for udspy-0.1.5.tar.gz:

Publisher: release.yml on baserow/udspy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file udspy-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: udspy-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 60.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for udspy-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 07414eb07b352b5dc12a493ba005d2f3380d219009539001a096c7fd1ce7d4aa
MD5 ceb95f6d81e03cc1f1dda20ab2be8030
BLAKE2b-256 b779a5988259353f162557d8be38e61094c3d1aed6fc25df981b0de9862f66fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for udspy-0.1.5-py3-none-any.whl:

Publisher: release.yml on baserow/udspy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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