---
title: Agents and Threads
sidebar:
  order: 7
---
## Overview

A **thread** is a persistent, multi-turn AI conversation. You ask questions, request analysis, or assign work in natural language; the AI responds using Roboto's built-in tools and returns answers with clickable links to your data.

An **agent** is a named, purpose-built AI worker you define and reuse. It captures a prompt containing `{{variable}}` placeholders, optionally paired with [goals](/docs/learn/ai/goals). Launching an agent starts a thread, so the same workflow — "triage this dataset", "generate a flight report" — runs again with different inputs.

Key properties:

- Threads **persist**. You can leave and resume them, review their full history, and fork them from any point.
- The AI is **not read-only**: through [goals](/docs/learn/ai/goals) it can apply tags, write dataset summaries, and create events. Search and analysis remain read-only; in the web app, actions like creating events are gated behind your confirmation by default.
- Agents declare **typed variables** (e.g. dataset IDs, device IDs) that are validated at launch.
- Threads launched from an agent are stamped with that agent's ID, so the agent's detail page lists them all.

## Threads in the web app

In the Roboto web app, click the **AI Chat** button (the robot icon in the sidebar on the right) to open the chat panel, or expand it to fullscreen. The **Threads** tab of the **Agents** section lists your recent threads so you can resume or review them.

AI Chat automatically picks up what you're viewing. If you're on a [dataset](/docs/learn/concepts#datasets-section) page, it knows which dataset you're looking at and can answer questions about it directly — no need to specify IDs or names. Context items appear in the input area, and you can remove them to ask a general question instead.

## What the AI can do

- **Search your data** — find datasets, files, topics, and events using natural language, translated into [RoboQL](/docs/roboql/overview) behind the scenes.
- **Explore datasets and files** — summaries, file listings, topics, events, and metadata.
- **Analyze topic data** — statistics, anomalies, and patterns in time-series signals, without writing code.
- **Analyze media** — extract keyframes and describe the content of videos.
- **Navigate** — return links that open datasets, files, topics, and plots directly in the visualizer.
- **Act on your data** — when you declare [goals](/docs/learn/ai/goals), the AI can summarize datasets, apply triage labels as tags, and create events.
- **Apply your team's procedures** — via [skills](/docs/learn/ai/skills).
- **Use external tools** — via [MCP connections](/docs/learn/ai/mcp).

## Starting a thread from the CLI

With the [Roboto CLI](/docs/reference/cli) installed, start an interactive session on the command line:

```bash
roboto chat start
```

## Starting a thread from the SDK

Use [`AgentThread`](/docs/reference/python-sdk/roboto/ai#roboto.ai.AgentThread) to start and drive threads programmatically:

```python
from roboto.ai import AgentThread

thread = AgentThread.start("Summarize the most recent dataset from device drone-42")
thread.run()
print(thread.latest_message)
```

`run()` drives the turn to completion. To observe the response as it streams, iterate `thread.events()` instead.

You can also expose your own Python functions to the AI as client-side tools with the [`client_tool()`](/docs/reference/python-sdk/roboto/ai#roboto.ai.client_tool) decorator (tool names must start with `client_` and use lowercase snake\_case):

```python
from roboto.ai import AgentThread, client_tool

@client_tool
def client_lookup_firmware(device_id: str) -> str:
    """Look up the firmware version installed on a device."""
    return firmware_registry[device_id]

thread = AgentThread.start(
    "Which firmware was drone-42 running during its last flight?",
    client_tools=[client_lookup_firmware],
)
thread.run()
```

Resume an existing thread by ID:

```python
thread = AgentThread.from_id("ath_abc123")
thread.send_text("What changed since my last question?")
thread.run()
```

## Creating agents

Create an agent when a workflow is worth repeating. An agent binds a prompt template to typed variables; launching it substitutes your values, validates them (dataset, device, and collection IDs are checked for existence), and starts a thread.

```python
from roboto.ai.agent import Agent, TemplateVariable, TemplateVariableType
from roboto.ai.agent_thread import StartAgentThreadRequest, AgentMessage

agent = Agent.create(
    name="triage",
    request_template=StartAgentThreadRequest(
        messages=[AgentMessage.text("Triage dataset {{dataset_id}}.")],
    ),
    variables=[
        TemplateVariable(name="dataset_id", type=TemplateVariableType.DATASET_ID),
    ],
    description="Apply the triage label vocabulary to a dataset.",
)

thread = agent.launch(values={"dataset_id": "ds_abc123"})
thread.run()
```

In the web app, you can also ask AI Chat to turn the current conversation into a reusable agent, then review and save it from the **Agents** page.

## Security and permissions

- **Permission-scoped**: the AI cannot access anything beyond your existing permissions. Security is enforced at the system level, not by the AI.
- **Scoped writes**: the AI can modify your data only by applying tags, writing dataset summaries, and creating events — via the structured outcomes described in [Goals](/docs/learn/ai/goals), or in the web app via actions gated behind your confirmation. It cannot delete data.
- **Organization boundary**: your data stays within your organization.
- **AI-generated content**: responses are generated by an LLM and may be inaccurate. Always verify important information.

See the [Using AI Chat](/docs/user-guides/using-ai-chat) user guide for a walkthrough of the chat experience in the web app.
