Open source · MIT licensed · two independent packages

The plumbing between an LLM API and a real AI agent

Calling Gemini, Claude, or GPT is one function call. An agent that calls tools, remembers a conversation, retrieves the right tool out of hundreds, knows what it cost, and never loops forever — that's a week of plumbing every team rebuilds from scratch. VisvoAI is that plumbing: two small, composable Python packages instead of a framework you configure.

pip install visvoai-core "visvoai-ai[gemini]"

Raw provider API vs. an actual agent

Same model, same question — the left side is what you write against a provider's SDK directly; the right is the same call throughvisvoai-ai. Nothing hidden: pricing tracked for you instead of hardcoded and going stale.

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, a different response shape, a different pricing lookup, entirely. The right side is the same three lines with a different deployment id — see every supported provider & model.

Why this exists

LangChain and LangGraph give you the graph and the message primitives. They don't give you an opinion on the three things that actually break in production:

Runaway agents

create_react_agent covers the demo. The moment a model wants one tool call too many, you're debugging a GraphRecursionError in front of a user instead of getting one clean final answer.

Tool sprawl

Connect a handful of MCP servers and you're holding hundreds of tools. Binding all of them wrecks tool-choice accuracy and bloats every request — you need retrieval, not a bigger prompt.

Provider drift

Gemini calls it thinking_budget, Claude calls it extended thinking, OpenAI calls it reasoning_effort. Three vocabularies for the same idea, multiplied by every model you support.

VisvoAI files down exactly those edges — a soft step cap, semantic tool retrieval, one normalized thinking-level scale — as two small, MIT-licensed packages you can read end to end, not a platform you configure. Use either alone; visvoai-core takes any LangChain BaseChatModel, it doesn't require visvoai-ai.

visvoai-cliA real shipping product, not a demo

The same loop, running a full terminal agent

Every seam documented here is exercised by two real consumers: a full terminal coding agent and a hosted multi-tenant platform, both subclassing the same AgentRuntime — no forks, no private branches of this code.

See it running at cli.visvoai.com →

A working agent in about 20 lines

Tools are plain Python functions — type hints become the schema, the docstring becomes the description the model routes on. No framework imports required to write one.

from visvoai.ai import build_chat_model
from visvoai.core.runtime import AgentRuntime
from visvoai.core import ask

def read_file(path: str) -> str:
    """Read a file and return its contents."""
    return open(path).read()

graph = AgentRuntime().build_graph(
    model=build_chat_model("gemini:gemini-2.5-flash"),
    core_tools=[read_file],
    system_prompt="You are a code assistant.",
)

answer = await ask(graph, "What's in pyproject.toml?")

Start with one command

pip install visvoai-core "visvoai-ai[gemini]"