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

# Chats and workspaces

> Start and continue conversations with the cloud agent from any host, or with Claude Code and Codex on the desktop, and list the workspaces an identity can reach.

`chat` starts and continues conversations in the client's bound cloud workspace, as the current user or service identity. A send is accepted, not answered: it returns a receipt, and you read the answer from the transcript or poll its status. `workspace.list()` is the read-only discovery call that goes with it.

```ts theme={null}
import { chat, workspace } from "@arg-ai/sdk";

const workspaces = await workspace.list();
const turn = await chat.start("Summarize this workspace", {
  title: "Workspace summary",
  openPanel: true,
});
const page = await chat.list({ limit: 20, offset: 0 });
const matches = await chat.search("summary", { limit: 10 });
const history = await chat.get(turn.chat_id);
await chat.continue(turn.chat_id, "What should I do next?");
```

## Start, continue, status

`start(message, options)` creates a chat and submits its first message. `continue(chatId, message, options)` submits to an existing chat. If you need the chat id before the first message lands, `create({ title, agent })` and `send(chatId, message, options)` expose the two steps.

A send returns either an accepted turn or a queued one:

```ts theme={null}
type ChatTurn = {
  chat_id: string;
  job_id?: string; // accepted: the run
  call_id?: string; // accepted: what to poll
  status?: "queued"; // the agent was busy; the turn waits its turn
  queue_id?: string;
  position?: number;
  panelOpened: boolean; // whether a host revealed the conversation
};
```

Poll `chat.status(chatId, callId ?? jobId)` for `pending`, `completed` (with `result.response`) or `error`. A queued turn has no call id until it is dispatched; watch the transcript with `chat.get` instead. Sends are not streamed. **Never retry an accepted send to fetch its answer** - that starts a second turn.

`model` on a send picks the model for that turn, subject to the organization's allowed models.

## Opening the conversation

`openPanel: true` on `start` or `continue`, and `chat.open(chatId)` on its own, ask the host to reveal the conversation: the docked chat panel on web and desktop, the native chat screen on iOS and Android. The result carries `panelOpened` (or `opened`), which is `false` where there is no Arg UI to open - a server, CI, `arg serve` or a hosted frontend. A panel that fails to open never discards the accepted send.

## Listing and searching

`chat.list({ limit, offset })` pages through the identity's chats bound to the workspace, newest first. `chat.search(query, { limit })` matches message text and returns `{ chatId, title, role, snippet, rank, messageCreatedAt }` hits. Both are scoped to the bound workspace and to chats the caller owns.

## Claude Code and Codex on the desktop

`agent` on `start` or `create` picks the harness that answers the conversation:

| `agent`         | Runs                                               | Available from                         |
| --------------- | -------------------------------------------------- | -------------------------------------- |
| `"arg"`         | The cloud agent (the default on a cloud workspace) | Every host                             |
| `"claude_code"` | Claude Code on the user's machine                  | An app open inside the Arg desktop app |
| `"codex"`       | Codex on the user's machine                        | An app open inside the Arg desktop app |

```ts theme={null}
const turn = await chat.start("Add tests for the parser", { agent: "claude_code" });
const status = await chat.status(turn.chat_id, turn.call_id!);
const transcript = await chat.get(turn.chat_id); // agent_type tells you who answered
```

The local harnesses are command-line processes the desktop app spawns, so only an app open inside the desktop can create or continue one. Every other host - web, iOS, Android, `arg serve`, a server or a gateway client - refuses with `unsupported_capability` and names the harness, rather than quietly substituting the cloud agent.

A local-harness send is a handoff to the desktop's chat panel, which owns that harness's transport, approvals and recovery. That has three consequences:

* The panel opens on the conversation for **every** send; there is no headless mode.
* The receipt is accepted once the panel has taken the message, and `call_id` is the id of the user message it was submitted as.
* `status` reads the desktop's own history: `pending` while the turn runs, `completed` with the assistant text answering that message, `error` when the turn failed or was stopped before replying.

`chat.list` includes the machine's Claude Code and Codex sessions for the workspace on its first page, and `chat.search` scans their transcripts on that machine. On a folder the desktop opened straight from disk, which has no cloud workspace, an unnamed `agent` means the desktop's default, Claude Code, and `agent: "arg"` is refused.

## Permissions

Inside an Arg preview, `chat` and `workspace` need **Workspace access** at **Workspace** scope; a folder-scoped grant cannot widen into chat authority. Creating or sending additionally needs **Read and write** and **Actions**, because a send is agent execution as the viewer. On a disk-only desktop folder, where **Actions** is never offered, **Read and write** is the whole consent.

From an agent's own script (`run_code`, `run_bash`), sends are refused unless the turn runs under full access - see [agent scripts](/guides/sdk/agent-scripts#what-a-script-may-start). Site and Server capability tokens grant no chat or discovery at all.

## Workspaces

```ts theme={null}
const accessible = await workspace.list();
// [{ id, name, organization_id }, ...] in the bound workspace's organization, including your private workspace
```

`workspace` deliberately exposes no create, update or delete. Use the [server client's](/guides/sdk/server) `workspaces` resource, or the [REST API](/guides/workspaces), for those.
