ReAct Agent Guide
Applies to: ChengOS v0.1.0+ | Last verified: 2026-08-12 | Source:
crates/cheng-nodes/src/nodes/builtin/agent/strategy/agent.rs,agent/strategy/task_mode.rs,agent/base
An ordinary workflow decides its own order at design time — you draw the edges. An agent
decides at runtime: it reasons about the task, calls a tool, looks at the result, and repeats
until it is done or a limit stops it. agent/react_agent is that node.
The trade is control for capability. Use an agent when the steps genuinely depend on what earlier steps find; use a plain graph when you already know the sequence, because a graph is cheaper, faster, and fully predictable.
The loop
agent/react_agent combines three phases into a single canvas node — Plan, Execute, and
Review — so you connect one node rather than wiring a loop by hand:
- Plan — decide the next action from the task and what has happened so far.
- Execute — call the chosen tool and capture the observation.
- Review — judge whether the task is complete, and if not, continue.
The cycle repeats until the agent produces a final answer, hits max_iterations, or a policy
stops it.
Configuration
| Input | Default | Purpose |
|---|---|---|
task | — | What to accomplish |
llm_config | — | Model configuration (JSON string or object) |
tools | — | Available tools, populated from connected tool nodes |
max_iterations | 10 | Iteration ceiling |
use_function_calling | true | Use the provider's native function calling |
use_llm_evaluation | false | Have the model judge completion during Review |
| Output | Contents |
|---|---|
final_answer | The result |
trace | The full reasoning and tool-call trace |
total_tokens | Tokens consumed |
iterations_used | Iterations actually executed |
success | Whether the task completed |
use_function_calling should normally stay on: native function calling lets the provider emit
structured tool calls instead of the agent parsing tool intentions out of prose, which is
markedly more reliable. Turn it off only for a model that lacks the capability — see
model configuration for which providers support it.
use_llm_evaluation costs an extra model call per review round in exchange for a better
completion judgment. Leave it off for tasks with an obvious end state; turn it on for
open-ended work where "done" is a judgment call.
Short and long tasks
The task_run_mode setting picks between two loop policies, and choosing correctly is the
difference between an agent that stops too early and one that runs forever:
| Mode | Behaviour | Use for |
|---|---|---|
short (default) | A bounded chunk of work. When the iteration budget is exhausted, pause and ask the user rather than stopping silently. | Interactive tasks, conversational turns |
long | Progress-driven. Internal windows are renewed as long as the agent is making progress. | Multi-step autonomous work |
long mode is not "more iterations" — it is a different termination rule. It has its own
advanced safety knobs (internal_window, no_progress_windows, partial_window_limit,
checkpoint_parse_failure_limit) which exist so an agent that stops progressing gets stopped
rather than looping on a budget. Leave them alone unless you have a specific stall to fix.
Giving the agent tools
Connect tool nodes to the tools port. Tool definitions from every connected source are merged
into the surface the model sees. The scalable path is Tool Hub,
which puts many tools behind one stable function rather than growing the model's tool list
linearly.
The agent also gets a few built-in capabilities: it can read its own execution trace, and it maintains a todo list for multi-step work.
Two guardrails run inside the loop, and knowing they exist explains behaviour that would otherwise look arbitrary:
- Redundant-read suppression. Reading the same file range twice, or repeating a search it already ran, is detected and discouraged, because agents otherwise burn iterations re-reading what they already have.
- Mutation pre-checks. A mutating operation may require prior inspection of the target, so the agent looks before it overwrites.
Credentials
Agents obey the same rule as every other node: tools receive credentials, the model does not. An agent can call an authenticated API without the key ever appearing in its context. This is what makes autonomous tool use safe to expose — a prompt injection cannot exfiltrate a secret the model was never given.
Approval and review
A tool may return requires_review: true, which moves the execution to waiting_for_review
and suspends it until a human decides. The decision is recorded durably on the approval context
rather than only broadcast, so a decision made while nothing is listening is not lost. Use this
for irreversible actions — see utils/approver.
Context management
Long runs eventually exceed the model's context window. The agent tracks context usage and
publishes CONTEXT_WINDOW_STATUS_UPDATED events, compacting history when needed and
classifying context overflow so it can recover instead of failing outright.
Watching one run
Agent runs emit a much richer event stream than plain nodes: AGENT_ITERATION_COMPLETED,
TOOL_EXECUTION_STARTED / COMPLETED / FAILED, AGENT_TURN_STARTED / COMPLETED,
AGENT_PAUSED_FOR_REVIEW, and CONTEXT_WINDOW_STATUS_UPDATED. For an agent, reading that
stream is the debugging method — a trace output read after the fact tells you what happened,
but the stream tells you where it is stuck.
Starting from a template
Two built-in templates are working agents worth reading before writing your own:
tools-user (a ReAct agent with file operation tools in a sandbox) and create-workflow (an
agent that builds workflows from natural language).
Next steps
- Tool discovery and Tool Hub — scaling the tool surface.
- Model configuration — picking a model that suits agent work.
- Testing and debugging — watching a run.