# Run

> Run a prompt to completion and get the final output.

Source: https://maincode.com/docs/agent-sdk-run
Section: Agent SDK · Matilda documentation

---

## `runner.run(agent, input, options?)`

Runs an agent turn and returns the complete result. Internally streams and collects all events.

```ts
import { Runner } from '@maincode-ai/matilda-agent-sdk';

const runner = new Runner();

const result = await runner.run(
  { name: 'helper', instructions: 'Be concise.' },
  'What is the capital of Australia?',
  {
    conversationId: 'conv-123',
    responseMode: 'instant',
    callbacks: {
      onToken: (delta) => process.stdout.write(delta),
      onDone: () => console.log('\n[done]'),
    },
  },
);

console.log(result.finalOutput);
console.log(result.usage);
```

## `AgentRunOptions`

Extends `RequestOptions`. All fields optional.

| Field | Type | Description |
| - | - | - |
| `signal` | `AbortSignal` | Abort the run. |
| `conversationId` | `string` | Associates this turn with a conversation thread. Auto-generated when omitted. |
| `fileIds` | `string[]` | File IDs to attach (from files.upload()). |
| `clientTools` | `ClientTool[]` | Client tools to advertise for this turn. |
| `context` | `string` | Override the agent's context. |
| `responseMode` | `ChatResponseMode` | Override the response mode. |
| `responseSchema` | `string` | Raw JSON Schema (as a string) to grammar-constrain the response to. Prefer runner.runObject / runner.streamObject, which convert a zod schema for you. |
| `stallTimeoutMs` | `number` | SSE stall watchdog timeout in ms. Defaults to 45\_000. Pass 0 to disable. |
| `metadata` | `Record<string, unknown>` | Custom data available to dynamic instructions. |
| `toolHandlers` | `ToolHandlers` | Handlers for client tools. |
| `maxToolRoundtrips` | `number` | Maximum tool roundtrip cycles before stopping. Defaults to 25. |
| `maxRetries` | `number` | Maximum retries on retryable errors (5xx, 429, 408, network). Defaults to 0. |
| `throwOnStreamError` | `boolean` | Throw MatildaAgentStreamError if the stream emits an error event. Defaults to true. |
| `callbacks` | `AgentCallbacks` | Callback hooks for events (see below). |
| `core` | `MatildaCore` | Override the runner's core for this run. |
| `fingerprint` | `string` | Device fingerprint for rate limiting. |
| `accessToken` | `string` | Override the core-level access token for this request. |

> **Note** — Prefer `runner.runObject` / `runner.streamObject` over `responseSchema` — they convert a zod schema for you; see [Structured output](https://maincode.com/docs/agent-sdk-structured-output). Client tool handlers are wired up in [Client tools](https://maincode.com/docs/agent-sdk-client-tools).

## `AgentCallbacks`

Simple callback hooks that fire as events arrive. An alternative to manually iterating `stream()`.

```ts
const result = await runner.run(agent, input, {
  callbacks: {
    onToken: (delta) => process.stdout.write(delta),
    onToolCall: (name, args) => console.log(`Tool: ${name}`),
    onToolResult: (name, result, isError) => console.log(`Result: ${result}`),
    onUsage: (usage) => console.log(`Tokens: ${usage.output_tokens}`),
    onError: (code, message) => console.error(`Error: ${code}`),
    onRetry: (attempt, error, delayMs) => console.log(`Retry ${attempt} in ${delayMs}ms`),
    onDone: () => console.log('Done'),
  },
});
```

| Field | Type | Description |
| - | - | - |
| `onEvent` | `(event: AgentRunEvent) => void` | Every event — catch-all, fires before the typed hooks below. Useful for telemetry, UI plumbing, or event logging. |
| `onToken` | `(delta: string) => void` | A text chunk arrives. |
| `onToolCall` | `(name: string, args: Record<string, unknown>) => void` | The agent calls a client tool. |
| `onToolResult` | `(name: string, result: string, isError: boolean) => void` | A client tool handler returns. |
| `onUsage` | `(usage: UsageEvent) => void` | Token usage data arrives. |
| `onError` | `(code: ChatErrorCode, message: string) => void` | A stream error occurs. |
| `onRetry` | `(attempt: number, error: { code: string; message: string }, delayMs: number) => void` | A retryable error triggers a retry. |
| `onDone` | `() => void` | The stream finishes. Fires per-turn in multi-turn tool loops. |

## `AgentRunResult`

| Field | Type | Description |
| - | - | - |
| `agentName` | `string` | The agent's name. |
| `finalOutput` | `string` | The full assistant response text. Accumulated from message.delta events. |
| `events` | `AgentRunEvent[]` | Every event emitted during the run. |
| `streamId` | `string \| undefined` | Durable stream ID (from stream.started event). |
| `lastEventId` | `string \| undefined` | Last stream event ID (for resume). |
| `usage` | `UsageEvent \| undefined` | Token usage. Accumulated across multi-roundtrip runs. |
| `errors` | `Array<{ code: ChatErrorCode; message: string }>` | Any errors emitted during the run. |
| `truncatedReason` | `string \| undefined` | Why the response was truncated (e.g. 'max\_tokens', 'max\_tool\_roundtrips'). |
| `safetyReplace` | `{ message: string; categories: string[] } \| undefined` | Set when the backend replaced the answer for safety. finalOutput holds the replacement text. |

## `throwOnStreamError: false`

By default, `run()` throws `MatildaAgentStreamError` if the stream emits an error event. Pass `throwOnStreamError: false` to suppress the throw and inspect errors on the returned result instead:

```ts
const result = await runner.run(agent, input, { throwOnStreamError: false });

if (result.errors.length > 0) {
  for (const err of result.errors) {
    console.log(`${err.code}: ${err.message}`);
  }
}
console.log('Partial output:', result.finalOutput || '(none)');
```
