Workflow Agents
A core objective is to comprehend the fundamental building blocks that constitute the Axiomkit framework.
🌀 Overview
At its core, an agent follows a simple loop:
- Input – Something happens (an input arrives)
- Think – The agent uses an LLM to decide what to do
- Act – It performs an action or sends a response
- Remember – The agent stores what happened in memory
- Repeat – The cycle continues
This loop runs continuously, allowing the agent to process new inputs and respond intelligently based on its memory and current context.
Technical Overview
At the heart of the Axiomkit framework is the agent execution lifecycle - a structured loop that governs how agents process inputs, invoke LLM-based reasoning, execute registered actions, and manage outputs. A clear understanding of this lifecycle is essential for developing, extending, and debugging agent behaviour.
Walk through the lifecycle of a typical request:
1. Input Reception
- Source: An external system - such as Discord, Telegram, CLI, or a custom API - delivers incoming data to the agent. These systems are integrated via providers.
- Listener: An input handler, defined either within the agent or an provider, continuously listens for specific external events (e.g., a new user message).
- Trigger: When such an event occurs, the listener is activated.
- Invocation: The listener invokes
agent.send()
with:- A target context definition specifying which part of the agent should handle the input.
- args to identify or initialize the relevant context instance (e.g., a specific chat thread).
- The input data itself (e.g., message text or event payload).
2. agent.send - Start Process
- Log Input: The framework records the incoming data as an
InputRef
, creating a persistent reference for traceability and debugging. - Initiate Run: It then calls the internal
agent.run(...)
method, initiating or resuming the agent’s processing loop for the specified context instance, with theInputRef
passed as input.
3. agent.run - Managing the execution cycle
- Load/Initialize Context: The framework locates the
ContextState
for the specified instance (e.g., chat session #123). If this is the first interaction, it initializes the state, including persistent memory (ContextState.memory
) and a freshWorkingMemory
scoped to the current run. - Concurrency Handling: If the context is already mid-execution, the new
InputRef
is typically queued or merged into the active run. Otherwise, a new run instance is initialized. - Run Environment Setup: The framework prepares the full execution environment—loading available actions, output handlers, context metadata, and any relevant system state needed for reasoning.
- Start Step Loop: It enters the main execution loop, progressing through one or more reasoning steps (LLM calls and action executions) until the run is complete or paused.
4. Inside the Step Loop – Perception, Reasoning, Action
Each iteration of the agent.run
loop represents a full reasoning cycle, consisting of the following phases:
- Prepare State:
- Gather the latest
ContextState.memory
via each context’srender()
method. - Retrieve interaction history from
WorkingMemory
(inputs, outputs, past actions). - Include new, unprocessed data such as the initial
InputRef
or completed action results. - Collect the current set of available
actions
andoutputs
.
- Gather the latest
- Prompt Generation:
- All state and interaction data are compiled into a structured XML-based prompt.
- This prompt defines available tools (actions, outputs), current state snapshots, new inputs, and clear execution instructions for the LLM.
&#xNAN;(See: Prompting Format & Specification)
- LLM Inference:
- The prompt is sent to the configured LLM provider.
- The response is streamed token-by-token and parsed in real-time.
- Response Parsing:
- The stream is scanned for structured XML tags such as:
<reasoning>
– logged for interpretability and debugging.<action_call>
– instructs which action to execute with what args.<output>
– specifies external communications or responses to emit.
- The agent interprets and queues these instructions accordingly.
- The stream is scanned for structured XML tags such as:
- Action & Output Execution:
- For each
<action_call>
:- Arguments are validated against the action’s schema.
- Execution is delegated to the
TaskRunner
, which handles async task scheduling.
- For each
<output>
:- Output data is validated and dispatched via the output handler.
- For each
- Await Results:
- The loop suspends until any required async tasks complete.
- All resulting
ActionResult
s are appended toWorkingMemory
.
- Completion Check:
- The agent evaluates whether another step is needed, based on:
- Remaining unprocessed events.
shouldContinue
hook results.- Explicit halting conditions from the LLM or agent logic
- The agent evaluates whether another step is needed, based on:
5. Run Completion
- Exit Step Loop: The reasoning loop exits once continuation conditions are no longer met.
- Finalization:
- Executes any
onRunEnd
or cleanup hooks defined by the context. - Persists final
ContextState.memory
snapshots to theMemoryStore
.
- Executes any
- Return Response:
- Resolves the original
agent.send
oragent.run
call. - Returns a full
AgentRunResult
, including the complete interaction log.
- Resolves the original