diff --git a/docs/ai-coder/agents/chats-api.md b/docs/ai-coder/agents/chats-api.md index a1a43492c5..7b755434ac 100644 --- a/docs/ai-coder/agents/chats-api.md +++ b/docs/ai-coder/agents/chats-api.md @@ -39,13 +39,22 @@ The response is the newly created `Chat` object: "id": "a1b2c3d4-...", "owner_id": "...", "workspace_id": null, + "build_id": null, + "agent_id": null, + "parent_chat_id": null, + "root_chat_id": null, "last_model_config_id": "...", "title": "hello world", "status": "waiting", "last_error": null, + "diff_status": null, "created_at": "2025-07-17T00:00:00Z", "updated_at": "2025-07-17T00:00:00Z", - "archived": false + "archived": false, + "pin_order": 0, + "mcp_server_ids": [], + "labels": {}, + "has_unread": false } ``` @@ -70,11 +79,13 @@ A typical integration follows three steps: `POST /api/experimental/chats` -| Field | Type | Required | Description | -|-------------------|-------------------|----------|-------------------------------------------------| -| `content` | `ChatInputPart[]` | yes | The user's prompt as one or more content parts. | -| `workspace_id` | `uuid` | no | Pin the chat to a specific workspace. | -| `model_config_id` | `uuid` | no | Override the default model configuration. | +| Field | Type | Required | Description | +|-------------------|---------------------|----------|-------------------------------------------------| +| `content` | `ChatInputPart[]` | yes | The user's prompt as one or more content parts. | +| `workspace_id` | `uuid` | no | Pin the chat to a specific workspace. | +| `model_config_id` | `uuid` | no | Override the default model configuration. | +| `mcp_server_ids` | `uuid[]` | no | Attach MCP servers to this chat. | +| `labels` | `map[string]string` | no | Key-value labels for the chat (max 50). | Each `ChatInputPart` has a `type` field. The simplest form is a text part: @@ -92,10 +103,11 @@ range). `POST /api/experimental/chats/{chat}/messages` -| Field | Type | Required | Description | -|-------------------|-------------------|----------|-----------------------------------| -| `content` | `ChatInputPart[]` | yes | The follow-up message content. | -| `model_config_id` | `uuid` | no | Override the model for this turn. | +| Field | Type | Required | Description | +|-------------------|-------------------|----------|-------------------------------------| +| `content` | `ChatInputPart[]` | yes | The follow-up message content. | +| `model_config_id` | `uuid` | no | Override the model for this turn. | +| `mcp_server_ids` | `uuid[]` | no | Override MCP servers for this turn. | If the agent is currently processing, the message is queued automatically. The response indicates whether the message was delivered immediately or @@ -111,6 +123,17 @@ queued: When `queued` is `true`, `message` is absent and `queued_message` is returned instead. +### Edit a message + +`PATCH /api/experimental/chats/{chat}/messages/{message}` + +Edits a previously sent user message. The agent re-processes from the +edited message onward, truncating any messages that followed it. + +| Field | Type | Required | Description | +|-----------|-------------------|----------|----------------------------------| +| `content` | `ChatInputPart[]` | yes | The replacement message content. | + ### Stream updates `GET /api/experimental/chats/{chat}/stream` @@ -141,6 +164,10 @@ connect the server sends an initial snapshot of the chat state before switching to live events. Use `after_id` when reconnecting to skip messages the client already has. +Connecting to the stream also updates the caller's read cursor for +unread tracking. On disconnect the cursor is advanced to the latest +message. + Event types inside each batch: | Type | Description | @@ -152,12 +179,35 @@ Event types inside each batch: | `retry` | The server is retrying a failed LLM call (includes backoff). | | `queue_update` | The queued message list changed. | +### Watch all chats + +`GET /api/experimental/chats/watch` + +Opens a **one-way WebSocket** that pushes events for all chats owned by +the authenticated user. Use this to drive a sidebar or notification +indicator without polling. + +Each event is a JSON object with `kind` and `chat` fields: + +| Kind | Description | +|----------------------|----------------------------------| +| `created` | A new chat was created. | +| `status_change` | A chat's status changed. | +| `title_change` | A chat's title was updated. | +| `diff_status_change` | A chat's diff/PR status changed. | +| `deleted` | A chat was deleted. | + ### List chats `GET /api/experimental/chats` Returns all chats owned by the authenticated user. +| Query parameter | Type | Required | Description | +|-----------------|----------|----------|------------------------------------------------------------------| +| `q` | `string` | no | Search query string. | +| `label` | `string` | no | Filter by label as `key:value`. Repeat for multiple (AND logic). | + ### Get a chat `GET /api/experimental/chats/{chat}` @@ -177,12 +227,28 @@ Returns the messages and queued messages for a chat. Returns available models. Use this to discover valid values for `model_config_id`. -### Archive / unarchive +### Update a chat -`POST /api/experimental/chats/{chat}/archive` -`POST /api/experimental/chats/{chat}/unarchive` +`PATCH /api/experimental/chats/{chat}` -Archive hides a chat from the default list without deleting it. +Updates chat metadata. All fields are optional; omitted fields are left +unchanged. + +| Field | Type | Description | +|-------------|---------------------|-------------------------------------------------------------------------------------| +| `title` | `string` | Set a new title. | +| `archived` | `bool` | `true` to archive, `false` to unarchive. Archiving clears `pin_order`. | +| `pin_order` | `int32` | `0` to unpin; `>0` on an unpinned chat to pin it; `>0` on a pinned chat to reorder. | +| `labels` | `map[string]string` | Replace all labels. Use `null`/omit to leave unchanged, `{}` to clear. | + +**Response**: `204 No Content`. + +### Regenerate title + +`POST /api/experimental/chats/{chat}/title/regenerate` + +Regenerates the chat title using conversation context. Returns the +updated `Chat` object. ### Interrupt @@ -191,6 +257,26 @@ Archive hides a chat from the default list without deleting it. Stops the agent's current processing loop and returns the chat to `waiting` status. +### Manage queued messages + +When a message is queued because the agent is busy, you can manage the +queue: + +`DELETE /api/experimental/chats/{chat}/queue/{queuedMessage}` + +Removes a queued message before it is processed. + +`POST /api/experimental/chats/{chat}/queue/{queuedMessage}/promote` + +Promotes a queued message to be processed next. + +### Get diff contents + +`GET /api/experimental/chats/{chat}/diff` + +Returns the current diff/PR status for a chat, including additions, +deletions, changed files, and pull request metadata when available. + ## File uploads Attach images to a chat by uploading them first: @@ -211,9 +297,11 @@ validates actual file content regardless of the declared `Content-Type`. ## Chat statuses -| Status | Meaning | -|-----------|--------------------------------------------------------------| -| `waiting` | Idle — newly created, finished successfully, or interrupted. | -| `pending` | Queued for processing. | -| `running` | Agent is actively working. | -| `error` | Agent encountered an error. | +| Status | Meaning | +|-------------|--------------------------------------------------------------| +| `waiting` | Idle — newly created, finished successfully, or interrupted. | +| `pending` | Queued for processing. | +| `running` | Agent is actively working. | +| `paused` | Agent is paused (e.g. waiting for user input). | +| `completed` | Agent finished and the task is complete. | +| `error` | Agent encountered an error. | diff --git a/docs/ai-coder/agents/platform-controls/index.md b/docs/ai-coder/agents/platform-controls/index.md index 0636033a73..e3d4867acc 100644 --- a/docs/ai-coder/agents/platform-controls/index.md +++ b/docs/ai-coder/agents/platform-controls/index.md @@ -61,9 +61,18 @@ Python backend services in the payments repo" — platform teams can guide the agent toward the correct infrastructure without requiring developers to understand template selection at all. +Administrators can also restrict which templates are available to agents using +the template allowlist in **Agents** > **Settings** > **Templates**. When the +allowlist is configured, the agent can only see and provision workspaces from +the selected templates. When the allowlist is empty, all templates are +available. This is separate from what developers see when manually creating +workspaces, so you can apply stricter policies to agent-created workspaces +without affecting the manual workspace experience. + See [Template Optimization](./template-optimization.md) for best practices on writing -discoverable descriptions, configuring network boundaries, scoping credentials, -and designing template parameters for agent use. +discoverable descriptions, restricting template visibility, configuring network +boundaries, scoping credentials, and designing template parameters for agent +use. ## Where we are headed @@ -97,11 +106,6 @@ Examples of what this looks like: from the control plane, agent workspaces do not need outbound access to LLM providers. You can create templates that only permit access to your git provider and nothing else. -- **Template scoping for agents.** We intend to let administrators restrict - which templates are available in the agentic interface, separate from what - developers see when manually creating workspaces. This lets you apply stricter - policies to agent-created workspaces without affecting the developer - experience for manually-created ones. ### Tool customization diff --git a/docs/ai-coder/agents/platform-controls/template-optimization.md b/docs/ai-coder/agents/platform-controls/template-optimization.md index 1415045419..4e428f4744 100644 --- a/docs/ai-coder/agents/platform-controls/template-optimization.md +++ b/docs/ai-coder/agents/platform-controls/template-optimization.md @@ -6,11 +6,37 @@ execute builds. When a workspace is needed, the agent reads the available templates, selects the appropriate one based on its name and description, and provisions a -workspace automatically. +workspace automatically. Administrators can restrict which templates the agent +can see using the [template allowlist](#restrict-available-templates). This guide covers best practices for creating templates that are discoverable and useful to Coder Agents. +## Restrict available templates + +By default, the agent can see and provision any template in the deployment. +Administrators can restrict this to a specific set of templates using the +template allowlist. + +To configure the allowlist: + +1. Navigate to **Agents** > **Settings** > **Templates**. +2. Select the templates you want agents to be able to use. +3. Click **Save**. + +When the allowlist is configured, the agent's `list_templates`, +`read_template`, and `create_workspace` tools are filtered to only include +the selected templates. The agent cannot see or provision templates that are +not on the list. + +When no templates are selected, the allowlist is inactive and all templates +are available to agents. + +The allowlist only affects agent-created workspaces. Developers can still +manually create workspaces from any template they have access to. This lets +platform teams apply stricter policies to agent workloads without affecting +the manual workspace experience. + ## Write discoverable template descriptions The agent selects templates by reading their names and descriptions — the same