ConnectOnionConnectOnion

ConnectOnion

Keep simple things simplemake complicated things possible
Terminal
$pip install connectonion
from connectonion import Agent

agent = Agent("You are helpful", tools=[get_weather])
agent.input("What's the weather in NYC?")
Production ReadyMIT LicensePython 3.9+PyPI Downloads
Why ConnectOnion

See the Difference

Same task, dramatically different complexity. Scroll to see real code comparisons.

Calculator Agent

vs LangChain

Type hints = automatic tool conversion. No wrappers needed.

ConnectOnion8 lines
from connectonion import Agent

def add(a: float, b: float) -> float:
    return a + b

def multiply(a: float, b: float) -> float:
    return a * b

agent = Agent("You are a calculator", tools=[add, multiply])
agent.input("What is 5 + 3, then multiply by 2?")
LangChain30+ lines
from langchain.agents import Tool, AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate

def add(input_str: str) -> str:
    """Add two numbers. Input: 'a,b'"""
    a, b = map(float, input_str.split(','))
    return str(a + b)

def multiply(input_str: str) -> str:
    """Multiply two numbers. Input: 'a,b'"""
    a, b = map(float, input_str.split(','))
    return str(a * b)

tools = [
    Tool(name="add", func=add, description="Add two numbers. Input: 'a,b'"),
    Tool(name="multiply", func=multiply, description="Multiply. Input: 'a,b'"),
]

template = """You are a calculator assistant.
Available tools: {tools}
Tool names: {tool_names}
Question: {input}
{agent_scratchpad}"""

prompt = PromptTemplate.from_template(template)
llm = ChatOpenAI(model="gpt-4", temperature=0)
agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "What is 5 + 3, then multiply by 2?"})

Browser Automation

vs OpenAI SDK

Just pass a class. Public methods become tools, self = shared state.

ConnectOnion16 lines
from connectonion import Agent

class BrowserAutomation:
    def __init__(self):
        self._browser = None
        self._page = None
        self._screenshots = []

    def start_browser(self):
        self._browser = launch_browser()
        self._page = self._browser.new_page()
        return "Browser started"

    def navigate(self, url: str):
        self._page.goto(url)  # Uses shared state via self
        return f"Navigated to {url}"

    def take_screenshot(self, path: str):
        self._page.screenshot(path=path)
        self._screenshots.append(path)
        return f"Saved: {path}"

browser = BrowserAutomation()
agent = Agent("You automate browsers", tools=[browser])
OpenAI SDK30+ lines
from dataclasses import dataclass
from agents import Agent, Runner, function_tool
from agents.types import RunContextWrapper

@dataclass
class BrowserContext:
    browser: object = None
    page: object = None
    screenshots: list = None

    def __post_init__(self):
        self.screenshots = self.screenshots or []

@function_tool
def start_browser(wrapper: RunContextWrapper[BrowserContext]):
    wrapper.context.browser = launch_browser()
    wrapper.context.page = wrapper.context.browser.new_page()
    return "Browser started"

@function_tool
def navigate(wrapper: RunContextWrapper[BrowserContext], url: str):
    wrapper.context.page.goto(url)  # Access via wrapper.context
    return f"Navigated to {url}"

@function_tool
def take_screenshot(wrapper: RunContextWrapper[BrowserContext], path: str):
    wrapper.context.page.screenshot(path=path)
    wrapper.context.screenshots.append(path)
    return f"Saved: {path}"

agent = Agent(name="browser", instructions="...",
    tools=[start_browser, navigate, take_screenshot])

ctx = BrowserContext()
result = await Runner.run(agent, "Open google", context=ctx)

ReAct Reasoning

vs Google ADK

plugins=[re_act] - one line adds Plan + Act + Reflect loop.

ConnectOnion1 line to add
from connectonion import Agent
from connectonion.useful_plugins import re_act

def search(query: str) -> str:
    return f"Results for: {query}"

# Just add plugins=[re_act] - that's it!
agent = Agent(
    "You are a research assistant",
    tools=[search],
    plugins=[re_act]  # Plan + Act + Reflect loop
)

agent.input("Research the history of Python")
Google ADKPlanner class
from google.adk import Agent
from google.adk.planners import PlanReActPlanner

def search(query: str) -> dict:
    """Search for information.

    Args:
        query: The search query.

    Returns:
        dict with search results.
    """
    return {"status": "success", "results": f"Results for: {query}"}

# Must use special planner class
agent = Agent(
    model="gemini-2.0-flash",
    planner=PlanReActPlanner(),  # Special planner object
    tools=[search],
)
# Run with: adk web

Memory System

vs All Frameworks

Memory is just a tool. No services, no sessions, no deprecated APIs.

ConnectOnion8 lines
from connectonion import Agent, Memory

memory = Memory()  # That's it!

agent = Agent(
    "You remember user preferences",
    tools=[memory]  # Memory is just a tool
)

agent.input("Remember: I prefer dark mode")
agent.input("What are my preferences?")
LangChainDEPRECATED
from langchain.memory import ConversationBufferMemory
from langchain.chains import LLMChain
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.prompts.chat import MessagesPlaceholder

# Choose from 6+ memory types:
# - ConversationBufferMemory
# - ConversationSummaryMemory
# - ConversationBufferWindowMemory
# - ConversationKGMemory
# - VectorStoreRetrieverMemory
# ... and more

prompt = ChatPromptTemplate([
    MessagesPlaceholder(variable_name="chat_history"),
    # ... more setup
])

memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# DEPRECATED in v0.3.1 - must migrate to LangGraph

Event Hooks

vs All Frameworks

9 event types with full agent access. Not just guardrails.

ConnectOnion9 event types
from connectonion import after_tools

def my_hook(agent):
    # Access EVERYTHING:
    session = agent.current_session
    messages = session['messages']      # All conversation
    trace = session['trace']            # Every LLM call
    user_input = session['user_prompt'] # Original request

    # Modify ANYTHING:
    session['messages'].append({
        'role': 'assistant',
        'content': 'Thinking about next step...'
    })

# That's it - just pass it
agent = Agent("assistant", tools=[...],
    on_events=[after_tools(my_hook)])

# Available: after_user_input, before_llm, after_llm,
# before_tools, before_each_tool, after_each_tool,
# after_tools, on_error, on_complete
OpenAI SDKGuardrails only
from agents import Agent, output_guardrail
from agents.types import OutputGuardrailTripwireTriggered

# OpenAI SDK has NO event system
# Only "guardrails" for input/output validation

@output_guardrail
async def check_output(ctx, agent, output):
    # Can only validate, not modify behavior
    # No access to tool execution
    # No access to conversation history
    if "bad" in output:
        raise OutputGuardrailTripwireTriggered("Invalid")
    return output

# Want ReAct? Build it yourself
# Want custom logging? No standard way
# Want approval flows? No standard way

Quick Comparison

FeatureConnectOnionOthers
Tool definitionJust a functionDecorators, wrappers, classes
Shared stateself.fieldwrapper.context, dataclass, services
Add ReActplugins=[re_act]Planner classes, different agent types
MemoryMemory as toolSessions, services, deprecated APIs
Event hooks9 types, full accessGuardrails only, limited callbacks
Free creditsYesNo
FREE

Start Free - No API Key Needed

Get started immediately with free credits for GPT-4o, Claude, and Gemini.

model="co/gemini-2.5-pro"
Check balance: co status

What You Can Build

Functions = Tools

def search(q: str):
return results

No wrappers. No decorators. Just functions.

Deploy Anywhere

agent.serve()
# Globally accessible

From your laptop. No AWS needed.

Connect Agents

other = connect("0x...")
# Agents as tools

Build agent networks. Like the internet, but for AI.

Production Ready

Built for production from day one

Auto Log

.co/logs/

@xray

Breakpoints

Plugins

Just functions

Human Loop

Approval flows

"Keep simple things simple, make complicated things possible"
8 lines

For basic agents. No boilerplate.

Full power

Production features when you need them.

Your code

Not framework code. Just Python.

Ready to Start?

Terminal
$pip install connectonion
Quick Start →

60 seconds to your first agent. No AWS. Just code.