Open source · MIT licensed

The Python toolkit for building AI agents

Calling a provider's raw API is easy. Turning that into a real agent — one that calls tools, remembers a conversation, knows what it costs, and doesn't loop forever — is a week of plumbing every team ends up rebuilding. VisvoAI is that plumbing, published.

pip install visvoai
730+
tests, all green
MIT
no strings attached
3
independent packages
0
open security alerts
Works with
Gemini · Claude · GPT · Groq · Together AI · OpenRouter

We think the boundaries should be real

Most coding agents run on politeness — a prompt that says "please ask before deleting things." That conviction, applied three times:

The OS enforces the rules, not the prompt

Commands that only read run instantly — on macOS and Linux, inside an operating-system sandbox that physically cannot write to your disk. Even if the AI is tricked, the sandbox is not.

Nothing arms itself silently

Agents, skills, and tools that a repo defines stay off until you approve them once — and if the file changes later, you're asked again.

The engine is published, not hidden

Every agent product needs the same core loop, and most teams rebuild it badly once. Ours is here, tested by two real products, for the next person building their own.

The plumbing you'd otherwise write yourself

Same call, same model — provider pricing tracked and updated for you instead of hardcoded and going stale. Real code on both sides.

Raw google-genai SDK
from google import genai

client = genai.Client(api_key="...")
response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Explain attention in one sentence.",
)

# pricing isn't in the SDK — hardcode
# it, and keep it updated by hand
IN_COST = 0.30   # $ / million input tokens
OUT_COST = 2.50  # $ / million output tokens
u = response.usage_metadata
cost = (
    u.prompt_token_count / 1e6 * IN_COST
    + u.candidates_token_count / 1e6 * OUT_COST
)
visvoai-ai
from visvoai.ai import build_chat_model
from visvoai.ai import cost_of, usage_from

model = build_chat_model("gemini:gemini-2.5-flash")
response = model.invoke(
    "Explain attention in one sentence."
)

u = usage_from(response)
cost = cost_of(
    "gemini:gemini-2.5-flash", u["input"], u["output"]
)

Switch to Claude or GPT and the left side is a different SDK, different response shape, different pricing lookup entirely. The right side is the same three lines with a different id.

The loop itself — hand-built vs. done once

LangGraph's create_react_agenthelper covers the demo case. The moment you need a step budget the model can't talk its way past, you're back to wiring the graph yourself — and re-solving the same recursion problem on every project.

Raw LangGraph — hand-built loop
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode, tools_condition

MAX_STEPS = 25
model_with_tools = model.bind_tools(tools)

class State(MessagesState):
    steps: int

def call_model(state: State):
    steps = state["steps"] + 1
    if steps >= MAX_STEPS:
        # drop tools so the model is forced to answer —
        # easy to get wrong: forget this and a model that
        # wants one more tool call just loops forever
        reply = model.invoke(state["messages"])
    else:
        reply = model_with_tools.invoke(state["messages"])
    return {"messages": [reply], "steps": steps}

builder = StateGraph(State)
builder.add_node("agent", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge("__start__", "agent")
builder.add_conditional_edges("agent", tools_condition)
builder.add_edge("tools", "agent")
graph = builder.compile()

result = graph.invoke({"messages": [("user", query)], "steps": 0})
visvoai-core
from visvoai.core.runtime import AgentRuntime
from visvoai.core import ask

graph = AgentRuntime().build_graph(
    model=model,
    core_tools=tools,
    system_prompt="You are a code assistant.",
)

# the step budget, the tools-drop, the retry —
# written once, tested by two shipping products
result = await ask(graph, query)

The left side is ~20 lines you write, test, and maintain per project — and it's still missing retrieval for large tool sets. The right side is three.

Three packages, one conviction each

Use any layer on its own — start wherever your problem is.

visvoai-ai

The foundation: one interface, many providers

One line to any provider's streaming model, plus what most facades skip: a live registry of model facts — pricing, context window, capabilities, normalized thinking levels — so your app can choose and meter models, not just call them.

Providers, registry, metering →
from visvoai.ai import build_chat_model, cost_of

model = build_chat_model(
    "anthropic:claude-sonnet-4-5",
    level="high",
)
visvoai-core

The agent loop, built on it

The loop with a soft step cap (clean final answers, never a recursion error), semantic tool retrieval at fleet scale, a tool lifecycle with pluggable persistence, and extension seams proven by two shipping consumers.

Seams, examples, when-not-to-use →
def word_count(text: str) -> int:
    """Count the words in a piece of text."""
    return len(text.split())

graph = AgentRuntime().build_graph(
    model=model, core_tools=[word_count],
    system_prompt="You are ...",
)
visvoai-cliA real recorded session — not a mockup

The proof: a full product, running on both

Not a demo of the toolkit — the same loop and model layer, unmodified, under a full-terminal agent where the permission model is enforced by the OS, not the prompt. Building your own agent product? This is the reference for how far it goes.

Full tour →

A working agent in 20 lines

No API key needed to see the machinery work — the whole loop (retrieval, memory, an audit trail) runs on a scripted model.

pip install visvoai-core "visvoai-ai[gemini]"
See the full capstone example →
from visvoai.core import ask
from visvoai.core.runtime import AgentRuntime

graph = AgentRuntime().build_graph(
    model=model,
    core_tools=[search_docs, file_ticket],
    system_prompt="You are our helpdesk bot.",
)

answer = await ask(graph, "how do I reset my password?")

What this actually gets you today

Going from zero to a working, multi-provider agent — with a real trust model, not a toy — takes minutes, not the week of SDK-reading and plumbing that calling providers directly usually costs.

Honestly: production hardening — retries across providers, cost caps, shipped observability — is still yours to add today. It's the top of our public roadmap, not a secret. We'd rather tell you what's next than let you find out the hard way.

FAQ

Questions people actually ask.

Start with one command

pip install visvoai