
Plain async functions instead of graph nodes. 3 deps. Append-only checkpointing.
| langgraph | CubePi | |
|---|---|---|
| Abstraction | Graph nodes + edges + channels | Plain async functions â run_agent_loop is a while loop |
| Streaming | Callback-based, multiple handler types | async for event in stream â one pattern everywhere |
| Checkpointing | Full snapshot per step; serializes entire message list | Append-only â O(1) DB I/O regardless of conversation length |
| Dependencies | langchain-core, langgraph-sdk, and transitive deps | 3 core deps: pydantic, anthropic, openai |
| Tool execution | Tools are graph nodes with manual wiring | Declare tools as functions; framework routes and parallelizes |
| Multi-provider | Via langchain chat model adapters | Native Provider protocol â Anthropic, OpenAI built in |
| Middleware | Graph-level middleware on node entry/exit | 5 typed hooks with declarative composition rules |
| Observability | LangSmith / Langfuse integration | Events + middleware hooks â bring your own tracing |
A single async function loop. One Provider, one AgentTool, and you're streaming.
import asyncio
from pydantic import BaseModel
from cubepi import Agent, AgentTool, Model
from cubepi.agent.types import AgentToolResult
from cubepi.providers.anthropic import AnthropicProvider
from cubepi.providers.base import TextContent
provider = AnthropicProvider(api_key="sk-...")
class GetWeatherParams(BaseModel):
city: str
async def get_weather(tool_call_id, params: GetWeatherParams, *, signal=None, on_update=None):
return AgentToolResult(
content=[TextContent(text=f"72°F and sunny in {params.city}")]
)
agent = Agent(
provider=provider,
model=Model(id="claude-sonnet-4-5-20250929", provider="anthropic"),
tools=[AgentTool(
name="get_weather",
description="Get current weather for a city",
parameters=GetWeatherParams,
execute=get_weather,
)],
system_prompt="You are a helpful weather assistant.",
)
def on_event(event, signal=None):
if event.type == "text_delta":
print(event.delta, end="", flush=True)
agent.subscribe(on_event)
asyncio.run(agent.prompt("What's the weather in Tokyo?"))
One async loop, fully typed events.
â Guides / Agentsasync for event in stream.
â Guides / StreamingPlain functions, parallel execution.
â Guides / ToolsAnthropic, OpenAI, or write your own.
â Guides / ProvidersAppend-only, O(1) per turn.
â Guides / CheckpointingLoad remote tools at startup.
â Guides / MCPpip install cubepiuv add cubepipoetry add cubepipip install cubepi[sqlite,postgres,mcp]