Skip to content

Guide: Building Custom Tools

Basic Tool

from largestack import tool

@tool
async def get_stock_price(symbol: str) -> str:
    """Get current stock price for a ticker symbol."""
    import httpx
    async with httpx.AsyncClient() as c:
        r = await c.get(f"https://api.example.com/stock/{symbol}")
        return f"{symbol}: ${r.json()['price']}"

Type hints → JSON Schema. Docstring → tool description. That's it.

Tool Options

@tool(timeout=60)              # 60s timeout (default: 30s)
@tool(retries=3)               # Auto-retry on failure
@tool(name="stock_lookup")     # Override function name
@tool(description="...")       # Override docstring

Permissions

agent = Agent(
    tools=[get_stock_price, write_file, shell_command],
    tool_permissions={
        "allow": ["get_stock_price", "write_file"],  # Only these allowed
        "deny": ["shell_command"],                     # Explicitly blocked
    }
)

Convert RAG to Tool

from largestack import create_rag

rag = create_rag(documents=my_docs)
search_tool = rag.as_tool()  # Returns @tool-decorated function
agent = Agent(tools=[search_tool])

Idempotency

Tools are automatically idempotent — calling the same tool with the same parameters returns the cached result (SHA-256 keyed). This prevents duplicate API calls when the agent retries.