Skip to content

Runs & Events

Moxxy v4 uses a run-based execution model. Instead of sending chat messages, you start a run with a prompt, and the agent processes it asynchronously. You observe progress via Server-Sent Events (SSE).

Starting a Run

POST /v1/agents/{name}/runs

Request

json
{
  "prompt": "Analyze the latest sales data and summarize trends."
}

Response (200)

json
{
  "run_id": "run_550e8400",
  "agent": "analyst",
  "status": "started"
}

The run executes in the background. The agent may invoke skills, call primitives, query memory, and produce assistant messages, all of which are emitted as events.

SSE Event Stream

GET /v1/events/stream

Subscribe to real-time events from all agents, or filter by specific criteria.

Query Parameters

ParameterTypeDescription
agent_idstringFilter events to a specific agent
run_idstringFilter events to a specific run
event_typestringFilter by event type (e.g., message.assistant)

Example

bash
# All events for a specific run
curl -N "http://127.0.0.1:3000/v1/events/stream?run_id=run_550e8400"

# Only assistant messages from a specific agent
curl -N "http://127.0.0.1:3000/v1/events/stream?agent_id=analyst&event_type=message.assistant"

# All events (no filter)
curl -N "http://127.0.0.1:3000/v1/events/stream"

EventEnvelope Format

Every event is delivered as a JSON object with a consistent envelope:

json
{
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2025-03-15T10:00:01Z",
  "agent_id": "analyst",
  "run_id": "run_550e8400",
  "sequence": 1,
  "event_type": "run.started",
  "payload": {}
}
FieldTypeDescription
event_idUUIDUnique event identifier
timestampstringISO 8601 timestamp
agent_idstringAgent that produced the event
run_idstringRun associated with the event
sequenceintegerMonotonically increasing sequence number within the run
event_typestringType of event
payloadobjectEvent-specific data

Event Types

Moxxy emits approximately 60 event types. Key categories include:

Run lifecycle:

  • run.started -- A run has begun
  • run.completed -- A run finished successfully
  • run.failed -- A run encountered an error

Messages:

  • message.user -- User prompt was submitted
  • message.assistant -- Agent produced a response
  • message.system -- System-level message

Model interactions:

  • model.request -- Request sent to LLM provider
  • model.response -- Full response received from LLM
  • model.stream -- Streaming token from LLM

Skills and primitives:

  • skill.invoked -- A skill was called
  • skill.completed -- A skill finished execution
  • primitive.called -- A built-in primitive was invoked
  • primitive.result -- Primitive returned a result

Memory:

  • memory.stored -- A memory was written
  • memory.recalled -- A memory was retrieved

Vault:

  • vault.accessed -- A secret was accessed
  • vault.denied -- Secret access was denied

Heartbeats:

  • heartbeat.fired -- A scheduled heartbeat triggered
  • heartbeat.created -- A new heartbeat was registered

Sub-agents:

  • subagent.spawned -- A sub-agent was created
  • subagent.completed -- A sub-agent finished

Security:

  • security.violation -- A security policy was violated
  • security.redacted -- Content was redacted by security policy

Channels:

  • channel.message_received -- Message received from external channel
  • channel.message_sent -- Message sent to external channel

JavaScript Example

javascript
const eventSource = new EventSource(
  'http://127.0.0.1:3000/v1/events/stream?run_id=run_550e8400'
);

eventSource.onmessage = (event) => {
  const envelope = JSON.parse(event.data);

  switch (envelope.event_type) {
    case 'message.assistant':
      console.log('Agent:', envelope.payload.content);
      break;
    case 'skill.invoked':
      console.log('Calling skill:', envelope.payload.skill);
      break;
    case 'run.completed':
      console.log('Run finished');
      eventSource.close();
      break;
    case 'run.failed':
      console.error('Run failed:', envelope.payload.error);
      eventSource.close();
      break;
  }
};

Python Example

python
import requests
import json

url = 'http://127.0.0.1:3000/v1/events/stream'
params = {'run_id': 'run_550e8400'}

with requests.get(url, params=params, stream=True) as response:
    for line in response.iter_lines():
        if line and line.startswith(b'data: '):
            envelope = json.loads(line[6:])
            print(f"[{envelope['event_type']}] {envelope.get('payload', {})}")
            if envelope['event_type'] in ('run.completed', 'run.failed'):
                break

Conversation History

GET /v1/agents/{name}/history

Returns the conversation history for the agent's current session.

Response (200)

json
[
  {
    "role": "user",
    "content": "Analyze the latest sales data and summarize trends.",
    "timestamp": "2025-03-15T10:00:00Z"
  },
  {
    "role": "assistant",
    "content": "Based on the sales data, I identified three key trends...",
    "timestamp": "2025-03-15T10:00:08Z"
  }
]

Ask-Response Flow

During a run, an agent may ask a clarifying question via the ask primitive. When this happens, the run pauses and emits an event. You answer via the ask-responses endpoint.

POST /v1/agents/{name}/ask-responses/{question_id}

Request

json
{
  "answer": "Use the Q1 2025 data only."
}

Response (200)

json
{
  "question_id": "q_abc123",
  "status": "answered"
}

The run resumes after the answer is submitted.

Audit Log

GET /v1/audit

Query the audit log for historical event records. This endpoint provides access to persisted events beyond the live SSE stream.

Open source · Self-hosted · Data sovereign