Catalog PyPI
Back to packageRELEASE DETAILS

1.1.1

PyPI

agentino-framework

Lightweight Python agent framework. Config → agents → run.

agentaianthropicllmopenaitools
Published29 Aug 2026
Direct dependencies21
Transitive dependenciesNot calculated

README

Version 1.1.1 documentation

Agentino

A lightweight Python agent framework. YAML config → tool-calling loop → output. No graphs, no DSLs, no DAG editors — just functions you decorate and a runtime that knows how to call them.

pip install agentino-framework

The distribution is agentino-framework because the agentino name on PyPI belongs to an unrelated project. It imports as agentino regardless:

from agentino import Agent, tool

Hello agent in 8 lines

from agentino import Agent, tool

@tool
async def get_weather(city: str) -> str:
    """Look up current weather for a city."""
    return f"It's 22°C in {city}."

agent = Agent(instructions="You're a helpful assistant.", tools=[get_weather])
print(await agent.run("What's the weather in Lisbon?"))
# → "It's 22°C in Lisbon. Want a forecast?"

That's the whole API: define tools as plain async functions, hand them to an Agent, call .run(). The framework handles the LLM round-trip, tool dispatch, retries, and the final-text extraction.


What's in the box

src/agentino/
├── core/              Agent, Runner, LLM, Tool, Message, Context, State, Session
├── config/            YAML loaders for agents, pipelines, tools
├── pipeline/          Pipeline, StagedPipeline (multi-stage flows with verdicts)
├── safety/            GateManager, HookManager, security, sanitizers
├── reliability/       resilience (retry/backoff), compaction, error taxonomy
├── extras/            knowledge (TF-IDF + embeddings), memory, audio, skills
├── providers/         Codex, Anthropic — pluggable LLM backends
├── scheduler/         CronScheduler + JobStore protocol (file/sqlite/in-memory)
├── tools/std/         Built-in tools: files, shell, grep, web search and fetch,
│                      weather, document generation (pdf/docx/xlsx/pptx/csv),
│                      agent memory. `BUILTIN_TOOLS` is the ten a coding-style
│                      agent gets by default; the rest are opt-in.
├── transport/         Outbound channel adapters (Telegram, Slack, WhatsApp, WebSocket)
├── workers/           fork_agent, make_spawn_tool — multi-agent spawning
└── cli/               REPL renderer

Top-level from agentino import … exports the curated public API. Deeper paths like from agentino.safety.gates import GateManager are how internal packages talk to each other.


Configure agents from YAML

# agents.yml
agents:
  reviewer:
    model: gpt-5.4-codex
    instructions_file: prompts/reviewer.md
    tools: [read_file, grep, shell]            # auto-discovered from tools/
    knowledge:
      dir: ./knowledge                          # TF-IDF + dense embeddings
agentino run agents.yml                  # one-shot REPL
agentino run agents.yml --agent reviewer # specific agent
agentino run agents.yml --serve 8080     # HTTP server
agentino run agents.yml -m "Review PR #42"
agentino run agents.yml -m "Review PR #42" --mode json   # machine-readable (one envelope)
agentino run agents.yml -m "Review PR #42" --mode jsonl  # streaming events + final envelope

Headless / foreign-harness mode

--mode json|jsonl makes agentino run --message … emit a structured contract on stdout instead of ANSI-prettified markdown — the same shape pi --print, codex exec --json, and claude -p --output-format stream-json provide. Lets non-Python harnesses (IDE extensions, polyglot stacks) shell out to agentino and parse the result programmatically.

$ agentino run agents.yml -m "List open invoices" --mode json
{"type":"final","text":"…","tools_used":["list_invoices"],
 "tool_outputs":["…"],"usage":{"prompt_tokens":1200,"completion_tokens":85},
 "model":"gpt-5.4-codex","elapsed_ms":2254}

What you can do beyond a single tool call

Pipelines

StagedPipeline runs multi-stage flows where each stage produces a verdict the next stage can read. A benchmark harness can use it for security check → execute → report; the security stage rejects unsafe inputs before the execute stage ever runs.

from agentino import StagedPipeline, StageDef
pipeline = StagedPipeline(stages=[
    StageDef(name="security", agent=security_agent, verdict_required=True),
    StageDef(name="execute", agent=worker_agent, on_reject="report_threat"),
])

Gates — declarative tool preconditions

GateManager rejects tool calls whose preconditions haven't been met. Useful when you want guarantees beyond the LLM following its instructions.

from agentino.safety.gates import GateRule, GateManager
rules = [GateRule(
    gate="invoice_listed",
    tools=["set_invoice_status"],
    message="Run list_invoices first so you've actually seen the IDs.",
)]

When the agent loop encounters set_invoice_status and invoice_listed isn't marked, the tool returns the rejection message instead of running.

Hooks — observe + block tool calls without touching the tool

Two flavours of HookManager: Python callbacks (in-process, fast — for audit logs, history mirroring, metric emission) and shell commands (subprocess — for ops integrations, external validators).

from agentino.safety.hooks import HookManager
hooks = HookManager()
hooks.register("PostToolUse", matcher={"tool_name": "chat"},
               callback=lambda ctx: audit_db.insert(ctx))

Scheduler — cron-style routine execution

from agentino.scheduler import CronScheduler, FileJobStore
scheduler = CronScheduler(store=FileJobStore("data/jobs.json"))
await scheduler.start()

JobStore is a protocol — ship InMemoryJobStore, SqliteJobStore, FileJobStore, or write your own (e.g. file-as-truth tenant routines, see runspace's tenant routine store).

Knowledge base

Hybrid TF-IDF + dense-embedding retrieval with one tool: search_knowledge. Drop markdown files in a directory, point an agent at it, the LLM gets a search tool and reaches into the corpus when it needs to.

Multi-channel gateway

agentino run agents.yml --gateway

Maps Slack, Telegram, WhatsApp, and WebSocket transports onto the same agent config. One agent serves users from any channel without changing its code.


Pointing it at a model

export AGENTINO_BASE_URL=https://api.openai.com/v1   # or vLLM, Ollama, OpenRouter…
export AGENTINO_API_KEY=sk-…

The wire protocol is inferred from the URL: Anthropic for an Anthropic endpoint, Codex for chatgpt.com/backend-api or a /codex path, and plain OpenAI-compatible /chat/completions for everything else — which is what vLLM, Ollama, LM Studio, OpenRouter and api.openai.com all speak.

Set AGENTINO_PROVIDER to openai, openai-codex or anthropic to override the guess. A sk-ant- key implies Anthropic, and a ChatGPT subscription token implies Codex, whatever the URL says.

Why a new framework

Agentino was built around a few opinions other frameworks make hard:

  • Functions, not classes: tools are @tool-decorated async def. No BaseTool.execute() ceremony.
  • YAML for shape, code for behaviour: agent identity (model, prompt, available tools) is config. Logic stays in Python.
  • No graph editor: complex flows are just Pipeline / StagedPipeline composed in code. If you can read a function call, you can read your flow.
  • Async-first, batteries included: retry-with-backoff, context compaction, tool-output truncation, error taxonomy — all built in.
  • Provider-agnostic: Codex, OpenAI, Anthropic, anything OpenAI-compatible.

If you've fought a framework's abstractions to get a simple agent working, agentino is the one with the smallest surface that still grows with you.


Cookbook

Concrete recipes for the patterns above:


Used by

Agentino powers:

  • Runspace — a multi-agent workspace: channels, @mention routing, scheduled routines and a protocol layer (Store, Vision, Transport, FileStorage, Embeddings). Agentino is one of the runtimes it drives.
  • Multi-agent back offices — agents grouped by role (booking, finance, inventory, analytics), reached by @mention in a shared channel
  • Single-pane chat shells — the same gateway configured down to one agent
  • Agentic benchmarks — staged pipelines with security/execute/report stages and an LLM-gate pattern (the gates cookbook is built from it)

Stability

  • Public API at from agentino import … is stable as of v1.0
  • Internal layout (subpackages) was reshaped in v1.0 — deep imports like agentino.context moved to agentino.core.context
  • Async-first throughout. There is no synchronous wrapper: call it with asyncio.run(agent.run(...)) from sync code

License

Apache-2.0. See LICENSE and NOTICE.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 50

Native requirements
21 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
croniter
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
croniter>=2.0runtime
httpx
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
httpx>=0.27runtime
pyyaml
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pyyaml>=6.0runtime
aiogram
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiogram>=3.10; extra == "all"runtime
aiohttp
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiohttp>=3.9; extra == "all"runtime
beautifulsoup4
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
beautifulsoup4>=4.12; extra == "all"runtime
fastapi
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.109; extra == "all"runtime
feedparser
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
feedparser>=6.0; extra == "all"runtime
markdown
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
markdown>=3.5; extra == "all"runtime
numpy
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
numpy>=1.26; extra == "all"runtime
openpyxl
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
openpyxl>=3.1; extra == "all"runtime
python-docx
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-docx>=1.0; extra == "all"runtime
python-pptx
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-pptx>=0.6; extra == "all"runtime
reportlab
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
reportlab>=4.0; extra == "all"runtime
slack-bolt
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
slack-bolt>=1.18; extra == "all"runtime
starlette
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
starlette>=0.38; extra == "all"runtime
uvicorn
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
uvicorn>=0.30; extra == "all"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=0.23; extra == "dev"runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest>=8.0; extra == "dev"runtime
ruff
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
ruff>=0.5; extra == "dev"runtime
tomli
Environment
{
  "extras": "",
  "marker": "python_version < \"3.11\" and extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
tomli>=2.0; python_version < "3.11" and extra == "dev"runtime
markdown
Environment
{
  "extras": "",
  "marker": "extra == \"docgen\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
markdown>=3.5; extra == "docgen"runtime
openpyxl
Environment
{
  "extras": "",
  "marker": "extra == \"docgen\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
openpyxl>=3.1; extra == "docgen"runtime
python-docx
Environment
{
  "extras": "",
  "marker": "extra == \"docgen\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-docx>=1.0; extra == "docgen"runtime
python-pptx
Environment
{
  "extras": "",
  "marker": "extra == \"docgen\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-pptx>=0.6; extra == "docgen"runtime
reportlab
Environment
{
  "extras": "",
  "marker": "extra == \"docgen\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
reportlab>=4.0; extra == "docgen"runtime
numpy
Environment
{
  "extras": "",
  "marker": "extra == \"memory\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
numpy>=1.26; extra == "memory"runtime
fastapi
Environment
{
  "extras": "",
  "marker": "extra == \"serve\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.109; extra == "serve"runtime
starlette
Environment
{
  "extras": "",
  "marker": "extra == \"serve\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
starlette>=0.38; extra == "serve"runtime
uvicorn
Environment
{
  "extras": "",
  "marker": "extra == \"serve\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
uvicorn>=0.30; extra == "serve"runtime
aiohttp
Environment
{
  "extras": "",
  "marker": "extra == \"slack\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiohttp>=3.9; extra == "slack"runtime
slack-bolt
Environment
{
  "extras": "",
  "marker": "extra == \"slack\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
slack-bolt>=1.18; extra == "slack"runtime
beautifulsoup4
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
beautifulsoup4>=4.12; extra == "stdtools"runtime
feedparser
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
feedparser>=6.0; extra == "stdtools"runtime
markdown
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
markdown>=3.5; extra == "stdtools"runtime
numpy
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
numpy>=1.26; extra == "stdtools"runtime
openpyxl
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
openpyxl>=3.1; extra == "stdtools"runtime
python-docx
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-docx>=1.0; extra == "stdtools"runtime
python-pptx
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-pptx>=0.6; extra == "stdtools"runtime
reportlab
Environment
{
  "extras": "",
  "marker": "extra == \"stdtools\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
reportlab>=4.0; extra == "stdtools"runtime
aiogram
Environment
{
  "extras": "",
  "marker": "extra == \"telegram\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiogram>=3.10; extra == "telegram"runtime
aiogram
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiogram>=3.10; extra == "transports"runtime
aiohttp
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiohttp>=3.9; extra == "transports"runtime
fastapi
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.109; extra == "transports"runtime
slack-bolt
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
slack-bolt>=1.18; extra == "transports"runtime
starlette
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
starlette>=0.38; extra == "transports"runtime
uvicorn
Environment
{
  "extras": "",
  "marker": "extra == \"transports\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
uvicorn>=0.30; extra == "transports"runtime
beautifulsoup4
Environment
{
  "extras": "",
  "marker": "extra == \"web\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
beautifulsoup4>=4.12; extra == "web"runtime
feedparser
Environment
{
  "extras": "",
  "marker": "extra == \"web\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
feedparser>=6.0; extra == "web"runtime
aiohttp
Environment
{
  "extras": "",
  "marker": "extra == \"websocket\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiohttp>=3.9; extra == "websocket"runtime

Distribution files

2 collected
agentino_framework-1.1.1-py3-none-any.whl

bdist_wheel · 216.19 KB · Python py3

Source file
agentino_framework-1.1.1.tar.gz

sdist · 262.25 KB · Python source

Source file

Repository

PENDING
islavutin-oss/agentino

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 22:27 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:7a9e2db4d360662702011c1c8c679bbc2cb7e49addb7f895968d5568b1c386dd

Other collected versions

View all collected versions →