Skip to content

Brain & ReAct Loop

The brain is the reasoning engine that powers every Moxxy agent. It uses the ReAct (Reasoning + Acting) pattern to process requests and execute skills.

Overview

┌───────────────────────────────────────────────────────┐
│                    Trigger Input                       │
│              (User message, channel event, etc.)       │
└─────────────────────┬─────────────────────────────────┘


┌───────────────────────────────────────────────────────┐
│                   AutonomousBrain                      │
├───────────────────────────────────────────────────────┤
│                                                        │
│   ┌─────────┐    ┌─────────┐    ┌─────────┐          │
│   │   LLM   │───▶│  Parse  │───▶│ Execute │          │
│   │  Call   │    │ Invoke  │    │  Skill  │          │
│   └─────────┘    └─────────┘    └─────────┘          │
│        │                              │               │
│        │         ┌─────────┐          │               │
│        └────────▶│  Loop   │◀─────────┘               │
│                  │ (max 10)│                          │
│                  └─────────┘                          │
│                                                        │
└─────────────────────┬─────────────────────────────────┘


┌───────────────────────────────────────────────────────┐
│                    Response Output                     │
│                (To user, channel, etc.)               │
└───────────────────────────────────────────────────────┘

The ReAct Pattern

ReAct combines reasoning and acting in an interleaved manner:

  1. Thought - Agent thinks about what to do
  2. Action - Agent invokes a skill
  3. Observation - System returns skill result
  4. Repeat - Continue until done

Example Flow

User: "Check if my website is up and notify me on Telegram if it's down"

--- Iteration 1 ---

LLM Response:
I need to check if the website is responding. I'll use the web_crawler skill.
<invoke name="web_crawler">["https://mywebsite.com"]</invoke>

System: Executes skill...

Observation:
HTTP 503 - Service Unavailable

--- Iteration 2 ---

LLM Response:
The website is down (503 error). I should notify the user on Telegram.
<invoke name="telegram_notify">["Alert: Your website is down with HTTP 503 error"]</invoke>

System: Executes skill...

Observation:
Message sent successfully

--- Iteration 3 ---

LLM Response:
I've checked your website and found it's currently down with a 503 error.
I've sent you a Telegram notification about this issue.

[Task complete - no more iterations needed]

System Prompt

The brain uses a structured system prompt:

You are an autonomous AI agent running inside the moxxy framework.
You have SKILLS that let you take real actions on the host system.

RULES:
1. When the user asks you to DO something, use your skills via the 
   invocation format. Do NOT respond with code snippets.
2. For pure knowledge questions, respond directly.
3. Only use skills listed in AVAILABLE SKILLS.
4. Never tell the user to run commands manually — use host_shell.
5. After a skill result, present the result and STOP.
6. Be concise. Answer the question, present the result, done.

SKILL INVOCATION FORMAT:
<invoke name="skill_name">["arg1", "arg2"]</invoke>
Arguments MUST be a valid JSON array of strings.

--- AVAILABLE SKILLS ---
[skill catalog]
--- END OF SKILLS ---

--- AGENT PERSONA ---
[persona.md content]
--- END PERSONA ---

Invocation Format

Basic Format

xml
<invoke name="skill_name">["arg1", "arg2"]</invoke>

With Object Parameters (MCP)

xml
<invoke name="mcp_tool">{"param": "value", "other": 123}</invoke>

Parsing Rules

  1. Skill name must match exactly
  2. Arguments must be valid JSON
  3. Only one invocation per response
  4. System captures and executes

Loop Control

Maximum Iterations

The loop runs for a maximum of 10 iterations per trigger:

rust
const MAX_ITERATIONS: usize = 10;

This prevents infinite loops.

[CONTINUE] Tag

For tasks requiring multiple skill calls, agents can append [CONTINUE]:

I've created the file. [CONTINUE]
<invoke name="host_shell">["chmod +x script.sh"]</invoke>

This signals the system to continue processing.

Stop Conditions

The loop stops when:

  1. No <invoke> tags in response
  2. Maximum iterations reached
  3. Error occurs
  4. Agent indicates completion

Origin Handling

Different input sources are handled differently:

OriginRoleSession
WEB_UIuserPersistent
TELEGRAMuserPersistent
DISCORDuserPersistent
MOBILE_APPuserPersistent
LOCAL_TUIuserPersistent
SYSTEM_CRONsystemFresh
WEBHOOKsystemFresh
SWARM_DELEGATIONsystemFresh

Human vs System Origins

Human origins share a persistent conversation session:

  • Messages are added to STM
  • Context carries across messages
  • Memory is updated

System origins get a fresh session:

  • No prior context
  • Isolated execution
  • No memory contamination

Streaming

Brain responses can be streamed via Server-Sent Events (SSE):

javascript
const eventSource = new EventSource('/api/agents/default/chat/stream');

eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // data.content contains incremental response
  // data.done indicates completion
};

Event Types

EventDescription
tokenText token generated
invoke_startSkill invocation starting
invoke_endSkill execution complete
doneResponse complete

Context Building

Memory Injection

Before each LLM call, the brain injects context:

[Memory Context]
Previous conversation:
- User: Hello
- Agent: Hi there!
- User: What can you do?

Related memories:
- User prefers Python over JavaScript
- Working on project X

[/Memory Context]

Skill Catalog

Available skills are listed in the system prompt:

--- AVAILABLE SKILLS ---

host_shell (v1.0.0)
  Execute shell commands on the host system
  Usage: <invoke name="host_shell">["command"]</invoke>

web_crawler (v1.0.0)
  Fetch and parse web content
  Usage: <invoke name="web_crawler">["url"]</invoke>

...
--- END OF SKILLS ---

Error Handling

Skill Errors

When a skill fails:

Observation: ERROR: Command failed with exit code 1
stderr: permission denied

The agent can:

  1. Try a different approach
  2. Ask for clarification
  3. Report the error to the user

LLM Errors

If the LLM call fails:

  1. Error is logged
  2. User is notified
  3. Gateway may restart agent

Timeout

Long-running operations timeout:

bash
# Configure timeout (default: 60s)
moxxy run --agent default --prompt "Store '120' in vault as skill_timeout_seconds"

Advanced Features

Multi-Step Tasks

For complex workflows:

User: "Set up a new project with git, create a README, and push to GitHub"

Agent plans:
1. Create directory structure
2. Initialize git
3. Create README
4. Add remote
5. Push

Each step is executed in sequence via the ReAct loop.

Conditional Logic

Agents can make decisions:

I'll check the file first.
<invoke name="host_shell">["test -f config.json"]</invoke>

[If file exists]
The config exists. I'll read it...
<invoke name="host_shell">["cat config.json"]</invoke>

[If not]
The config doesn't exist. I'll create a default...
<invoke name="host_shell">["echo '{}' > config.json"]</invoke>

Tool Chaining

Skills can be chained:

<invoke name="host_shell">["curl -s API_URL"]</invoke>
[Parse JSON response]
<invoke name="telegram_notify">["Result: ..."]</invoke>

Debugging

View Brain Activity

bash
moxxy logs | grep -i brain

Trace Invocations

bash
moxxy logs | grep -i invoke

Verbose Mode

In dev mode, additional debug info is logged:

bash
moxxy dev
moxxy logs

Configuration

Model Selection

Choose the LLM for each agent:

bash
# Via vault
moxxy run --agent default --prompt "Store 'gpt-4o' in vault as llm_model"

# Or during init
moxxy init

Temperature

Control response creativity:

bash
moxxy run --agent default --prompt "Store '0.7' in vault as llm_temperature"

Max Tokens

Limit response length:

bash
moxxy run --agent default --prompt "Store '2048' in vault as llm_max_tokens"

Open source · Self-hosted · Data sovereign