> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runtools.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents

> Define, deploy, run, and stream AI agents

An agent is a model with a job: instructions, the tools it's allowed to use, where it runs, and what it can reach. Define one in a file, in the dashboard, or over `POST /v1/agents` — then run it from anywhere (CLI, SDK, REST, or a registered device), and every run writes to the same durable thread.

## Define an agent

```typescript agents/code-assistant.ts theme={null}
import { defineAgent } from '@runtools-ai/sdk';

export default defineAgent({
  slug: 'code-assistant',
  name: 'Code Assistant',
  model: 'claude-sonnet-4',
  systemPrompt: 'You are a careful software engineer.',
  tools: ['exec_command', 'write_stdin', 'apply_patch', 'view_image', 'web_search', 'get_dev_url'],
  sandbox: 'dev-env',
  maxIterations: 25,
  maxTokens: 16384,
  temperature: 0.4,
});
```

Deploy:

```bash theme={null}
runtools deploy
```

## Execution Modes

| Mode         | Description                                                                                                                    |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `in_sandbox` | Default. The agent runs against one linked sandbox                                                                             |
| `managed`    | The agent runs in the managed runtime and can attach workspaces or sandboxes as resources                                      |
| `local-mac`  | Local device agent. The agent is bound to one registered RunMesh device. Any client can start it; the work runs on that device |

For `in_sandbox`, set `sandbox` to a sandbox slug from `sandboxes/*.ts` or an existing sandbox reference.

For `local-mac`, bind the agent to a registered RunMesh device with `targetDeviceId`. Local device agents can be created and edited from the dashboard or API today. When a run starts, the desktop app registers the cloud thread through `/v1/run`, executes locally, and publishes thread events back to the platform.

## Filesystem Memory

When an `in_sandbox` agent needs durable storage, mount a workspace into the linked sandbox. The sandbox gives the agent an environment to run commands and use file tools; the workspace mount is the part of that environment that persists across agent runs and sandbox lifecycle changes.

```typescript sandboxes/dev-env.ts theme={null}
import { defineSandbox } from '@runtools-ai/sdk';

export default defineSandbox({
  slug: 'dev-env',
  name: 'Development Environment',
  template: 'base-ubuntu',
  mounts: [
    {
      workspaceId: '9b84ef42-9c3a-4930-9d4c-45c7f5c22d8e',
      path: '/workspace',
    },
  ],
});
```

```typescript agents/code-assistant.ts theme={null}
import { defineAgent } from '@runtools-ai/sdk';

export default defineAgent({
  slug: 'code-assistant',
  model: 'claude-sonnet-4',
  systemPrompt: 'Work carefully in the mounted project workspace.',
  tools: ['exec_command', 'write_stdin', 'apply_patch', 'view_image', 'web_search'],
  sandbox: 'dev-env',
});
```

The agent can read and write `/workspace` during each run. Conversation threads preserve dialogue context; workspaces preserve repo files, artifacts, task notes, and other filesystem state.

For `managed` and `local-mac`, use explicit `resources` when the agent needs workspaces or sandboxes beyond its bound runtime:

```typescript theme={null}
export default defineAgent({
  slug: 'release-coordinator',
  executionMode: 'managed',
  model: 'claude-sonnet-4',
  systemPrompt: 'Coordinate release work across attached resources.',
  tools: ['web_search'],
  resources: [
    { type: 'workspace', resourceId: 'shared-docs' },
    { type: 'sandbox', resourceId: 'release-env', alias: 'release-box' },
  ],
});
```

## Run an Agent

<CodeGroup>
  ```bash CLI theme={null}
  runtools agent run code-assistant "Create a REST API with Express and TypeScript"
  ```

  ```typescript SDK theme={null}
  const result = await rt.agent.run(
    'code-assistant',
    'Create a REST API with Express and TypeScript',
  );

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

  ```bash cURL theme={null}
  curl -X POST https://api.runtools.ai/v1/run \
    -H "X-API-Key: rt_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{"agent":"code-assistant","prompt":"Create a REST API"}'
  ```
</CodeGroup>

## Threads

Use threads for persisted conversations:

```typescript theme={null}
const first = await rt.agent.run('code-assistant', 'Start a todo app', {
  thread: true,
});

await rt.agent.run('code-assistant', 'Add filtering', {
  threadId: first.threadId,
});

const agentThreads = await rt.agent.threads('code-assistant', 20);
const { threads } = await rt.threads.list({ limit: 20 });
```

Use `rt.agent.threads(agentSlug)` for an agent's conversation history. The lower-level thread API is available through `rt.threads` for listing cloud threads, reading event history, archiving, renaming, compacting, and subscribing to live frames.

Live thread updates use `/v1/threads/{threadId}/events` WebSockets. Final messages and tool results are durable; token, reasoning, source, and tool-output deltas are live-only.

## Attachments

For file inputs, create an upload target and include the returned message part in the next run:

```typescript theme={null}
const { part } = await rt.agent.uploadAttachment({
  threadId,
  agentSlug: 'code-assistant',
  filename: 'requirements.md',
  contentType: 'text/markdown',
  data: fileBytes,
});

await rt.agent.run('code-assistant', 'Use this spec', {
  threadId,
  attachments: [part],
});
```

## Tools

Agents can use tool slugs from three sources:

| Source              | Example                                                                                                       |
| ------------------- | ------------------------------------------------------------------------------------------------------------- |
| Agent runtime tools | `exec_command`, `write_stdin`, `apply_patch`, `view_image`, `web_search`, `get_dev_url`, `request_user_input` |
| Marketplace tools   | `github`, `gmail`, `slack`                                                                                    |
| Custom org tools    | Any `defineTool()` deployed from your project                                                                 |

Install marketplace tools before using them:

```bash theme={null}
runtools tool search github
runtools tool install github
runtools oauth connect github
```

`get_dev_url` is available when the agent is attached to a sandbox runtime. `request_user_input` is available when the run has a user-attached channel that can answer prompts.

## Configuration

`defineAgent()` validates common model parameters:

| Field                                  | Range                                          |
| -------------------------------------- | ---------------------------------------------- |
| `maxIterations`                        | 1-100                                          |
| `maxTokens`                            | 1-128000                                       |
| `temperature`                          | 0-2                                            |
| `topP`                                 | 0-1                                            |
| `presencePenalty` / `frequencyPenalty` | -2 to 2                                        |
| `toolChoice`                           | `auto`, `none`, `required`, or a specific tool |

Provider-specific options pass through in `providerOptions`.

## Model Tiers

Platform models are served by Runtools-managed capacity and billed by token usage. BYOK models use the caller's configured provider secrets and are not billed as Platform inference. Use the model availability API when a UI needs to show which Platform and BYOK models are currently selectable.

## Best Practices

<AccordionGroup>
  <Accordion title="Keep agent definitions deployable">
    `defineAgent()` should contain serializable configuration. Put integration logic in tools.
  </Accordion>

  <Accordion title="Prefer OAuth-connected tools">
    OAuth tokens are resolved by Runtools services, so agents do not need provider tokens in prompts or sandbox files.
  </Accordion>

  <Accordion title="Use threads for product chat">
    Threads preserve context and expose live event streams for UI surfaces.
  </Accordion>

  <Accordion title="Keep runtime-specific assumptions out of prompts">
    The same thread can be controlled from different clients. Bind the agent to the right primitive (`in_sandbox`, `managed`, or `local-mac`) and let Runtools provide runtime context.
  </Accordion>
</AccordionGroup>
