Skip to main content
AgentModule is the contract you implement to define agent behavior. It owns everything about how your agent thinks — state initialization, prompt construction, decision logic, and state reduction — but it never runs the loop itself. That is the Engine’s job.

Generic type parameters

AgentModule is generic over three type variables:
ParameterWhat it represents
StateTYour typed state class (must extend StateSchema)
ObservationTThe observation dict the Engine passes to your hooks
ActionTThe action type your decide hook produces
A fully-typed declaration looks like:

The six hooks

AgentModule defines six hooks. Two are required (init_state and reduce). The rest are optional and have sensible defaults.

init_state (required)

Called once at the start of every run. Return your typed state object, initialized from the task string.
Any keyword arguments passed to Engine.run() flow through here, so you can accept max_steps or other initial fields via kwargs.

reduce (required)

Called after every action cycle (one full round of decide → act → observe). Transform the previous state plus the new observation and decision into the next state. This is where your agent absorbs what just happened and updates its progress.
Always return state (or a new state object) from reduce. Returning None will cause a runtime error.

build_system_prompt (optional)

Return a dynamic system prompt string, or None to skip. Called before every decide step, so your prompt can adapt to the current state.
The default implementation returns None.

prepare (optional)

Converts current state into the model-ready text that becomes the user turn (the message sent to the LLM as the user’s input). Defaults to str(state). Override this to format a structured prompt from your state fields.

decide (optional)

Override to provide your own decision logic before the Engine calls the LLM. Return None to let the Engine use its standard model decision path.

should_stop (optional)

An additional stop condition checked each step after reduce. Return True to halt the run. The Engine’s built-in stop criteria (step budget, FinalResultCriteria, etc.) still apply on top of this.

Minimal example

In QitOS, the minimal public example is still a real coding agent: it configures a model, mounts a workspace, and lets the Engine drive tool use and verification.

Running an agent

Call agent.run() to execute a task. This is the primary entry point — it creates an Engine internally, runs the loop, and returns the result.
Key parameters for agent.run():
ParameterTypeDescription
taskstr | TaskPlain text objective or a structured Task object
max_stepsint | NoneOverride the step budget for this run
workspacestr | NoneWorking directory mounted into the host environment
return_stateboolReturn EngineResult instead of state.final_result
tracebool | TraceWriterTrue to auto-create a trace writer, False to disable
trace_logdirstrDirectory for trace output (default: "./runs")
parserParserOutput parser matched to your prompt format
criticslist[Critic]Critics (post-step evaluators that can stop or retry) evaluated after each step
stop_criterialist[StopCriteria]Additional stop conditions beyond the default
If you need finer control over the Engine — custom hooks, branch selectors, or a shared Engine instance — use agent.build_engine(**kwargs) and call engine.run(task) directly.

Constructor arguments

AgentModule.__init__ accepts these keyword arguments, all optional: