Agent¶
The Agent is the orchestrator that combines connectors, an LLM, and the domain model into a working maintenance assistant. It receives messages from channels (CLI, Telegram, Slack, …), resolves referenced assets, gathers context from connectors, calls the LLM with domain-aware prompts, and executes tool calls.
This page is the auto-generated API reference. For tutorial-level usage see Quickstart and Architecture.
Agent¶
The central runtime class. Public attributes worth knowing:
sandbox— boolean property with a propagating setter. When mutated after construction (e.g.agent.sandbox = Falseto switch from sandbox to live), the change propagates to the internal workflow engine so write actions are no longer intercepted.tracer— theActionTracerinstance recording every action.plant— thePlantregistered to this agent.
Agent ¶
Agent(*, name: str = 'Machina Agent', description: str = 'Maintenance AI assistant', plant: Plant | None = None, connectors: list[Any] | None = None, channels: list[Any] | None = None, llm: str | LLMProvider = 'openai:gpt-4o', temperature: float = 0.1, max_history: int = 20, workflows: list[Workflow] | None = None, sandbox: bool = False, confirmations: bool = True)
Maintenance AI agent that orchestrates reasoning and actions.
The agent receives user queries, resolves referenced assets, gathers context from configured connectors, and uses an LLM to produce grounded, domain-aware responses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Human-readable agent name. |
'Machina Agent'
|
description
|
str
|
What this agent specialises in. |
'Maintenance AI assistant'
|
plant
|
Plant | None
|
The plant with its asset registry. |
None
|
connectors
|
list[Any] | None
|
List of connector instances to register. |
None
|
channels
|
list[Any] | None
|
Communication channels (Telegram, CLI, etc.). |
None
|
llm
|
str | LLMProvider
|
LLM provider string (e.g. |
'openai:gpt-4o'
|
temperature
|
float
|
LLM sampling temperature. |
0.1
|
max_history
|
int
|
Maximum conversation turns to keep in memory. |
20
|
workflows
|
list[Workflow] | None
|
List of workflow definitions to register. |
None
|
sandbox
|
bool
|
If |
False
|
confirmations
|
bool
|
If |
True
|
Example
from machina import Agent, Plant
from machina.connectors.cmms import GenericCmmsConnector
from machina.connectors.comms.cli import CliChannel
plant = Plant(name="Demo Plant")
cmms = GenericCmmsConnector(data_dir="sample_data/cmms")
agent = Agent(
name="Maintenance Assistant",
plant=plant,
connectors=[cmms],
channels=[CliChannel()],
llm="openai:gpt-4o",
)
agent.run()
sandbox
property
writable
¶
Whether write actions are intercepted (True) or executed.
Read this attribute through normal access — no behaviour change
for existing call sites that branch on if self.sandbox.
confirmations
property
writable
¶
Whether write/mutation tool calls require human confirmation.
Read this attribute through normal access — the value is consumed
inside the agent loop to gate side-effecting tool calls. Unlike
:attr:sandbox, there is no contextvar or engine snapshot: the
switch is purely agent-loop-local.
from_config
classmethod
¶
Create an Agent from a machina.yaml configuration file.
Connectors and channels are instantiated from their type
strings. Workflows cannot be defined in YAML (they may
contain Python callables); register them after construction
with :meth:register_workflow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to the YAML configuration file. |
required |
Returns:
| Type | Description |
|---|---|
Agent
|
A fully configured |
register_workflow ¶
Register a workflow for later execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workflow
|
Workflow
|
The workflow definition to register. |
required |
trigger_workflow
async
¶
Trigger a registered workflow by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workflow_name
|
str
|
Name of a previously registered workflow. |
required |
event
|
dict[str, Any] | None
|
Event data to pass to the workflow. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
WorkflowResult
|
class: |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the workflow is not found. |
handle_message
async
¶
handle_message(text: str, *, chat_id: str = 'default', confirmer: Callable[[str], Awaitable[bool]] | None = None, user_id: str = '') -> str
Process a user message and return the agent's response text.
This is the main entry point for programmatic usage. The returned
string is the rendered answer with inline [n] citation markers
renormalized to 1..N by first appearance and the trailing
<citations> block stripped. Use :meth:handle_message_full to
also access structured :class:Citation objects —
citations[n-1] aligns with the inline [n] marker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The user's message. |
required |
chat_id
|
str
|
Identifier for the conversation. |
'default'
|
confirmer
|
Callable[[str], Awaitable[bool]] | None
|
Optional async callable that renders a confirmation
prompt and returns the user's yes/no decision. Supplied by a
channel that can confirm a write synchronously (e.g.
|
None
|
user_id
|
str
|
Identifier for the sender, forwarded for cross-user
confirmation scoping. Note: |
''
|
Returns:
| Type | Description |
|---|---|
str
|
The agent's response text. |
Raises:
| Type | Description |
|---|---|
LLMError
|
If the underlying LLM call fails. |
handle_message_full
async
¶
handle_message_full(text: str, *, chat_id: str = 'default', confirmer: Callable[[str], Awaitable[bool]] | None = None, user_id: str = '') -> AgentResponse
Process a user message and return the structured agent response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The user's message. |
required |
chat_id
|
str
|
Identifier for the conversation. |
'default'
|
confirmer
|
Callable[[str], Awaitable[bool]] | None
|
Optional async callable that renders a confirmation
prompt and returns the user's yes/no decision (see
:meth: |
None
|
user_id
|
str
|
Identifier for the sender, forwarded for cross-user confirmation scoping. |
''
|
Returns:
| Name | Type | Description |
|---|---|---|
An |
AgentResponse
|
class: |
AgentResponse
|
citations the agent emitted. |
Raises:
| Type | Description |
|---|---|
LLMError
|
If the underlying LLM call fails. |
run ¶
Start the agent with all channels (blocking, sync wrapper).
Connects connectors, loads assets, and starts listening on all configured channels. Automatically detects Jupyter notebooks and other environments with an already-running event loop.
EntityResolver¶
Resolves free-text mentions in user messages (e.g. "the pump P-201", "compressore C-301") to concrete assets registered on the agent's Plant.
Both examples above resolve on the asset ID (P-201, C-301), which is language-independent — the surrounding word does the work only when it matches the asset's registered name. There is no cross-language matching and no typo tolerance: matching is verbatim containment at every stage. To make an asset resolvable by a word other than its registered name — the local-language term, plant jargon, a nickname — put that word in Asset.aliases, which is searched at the same authority as the name.
When several candidates tie at the top, resolution is ambiguous: the runtime withholds the asset for that turn, asks which one is meant, and remembers the candidates so the next message can answer by ID, by name, or by position.
EntityResolver ¶
Resolves natural language references to assets in a plant.
Uses a cascading strategy:
1. Exact ID match (e.g. "P-201")
2. Name match (e.g. "cooling water pump"), including any curated
Asset.aliases — the plant's own words for the machine, searched at
the same authority as the registered name
3. Location match (e.g. "building A")
4. Keyword match — verbatim token containment across all asset fields
(no typo tolerance)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plant
|
Plant
|
The plant containing the asset registry. |
required |
Example
resolve ¶
Resolve a natural language reference to zero or more assets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
User input that may reference an asset. |
required |
Returns:
| Type | Description |
|---|---|
list[ResolvedEntity]
|
List of :class: |
list[ResolvedEntity]
|
(highest first). Empty if no matches found. |
ResolvedEntity
dataclass
¶
Result of entity resolution.
confidence is required. It previously defaulted to 1.0, which made
an entity built without a stated confidence maximally confident — the
authority gate then acted on a match nobody had scored. Omitting it is now
a TypeError at construction rather than silent full trust.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
asset
|
Asset
|
The matched asset. |
required |
confidence
|
float
|
Confidence score (0.0-1.0). |
required |
match_reason
|
str
|
How the match was determined. |
''
|
LLMProvider¶
Thin wrapper around LiteLLM exposing complete() and complete_with_tools(). Constructed implicitly by Agent(llm="provider:model") but can also be passed in explicitly for custom providers.
LLMProvider ¶
LLMProvider(model: str = 'openai:gpt-4o', *, temperature: float = 0.1, max_tokens: int = 4096, request_timeout: float = 120.0, tracer: ActionTracer | None = None)
Provider-agnostic LLM interface.
Wraps LiteLLM to provide async complete() and
complete_with_tools() methods. Machina's agent layer uses
this instead of calling LLM libraries directly.
Both methods pass drop_params=True to LiteLLM so that parameters a
given model does not accept are silently dropped rather than raising.
The motivating case is OpenAI reasoning models (o1/o3/gpt-5
family) that reject any explicit temperature other than the default
1 with a 400 error; LiteLLM knows the per-model support matrix and
omits the unsupported value instead of failing the call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
Provider and model identifier (e.g. |
'openai:gpt-4o'
|
temperature
|
float
|
Sampling temperature. |
0.1
|
max_tokens
|
int
|
Maximum tokens in the response. |
4096
|
tracer
|
ActionTracer | None
|
Optional ActionTracer for cost/token instrumentation. |
None
|
complete
async
¶
Send a chat completion request and return the response text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[dict[str, str]]
|
Chat messages in OpenAI format. |
required |
conversation_id
|
str
|
Conversation identifier for tracing. |
''
|
**kwargs
|
Any
|
Extra parameters forwarded to LiteLLM. |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
The assistant's response text. |
complete_with_tools
async
¶
complete_with_tools(messages: list[dict[str, str]], tools: list[dict[str, Any]], *, conversation_id: str = '', **kwargs: Any) -> dict[str, Any]
Send a chat completion with tool/function definitions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
messages
|
list[dict[str, str]]
|
Chat messages in OpenAI format. |
required |
tools
|
list[dict[str, Any]]
|
Tool definitions (OpenAI function calling schema). |
required |
conversation_id
|
str
|
Conversation identifier for tracing. |
''
|
**kwargs
|
Any
|
Extra parameters forwarded to LiteLLM. |
{}
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
The full response dict including any tool calls. |
Capability¶
Enum identifying what a connector can do. Used by ConnectorRegistry.find_by_capability(...) for capability-based dispatch (the agent and workflow engine both rely on this to discover available actions at runtime).
Capability ¶
Bases: StrEnum
Actions a connector can perform, declared at registration.
Membership in a connector's capabilities frozenset grants
permission for the agent/MCP layer to invoke the corresponding
method. String values are stable wire identifiers — do not change
them without a deprecation cycle.
Citations¶
When the agent answers a question from retrieved documents it returns a structured AgentResponse carrying inline citations alongside the prose answer. Each Citation references a chunk_id produced by DocumentStoreConnector.search() so callers can audit which exact passage drove the answer.
AgentResponse ¶
Bases: BaseModel
Structured agent output carrying text and grounded citations.
Attributes:
| Name | Type | Description |
|---|---|---|
text |
str
|
The rendered answer, carrying inline |
citations |
list[Citation]
|
List of source citations, one per chunk the agent
relied on, in display order: |
is_fallback |
bool
|
|
completeness |
Literal['complete', 'partial']
|
|
Citation ¶
Bases: BaseModel
A pointer from an answer back to its source chunk.
Attributes:
| Name | Type | Description |
|---|---|---|
chunk_id |
str
|
Deterministic identifier of the source chunk (matches
:attr: |
source |
str
|
Source file path or document name. |
page |
int
|
Page number, when known. |
quote |
str
|
Optional short verbatim excerpt the claim is grounded in. |
confidence |
float
|
Optional confidence score in |
inline_marker ¶
Render a compact inline marker like [source:page].
Note
:attr:AgentResponse.text now carries numeric [n] markers
renormalized at egress; this [source:page] format is used
nowhere in the rendered text. Kept for backward compatibility.