Concepts & Glossary¶
Build a mental model of Agentomatic before writing your first line of code. This page covers every core abstraction, shows how a request flows end-to-end, and helps you choose the right pattern for your agent.
π§© Core Concepts¶
Every Agentomatic application is built from a handful of composable primitives. Learn these once and everything else clicks into place.
Agent¶
A self-contained unit of AI logic that processes requests and returns responses. An agent can be as simple as a single function or as complex as a multi-step execution graph with branching, loops, and tool calls.
from agentomatic.agents import BaseGraphAgent
class MyAgent(BaseGraphAgent[MyState]):
"""A class-based agent β all logic in one file."""
...
Think of it asβ¦
A micro-service with exactly one job. It receives input, does smart work (often involving an LLM), and returns structured output.
Node¶
A single processing step within an agent's execution graph. Each node receives the current state, performs work (LLM call, tool use, data transform), and returns the updated state.
def retrieve_docs(self, state: MyState) -> dict:
"""Node: fetch relevant documents from the knowledge base."""
state.documents = self.retriever.search(state.query)
return {"documents": state.documents}
Nodes are the atoms of your agent β keep them small and focused.
State¶
The data structure passed between nodes during a single execution run. It acts as shared memory for the entire graph.
Immutability in Practice
Nodes return a dict of updated fields. The framework merges these updates
into the current state β you never need to mutate state in-place.
Graph¶
The directed flow of nodes that defines an agent's logic. Nodes are connected by edges (linear) or conditional edges (branching).
graph LR
START(["βΆ START"]) --> A["retrieve_docs"]
A --> B["generate_response"]
B --> C{"needs_followup?"}
C -- yes --> A
C -- no --> END_(["βΉ END"])
style START fill:#e8f5e9,stroke:#43a047
style END_ fill:#ffebee,stroke:#e53935
Graphs are built declaratively inside build_graph() (class-based) or
graph_fn() (functional). The framework compiles them into an optimised
execution plan.
Manifest¶
An AgentManifest dataclass that declares an agent's identity β name,
slug, description, framework, and version. The registry reads the manifest
to know what agents exist and how to route to them.
from agentomatic.core.manifest import AgentManifest
manifest = AgentManifest(
name="Search Bot",
slug="search_bot",
description="Knowledge-base search with citations.",
framework="langgraph",
version="1.0.0",
)
Class-based agents generate their manifest automatically
If you use BaseGraphAgent, the manifest is derived from class attributes.
You only write one explicitly when using the functional pattern.
Thread¶
A conversation session with persistent history. Each thread has a unique
thread_id and stores messages across multiple requests, enabling multi-turn
dialogue.
# Client-side: continue a conversation
response = client.post(
"/agents/search_bot/chat",
json={
"message": "Tell me more about that last point.",
"thread_id": "abc-123", # β same thread
},
)
Threads are stored in the configured storage backend (SQLite, PostgreSQL, or in-memory).
Platform¶
The AgentPlatform β the FastAPI server that hosts, discovers, and serves
all agents. Created with a single call:
from agentomatic import AgentPlatform
platform = AgentPlatform.from_folder("./agents")
platform.run() # π FastAPI is live
The platform handles middleware (auth, rate limiting, CORS), health checks, and the Studio debugger β you focus on agent logic.
Discovery¶
The automatic process where the registry scans your agents/ folder at
startup, imports each agent module, reads its manifest (or introspects the
BaseGraphAgent subclass), and registers it with REST endpoints.
flowchart LR
A["agents/"] --> B["Registry Scan"]
B --> C{"agent.py?"}
C -- yes --> D["Class-Based\nBaseGraphAgent"]
C -- no --> E{"__init__.py?"}
E -- yes --> F["Functional\nmanifest + graph_fn"]
D --> G["Register\n26 REST Endpoints"]
F --> G
style G fill:#e3f2fd,stroke:#1565c0
Zero configuration
Drop a new folder into agents/, restart the server, and your agent is
live β complete with docs, streaming, threads, and Studio integration.
Studio¶
The visual debugger (React frontend) that ships with Agentomatic. Studio shows graph topology, execution state, node timings, and time-travel debugging so you can step through each node's input/output.
See Agentomatic Studio for the full guide.
Endpoint¶
One of the 26 auto-generated REST API routes per agent. Every registered agent automatically receives endpoints for:
| Category | Example Routes |
|---|---|
| Execution | /invoke, /stream, /batch |
| Chat | /chat, /chat/stream |
| Threads | /threads, /threads/{id}/history |
| Introspection | /config, /schema, /graph, /health |
| Management | /feedback, /state, /metrics |
No boilerplate
You never write a route. The platform generates them from your agent class
and serves an OpenAPI spec at /docs.
Task & Execution Modes¶
A unit of work tracked by the platform's task engine. The same resource can
be invoked in several execution modes β sync (wait for the result),
streaming (SSE), async (submit now, poll later), batch (many inputs), or
A2A. Async/batch calls return a TaskRecord with a status
(queued β running β succeeded/failed/cancelled) and live progress, pollable
at /api/v1/tasks/{id}.
# Submit an async job, then poll it
curl -X POST /api/v1/my_agent/invoke/async -d '{"query": "long job"}'
curl /api/v1/tasks/task_abc123 # β {"status": "running", "progress": {...}}
Think of it asβ¦
A background job with a receipt. Perfect for long-running work (e.g. document ingestion) where a UI submits, then shows a progress bar. See Tasks & Execution Modes.
Plugin¶
A classical ML model wrapped as a deployable resource (BaseMLPlugin). Drop
it in plugins/ and it's auto-discovered with /predict endpoints β callable
sync, async, or as a task, and usable as a pipeline step. Use it to serve
scikit-learn, PyTorch, or any model alongside your LLM agents. See
ML Plugins.
Pipeline¶
A declarative graph that chains resources β agents, plugins, endpoints,
ingestors, transforms, loops, and sub-pipelines β with explicit data-passing
between steps. Defined in YAML under pipelines/, with conditionals, retries,
timeouts, rollback/compensation, and optional schema enforcement. See
Pipelines.
Ingestor¶
A user-defined ingestion/RAG job packaged as a resource (BaseIngestor).
Agentomatic handles the ops (discovery, endpoints, task tracking, progress);
you bring the implementation by reusing any library (PDFβmarkdown, splitters,
embedders, vector stores). Drop it in ingestion/. See
Ingestion & RAG.
π How a Request Flows¶
Every request β whether REST, streaming, or chat β follows the same path through the system:
sequenceDiagram
participant C as Client
participant F as FastAPI
participant M as Middleware
participant R as Router
participant A as Agent
participant G as Graph Engine
C->>F: POST /agents/search_bot/invoke
F->>M: Auth Β· Rate Limit Β· CORS
M->>R: Route to agent
R->>A: agent.invoke(payload)
A->>A: input_to_state(payload)
A->>G: Execute graph
loop Each Node
G->>G: node(state) β updated state
end
G-->>A: Final state
A->>A: state_to_output(state)
A-->>R: Structured response
R-->>F: HTTP response
F-->>C: 200 OK + JSON body
| Step | What Happens |
|---|---|
| 1. Middleware | Auth tokens are validated, rate limits are checked, CORS headers are set. |
| 2. Router | The platform routes to the correct agent by slug. |
3. input_to_state() |
Your raw request payload is transformed into the agent's state dataclass. |
| 4. Graph Execution | Nodes run in topological order. Conditional edges choose branches dynamically. |
5. state_to_output() |
The final state is transformed into your response schema. |
βοΈ Two Patterns: Class-Based vs Functional¶
Agentomatic supports two ways to define agents. Both are fully auto-discovered and receive the same 26 REST endpoints.
Choosing a Pattern¶
flowchart TD
Q["Starting a new agent?"] --> A{"Need typed state,\nML lifecycle, or\nmulti-node graphs?"}
A -- Yes --> B["β
Class-Based\n(Recommended)"]
A -- No --> C{"Quick prototype\nor single-node\nlogic?"}
C -- Yes --> D["β
Functional"]
C -- No --> B
style B fill:#c8e6c9,stroke:#388e3c
style D fill:#fff9c4,stroke:#f9a825
Side-by-Side Comparison¶
from __future__ import annotations
from dataclasses import dataclass, field
from agentomatic.agents import BaseGraphAgent
from agentomatic.agents.graph import GraphBuilder
@dataclass
class SearchState:
query: str = ""
documents: list[str] = field(default_factory=list)
answer: str = ""
class SearchBot(BaseGraphAgent[SearchState]):
name = "Search Bot"
description = "Knowledge-base search with citations."
def build_graph(self, builder: GraphBuilder) -> None:
builder.add_node("retrieve", self.retrieve_docs)
builder.add_node("generate", self.generate_response)
builder.add_edge("retrieve", "generate")
builder.set_entry_point("retrieve")
builder.set_finish_point("generate")
def retrieve_docs(self, state: SearchState) -> dict:
state.documents = ["doc1", "doc2"]
return {"documents": state.documents}
def generate_response(self, state: SearchState) -> dict:
state.answer = f"Based on {len(state.documents)} docs..."
return {"answer": state.answer}
def input_to_state(self, payload: dict) -> SearchState:
return SearchState(query=payload.get("query", ""))
def state_to_output(self, state: SearchState) -> dict:
return {"answer": state.answer}
Why class-based?
- Typed state β catch bugs at development time
- ML lifecycle β
compile() β fit() β evaluate() β transform() - Self-contained β one file, one class, one import
- Graph viz β Studio renders your
build_graph()topology
from __future__ import annotations
from agentomatic.core.manifest import AgentManifest
manifest = AgentManifest(
name="Search Bot",
slug="search_bot",
description="Knowledge-base search with citations.",
framework="langgraph",
version="1.0.0",
)
def retrieve_docs(state: dict) -> dict:
"""Node: fetch relevant documents."""
state["documents"] = ["doc1", "doc2"]
return state
def generate_response(state: dict) -> dict:
"""Node: produce an answer from documents."""
state["answer"] = f"Based on {len(state['documents'])} docs..."
return state
def graph_fn():
"""Build and return the LangGraph StateGraph."""
from langgraph.graph import StateGraph
g = StateGraph(dict)
g.add_node("retrieve", retrieve_docs)
g.add_node("generate", generate_response)
g.add_edge("retrieve", "generate")
g.set_entry_point("retrieve")
g.set_finish_point("generate")
return g.compile()
When to use functional
- Quick prototypes or single-node agents
- Gradual migration from raw LangGraph code
- Scripts that don't need typed state or ML lifecycle
Feature Matrix¶
| Feature | Class-Based | Functional |
|---|---|---|
Typed @dataclass state |
β | β |
ML lifecycle (compile/fit/evaluate) |
β | β |
build_graph() with GraphBuilder |
β | β |
input_to_state() / state_to_output() |
β | β |
| Auto-generated 26 endpoints | β | β |
| Studio graph visualization | β | β |
Custom config (config.py) |
β | β |
Custom schemas (schemas.py) |
β | β |
Prompt management (prompts.json) |
β | β |
Tool definitions (tools.py) |
β | β |
π Key Files at a Glance¶
Every agent lives in a subfolder under agents/. Here's what each file does:
| File | Pattern | Purpose |
|---|---|---|
agent.py |
Class-Based | Your BaseGraphAgent subclass β nodes, graph, state transforms |
__init__.py |
Functional | Module-level manifest + node_fn / graph_fn |
config.py |
Both | Pydantic settings model β LLM params, feature flags, thresholds |
schemas.py |
Both | Custom request/response models (overrides auto-generated ones) |
prompts.json |
Both | Versioned prompt templates with variable interpolation |
tools.py |
Both | LangChain-compatible tool definitions for tool-calling agents |
api.py |
Both | Custom FastAPI routers (add or override auto-generated routes) |
.env.example |
Both | Environment variable blueprint for your agent |
README.md |
Both | Agent-level documentation |
Only one file is required
Class-based: agent.py is the only mandatory file.
Functional: __init__.py with a manifest is the only mandatory file.
Everything else is optional β add files as your agent grows.
agents/
βββ search_bot/
β βββ agent.py β REQUIRED (class-based)
β βββ config.py β optional
β βββ schemas.py β optional
β βββ tools.py β optional
β βββ prompts.json β optional
β βββ README.md β optional
β
βββ echo_bot/
βββ __init__.py β REQUIRED (functional)
βββ config.py β optional
πΊοΈ What's Next?¶
You now have the vocabulary to navigate every part of Agentomatic. Pick your path:
| Goal | Page |
|---|---|
| Run your first agent in 60 seconds | Quick Start |
| Step-by-step agent tutorial | Your First Agent |
| Deep dive into class-based agents | Class-Based Agents |
| File conventions & discovery | Agent Structure & Discovery |
| Patterns & recipes | Cookbook & Recipes |
| Visual debugging with Studio | Agentomatic Studio |
| Configure LLMs & middleware | Configuration |
Recommended Reading Order
Concepts (you are here) β Quick Start β Your First Agent β Class-Based Agents β Cookbook