docs(docs/ai-coder/agents): reformat to one sentence per line (#30700)

Reformats the Coder Agents docs under `docs/ai-coder/agents` to one
sentence per line, as the [docs style
guide](https://github.com/coder/coder/blob/main/docs/.style/style-guide/formatting.md#one-sentence-per-line)
requires. Hard-wrapped paragraphs are unwrapped and lines holding
several sentences are split, so a later edit to one sentence shows up as
a one-line diff.

Apart from the exception below, only whitespace inside paragraphs and
list items changes, and the rendered pages are the same. Comparing the
changed files against `main` word for word, ignoring whitespace and
blockquote `>` markers, finds differences only on the reworded lines.
`git diff --word-diff` is easier to read than the line diff.

59 lines that already contained an em or en dash were reworded by hand,
because `lint/emdash` treats every reflowed line as newly added. Each
uses a parenthetical, a separate sentence, or a colon after a lead-in.
Dashes on lines the reflow did not touch are left alone.

Applied with an in-progress formatter, limited to pages listed in
`docs/manifest.json` and excluding generated reference docs. This is one
of a batch of PRs that split the docs by area (21 files changed, 870
insertions(+), 1294 deletions(-)).

---
🤖 Built with AI assistance.
This commit is contained in:
Nick Vigilante
2026-10-15 14:38:40 -04:00
committed by GitHub
parent 7aef110ca2
commit 9eba637584
21 changed files with 852 additions and 1272 deletions
+107 -156
View File
@@ -2,142 +2,112 @@
title: Architecture
---
Coder's AI agent interacts with workspaces over the same
connection path as a developer's IDE, web terminal, and SSH session already
use. There is no sidecar process and no new network paths. If your developers
can already connect to their workspaces, the agent can too.
Coder's AI agent interacts with workspaces over the same connection path as a developer's IDE, web terminal, and SSH session already use.
There is no sidecar process and no new network paths.
If your developers can already connect to their workspaces, the agent can too.
## Architecture at a glance
Three components are involved in every agent interaction:
1. **The control plane** runs the agent loop. It receives prompts, streams them
to the LLM provider, interprets tool calls, and dispatches them to
workspaces.
1. **The LLM provider** (Anthropic, OpenAI, Google, Azure, AWS Bedrock, or any
OpenAI-compatible endpoint) performs model inference. It never communicates
with the workspace directly.
1. **The workspace** is standard compute infrastructure. It runs shell commands,
reads and writes files, and executes processes — exactly what occurs when a
developer connects via their IDE.
1. **The control plane** runs the agent loop.
It receives prompts, streams them to the LLM provider, interprets tool calls, and dispatches them to workspaces.
1. **The LLM provider** (Anthropic, OpenAI, Google, Azure, AWS Bedrock, or any OpenAI-compatible endpoint) performs model inference.
It never communicates with the workspace directly.
1. **The workspace** is standard compute infrastructure.
It runs shell commands, reads and writes files, and executes processes (exactly what occurs when a developer connects via their IDE).
<img src="../../images/guides/ai-agents/agent-loop-detailed.png" alt="Architecture diagram">
## The same connection your IDE uses
This is the key architectural insight: the agent reaches into a workspace
over the same Tailnet tunnel that a developer's tools already use.
This is the key architectural insight: the agent reaches into a workspace over the same Tailnet tunnel that a developer's tools already use.
When a developer opens a web terminal in the Coder dashboard, connects via
VS Code Remote, or runs `coder ssh`, the traffic follows this path:
When a developer opens a web terminal in the Coder dashboard, connects via VS Code Remote, or runs `coder ssh`, the traffic follows this path:
1. The client connects to the control plane.
1. The control plane routes the connection through its internal Tailnet node.
1. The connection reaches the workspace daemon over a DERP relay or
direct peer-to-peer link.
1. The workspace daemon handles the request — spawning a shell,
forwarding a port, or serving a file.
1. The connection reaches the workspace daemon over a DERP relay or direct peer-to-peer link.
1. The workspace daemon handles the request (spawning a shell, forwarding a port, or serving a file).
When the agent executes a tool call — reading a file, running a command,
writing code — it follows the same tunnel:
When the agent executes a tool call (reading a file, running a command, writing code), it follows the same tunnel:
1. The agent loop in the control plane issues a tool call.
1. The control plane routes the call through its internal Tailnet node.
1. The call reaches the workspace daemon over the same DERP relay or
peer-to-peer link.
1. The workspace daemon handles the request via its HTTP API — reading a file,
starting a process, or writing content.
1. The call reaches the workspace daemon over the same DERP relay or peer-to-peer link.
1. The workspace daemon handles the request via its HTTP API (reading a file, starting a process, or writing content).
The underlying tunnel is identical. IDE connections use SSH, web terminals use
a WebSocket protocol, and the agent uses the workspace daemon's HTTP API — but
all three traverse the same Tailnet connection and rely on the same security
boundary. No additional ports or network paths are introduced.
The underlying tunnel is identical.
IDE connections use SSH, web terminals use a WebSocket protocol, and the agent uses the workspace daemon's HTTP API, but all three traverse the same Tailnet connection and rely on the same security boundary.
No additional ports or network paths are introduced.
### No inbound ports
The workspace daemon always dials _out_ to the control plane — never
the reverse. The control plane then uses that established tunnel to reach back
in. This means:
The workspace daemon always dials _out_ to the control plane, never the reverse.
The control plane then uses that established tunnel to reach back in.
This means:
- The workspace needs no inbound ports or exposed services.
- You can block all inbound traffic to the workspace.
- The only required outbound connection from the workspace is to the control
plane itself.
- The only required outbound connection from the workspace is to the control plane itself.
This is unchanged from how workspaces already operate in Coder. Enabling
Coder Agents does not change your workspace network requirements.
This is unchanged from how workspaces already operate in Coder.
Enabling Coder Agents does not change your workspace network requirements.
## The agent loop
When a user submits a prompt, the control plane processes it as a background
job:
When a user submits a prompt, the control plane processes it as a background job:
1. The prompt is saved to the database and the chat is marked `running`.
1. A chat worker in the control plane claims the chat and starts a turn.
1. The control plane streams the conversation to the configured LLM provider.
1. The model responds with text, reasoning, or tool calls.
1. If the response includes tool calls, the control plane executes them
(connecting to the workspace as needed) and returns the results to the model.
1. Steps 3–5 repeat until the model produces a final response with no further
tool calls.
1. If the response includes tool calls, the control plane executes them (connecting to the workspace as needed) and returns the results to the model.
1. Steps 3 through 5 repeat until the model produces a final response with no further tool calls.
1. The chat is marked `waiting` for the next user message.
This loop runs inside the control plane process. There is no separate service
to deploy — it is part of the same binary that serves the dashboard and API.
This loop runs inside the control plane process.
There is no separate service to deploy.
It is part of the same binary that serves the dashboard and API.
### Context compaction
As conversations grow, the agent automatically summarizes older context to stay
within the model's context window. When token usage exceeds a threshold, the
agent generates a compressed summary and inserts it as a new message. Earlier
messages remain in the database and are still visible to users, but are excluded
from the model's context window. This happens transparently and keeps
long-running sessions productive.
As conversations grow, the agent automatically summarizes older context to stay within the model's context window.
When token usage exceeds a threshold, the agent generates a compressed summary and inserts it as a new message.
Earlier messages remain in the database and are still visible to users, but are excluded from the model's context window.
This happens transparently and keeps long-running sessions productive.
You can also trigger a compaction on demand by sending `/compact` while the
agent is idle or in an error state, which clears the error. Manual compaction
runs the same summarization regardless of current token usage and is labeled
as manual in the conversation.
You can also trigger a compaction on demand by sending `/compact` while the agent is idle or in an error state, which clears the error.
Manual compaction runs the same summarization regardless of current token usage and is labeled as manual in the conversation.
To start over without a summary, send `/clear` while the agent is idle or in
an error state. The transcript stays visible, but the next message runs with
a fresh context, as if the conversation were new. A "Context cleared" marker
shows where the reset happened.
To start over without a summary, send `/clear` while the agent is idle or in an error state.
The transcript stays visible, but the next message runs with a fresh context, as if the conversation were new.
A "Context cleared" marker shows where the reset happened.
### Message queuing
Users can send follow-up messages while the agent is actively working. Messages
are queued in the database and delivered when the agent completes its current
turn — the full sequence of steps until the model stops calling tools. There is
no need to wait for a response before providing additional context or
redirecting the agent.
Users can send follow-up messages while the agent is actively working.
Messages are queued in the database and delivered when the agent completes its current turn (the full sequence of steps until the model stops calling tools).
There is no need to wait for a response before providing additional context or redirecting the agent.
## Tool execution
Tools are how the agent takes action. Each tool call from the LLM translates to
a concrete operation — either inside a workspace or within the control plane
itself.
Tools are how the agent takes action.
Each tool call from the LLM translates to a concrete operation, either inside a workspace or within the control plane itself.
The agent is restricted to the built-in tool set defined in this section,
plus any additional tools from workspace skills and MCP servers. Skills
provide structured instructions the agent loads on demand
(see [Extending Agents](./extending-agents.md)). MCP tools come from
admin-configured external servers
(see [MCP Servers](./platform-controls/mcp-servers.md)) and from workspace
`.mcp.json` files. The agent has no direct access to the Coder API beyond
what these tools expose and cannot execute arbitrary operations against the
control plane.
The agent is restricted to the built-in tool set defined in this section, plus any additional tools from workspace skills and MCP servers.
Skills provide structured instructions the agent loads on demand (see [Extending Agents](./extending-agents.md)).
MCP tools come from admin-configured external servers (see [MCP Servers](./platform-controls/mcp-servers.md)) and from workspace `.mcp.json` files.
The agent has no direct access to the Coder API beyond what these tools expose and cannot execute arbitrary operations against the control plane.
### Workspace connection lifecycle
The connection to a workspace is **lazy**. It is not established when a chat
starts — only when something needs to reach the workspace. This is typically
triggered by the first tool call that requires workspace access. Once
established, the connection is cached and reused for the duration of that chat
session.
The connection to a workspace is **lazy**.
It is not established when a chat starts, only when something needs to reach the workspace.
This is typically triggered by the first tool call that requires workspace access.
Once established, the connection is cached and reused for the duration of that chat session.
Chats that don't need workspace access (answering questions, planning an
approach, discussing architecture) never provision or connect to a workspace.
Chats that don't need workspace access (answering questions, planning an approach, discussing architecture) never provision or connect to a workspace.
### Workspace tools
@@ -158,17 +128,16 @@ They traverse the same Tailnet tunnel used by web terminals and IDE connections.
#### Windows workspace shell requirement
Coder Agents run workspace commands through a POSIX-compatible shell (`sh`).
Windows workspaces must provide `sh` on `PATH`, for example from
[Git for Windows](https://gitforwindows.org/) (Git Bash), MSYS2, or WSL.
PowerShell alone cannot run the `execute` tool. After installing a
shell, restart the workspace to pick up the updated `PATH`.
Windows workspaces must provide `sh` on `PATH`, for example from [Git for Windows](https://gitforwindows.org/) (Git Bash), MSYS2, or WSL.
PowerShell alone cannot run the `execute` tool.
After installing a shell, restart the workspace to pick up the updated `PATH`.
### Platform tools
These tools run entirely within the control plane. They do not require a
workspace connection. Platform and orchestration tools are only available to
root chats — sub-agents spawned by `spawn_agent` do not have access to them
and cannot create workspaces or spawn further sub-agents.
These tools run entirely within the control plane.
They do not require a workspace connection.
Platform and orchestration tools are only available to root chats.
Sub-agents spawned by `spawn_agent` do not have access to them and cannot create workspaces or spawn further sub-agents.
| Tool | What it does |
|---------------------|---------------------------------------------------------------------------------------------------|
@@ -180,19 +149,15 @@ and cannot create workspaces or spawn further sub-agents.
| `propose_plan` | Presents a Markdown plan file from the workspace for user review before implementation. |
| `ask_user_question` | Asks the user structured clarification questions during plan mode. |
`propose_plan` and `ask_user_question` are only exposed while plan mode is
active. In that mode, `write_file` and `edit_files` are restricted to the
chat-specific plan file, while `execute` and `process_output` remain available
for exploration such as cloning repositories, searching code, and running
inspection commands. Root plan-mode chats may also receive administrator-approved
external MCP tools. Workspace MCP tools remain unavailable in plan mode, and
plan-mode sub-agents still do not receive any MCP tools. Dynamic,
provider-native, and computer-use tools are not available.
`propose_plan` and `ask_user_question` are only exposed while plan mode is active.
In that mode, `write_file` and `edit_files` are restricted to the chat-specific plan file, while `execute` and `process_output` remain available for exploration such as cloning repositories, searching code, and running inspection commands.
Root plan-mode chats may also receive administrator-approved external MCP tools.
Workspace MCP tools remain unavailable in plan mode, and plan-mode sub-agents still do not receive any MCP tools.
Dynamic, provider-native, and computer-use tools are not available.
### Orchestration tools
These tools manage sub-agents — child chats that work on independent tasks in
parallel.
These tools manage sub-agents (child chats that work on independent tasks in parallel).
| Tool | What it does |
|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -206,9 +171,8 @@ parallel.
### Provider tools
These tools are executed server-side by the LLM provider, not by the control
plane or workspace. They are conditionally available based on the model
configuration set by an administrator.
These tools are executed server-side by the LLM provider, not by the control plane or workspace.
They are conditionally available based on the model configuration set by an administrator.
| Tool | What it does |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -233,8 +197,7 @@ This tool runs in the control plane and replaces the full MCP tool schemas with
## What runs where
Understanding the split between the control plane and the workspace is central
to the security model.
Understanding the split between the control plane and the workspace is central to the security model.
| Responsibility | Where it runs | Details |
|---------------------|---------------|---------------------------------------------------------------------------|
@@ -249,60 +212,54 @@ to the security model.
| Git operations | Workspace | Commits, pushes, and branch management happen inside the workspace. |
| Build and test | Workspace | Compilation, test suites, and dev servers run on workspace compute. |
The workspace has **zero AI awareness**. There are no LLM API keys, no agent
processes, and no AI-specific software installed. If you inspect a workspace
created by the agent, it looks identical to one a developer created
manually.
The workspace has **zero AI awareness**.
There are no LLM API keys, no agent processes, and no AI-specific software installed.
If you inspect a workspace created by the agent, it looks identical to one a developer created manually.
## Chat state and persistence
All chat data is stored in the control plane database, not in the workspace.
- **Chat metadata** — status, owner, associated workspace, timestamps, and
parent/child relationships for sub-agents.
- **Messages** — every message (user, assistant, tool calls, tool results) is
stored as a separate record with role, content, and token usage.
- **Compressed context** — when the agent compacts the conversation, summaries
are stored with a compression flag so the original context budget is
preserved.
- **Queued messages** — follow-up messages sent while the agent is working are
held in a queue and delivered in order.
- **Chat metadata**:
status, owner, associated workspace, timestamps, and parent/child relationships for sub-agents.
- **Messages**:
every message (user, assistant, tool calls, tool results) is stored as a separate record with role, content, and token usage.
- **Compressed context**:
when the agent compacts the conversation, summaries are stored with a compression flag so the original context budget is preserved.
- **Queued messages**:
follow-up messages sent while the agent is working are held in a queue and delivered in order.
Because state lives in the database:
- Chat history survives workspace stops, rebuilds, and deletions.
- An administrator can inspect any chat for audit or debugging.
- The agent can resume work by targeting a new workspace and continuing from the
last git branch or checkpoint.
- The agent can resume work by targeting a new workspace and continuing from the last git branch or checkpoint.
## Security posture
The control plane architecture provides built-in security properties for AI
coding workflows. These are structural guarantees, not configuration options —
they hold by default for every agent session.
The control plane architecture provides built-in security properties for AI coding workflows.
These are structural guarantees, not configuration options.
They hold by default for every agent session.
### No API keys in workspaces
LLM provider credentials exist only in the control plane. The workspace never
sees them. There is nothing for a developer, a compromised dependency, or a
rogue process to exfiltrate.
LLM provider credentials exist only in the control plane.
The workspace never sees them.
There is nothing for a developer, a compromised dependency, or a rogue process to exfiltrate.
### Workspaces can be fully network-isolated
Because the workspace does not need to reach any LLM provider, you can restrict
its network access to only:
Because the workspace does not need to reach any LLM provider, you can restrict its network access to only:
- The control plane (required for the workspace daemon to function).
- Your git provider (for push/pull operations).
Everything else can be blocked. The AI functionality comes from the control
plane, not from the workspace's network.
Everything else can be blocked.
The AI functionality comes from the control plane, not from the workspace's network.
> [!TIP]
> For sensitive environments, create dedicated templates for agent workloads
> with stricter egress rules than your standard developer templates. Because
> the AI comes from the control plane, these templates do not need any
> outbound access to LLM providers.
> For sensitive environments, create dedicated templates for agent workloads with stricter egress rules than your standard developer templates.
> Because the AI comes from the control plane, these templates do not need any outbound access to LLM providers.
### Centralized enforcement
@@ -317,34 +274,28 @@ Refer to [Organization scope](./platform-controls/organizations.md) for the sett
### User identity on every action
Every action the agent takes — PRs opened, code committed, commands executed —
is tied to the user who submitted the prompt. There is no shared bot account or
anonymous identity. If a developer submits a prompt that results in a pull
request, that pull request is attributed to them via the git authentication
already configured in your Coder deployment.
Every action the agent takes (PRs opened, code committed, commands executed) is tied to the user who submitted the prompt.
There is no shared bot account or anonymous identity.
If a developer submits a prompt that results in a pull request, that pull request is attributed to them via the git authentication already configured in your Coder deployment.
### Permission boundaries
The agent operates with the exact same permissions as the user who submitted
the prompt. If a user cannot access a template, workspace, or API endpoint
through the Coder dashboard or CLI, the agent cannot access it either. There
is no privilege escalation.
The agent operates with the exact same permissions as the user who submitted the prompt.
If a user cannot access a template, workspace, or API endpoint through the Coder dashboard or CLI, the agent cannot access it either.
There is no privilege escalation.
This extends to workspace isolation: the agent can only interact with
workspaces owned by the user who started the chat. It cannot read files,
execute commands, or connect to workspaces belonging to other users.
This extends to workspace isolation: the agent can only interact with workspaces owned by the user who started the chat.
It cannot read files, execute commands, or connect to workspaces belonging to other users.
Template visibility follows the same rule. When the agent lists available
templates, it sees only the templates the user is authorized to access.
The agent cannot provision a workspace from a template the user does not
have permission to use.
Template visibility follows the same rule.
When the agent lists available templates, it sees only the templates the user is authorized to access.
The agent cannot provision a workspace from a template the user does not have permission to use.
## Scaling and resource impact
The control plane overhead for Coder Agents is minimal. The heavy computation
happens elsewhere:
The control plane overhead for Coder Agents is minimal.
The heavy computation happens elsewhere:
- **LLM inference** runs on the external provider's infrastructure.
- **File I/O, builds, and tests** run on workspace compute.
- **The control plane** primarily proxies streaming responses and dispatches
tool calls over existing network connections.
- **The control plane** primarily proxies streaming responses and dispatches tool calls over existing network connections.
+15 -19
View File
@@ -2,10 +2,9 @@
title: Conversation search syntax
---
The chat list endpoint accepts a `q` query parameter for filtering
conversations. All filters use `key:value` syntax. Bare search terms
are rejected; use `title:` for title filtering or `search:` for
full-text search.
The chat list endpoint accepts a `q` query parameter for filtering conversations.
All filters use `key:value` syntax.
Bare search terms are rejected; use `title:` for title filtering or `search:` for full-text search.
## Filters
@@ -23,26 +22,21 @@ full-text search.
| `source` | `created_by_me`, `shared_with_me` | Ownership scope. Default: `created_by_me`. Pass both values comma-separated to return owned and shared conversations. |
| `search` | text | Full-text search across chat titles, PR titles, PR numbers, and message content. Quote multi-word values. |
Multiple filters in one query combine with AND logic. `search:` cannot
be combined with `title:`, `pr_title:`, or `pr:`.
Multiple filters in one query combine with AND logic.
`search:` cannot be combined with `title:`, `pr_title:`, or `pr:`.
## Full-text search
`search:` uses token-based PostgreSQL full-text search:
- Case-insensitive whole-word matching with AND semantics. Quoted
phrases, `OR`, and `-` negation follow
[`websearch_to_tsquery`](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES)
rules.
- Message content matches English word stems (`refactor` matches
`refactoring`) and ignores English stopwords. Titles and PR titles
do not stem.
- Case-insensitive whole-word matching with AND semantics.
Quoted phrases, `OR`, and `-` negation follow [`websearch_to_tsquery`](https://www.postgresql.org/docs/current/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES) rules.
- Message content matches English word stems (`refactor` matches `refactoring`) and ignores English stopwords.
Titles and PR titles do not stem.
- No fuzzy, semantic, or word-prefix matching.
- Whole-number values also match PR numbers by prefix: `302` matches PR `30281`.
- A value with no searchable words (punctuation only) returns an empty
list; an empty value returns HTTP 400.
- Results use the standard chat list ordering (pinned first, then most
recently updated) and pagination, without match snippets.
- A value with no searchable words (punctuation only) returns an empty list; an empty value returns HTTP 400.
- Results use the standard chat list ordering (pinned first, then most recently updated) and pagination, without match snippets.
- Message content becomes searchable shortly after it is written (background indexing, usually within 10&nbsp;minutes).
Titles and PR titles are searchable immediately.
@@ -99,9 +93,11 @@ be combined with `title:`, `pr_title:`, or `pr:`.
- `status:waiting` is an idle conversation, `status:running` is a turn in progress, and `status:interrupting` is a turn being stopped.
- `status:requires_action` means the agent needs you before it can continue, and `status:error` means the turn failed.
- `title:`, `repo:`, and `pr_title:` use ILIKE matching. `%` and `_` act as wildcards.
- `title:`, `repo:`, and `pr_title:` use ILIKE matching.
`%` and `_` act as wildcards.
- `pr_status:draft` means the PR is open **and** marked as a draft.
`pr_status:open` means the PR is open and not a draft.
- `pr_status:none` matches conversations with no pull request, including those whose linked PR was cleared.
- Conversations without a linked diff status are excluded when `pr`, `repo`, `pr_title`, or any `pr_status` value other than `none` is set. The `repo:` filter also matches chats tracking a branch with no PR.
- Conversations without a linked diff status are excluded when `pr`, `repo`, `pr_title`, or any `pr_status` value other than `none` is set.
The `repo:` filter also matches chats tracking a branch with no PR.
- Unrecognized keys, bare terms, or combining `search:` with `title:`, `pr_title:`, or `pr:` return HTTP 400 with a validation error.
+12 -4
View File
@@ -6,21 +6,29 @@ Chat sharing lets you give other users or groups read-only access to a Coder Age
## Share a chat
1. Open the chat you want to share on the **Agents** page. Only top-level chats can be shared; sub-agent chats inherit sharing from their parent.
1. Open the chat you want to share on the **Agents** page.
Only top-level chats can be shared; sub-agent chats inherit sharing from their parent.
1. Select the share icon in the chat top bar.
1. Select the **Search for user or group** field.
1. Search for and select a user or group.
1. Select **Add member** to grant **Read** access.
1. If you shared with a group, copy the chat URL from your browser and send it to the group members.
Coder does not create a separate share link. Users you share with directly receive a **Chat Shared** notification with a link to open the chat. Members who gain access only through a group are not notified.
Coder does not create a separate share link.
Users you share with directly receive a **Chat Shared** notification with a link to open the chat.
Members who gain access only through a group are not notified.
## Shared chat access
Viewers can open the chat from a direct link, view messages, stream live updates, and download chat attachments. Chats shared by other users can appear in the sidebar under **Shared with you** when they are in the chat list. Pinned shared chats appear under **Pinned**. Viewers reach sub-agent chats by following sub-agent links inside the parent chat or by opening a direct URL.
Viewers can open the chat from a direct link, view messages, stream live updates, and download chat attachments.
Chats shared by other users can appear in the sidebar under **Shared with you** when they are in the chat list.
Pinned shared chats appear under **Pinned**.
Viewers reach sub-agent chats by following sub-agent links inside the parent chat or by opening a direct URL.
Viewers have read-only access: they cannot send or edit messages, regenerate the chat title, archive the chat, or change its sharing settings.
## Disable chat sharing
Administrators can disable chat sharing for a deployment with `--disable-chat-sharing`, `CODER_DISABLE_CHAT_SHARING`, or `disableChatSharing`. The flag also turns off chat project sharing. While it is set, existing shares are ignored, new shares are rejected, and only creators and administrators can access chats and chat projects.
Administrators can disable chat sharing for a deployment with `--disable-chat-sharing`, `CODER_DISABLE_CHAT_SHARING`, or `disableChatSharing`.
The flag also turns off chat project sharing.
While it is set, existing shares are ignored, new shares are rejected, and only creators and administrators can access chats and chat projects.
+30 -41
View File
@@ -3,9 +3,7 @@ title: Extending agents
---
Workspace templates can extend the agent with custom skills and MCP tools.
These mechanisms let platform teams provide repository-specific instructions,
domain expertise, and external tool integrations without modifying the agent
itself.
These mechanisms let platform teams provide repository-specific instructions, domain expertise, and external tool integrations without modifying the agent itself.
## How the workspace shares context with chats
@@ -97,12 +95,9 @@ Two tools are registered when skills are present:
| `read_skill` | `name` (string) | Returns the SKILL.md body, the absolute skill directory (workspace skills), and a list of supporting files |
| `read_skill_file` | `name` (string), `path` (string) | Returns the content of a supporting file |
For workspace skills, `read_skill` also returns `dir`, the absolute path to
the skill directory in the workspace. The agent's `read_file` and `execute`
tools operate on that same workspace filesystem, so you can join `dir` with a
supporting file's relative path to read or run that file directly, for example
to execute a bundled `scripts/` helper. `read_skill_file` remains available as
a path-safe convenience for reading supporting files.
For workspace skills, `read_skill` also returns `dir`, the absolute path to the skill directory in the workspace.
The agent's `read_file` and `execute` tools operate on that same workspace filesystem, so you can join `dir` with a supporting file's relative path to read or run that file directly, for example to execute a bundled `scripts/` helper.
`read_skill_file` remains available as a path-safe convenience for reading supporting files.
Supporting files are read over the workspace connection, so `read_skill_file` and the supporting-file list need a reachable workspace.
The skill body comes from the pin and keeps working when the workspace is unreachable.
@@ -124,8 +119,7 @@ The skill body comes from the pin and keeps working when the workspace is unreac
### SKILL.md format
Each `SKILL.md` starts with YAML frontmatter containing a `name` and an
optional `description`, followed by the full instructions in markdown:
Each `SKILL.md` starts with YAML frontmatter containing a `name` and an optional `description`, followed by the full instructions in markdown:
```md
---
@@ -140,8 +134,7 @@ Instructions for the skill go here...
### Naming and size constraints
- Names must be kebab-case (`^[a-z0-9]+(-[a-z0-9]+)*$`) and match the
directory name exactly.
- Names must be kebab-case (`^[a-z0-9]+(-[a-z0-9]+)*$`) and match the directory name exactly.
- `SKILL.md` has a maximum size of 64&nbsp;KB.
A larger file is reported with an oversize status and contributes no content to the chat.
- Supporting files have a maximum size of 512&nbsp;KB.
@@ -151,9 +144,8 @@ A skill with its frontmatter missing, unparsable, not kebab-case, or not matchin
### Path safety
`read_skill_file` rejects absolute paths, paths containing `..`, and
references to hidden files. All paths are resolved relative to the skill
directory.
`read_skill_file` rejects absolute paths, paths containing `..`, and references to hidden files.
All paths are resolved relative to the skill directory.
## Personal skills
@@ -161,10 +153,8 @@ Personal skills are user-owned skills that are available to all of your chats.
They are not tied to a specific workspace.
Manage them from the **Agents** page, under **Settings** > **Skills**, in the **Personal skills** section.
Personal skills use the same `SKILL.md` format as workspace skills: YAML
frontmatter with a kebab-case `name`, an optional `description`, and a
markdown body. This keeps content portable between personal skills and
workspace skills.
Personal skills use the same `SKILL.md` format as workspace skills: YAML frontmatter with a kebab-case `name`, an optional `description`, and a markdown body.
This keeps content portable between personal skills and workspace skills.
```md
---
@@ -177,15 +167,14 @@ description: "Personal review guidance"
Instructions for the skill go here...
```
Each personal skill is stored as a single `SKILL.md` file containing
frontmatter and body content. Supporting files are not supported. Each
`SKILL.md` file can be up to 64&nbsp;KB, and each user can create up to 100 personal skills.
Each personal skill is stored as a single `SKILL.md` file containing frontmatter and body content.
Supporting files are not supported.
Each `SKILL.md` file can be up to 64&nbsp;KB, and each user can create up to 100 personal skills.
Personal skills are stored in Coder, not in the workspace, so they are not part of a workspace context snapshot and do not depend on a pin or a refresh.
If you need richer skills with supporting files or multiple files, use
workspace skills instead. Store them in the repo under
`.agents/skills/<name>/`, or load them from a workspace.
If you need richer skills with supporting files or multiple files, use workspace skills instead.
Store them in the repo under `.agents/skills/<name>/`, or load them from a workspace.
## Organization skills
@@ -292,18 +281,15 @@ The `read_skill` result returns the skill body without the frontmatter, so it do
## Workspace MCP tools
Workspace templates can expose custom
[MCP](https://modelcontextprotocol.io/introduction) tools by placing a
`.mcp.json` file in the workspace working directory.
Workspace templates can expose custom [MCP](https://modelcontextprotocol.io/introduction) tools by placing a `.mcp.json` file in the workspace working directory.
The agent connects to these servers, reports their tools in the context snapshot it pushes, and chats register those tools alongside their built-in tools.
To declare an MCP server inline on one chat through the API instead, refer to [Inline MCP servers](./platform-controls/mcp-servers.md#inline-mcp-servers-experimental).
### Configuration
Define MCP servers in `.mcp.json` at the workspace root. Each entry under
`mcpServers` describes a server. The transport type is inferred from
whether `command` or `url` is present, or you can set it explicitly with
`type`:
Define MCP servers in `.mcp.json` at the workspace root.
Each entry under `mcpServers` describes a server.
The transport type is inferred from whether `command` or `url` is present, or you can set it explicitly with `type`:
```json
{
@@ -321,11 +307,13 @@ whether `command` or `url` is present, or you can set it explicitly with
}
```
**Stdio transport**: set `command`, and optionally `args` and `env`. The
agent spawns the process in the workspace.
**Stdio transport**:
set `command`, and optionally `args` and `env`.
The agent spawns the process in the workspace.
**HTTP transport**: set `url`, and optionally `headers`. The agent connects
to the HTTP endpoint from the workspace.
**HTTP transport**:
set `url`, and optionally `headers`.
The agent connects to the HTTP endpoint from the workspace.
### How discovery works
@@ -346,10 +334,11 @@ Every workspace MCP tool call is proxied back through the workspace agent, so a
### Tool naming
Tool names are prefixed with the server name as `serverName__toolName` to
avoid collisions between servers and with built-in tools.
Tool names are prefixed with the server name as `serverName__toolName` to avoid collisions between servers and with built-in tools.
### Timeouts
- **Server connect**: 30&nbsp;seconds per server.
- **Tool calls**: 60&nbsp;seconds per invocation.
- **Server connect**:
30&nbsp;seconds per server.
- **Tool calls**:
60&nbsp;seconds per invocation.
+64 -89
View File
@@ -2,22 +2,19 @@
title: Getting started
---
This guide walks platform teams and administrators through setting up Coder
Agents, preparing your deployment, and running your first Coder Agent.
This guide walks platform teams and administrators through setting up Coder Agents, preparing your deployment, and running your first Coder Agent.
## Prerequisites
Before you begin, confirm the following:
- **Coder deployment** running the latest release.
- **LLM provider credentials** — an API key for at least one
[supported provider](./models.md) (Anthropic, OpenAI, Google, Azure OpenAI,
AWS Bedrock, OpenAI Compatible, OpenRouter, or Vercel AI Gateway).
- **Network access** from the control plane to your LLM provider. Workspaces
do not need LLM access — only the control plane does.
- **At least one template** with a
[descriptive name and description](./platform-controls/template-optimization.md)
for the agent to select when provisioning workspaces.
- **LLM provider credentials**:
an API key for at least one [supported provider](./models.md) (Anthropic, OpenAI, Google, Azure OpenAI, AWS Bedrock, OpenAI Compatible, OpenRouter, or Vercel AI Gateway).
- **Network access** from the control plane to your LLM provider.
Workspaces do not need LLM access.
Only the control plane does.
- **At least one template** with a [descriptive name and description](./platform-controls/template-optimization.md) for the agent to select when provisioning workspaces.
- **Admin access** to the Coder deployment for configuring providers.
- **Access to configure models** in each organization where you configure models.
The **Organization Admin** role and the **Owner** role include this access.
@@ -42,8 +39,7 @@ Before you begin, confirm the following:
To configure Coder Agents:
1. Navigate to **Admin settings** > **AI** and select **Providers**.
1. Add or update a provider with its credentials and upstream endpoint, then
save it.
1. Add or update a provider with its credentials and upstream endpoint, then save it.
1. Navigate to **Admin settings** > **AI** > **Models**.
1. Select the correct organization.
Coder shows the organization picker when you can access more than 1 organization.
@@ -56,12 +52,10 @@ Each organization has its own model list and its own default model.
Repeat the model steps in every organization that uses Coder Agents.
Refer to [Organization scope](./platform-controls/organizations.md) for the settings that stay deployment-wide.
Detailed instructions for each provider and model option are in the
[Models](./models.md) documentation.
Detailed instructions for each provider and model option are in the [Models](./models.md) documentation.
> [!TIP]
> Start with a single frontier model to validate your setup before adding
> additional providers.
> Start with a single frontier model to validate your setup before adding additional providers.
## Step 2: Start your first Coder Agent
@@ -105,8 +99,8 @@ Keep the following behavior in mind:
## Optimize your templates
The agent selects templates based on their **name, description, and README**.
It does not read Terraform. Clear, specific descriptions are the most important
factor in whether the agent picks the right template.
It does not read Terraform.
Clear, specific descriptions are the most important factor in whether the agent picks the right template.
Update your template descriptions to include:
@@ -114,14 +108,9 @@ Update your template descriptions to include:
- Which repository or service it is for, if applicable.
- What type of work it supports (backend, frontend, data pipeline, etc.).
When 128 characters is not enough, put the most important routing context near
the top of the template's
[`README.md`](./platform-controls/template-optimization.md#put-routing-context-near-the-top-of-the-readme).
The chat agent's template listing includes a bounded README excerpt (roughly the
first 1,000 characters), and template detail includes the README (up to roughly
8,000 characters). Both are reduced to plain text: frontmatter is stripped,
link text is kept while link URLs are dropped, images and badges are dropped
entirely, and code blocks and tables are preserved as text.
When 128 characters is not enough, put the most important routing context near the top of the template's [`README.md`](./platform-controls/template-optimization.md#put-routing-context-near-the-top-of-the-readme).
The chat agent's template listing includes a bounded README excerpt (roughly the first 1,000 characters), and template detail includes the README (up to roughly 8,000 characters).
Both are reduced to plain text: frontmatter is stripped, link text is kept while link URLs are dropped, images and badges are dropped entirely, and code blocks and tables are preserved as text.
**Good examples:**
@@ -139,9 +128,7 @@ entirely, and code blocks and tables are preserved as text.
| Dev environment | Too generic to distinguish from other templates |
| Default | Tells the agent nothing |
See [Template Optimization](./platform-controls/template-optimization.md) for
the full guide, including dedicated agent templates, network boundaries,
credential scoping, and pre-installing dependencies.
See [Template Optimization](./platform-controls/template-optimization.md) for the full guide, including dedicated agent templates, network boundaries, credential scoping, and pre-installing dependencies.
## Things to know before you start
@@ -153,20 +140,17 @@ As always, you should review [release notes](https://github.com/coder/coder/rele
### Use HTTPS for push notifications
Coder Agents use browser push notifications to alert you when a task
completes or needs attention. Most browsers require a secure (HTTPS)
origin for the [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API)
to work. If your access URL uses plain HTTP,
push notifications may not function.
Coder Agents use browser push notifications to alert you when a task completes or needs attention.
Most browsers require a secure (HTTPS) origin for the [Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API) to work.
If your access URL uses plain HTTP, push notifications may not function.
This does not affect agents themselves — only the browser notification
delivery. If you terminate TLS at a reverse proxy, ensure the
[access URL](../../admin/setup/index.md) is configured with an `https://` scheme.
This does not affect agents themselves, only the browser notification delivery.
If you terminate TLS at a reverse proxy, ensure the [access URL](../../admin/setup/index.md) is configured with an `https://` scheme.
### Set a deployment-wide system prompt
Administrators can set a system prompt that applies to all Coder Agents across the
deployment. Use this to encode organizational conventions:
Administrators can set a system prompt that applies to all Coder Agents across the deployment.
Use this to encode organizational conventions:
- Coding standards and style guidelines.
- Commit message formats.
@@ -174,8 +158,7 @@ deployment. Use this to encode organizational conventions:
- Required review processes before merging.
- Any guardrails specific to your environment.
Configure the system prompt from **Admin settings** > **AI** > **Coder Agents** > **Instructions**
or via the API at `PUT /api/v2/chats/config/system-prompt`.
Configure the system prompt from **Admin settings** > **AI** > **Coder Agents** > **Instructions** or via the API at `PUT /api/v2/chats/config/system-prompt`.
In a deployment with several organizations, organization administrators can also add organization instructions under **Admin settings** > **AI** > **Coder Agents** > **Instructions**.
Coder adds them after the deployment system prompt for new chats in that organization.
@@ -183,27 +166,27 @@ Refer to [Platform Controls](./platform-controls/index.md#system-prompt) for det
### Understand the security model
The agent runs in the control plane, not inside workspaces. This means:
The agent runs in the control plane, not inside workspaces.
This means:
- **No LLM API keys in workspaces.** Credentials stay in the control plane.
- **No agent software in workspaces.** No supply chain risk from
third-party agent tools.
- **User identity is always attached.** Every action is tied to the user
who submitted the prompt — no shared bot accounts.
- **No privilege escalation.** The agent has exactly the same permissions
as the prompting user.
- **No LLM API keys in workspaces.**
Credentials stay in the control plane.
- **No agent software in workspaces.**
No supply chain risk from third-party agent tools.
- **User identity is always attached.**
Every action is tied to the user who submitted the prompt, with no shared bot accounts.
- **No privilege escalation.**
The agent has exactly the same permissions as the prompting user.
Agent workspaces inherit the same network access as any manually created
workspace. If your templates don't restrict egress, the agent has full
internet access from the workspace. Consider
[creating dedicated agent templates](./platform-controls/template-optimization.md#create-dedicated-agent-templates)
with tighter network policies.
Agent workspaces inherit the same network access as any manually created workspace.
If your templates don't restrict egress, the agent has full internet access from the workspace.
Consider [creating dedicated agent templates](./platform-controls/template-optimization.md#create-dedicated-agent-templates) with tighter network policies.
### Plan for LLM costs
Every conversation turn sends tokens to your LLM provider. Long-running tasks,
sub-agent delegation, and complex multi-step work can consume significant
token volume. Consider:
Every conversation turn sends tokens to your LLM provider.
Long-running tasks, sub-agent delegation, and complex multi-step work can consume significant token volume.
Consider:
- Starting with a single model to establish a cost baseline.
- Capping spend with [AI Gateway budgets](./platform-controls/spend-management.md).
@@ -223,12 +206,12 @@ Refer to [Concurrent agents](./platform-controls/index.md#concurrent-agents) for
Identify 3–5 developers and a few concrete use cases for the initial rollout.
Good starting points:
- **Low-risk, high-visibility tasks** — generating unit tests, writing inline
documentation, small refactors.
- **Investigation and triage** — exploring unfamiliar code, triaging bugs,
understanding legacy systems.
- **Prototyping** — building proof-of-concept implementations, simple
dashboards, internal tools.
- **Low-risk, high-visibility tasks**:
generating unit tests, writing inline documentation, small refactors.
- **Investigation and triage**:
exploring unfamiliar code, triaging bugs, understanding legacy systems.
- **Prototyping**:
building proof-of-concept implementations, simple dashboards, internal tools.
To limit Coder Agents to the pilot group, see [Control who can use Coder Agents](#control-who-can-use-coder-agents).
@@ -265,10 +248,8 @@ Stream updates in real time by connecting to the WebSocket endpoint:
GET /api/v2/chats/{chat}/stream
```
For service-to-service automation, use
[API keys](../../admin/users/sessions-tokens.md)
rather than developer session tokens. Keep automation credentials
narrowly scoped.
For service-to-service automation, use [API keys](../../admin/users/sessions-tokens.md) rather than developer session tokens.
Keep automation credentials narrowly scoped.
### Link to a new chat with a prompt
@@ -291,10 +272,8 @@ URLs end up in browser history and server logs.
### Add workspace context with AGENTS.md
Create an `AGENTS.md` file in the home directory (`~/.coder/AGENTS.md`) or
the workspace agent's working directory to provide persistent context to the
agent. This file is automatically read and included in the system prompt
for every conversation with a Coder Agent that uses that workspace.
Create an `AGENTS.md` file in the home directory (`~/.coder/AGENTS.md`) or the workspace agent's working directory to provide persistent context to the agent.
This file is automatically read and included in the system prompt for every conversation with a Coder Agent that uses that workspace.
Use it for:
@@ -305,12 +284,9 @@ Use it for:
### Consider prebuilt workspaces for faster startup
Workspace provisioning is the main source of latency when the agent starts a
task. If your templates take more than a minute to provision, consider
configuring
[prebuilt workspaces](../../admin/templates/extending-templates/prebuilt-workspaces.md)
to maintain a pool of ready-to-use workspaces. The agent gets assigned an
already-running workspace instead of provisioning from scratch.
Workspace provisioning is the main source of latency when the agent starts a task.
If your templates take more than a minute to provision, consider configuring [prebuilt workspaces](../../admin/templates/extending-templates/prebuilt-workspaces.md) to maintain a pool of ready-to-use workspaces.
The agent gets assigned an already-running workspace instead of provisioning from scratch.
<a id="providing-feedback"></a>
@@ -321,20 +297,19 @@ For deployment-specific problems, such as provider configuration or performance
Good reports include:
- **What you tried**: the prompt, the template, and the model.
- **What happened**: the agent's behavior, any errors, and unexpected results.
- **What you expected**: the outcome you were looking for.
- **Context**: screenshots, `chat_id` values, or links to the Agents page help
the team investigate quickly.
- **What you tried**:
the prompt, the template, and the model.
- **What happened**:
the agent's behavior, any errors, and unexpected results.
- **What you expected**:
the outcome you were looking for.
- **Context**:
screenshots, `chat_id` values, or links to the Agents page help the team investigate quickly.
## Next steps
- [Architecture](./architecture.md) — how the control plane, LLM providers,
and workspaces interact.
- [Architecture](./architecture.md): how the control plane, LLM providers, and workspaces interact.
- [Models](./models.md) — configure additional providers and models.
- [Platform Controls](./platform-controls/index.md) — system prompts,
template routing, and admin-level configuration.
- [Template Optimization](./platform-controls/template-optimization.md) —
create agent-friendly templates with network boundaries and scoped
credentials.
- [Platform Controls](./platform-controls/index.md): system prompts, template routing, and admin-level configuration.
- [Template Optimization](./platform-controls/template-optimization.md): create agent-friendly templates with network boundaries and scoped credentials.
- [Chats API](../../reference/api/chats.md): build programmatic integrations.
+93 -134
View File
@@ -2,12 +2,13 @@
title: Coder Agents
---
Coder Agents is a chat interface and API for delegating development work and research to coding agents in your Coder deployment. Developers describe the work they want done, and Coder Agents handles selecting a template, provisioning a workspace, and executing the task.
Coder Agents is a chat interface and API for delegating development work and research to coding agents in your Coder deployment.
Developers describe the work they want done, and Coder Agents handles selecting a template, provisioning a workspace, and executing the task.
Coder Agents includes its own self-hosted AI coding
agent that runs the agent loop directly within the Coder control plane.
Coder Agents includes its own self-hosted AI coding agent that runs the agent loop directly within the Coder control plane.
No specialized software, API keys, or network access is required inside your workspace. The only requirement is network access between the control plane and external LLM providers.
No specialized software, API keys, or network access is required inside your workspace.
The only requirement is network access between the control plane and external LLM providers.
<video autoplay controls muted playsinline loop>
<source src="https://raw.githubusercontent.com/coder/coder/refs/heads/main/docs/images/guides/ai-agents/coder-agents-ui.mp4" type="video/mp4">
@@ -22,56 +23,44 @@ It is a standalone agent written in Go.
It implements standard agentic patterns, such as sub-agent delegation, context compaction, file editing, and shell execution.
It works with any LLM provider you configure.
It is not a wrapper around third-party agent tools like Claude Code
or Codex.
It is not a wrapper around third-party agent tools like Claude Code or Codex.
Coder Agents is not a replacement for your text editor or IDE. It is the
primary interface where developers work with and orchestrate coding agents.
Developers still connect to workspaces via VS Code, Cursor, JetBrains, or any
other editor to review, refine, and complete work that the agent produces.
Coder Agents is not a replacement for your text editor or IDE.
It is the primary interface where developers work with and orchestrate coding agents.
Developers still connect to workspaces via VS Code, Cursor, JetBrains, or any other editor to review, refine, and complete work that the agent produces.
## Who Coder Agents is for
Coder Agents is designed for organizations that need to self-host their AI
coding workflows and maintain full control over how agents operate. It is a
strong fit for:
Coder Agents is designed for organizations that need to self-host their AI coding workflows and maintain full control over how agents operate.
It is a strong fit for:
- **Regulated industries** such as financial services, healthcare, and
government, where AI tools must run on controlled infrastructure with
auditable access and strict network boundaries.
- **Platform engineering teams** that want to provide developers with a
high-quality AI coding experience without managing per-workspace agent
installations, API key distribution, or third-party agent licensing.
- **Organizations with existing Coder deployments** that want to add agentic
capabilities using their current templates, workspaces, and identity
providers rather than adopting a separate SaaS product.
- **Regulated industries** such as financial services, healthcare, and government, where AI tools must run on controlled infrastructure with auditable access and strict network boundaries.
- **Platform engineering teams** that want to provide developers with a high-quality AI coding experience without managing per-workspace agent installations, API key distribution, or third-party agent licensing.
- **Organizations with existing Coder deployments** that want to add agentic capabilities using their current templates, workspaces, and identity providers rather than adopting a separate SaaS product.
Coder Agents runs entirely self-hosted. There is no SaaS or managed component — the agent
loop, chat history, and all tool execution happen within your Coder deployment.
Coder Agents runs entirely self-hosted.
There is no SaaS or managed component.
The agent loop, chat history, and all tool execution happen within your Coder deployment.
## How it works
The agent loop runs inside [the control plane](./architecture.md). When a user
submits a prompt, the control plane:
The agent loop runs inside [the control plane](./architecture.md).
When a user submits a prompt, the control plane:
1. Sends the prompt to the configured LLM provider (Anthropic, OpenAI, Google,
Azure, AWS Bedrock, or any OpenAI-compatible endpoint).
1. Receives the model's response, which may include tool calls such as reading
files, writing code, or running shell commands.
1. Executes tool calls by connecting to a Coder workspace over the existing
workspace connection — the same path used for web terminals, port
forwarding, and IDE access.
1. Returns tool results to the model and continues the loop until the task is
complete.
1. Sends the prompt to the configured LLM provider (Anthropic, OpenAI, Google, Azure, AWS Bedrock, or any OpenAI-compatible endpoint).
1. Receives the model's response, which may include tool calls such as reading files, writing code, or running shell commands.
1. Executes tool calls by connecting to a Coder workspace over the existing workspace connection (the same path used for web terminals, port forwarding, and IDE access).
1. Returns tool results to the model and continues the loop until the task is complete.
The workspace itself has no knowledge of AI. It is standard compute
infrastructure — there are no LLM API keys, no agent harnesses, and no special
software installed. All intelligence lives in the control plane.
The workspace itself has no knowledge of AI.
It is standard compute infrastructure.
There are no LLM API keys, no agent harnesses, and no special software installed.
All intelligence lives in the control plane.
<img src="../../images/guides/ai-agents/agent-loop.png" alt="Architecture diagram showing the control plane in the center, with arrows out to LLM providers and arrows to workspaces">
<small>The agent loop runs in the control plane. It makes outbound requests to LLM
providers and connects to workspaces only when tool execution is needed.</small>
<small>The agent loop runs in the control plane.
It makes outbound requests to LLM providers and connects to workspaces only when tool execution is needed.</small>
### Automatic workspace provisioning
@@ -84,17 +73,17 @@ Questions and self-contained code examples don't need a workspace when the conve
This means:
- **Faster responses** — conversations that don't require workspace access
start immediately with no provisioning delay.
- **Lower infrastructure cost**: the agent uses existing tools and context when they can complete your request without a workspace.
- **Faster responses**:
conversations that don't require workspace access start immediately with no provisioning delay.
- **Lower infrastructure cost**:
the agent uses existing tools and context when they can complete your request without a workspace.
When a workspace _is_ needed, the agent reads the templates available to that user —
including their descriptions and parameters — selects the appropriate one, and
creates a workspace automatically. Template visibility is scoped to the user's role and permissions, so the agent can only select templates the user is authorized to use. Users can also manually choose which workspace is used when starting a new chat.
When a workspace _is_ needed, the agent reads the templates available to that user (including their descriptions and parameters), selects the appropriate one, and creates a workspace automatically.
Template visibility is scoped to the user's role and permissions, so the agent can only select templates the user is authorized to use.
Users can also manually choose which workspace is used when starting a new chat.
Platform teams control template routing by writing clear template descriptions.
For example, a description like "Use this template for Python backend services
in the payments repo" helps the agent select the correct infrastructure.
For example, a description like "Use this template for Python backend services in the payments repo" helps the agent select the correct infrastructure.
Administrators can also block agents on a template, which hides it from the agent completely.
Refer to [Platform Controls](./platform-controls/index.md#template-routing) for that setting.
@@ -115,28 +104,22 @@ The agent can continue with available file and shell tools, but provisioning doe
### Sub-agents
Coder Agents supports sub-agent delegation. The root agent can spawn child
agents to work on independent tasks in parallel. Each sub-agent gets its own
context window, which keeps individual conversations focused and avoids the
quality degradation that occurs as context windows grow large.
Coder Agents supports sub-agent delegation.
The root agent can spawn child agents to work on independent tasks in parallel.
Each sub-agent gets its own context window, which keeps individual conversations focused and avoids the quality degradation that occurs as context windows grow large.
For example, an agent tasked with "explore this repository and document its
structure" might spawn separate sub-agents to analyze the backend, frontend,
and infrastructure directories simultaneously.
For example, an agent tasked with "explore this repository and document its structure" might spawn separate sub-agents to analyze the backend, frontend, and infrastructure directories simultaneously.
### Chat persistence
All chat state is stored in the Coder database, not in the workspace. If a
workspace is stopped, deleted, or rebuilt, the full conversation history
survives. The agent can resume work by creating a new workspace with the same
template and continuing from the last known state, such as a git branch.
All chat state is stored in the Coder database, not in the workspace.
If a workspace is stopped, deleted, or rebuilt, the full conversation history survives.
The agent can resume work by creating a new workspace with the same template and continuing from the last known state, such as a git branch.
### Message queuing
Users can send follow-up messages while the agent is actively working. Messages
are queued and delivered when the agent completes its current step, so there is
no need to wait for a response before providing additional context or changing
direction.
Users can send follow-up messages while the agent is actively working.
Messages are queued and delivered when the agent completes its current step, so there is no need to wait for a response before providing additional context or changing direction.
### File attachments
@@ -155,69 +138,55 @@ Providers differ in which types they accept as native file content; a part the p
## Security benefits of the control plane architecture
Running the agent loop in the control plane rather than inside the developer
workspace is an architectural decision that directly addresses the primary
concerns regulated organizations have with AI coding tools: how do you give
developers access to coding agents without introducing unnecessary risk?
Running the agent loop in the control plane rather than inside the developer workspace is an architectural decision that directly addresses the primary concerns regulated organizations have with AI coding tools: how do you give developers access to coding agents without introducing unnecessary risk?
Traditionally, agents run inside the same compute where code
lives. This means the agent needs LLM API keys in the workspace, outbound
network access to model providers, and often elevated permissions. In a
regulated environment, this creates a surface area that is difficult to lock
down.
Traditionally, agents run inside the same compute where code lives.
This means the agent needs LLM API keys in the workspace, outbound network access to model providers, and often elevated permissions.
In a regulated environment, this creates a surface area that is difficult to lock down.
Coder Agents eliminates this by moving the agent loop out of the workspace
entirely:
Coder Agents eliminates this by moving the agent loop out of the workspace entirely:
- **No API keys in workspaces.** LLM provider credentials never enter the
workspace. The control plane makes all outbound requests to model providers
directly, so there is nothing for a developer or a compromised process to
exfiltrate.
- **No agent software to manage.** Workspaces don't need Claude Code, Codex,
or any agent harness installed. This eliminates a class of supply chain risk
and removes the need to keep agent software up to date across all workspaces.
- **Network boundaries are simpler.** Because the workspace doesn't need access
to LLM APIs, you can apply strict egress rules. An agent-only template might
permit access to only your git provider (e.g., `github.com`) and nothing
else. The workspace never needs to reach the internet for AI functionality.
- **Centralized, enforced control.** Platform teams configure models, system
prompts, and tool permissions from the control plane. These settings are
enforced server-side, so they are not user preferences that developers can
override.
- **User identity is always attached.** Every action the agent takes — PRs
opened, code pushed, commands run — is tied to the user who submitted the
prompt. There is no shared bot identity or anonymous execution.
- **No privilege escalation.** The agent operates with the exact same
permissions as the user who submitted the prompt. If a developer cannot
access a template, workspace, or resource through the Coder dashboard,
the agent cannot access it either. There is no escalation of privileges
and no shared service account.
- **Workspace isolation is preserved.** The agent can only access workspaces
owned by the user who submitted the prompt. There is no cross-user
workspace access — an agent running on behalf of one developer cannot
read files, execute commands, or interact with another developer's
workspaces.
- **No API keys in workspaces.**
LLM provider credentials never enter the workspace.
The control plane makes all outbound requests to model providers directly, so there is nothing for a developer or a compromised process to exfiltrate.
- **No agent software to manage.**
Workspaces don't need Claude Code, Codex, or any agent harness installed.
This eliminates a class of supply chain risk and removes the need to keep agent software up to date across all workspaces.
- **Network boundaries are simpler.**
Because the workspace doesn't need access to LLM APIs, you can apply strict egress rules.
An agent-only template might permit access to only your git provider (e.g., `github.com`) and nothing else.
The workspace never needs to reach the internet for AI functionality.
- **Centralized, enforced control.**
Platform teams configure models, system prompts, and tool permissions from the control plane.
These settings are enforced server-side, so they are not user preferences that developers can override.
- **User identity is always attached.**
Every action the agent takes (PRs opened, code pushed, commands run) is tied to the user who submitted the prompt.
There is no shared bot identity or anonymous execution.
- **No privilege escalation.**
The agent operates with the exact same permissions as the user who submitted the prompt.
If a developer cannot access a template, workspace, or resource through the Coder dashboard, the agent cannot access it either.
There is no escalation of privileges and no shared service account.
- **Workspace isolation is preserved.**
The agent can only access workspaces owned by the user who submitted the prompt.
There is no cross-user workspace access.
An agent running on behalf of one developer cannot read files, execute commands, or interact with another developer's workspaces.
> [!TIP]
> For highly sensitive environments, create a dedicated set of templates for
> agent workloads with stricter network policies than your standard developer
> templates. Because the AI comes from the control plane, these templates don't
> need any outbound access to LLM providers.
> For highly sensitive environments, create a dedicated set of templates for agent workloads with stricter network policies than your standard developer templates.
> Because the AI comes from the control plane, these templates don't need any outbound access to LLM providers.
<!-- break between callouts -->
> [!WARNING]
> By default, agent workspaces have the same network access and permissions
> as any workspace the user creates manually. If your templates do not
> restrict outbound network access, the agent has full internet access from
> the workspace. See [Template Optimization](./platform-controls/template-optimization.md)
> for guidance on configuring network boundaries and scoping credentials for
> agent workloads.
> By default, agent workspaces have the same network access and permissions as any workspace the user creates manually.
> If your templates do not restrict outbound network access, the agent has full internet access from the workspace.
> See [Template Optimization](./platform-controls/template-optimization.md) for guidance on configuring network boundaries and scoping credentials for agent workloads.
## LLM provider support
Coder Agents works with any LLM provider. Administrators configure providers
and models from the Coder dashboard or API. Supported providers include:
Coder Agents works with any LLM provider.
Administrators configure providers and models from the Coder dashboard or API.
Supported providers include:
| Provider | Description |
|-------------------|------------------------------------------|
@@ -230,8 +199,7 @@ and models from the Coder dashboard or API. Supported providers include:
| OpenRouter | Multi-model routing via OpenRouter |
| Vercel AI Gateway | Models via Vercel AI SDK |
Most providers support custom base URLs, which allows integration with
enterprise LLM proxies, self-hosted model endpoints, and internal gateways.
Most providers support custom base URLs, which allows integration with enterprise LLM proxies, self-hosted model endpoints, and internal gateways.
Administrators can configure multiple providers simultaneously and set a default model in each organization.
Developers select from enabled models when starting a chat.
@@ -244,8 +212,7 @@ Refer to [Organization scope](./platform-controls/organizations.md) for details.
## Built-in tools
The agent has access to a set of workspace tools that it uses to accomplish
tasks:
The agent has access to a set of workspace tools that it uses to accomplish tasks:
| Tool | Description |
|---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -276,21 +243,14 @@ tasks:
| `web_search` | Search the internet (provider-native, when enabled) |
| `find_tools` | Search the deferred MCP tool catalog and activate matching tools. Only available when the `mcp-tool-search` experiment is enabled and the turn has MCP tools to defer |
These tools connect to the workspace over the same secure connection used for
web terminals and IDE access. No additional ports or services are required in
the workspace.
These tools connect to the workspace over the same secure connection used for web terminals and IDE access.
No additional ports or services are required in the workspace.
Platform tools (`list_templates`, `read_template`, `create_workspace`,
`start_workspace`, `stop_workspace`, `propose_plan`, `ask_user_question`) and orchestration tools (`spawn_agent`,
`list_subagent_models`, `wait_agent`, `message_agent`, `interrupt_agent`, `list_agents`)
are only available to root chats. Sub-agents do not have access to these
tools and cannot create workspaces or spawn further sub-agents.
Platform tools (`list_templates`, `read_template`, `create_workspace`, `start_workspace`, `stop_workspace`, `propose_plan`, `ask_user_question`) and orchestration tools (`spawn_agent`, `list_subagent_models`, `wait_agent`, `message_agent`, `interrupt_agent`, `list_agents`) are only available to root chats.
Sub-agents do not have access to these tools and cannot create workspaces or spawn further sub-agents.
`spawn_agent` with `type=computer_use` additionally requires an
Anthropic or OpenAI provider and the virtual desktop feature to be
enabled by an administrator.
`read_skill` and `read_skill_file` are available when the workspace contains
skills in its `.agents/skills/` directory.
`spawn_agent` with `type=computer_use` additionally requires an Anthropic or OpenAI provider and the virtual desktop feature to be enabled by an administrator.
`read_skill` and `read_skill_file` are available when the workspace contains skills in its `.agents/skills/` directory.
`propose_plan` and `ask_user_question` are only available while plan mode is active.
In plan mode, the agent can still inspect the workspace and template metadata, execute shell commands for exploration, and read process output.
@@ -299,9 +259,8 @@ Workspace MCP tools are unavailable in plan mode, and plan-mode sub-agents recei
## Plan mode
Plan mode lets you ask the agent to investigate first and present a plan before
implementation. Open the chat input menu and choose **Plan first** to enable it
for the current chat.
Plan mode lets you ask the agent to investigate first and present a plan before implementation.
Open the chat input menu and choose **Plan first** to enable it for the current chat.
After you enable it, later turns in that chat stay in plan mode until you turn it off or select **Implement plan** after a proposed plan.
Because the mode is stored on the chat, reloading the page preserves the current setting.
+67 -119
View File
@@ -4,18 +4,17 @@ title: Models
Administrators configure LLM providers from **Admin settings** > **AI** and Coder Agents models from **Admin settings** > **AI** > **Models**.
Providers and centrally managed credentials are deployment-wide settings managed by platform teams.
Each model belongs to an organization. Each organization has its own model list.
Each model belongs to an organization.
Each organization has its own model list.
Developers select from the set of models that an administrator has enabled in their organization.
Refer to [Organization scope](./platform-controls/organizations.md) for the split between deployment-wide and organization-scoped settings.
Optionally, administrators can enable AI Gateway Bring Your Own Key (BYOK)
so developers can supply personal API keys for providers. See
[User API keys](#user-api-keys-byok) below.
Optionally, administrators can enable AI Gateway Bring Your Own Key (BYOK) so developers can supply personal API keys for providers.
See [User API keys](#user-api-keys-byok) below.
## Providers
Each LLM provider has a type, credentials, and an endpoint/base URL for the
upstream provider or proxy.
Each LLM provider has a type, credentials, and an endpoint/base URL for the upstream provider or proxy.
Coder supports the following provider types:
@@ -30,18 +29,14 @@ Coder supports the following provider types:
| OpenRouter | Multi-model routing via OpenRouter |
| Vercel AI Gateway | Models via Vercel AI SDK |
The **OpenAI Compatible** type is a catch-all for any service that exposes an
OpenAI-compatible chat completions endpoint. Use it to connect to self-hosted
models, internal gateways, or third-party proxies like LiteLLM.
The **OpenAI Compatible** type is a catch-all for any service that exposes an OpenAI-compatible chat completions endpoint.
Use it to connect to self-hosted models, internal gateways, or third-party proxies like LiteLLM.
Coder Agents route model requests through AI Gateway automatically by using
the provider configuration stored in Coder's database.
Coder Agents route model requests through AI Gateway automatically by using the provider configuration stored in Coder's database.
Some provider types work as AI Gateway proxy targets but cannot back Coder
Agents. GitHub Copilot, for example, authenticates with a per-request token
that only an official Copilot client can mint, so the server-side Agents
harness cannot use it. Configuring such a provider does not unlock Agents;
add one of the supported provider types above instead.
Some provider types work as AI Gateway proxy targets but cannot back Coder Agents.
GitHub Copilot, for example, authenticates with a per-request token that only an official Copilot client can mint, so the server-side Agents harness cannot use it.
Configuring such a provider does not unlock Agents; add one of the supported provider types above instead.
### Add a provider
@@ -52,9 +47,7 @@ A provider is deployment-wide, whilst the models that reference it are organizat
1. Select **Providers**.
1. Select **Add provider**.
1. Select the provider type.
1. Enter a unique lowercase provider name, the credentials, and the upstream
provider or proxy
[endpoint/base URL](#endpointbase-url-for-openai-compatible-providers).
1. Enter a unique lowercase provider name, the credentials, and the upstream provider or proxy [endpoint/base URL](#endpointbase-url-for-openai-compatible-providers).
1. Select **Save**.
After saving a provider, add an Agents model for it from **Admin settings** > **AI** > **Models**.
@@ -63,19 +56,14 @@ For provider-specific setup, including AWS Bedrock, refer to [AI Gateway provide
## Endpoint/base URL for OpenAI-compatible providers
Provider configuration stores an absolute HTTP(S) endpoint/base URL. Syntax
validation confirms that the value is a URL, but it does not prove the upstream
implements the APIs Coder sends.
Provider configuration stores an absolute HTTP(S) endpoint/base URL.
Syntax validation confirms that the value is a URL, but it does not prove the upstream implements the APIs Coder sends.
For the default Agents path through AI Gateway, set the endpoint/base URL to
the upstream provider or proxy endpoint. Do not set it to Coder's public AI
Gateway route, such as `https://<coder-host>/api/v2/ai-gateway/openai/v1`.
For the default Agents path through AI Gateway, set the endpoint/base URL to the upstream provider or proxy endpoint.
Do not set it to Coder's public AI Gateway route, such as `https://<coder-host>/api/v2/ai-gateway/openai/v1`.
OpenAI-shaped provider types require the upstream OpenAI-compatible prefix in
the endpoint/base URL because Coder appends request suffixes such as
`/chat/completions`, `/responses`, and `/models`. This applies to **OpenAI**,
**Azure OpenAI**, **Google**, **OpenAI Compatible**, **OpenRouter**, and
**Vercel AI Gateway** provider types.
OpenAI-shaped provider types require the upstream OpenAI-compatible prefix in the endpoint/base URL because Coder appends request suffixes such as `/chat/completions`, `/responses`, and `/models`.
This applies to **OpenAI**, **Azure OpenAI**, **Google**, **OpenAI Compatible**, **OpenRouter**, and **Vercel AI Gateway** provider types.
Examples:
@@ -92,45 +80,35 @@ Confirm the exact endpoint/base URL in your provider or proxy documentation.
## Provider credentials and security
Provider API keys entered in the dashboard are stored encrypted in the Coder
database. They are never exposed to workspaces, developers, or the browser
after initial entry. The dashboard shows only whether a key is set, not the
key itself.
Provider API keys entered in the dashboard are stored encrypted in the Coder database.
They are never exposed to workspaces, developers, or the browser after initial entry.
The dashboard shows only whether a key is set, not the key itself.
Because the agent loop runs in the control plane, workspaces never need direct
access to LLM providers. See
[Architecture](./architecture.md#no-api-keys-in-workspaces) for details
on this security model.
Because the agent loop runs in the control plane, workspaces never need direct access to LLM providers.
See [Architecture](./architecture.md#no-api-keys-in-workspaces) for details on this security model.
## Credential selection
Coder Agents use the AI providers configured by administrators.
Provider API keys entered by administrators are centralized credentials for the deployment.
BYOK for Coder Agents is controlled by the
[global AI Gateway BYOK setting](../ai-gateway/auth.md#bring-your-own-key-byok),
not by per-provider key policy flags. When BYOK is enabled, users can save a
personal API key for any enabled AI provider. When BYOK is disabled, saved user
keys are ignored and users cannot add or update personal keys.
BYOK for Coder Agents is controlled by the [global AI Gateway BYOK setting](../ai-gateway/auth.md#bring-your-own-key-byok), not by per-provider key policy flags.
When BYOK is enabled, users can save a personal API key for any enabled AI provider.
When BYOK is disabled, saved user keys are ignored and users cannot add or update personal keys.
For AWS Bedrock providers, the personal key is an AWS Bedrock API key. AI
Gateway forwards it as a bearer token, which authenticates that user's requests
instead of the deployment-managed AWS credentials (SigV4). This applies to
every model family Bedrock serves, including Anthropic and OpenAI models.
For AWS Bedrock providers, the personal key is an AWS Bedrock API key.
AI Gateway forwards it as a bearer token, which authenticates that user's requests instead of the deployment-managed AWS credentials (SigV4).
This applies to every model family Bedrock serves, including Anthropic and OpenAI models.
For each provider request, Coder selects credentials in this order:
1. If BYOK is enabled and the user has saved a personal key for the selected
provider, Coder uses the user's key.
1. Otherwise, Coder uses centralized provider credentials when they are
configured.
1. If neither a usable user key nor centralized credentials are available, the
provider is unavailable for that user.
1. If BYOK is enabled and the user has saved a personal key for the selected provider, Coder uses the user's key.
1. Otherwise, Coder uses centralized provider credentials when they are configured.
1. If neither a usable user key nor centralized credentials are available, the provider is unavailable for that user.
## Models
Each model belongs to a provider and has its own configuration for context limits,
generation parameters, and provider-specific options.
Each model belongs to a provider and has its own configuration for context limits, generation parameters, and provider-specific options.
### Select an organization
@@ -193,12 +171,9 @@ The collection response also includes provider descriptors and unsupported provi
1. Navigate to **Admin settings** > **AI** > **Models**.
1. Select **Add model** and select the provider for the new model.
1. Enter the **Model Identifier**, the exact model string your provider
expects (e.g., `claude-opus-4-6`, `gpt-5.3-codex`).
1. Set a **Display Name** so developers see a human-readable label in the model
selector.
1. Set the **Context Limit**, the maximum number of tokens in the model's
context window (e.g., `200000` for Claude Sonnet).
1. Enter the **Model Identifier**, the exact model string your provider expects (e.g., `claude-opus-4-6`, `gpt-5.3-codex`).
1. Set a **Display Name** so developers see a human-readable label in the model selector.
1. Set the **Context Limit**, the maximum number of tokens in the model's context window (e.g., `200000` for Claude Sonnet).
1. Configure any provider-specific options (see below).
1. Select **Save**.
@@ -208,9 +183,8 @@ The collection response also includes provider descriptors and unsupported provi
<img src="../../images/guides/ai-agents/models-add-model.png" alt="Screenshot of the add model form">
<small>Adding a model requires a model identifier, display name, and context
limit. Provider-specific options appear dynamically based on the selected
provider.</small>
<small>Adding a model requires a model identifier, display name, and context limit.
Provider-specific options appear dynamically based on the selected provider.</small>
### Set a default model
@@ -234,11 +208,10 @@ If the current default is disabled or its provider is unavailable, the row shows
The Models list reflects whether each model can actually be used:
- When a model's connected provider has been deleted, the **Provider** column
shows **Unset**.
- When a model's provider is missing or disabled, an **Unavailable** badge
appears beside the model name. The badge's tooltip explains whether the
provider was deleted or disabled. Such a model cannot serve chat requests.
- When a model's connected provider has been deleted, the **Provider** column shows **Unset**.
- When a model's provider is missing or disabled, an **Unavailable** badge appears beside the model name.
The badge's tooltip explains whether the provider was deleted or disabled.
Such a model cannot serve chat requests.
- When a model is disabled, a **Disabled** badge appears beside the model name.
To reconnect a model to a working provider, open the model from the list, pick a new provider from the **Provider** dropdown, and select **Save**.
@@ -247,8 +220,7 @@ The Save button is enabled as soon as the selected provider differs from the mod
## Model options
Every model has a set of general options and provider-specific options.
The admin UI generates these fields automatically from the provider's
configuration schema, so the available options always match the provider type.
The admin UI generates these fields automatically from the provider's configuration schema, so the available options always match the provider type.
### General options
@@ -269,8 +241,8 @@ These options apply to all providers:
### Provider-specific options
Each provider type exposes additional options relevant to its models. These
fields appear dynamically in the admin UI when you select a provider.
Each provider type exposes additional options relevant to its models.
These fields appear dynamically in the admin UI when you select a provider.
#### Anthropic
@@ -311,9 +283,8 @@ fields appear dynamically in the admin UI when you select a provider.
| Reasoning Effort | Reasoning effort level. |
> [!NOTE]
> Azure OpenAI uses the same options as OpenAI except Reasoning Mode. AWS
> Bedrock uses the same model configuration options as Anthropic (thinking
> budget, reasoning effort).
> Azure OpenAI uses the same options as OpenAI except Reasoning Mode.
> AWS Bedrock uses the same model configuration options as Anthropic (thinking budget, reasoning effort).
### Prompt caching
@@ -334,9 +305,8 @@ The model selector uses the following precedence to pre-select a model:
1. **Organization default**, the model marked with the **Default** badge.
1. **First available model**, if no default is set and no history exists.
Developers cannot add their own providers or models. If no models are
configured, the chat interface displays a message directing developers to
contact an administrator.
Developers cannot add their own providers or models.
If no models are configured, the chat interface displays a message directing developers to contact an administrator.
## Model overrides
@@ -356,10 +326,8 @@ To change an organization override, you need permission to edit that organizatio
The **Deployment settings** section is visible only to deployment admins.
> [!IMPORTANT]
> When a deployment upgrades from the older deployment-wide override
> storage, existing admin and personal overrides are deleted rather than
> migrated. Admins and users must re-select their override models in
> settings after the upgrade.
> When a deployment upgrades from the older deployment-wide override storage, existing admin and personal overrides are deleted rather than migrated.
> Admins and users must re-select their override models in settings after the upgrade.
The configurable contexts:
@@ -372,37 +340,24 @@ The configurable contexts:
| **Advisor** | Admin only | The [advisor](./platform-controls/advisor.md). Requires the `chat-advisor` experiment. |
| **Root** | User only | The user's own root chats. |
Resolution order, evaluated per chat or subagent from the chat's
organization:
Resolution order, evaluated per chat or subagent from the chat's organization:
1. Explicit `model_config_id` on the `spawn_agent` tool call (general and
explore subagents only).
1. Explicit `model_config_id` on the `spawn_agent` tool call (general and explore subagents only).
1. Personal override (when the admin gate is on and a model is set).
1. Admin override.
1. The chat's selected model (or the organization default for new chats).
If a referenced model is later disabled or deleted, that layer is skipped
and resolution falls through to the next, with two exceptions: an unusable
explicit `spawn_agent` `model_config_id` fails the tool call, and an
unusable title generation override skips titles, status labels, and
summaries instead of falling back. Agents discover selectable models (and
their reasoning effort ranges) with the `list_subagent_models` tool, which
only returns enabled models usable with the chat owner's credentials.
Computer-use subagents always run on the administrator-configured
computer-use model and reject explicit model selection.
If a referenced model is later disabled or deleted, that layer is skipped and resolution falls through to the next, with two exceptions: an unusable explicit `spawn_agent` `model_config_id` fails the tool call, and an unusable title generation override skips titles, status labels, and summaries instead of falling back.
Agents discover selectable models (and their reasoning effort ranges) with the `list_subagent_models` tool, which only returns enabled models usable with the chat owner's credentials.
Computer-use subagents always run on the administrator-configured computer-use model and reject explicit model selection.
> [!NOTE]
> Both override layers may change between releases.
> Admin overrides are available through the API at
> `/api/v2/organizations/{organization}/chats/model-overrides`
> and personal overrides at
> `/api/v2/organizations/{organization}/members/{user}/chats/model-overrides`.
> Admin overrides are available through the API at `/api/v2/organizations/{organization}/chats/model-overrides` and personal overrides at `/api/v2/organizations/{organization}/members/{user}/chats/model-overrides`.
## User API keys (BYOK)
When [AI Gateway BYOK](../ai-gateway/auth.md#bring-your-own-key-byok) is
enabled, developers can supply personal API keys for any enabled AI provider
from the Agents settings page.
When [AI Gateway BYOK](../ai-gateway/auth.md#bring-your-own-key-byok) is enabled, developers can supply personal API keys for any enabled AI provider from the Agents settings page.
<a id="managing-personal-api-keys"></a>
@@ -411,17 +366,14 @@ from the Agents settings page.
1. Navigate to the **Agents** page in the Coder dashboard.
1. Open **Settings** and select the **API Keys** tab.
1. Each enabled provider is listed with a status indicator:
- **Key saved**, your personal key is active and will be used for requests to
that provider.
- **Shared key**, no personal key is set and Coder is using
deployment-managed credentials for that provider.
- **Key saved**, your personal key is active and will be used for requests to that provider.
- **Shared key**, no personal key is set and Coder is using deployment-managed credentials for that provider.
- **No key**, no personal key or deployment-managed credential is available.
Add a personal key before you use models from this provider.
1. Enter your API key and select **Save**.
Personal API keys are encrypted at rest using the same database encryption
used for deployment-managed provider secrets. The dashboard never displays a
saved key, only whether one is set.
Personal API keys are encrypted at rest using the same database encryption used for deployment-managed provider secrets.
The dashboard never displays a saved key, only whether one is set.
<a id="removing-a-personal-key"></a>
@@ -435,14 +387,10 @@ If no deployment-managed credential is available, add a new personal key before
## Use an LLM proxy
Organizations that route LLM traffic through a centralized proxy, such as
LiteLLM or an internal gateway, can point a provider's **Endpoint** or **Base
URL** at that upstream proxy endpoint. Enter the API key your proxy expects.
Organizations that route LLM traffic through a centralized proxy, such as LiteLLM or an internal gateway, can point a provider's **Endpoint** or **Base URL** at that upstream proxy endpoint.
Enter the API key your proxy expects.
Use the **OpenAI Compatible** provider type if your proxy serves multiple model
families through a single OpenAI-compatible endpoint. Include the proxy
provider's documented OpenAI-compatible path prefix, such as `/v1`, when
required.
Use the **OpenAI Compatible** provider type if your proxy serves multiple model families through a single OpenAI-compatible endpoint.
Include the proxy provider's documented OpenAI-compatible path prefix, such as `/v1`, when required.
This lets you keep existing proxy-level features like per-user budgets, rate
limiting, and audit logging while using Coder Agents as the developer interface.
This lets you keep existing proxy-level features like per-user budgets, rate limiting, and audit logging while using Coder Agents as the developer interface.
@@ -3,8 +3,8 @@ title: Advisor
---
> [!NOTE]
> This feature is experimental. Pin a release before broad rollout and review
> the release notes before upgrading.
> This feature is experimental.
> Pin a release before broad rollout and review the release notes before upgrading.
## Enable the experiment
@@ -20,20 +20,17 @@ CODER_EXPERIMENTS=chat-advisor
## What it does
Lets a root agent pause its current turn and request strategic guidance from
a separate, single-step model call. The advisor sees recent conversation
context, runs without any tools, and returns concise advice for the root
agent rather than the end user. While active, it is the only tool the root
agent can call for that turn.
Lets a root agent pause its current turn and request strategic guidance from a separate, single-step model call.
The advisor sees recent conversation context, runs without any tools, and returns concise advice for the root agent rather than the end user.
While active, it is the only tool the root agent can call for that turn.
Useful for planning ambiguity, architectural tradeoffs, debugging strategy
after repeated failures, or risk reduction before a destructive operation.
Useful for planning ambiguity, architectural tradeoffs, debugging strategy after repeated failures, or risk reduction before a destructive operation.
## Configuration
Once the experiment is enabled, configure the advisor's runtime limits
under **Admin settings** > **AI** > **Coder Agents** > **Deployment settings**.
Use the **Advisor** card. These limits apply deployment-wide.
Once the experiment is enabled, configure the advisor's runtime limits under **Admin settings** > **AI** > **Coder Agents** > **Deployment settings**.
Use the **Advisor** card.
These limits apply deployment-wide.
| Field | Default | Notes |
|-------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
@@ -47,7 +44,4 @@ When no override is set, the advisor reuses the root agent's model.
The advisor is not available in plan mode or to subagents.
Failed advisor invocations refund the per-turn budget.
The same configuration is available through the API: runtime limits at
`GET`/`PUT` `/api/experimental/chats/config/advisor`, and the advisor
model override at
`PUT /api/v2/organizations/{organization}/chats/model-overrides/advisor`.
The same configuration is available through the API: runtime limits at `GET`/`PUT` `/api/experimental/chats/config/advisor`, and the advisor model override at `PUT /api/v2/organizations/{organization}/chats/model-overrides/advisor`.
@@ -2,10 +2,8 @@
title: Conversation auto-archive
---
Coder Agents automatically archives long-inactive conversations so they
drop out of active chat lists without any user intervention. Archived
conversations are still visible (and can be unarchived) until they age
out of the separate retention window, at which point they are purged.
Coder Agents automatically archives long-inactive conversations so they drop out of active chat lists without any user intervention.
Archived conversations are still visible (and can be unarchived) until they age out of the separate retention window, at which point they are purged.
## How it works
@@ -17,28 +15,20 @@ Activity is defined as the most recent non-deleted message in the conversation f
Root chats that have ongoing work are never selected for auto-archiving.
Children inherit their root's archival decision.
Pinned root conversations (those with a non-zero pin order) are never
selected for auto-archiving. Children are archived alongside their
root regardless of individual pin status. Admins and users who want
to retain a conversation long after its last message should pin the
root.
Pinned root conversations (those with a non-zero pin order) are never selected for auto-archiving.
Children are archived alongside their root regardless of individual pin status.
Admins and users who want to retain a conversation long after its last message should pin the root.
## Notifications
When your chats are auto-archived, you receive a digest notification
listing the titles of the archived conversations and the
auto-archive window currently configured. Because eligibility uses
UTC day boundaries, in steady state this notification fires at most
once per day (on the first tick after midnight UTC that finds newly
eligible chats). A large backlog (initial enablement or bulk
inactivity) may span multiple ticks, producing multiple notifications
until the backlog drains.
When your chats are auto-archived, you receive a digest notification listing the titles of the archived conversations and the auto-archive window currently configured.
Because eligibility uses UTC day boundaries, in steady state this notification fires at most once per day (on the first tick after midnight UTC that finds newly eligible chats).
A large backlog (initial enablement or bulk inactivity) may span multiple ticks, producing multiple notifications until the backlog drains.
Each digest lists at most 25 conversation titles.
When a tick archives more than that, the notification names the first 25 and reports the remainder as a count.
If you find the digest noisy, you can disable the "Chats
Auto-Archived" notification entirely from your notification preferences.
If you find the digest noisy, you can disable the "Chats Auto-Archived" notification entirely from your notification preferences.
## Interaction with retention
@@ -49,29 +39,20 @@ Auto-archive and deletion are two independent controls:
| Auto-archive window | Moves inactive chats to the archived state | 0&nbsp;days (disabled) |
| Retention window | Deletes chats that have been archived long enough and orphaned chat files | 30&nbsp;days |
A conversation needs to be inactive for `auto_archive_days`, then
archived for `retention_days`, before it is deleted. The two windows
stack additively. With auto-archive disabled by default, inactive
chats are never auto-archived; once an admin opts in by setting a
non-zero `auto_archive_days`, a conversation lives for at least
`auto_archive_days + retention_days` from its last message before it
is permanently removed.
A conversation needs to be inactive for `auto_archive_days`, then archived for `retention_days`, before it is deleted.
The two windows stack additively.
With auto-archive disabled by default, inactive chats are never auto-archived; once an admin opts in by setting a non-zero `auto_archive_days`, a conversation lives for at least `auto_archive_days + retention_days` from its last message before it is permanently removed.
Auto-archive (like manual archive) resets the per-chat retention
clock, so the full `retention_days` runs from the tick that archived
the chat, not from its last message.
Auto-archive (like manual archive) resets the per-chat retention clock, so the full `retention_days` runs from the tick that archived the chat, not from its last message.
Setting either value to `0` disables that step. Setting
`auto_archive_days` to `0` means inactive chats are never
auto-archived (users still archive manually). Setting
`retention_days` to `0` means archived chats are kept indefinitely.
Setting either value to `0` disables that step.
Setting `auto_archive_days` to `0` means inactive chats are never auto-archived (users still archive manually).
Setting `retention_days` to `0` means archived chats are kept indefinitely.
## Configuration
The auto-archive window is stored as the
`agents_chat_auto_archive_days` key in the `site_configs` table.
The default is `0` (disabled); set to a positive number of days to
enable auto-archiving.
The auto-archive window is stored as the `agents_chat_auto_archive_days` key in the `site_configs` table.
The default is `0` (disabled); set to a positive number of days to enable auto-archiving.
Admins can set the window in the dashboard under **AI Settings** > **Coder Agents** > **Lifecycle**.
@@ -90,6 +71,5 @@ To disable, set `auto_archive_days` back to `0`.
## Audit trail
Each auto-archived root chat produces an audit log entry with the
background subsystem tag `chat_auto_archive`. Cascaded children are
not audited individually.
Each auto-archived root chat produces an audit log entry with the background subsystem tag `chat_auto_archive`.
Cascaded children are not audited individually.
@@ -2,38 +2,29 @@
title: Chat debug logging
---
Records a detailed trace of each chat turn for troubleshooting: the
normalized request sent to the LLM provider, the full response, token usage,
retry attempts, and errors.
Records a detailed trace of each chat turn for troubleshooting: the normalized request sent to the LLM provider, the full response, token usage, retry attempts, and errors.
Off by default. Three layers control whether it runs for a given chat:
Off by default.
Three layers control whether it runs for a given chat:
1. **Deployment override.** Setting `CODER_CHAT_DEBUG_LOGGING_ENABLED=true`
(or `--chat-debug-logging-enabled` at server start) forces debug logging
on for every chat. The runtime admin and user toggles become read-only.
1. **Runtime admin gate.** With the deployment override unset, the
*Let users record chat debug logs* toggle decides whether users can opt
in. Configure it under **Admin settings** > **AI** > **Coder Agents** > **Lifecycle**, or at
`GET/PUT /api/v2/chats/config/debug-logging`.
1. **Per-user toggle.** Users with the admin gate enabled can turn debug
logging on for their own chats from **Agents** > **Settings** > **General**
under *Record debug logs for my chats*. The endpoint
`PUT /api/v2/chats/config/user-debug-logging` returns
`409 Conflict` if the deployment override is active and `403 Forbidden`
if the admin has not enabled user opt-in.
1. **Deployment override.**
Setting `CODER_CHAT_DEBUG_LOGGING_ENABLED=true` (or `--chat-debug-logging-enabled` at server start) forces debug logging on for every chat.
The runtime admin and user toggles become read-only.
1. **Runtime admin gate.**
With the deployment override unset, the *Let users record chat debug logs* toggle decides whether users can opt in.
Configure it under **Admin settings** > **AI** > **Coder Agents** > **Lifecycle**, or at `GET/PUT /api/v2/chats/config/debug-logging`.
1. **Per-user toggle.**
Users with the admin gate enabled can turn debug logging on for their own chats from **Agents** > **Settings** > **General** under *Record debug logs for my chats*.
The endpoint `PUT /api/v2/chats/config/user-debug-logging` returns `409 Conflict` if the deployment override is active and `403 Forbidden` if the admin has not enabled user opt-in.
> [!IMPORTANT]
> Debug logs may contain sensitive content from prompts, responses, tool
> calls, and errors. Treat them with the same care as conversation history.
> Only the chat owner (or a user with read access to the chat) can fetch a
> chat's debug runs through the API. Administrators do not get blanket
> access to all users' debug data.
> Debug logs may contain sensitive content from prompts, responses, tool calls, and errors.
> Treat them with the same care as conversation history.
> Only the chat owner (or a user with read access to the chat) can fetch a chat's debug runs through the API.
> Administrators do not get blanket access to all users' debug data.
When debug logging is active for a chat, a **Debug** tab appears in the
right panel of the Agents page (alongside Git, Terminal, and Desktop) for
that chat's owner. The tab lists recent debug runs and lets you expand a run
into its per-step request, response, token usage, retry attempts, errors,
and policy metadata.
When debug logging is active for a chat, a **Debug** tab appears in the right panel of the Agents page (alongside Git, Terminal, and Desktop) for that chat's owner.
The tab lists recent debug runs and lets you expand a run into its per-step request, response, token usage, retry attempts, errors, and policy metadata.
## Export debug logs
@@ -44,18 +35,15 @@ You can export the same captured debug data from the UI:
1. Open the **Debug** tab in the right panel.
1. Select **Export debug logs** to download the chat's recent debug runs as JSON, or expand a run and select **Export this run** to download one run.
The chat-level export includes the full run detail for the runs returned by
the debug run list endpoint. The current list endpoint returns up to 100 of
the newest runs.
The chat-level export includes the full run detail for the runs returned by the debug run list endpoint.
The current list endpoint returns up to 100 of the newest runs.
### API access
The same data is available through the API:
- `GET /api/v2/chats/{chat}/debug/runs` lists the most recent runs
for a chat (up to 100, newest first).
- `GET /api/v2/chats/{chat}/debug/runs/{debugRun}` returns a single
run with all of its steps, including normalized request and response bodies.
- `GET /api/v2/chats/{chat}/debug/runs` lists the most recent runs for a chat (up to 100, newest first).
- `GET /api/v2/chats/{chat}/debug/runs/{debugRun}` returns a single run with all of its steps, including normalized request and response bodies.
Fetch a single run and save it as JSON:
@@ -72,8 +60,7 @@ curl -fsS \
```
Fetch every run returned by the list endpoint and save a chat-level export.
Using the same `CODER_URL`, `CODER_SESSION_TOKEN`, and `CHAT_ID` variables
from above:
Using the same `CODER_URL`, `CODER_SESSION_TOKEN`, and `CHAT_ID` variables from above:
```sh
RUN_IDS=$(curl -fsS \
@@ -112,7 +99,5 @@ jq -s \
}' "$RUN_EXPORTS" > "coder-agents-debug-chat-$CHAT_ID.json"
```
Debug runs are stored alongside the chat and are removed when the parent
conversation is deleted (manually, by retention, or by chat purge). See
[Data Retention](./chat-retention.md) for the conversation retention
controls.
Debug runs are stored alongside the chat and are removed when the parent conversation is deleted (manually, by retention, or by chat purge).
See [Data Retention](./chat-retention.md) for the conversation retention controls.
@@ -2,23 +2,19 @@
title: Chat debug data retention
---
Coder Agents automatically cleans up old chat debug data to manage database
growth. Debug data includes persisted debug runs and their associated debug
steps.
Coder Agents automatically cleans up old chat debug data to manage database growth.
Debug data includes persisted debug runs and their associated debug steps.
This setting is independent from [conversation data retention](./chat-retention.md),
which only purges archived conversations and orphaned files.
This setting is independent from [conversation data retention](./chat-retention.md), which only purges archived conversations and orphaned files.
## How it works
A background process removes debug runs older than the configured retention
period. When a debug run is deleted, its debug steps are deleted via cascade.
A background process removes debug runs older than the configured retention period.
When a debug run is deleted, its debug steps are deleted via cascade.
The retention clock uses the debug run's `updated_at` value, which reflects the
last write to the debug run. It does not use the chat archive time. If a debug
run remains in progress for an unusually long period, such as after broken
finalization, it can still be purged once its `updated_at` value is older than
the cutoff.
The retention clock uses the debug run's `updated_at` value, which reflects the last write to the debug run.
It does not use the chat archive time.
If a debug run remains in progress for an unusually long period, such as after broken finalization, it can still be purged once its `updated_at` value is older than the cutoff.
## Configuration
@@ -43,6 +39,5 @@ Conversation retention and debug data retention are orthogonal controls:
| Conversation retention | Archived conversations and orphaned files | 30&nbsp;days |
| Debug data retention | Debug runs and debug steps, based on debug run `updated_at` | 30&nbsp;days |
Deleting a chat still deletes its debug data immediately via cascade, regardless
of the debug retention window. Unarchiving a chat does not restore debug data
that was already purged.
Deleting a chat still deletes its debug data immediately via cascade, regardless of the debug retention window.
Unarchiving a chat does not restore debug data that was already purged.
@@ -2,16 +2,15 @@
title: Conversation data retention
---
Coder Agents automatically cleans up old conversation data to manage database
growth. Archived conversations and their associated files are periodically
purged based on a configurable retention period.
Coder Agents automatically cleans up old conversation data to manage database growth.
Archived conversations and their associated files are periodically purged based on a configurable retention period.
Conversations become eligible for purging only after they are archived. Old
conversations can be archived manually, or automatically. See
[Auto-Archive](./chat-auto-archive.md) for how the two controls interact.
Conversations become eligible for purging only after they are archived.
Old conversations can be archived manually, or automatically.
See [Auto-Archive](./chat-auto-archive.md) for how the two controls interact.
Debug run and step cleanup is controlled separately. See
[Chat Debug Data Retention](./chat-debug-retention.md).
Debug run and step cleanup is controlled separately.
See [Chat Debug Data Retention](./chat-debug-retention.md).
## How it works
@@ -2,18 +2,14 @@
title: Git providers
---
Coder Agents leverages your existing
[external authentication](../../../admin/external-auth.md) configuration
to power the in-chat diff viewer.
Self-hosted GitHub Enterprise deployments require one additional setting
(`API_BASE_URL`) for this feature to work.
Coder Agents leverages your existing [external authentication](../../../admin/external-auth.md) configuration to power the in-chat diff viewer.
Self-hosted GitHub Enterprise deployments require one additional setting (`API_BASE_URL`) for this feature to work.
## GitHub Enterprise configuration
For public `github.com`, no additional configuration is needed.
For self-hosted GitHub Enterprise, add `API_BASE_URL` to your
[existing configuration](../../../admin/external-auth.md#github-enterprise):
For self-hosted GitHub Enterprise, add `API_BASE_URL` to your [existing configuration](../../../admin/external-auth.md#github-enterprise):
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-github"
@@ -27,25 +23,21 @@ CODER_EXTERNAL_AUTH_0_API_BASE_URL="https://github.example.com/api/v3"
CODER_EXTERNAL_AUTH_0_REGEX=github\.example\.com
```
Without `API_BASE_URL`, Coder defaults to `https://api.github.com`. Clone
and push still work (they use `AUTH_URL` and `TOKEN_URL` directly), but
the diff viewer silently fails because Coder builds its URL-matching
patterns from the API base URL.
Without `API_BASE_URL`, Coder defaults to `https://api.github.com`.
Clone and push still work (they use `AUTH_URL` and `TOKEN_URL` directly), but the diff viewer silently fails because Coder builds its URL-matching patterns from the API base URL.
> [!NOTE]
> If you have both a `github.com` and a GHE external auth config, only the
> GHE config needs `API_BASE_URL`.
> If you have both a `github.com` and a GHE external auth config, only the GHE config needs `API_BASE_URL`.
## GitLab configuration
For `gitlab.com`, no additional `API_BASE_URL` is needed. Coder
automatically derives it from your `AUTH_URL` for self-hosted instances.
For `gitlab.com`, no additional `API_BASE_URL` is needed.
Coder automatically derives it from your `AUTH_URL` for self-hosted instances.
### Required scopes
The default GitLab scopes (`read_user`) are sufficient for basic
authentication. To use merge request features (diffs, status checks) with
Coder Agents, configure:
The default GitLab scopes (`read_user`) are sufficient for basic authentication.
To use merge request features (diffs, status checks) with Coder Agents, configure:
```dotenv
CODER_EXTERNAL_AUTH_0_ID="primary-gitlab"
@@ -55,9 +47,8 @@ CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=xxxxxxx
CODER_EXTERNAL_AUTH_0_SCOPES="write_repository read_api"
```
The `read_api` scope grants read access to the API (needed for fetching
merge request metadata and diffs). The `write_repository` scope allows
pushing commits and creating merge requests.
The `read_api` scope grants read access to the API (needed for fetching merge request metadata and diffs).
The `write_repository` scope allows pushing commits and creating merge requests.
### Self-hosted GitLab
@@ -76,23 +67,18 @@ CODER_EXTERNAL_AUTH_0_REGEX=gitlab\.example\.com
```
> [!NOTE]
> You may also set `API_BASE_URL` explicitly if needed (e.g.,
> `https://gitlab.example.com/api/v4`), but this is usually unnecessary.
> You may also set `API_BASE_URL` explicitly if needed (e.g., `https://gitlab.example.com/api/v4`), but this is usually unnecessary.
## Known limitations
### GitLab
The GitLab provider has some semantic differences compared to the GitHub
provider:
The GitLab provider has some semantic differences compared to the GitHub provider:
- **Approved** uses GitLab's threshold-based approval (e.g., "all required
approvals met") rather than GitHub's "at least one approval and no changes
requested" model.
- **Changes requested** has no GitLab equivalent. This field is always
reported as `false`.
- **Reviewer count** only counts users who have approved, not all assigned
reviewers.
- **Approved** uses GitLab's threshold-based approval (e.g., "all required approvals met") rather than GitHub's "at least one approval and no changes requested" model.
- **Changes requested** has no GitLab equivalent.
This field is always reported as `false`.
- **Reviewer count** only counts users who have approved, not all assigned reviewers.
These gaps are tracked internally and may be refined in future releases.
@@ -105,12 +91,10 @@ Diffs should appear within a couple of minutes.
### Users not seeing diffs
The chat owner must have linked their account through the relevant external
auth provider.
The chat owner must have linked their account through the relevant external auth provider.
<a id="checking-logs"></a>
### Check logs
Look for gitsync warnings such as `no provider for origin` or
`resolve token` errors.
Look for gitsync warnings such as `no provider for origin` or `resolve token` errors.
+61 -90
View File
@@ -4,67 +4,59 @@ title: Platform controls
## Design philosophy
Coder Agents is built on a simple premise: platform teams should have full
control over how agents operate, and developers should have zero configuration
burden.
Coder Agents is built on a simple premise: platform teams should have full control over how agents operate, and developers should have zero configuration burden.
This means:
- **All agent configuration is admin-level.** Providers, models, system prompts, and tool permissions are set by administrators from the control plane.
- **All agent configuration is admin-level.**
Providers, models, system prompts, and tool permissions are set by administrators from the control plane.
These are not user preferences.
Deployment administrators own the deployment-wide policies.
Users with organization configuration access own the models and the MCP servers of their organization.
Refer to [Organization scope](./organizations.md) for the split between the 2 scopes.
- **Developers never need to configure anything by default.** A developer just
describes the work they want done. They do not need to pick a provider or
write a system prompt. The platform team has already set all of that up.
When a platform team enables user API keys for a provider, developers may
optionally supply their own key, but this is an opt-in policy decision, not
a requirement.
- **Enforcement, not defaults.** Settings configured by administrators are enforced server-side.
- **Developers never need to configure anything by default.**
A developer just describes the work they want done.
They do not need to pick a provider or write a system prompt.
The platform team has already set all of that up.
When a platform team enables user API keys for a provider, developers may optionally supply their own key, but this is an opt-in policy decision, not a requirement.
- **Enforcement, not defaults.**
Settings configured by administrators are enforced server-side.
Developers cannot override them.
A setting that a user can change is a preference, not a policy.
This is an architectural decision, not just a product choice. Because the agent
loop runs in the control plane rather than inside developer workspaces, there is
no local configuration for developers to modify and no agent software for them
to reconfigure. The control plane is the single source of truth for how agents
behave.
This is an architectural decision, not just a product choice.
Because the agent loop runs in the control plane rather than inside developer workspaces, there is no local configuration for developers to modify and no agent software for them to reconfigure.
The control plane is the single source of truth for how agents behave.
## What platform teams control today
### Providers and models
Administrators configure which LLM providers and models are available from the
Coder dashboard. This includes API keys, base URLs (for enterprise proxies or
self-hosted models), and per-model parameters like context limits, thinking
budgets, and reasoning effort.
Administrators configure which LLM providers and models are available from the Coder dashboard.
This includes API keys, base URLs (for enterprise proxies or self-hosted models), and per-model parameters like context limits, thinking budgets, and reasoning effort.
Providers are deployment-wide.
Models belong to an organization, so each organization has its own model list and its own default model.
Developers select from the set of models an administrator has enabled. They
cannot add their own providers or access models that have not been explicitly
configured.
Developers select from the set of models an administrator has enabled.
They cannot add their own providers or access models that have not been explicitly configured.
When an administrator enables user API keys on a provider, developers can
supply their own key from the Agents settings page. Refer to
[User API keys (BYOK)](../models.md#user-api-keys-byok) for details.
When an administrator enables user API keys on a provider, developers can supply their own key from the Agents settings page.
Refer to [User API keys (BYOK)](../models.md#user-api-keys-byok) for details.
An administrator can also enable personal model overrides, which let a developer
select a different model for their own chats. Coder disables personal model
overrides until an administrator enables them.
An administrator can also enable personal model overrides, which let a developer select a different model for their own chats.
Coder disables personal model overrides until an administrator enables them.
Refer to [Models](../models.md) for setup instructions.
Refer to [Organization scope](./organizations.md) for the organization scope and the upgrade behavior.
### System prompt
Administrators can set a system prompt that applies to all agent sessions. This
is useful for establishing organizational conventions: coding standards,
commit message formats, preferred libraries, or repository-specific context.
Administrators can set a system prompt that applies to all agent sessions.
This is useful for establishing organizational conventions: coding standards, commit message formats, preferred libraries, or repository-specific context.
This setting is available under **Admin settings** > **AI** > **Coder Agents** > **Instructions** and is only accessible to administrators. Developers can't access or interact with it.
This setting is available under **Admin settings** > **AI** > **Coder Agents** > **Instructions** and is only accessible to administrators.
Developers can't access or interact with it.
Organization administrators can also set organization instructions that apply only to chats in their organization.
Coder adds them after the deployment system prompt and never uses them in place of it.
@@ -87,12 +79,11 @@ The organization instructions are exposed over the chat configuration API:
### Plan mode instructions
Administrators can add deployment-wide instructions that apply only when a chat
enters plan mode. These instructions supplement the built-in planning behavior
and are useful for organization-specific planning requirements such as required
plan sections, approval checkpoints, or review workflows.
Administrators can add deployment-wide instructions that apply only when a chat enters plan mode.
These instructions supplement the built-in planning behavior and are useful for organization-specific planning requirements such as required plan sections, approval checkpoints, or review workflows.
This setting is available under **Admin settings** > **AI** > **Coder Agents** > **Instructions**. Developers do not edit it directly.
This setting is available under **Admin settings** > **AI** > **Coder Agents** > **Instructions**.
Developers do not edit it directly.
The same value is exposed over the chat configuration API:
@@ -101,14 +92,10 @@ The same value is exposed over the chat configuration API:
### Template routing
Platform teams control which templates are available to agents and how the agent
selects them. When a developer describes a task, the agent reads template
descriptions to determine which template to provision.
Platform teams control which templates are available to agents and how the agent selects them.
When a developer describes a task, the agent reads template descriptions to determine which template to provision.
By writing clear template descriptions, for example, "Use this template for
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.
By writing clear template descriptions, for example, "Use this template for 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 at **Admin settings** > **AI** > **Coder Agents** > **Templates**.
Use the switch for each template in the list.
@@ -125,11 +112,8 @@ Check out [Template Optimization](./template-optimization.md) for best practices
### MCP servers
Administrators can register external MCP (Model Context Protocol) servers that
provide additional tools for agent chat sessions. This includes configuring
authentication, controlling which tools are exposed via allow/deny lists, and
setting availability policies that determine whether a server is mandatory,
opt-out, or opt-in for each chat.
Administrators can register external MCP (Model Context Protocol) servers that provide additional tools for agent chat sessions.
This includes configuring authentication, controlling which tools are exposed via allow/deny lists, and setting availability policies that determine whether a server is mandatory, opt-out, or opt-in for each chat.
Each organization has its own set of MCP servers.
@@ -137,9 +121,9 @@ Refer to [MCP Servers](./mcp-servers.md) for configuration details.
### Workspace autostop fallback
Administrators can set a default autostop timer for agent-created workspaces
that do not define one in their template. Template-defined autostop rules always
take precedence. Active conversations extend the stop time automatically.
Administrators can set a default autostop timer for agent-created workspaces that do not define one in their template.
Template-defined autostop rules always take precedence.
Active conversations extend the stop time automatically.
This setting is available under **Admin settings** > **AI** > **Coder Agents** > **Lifecycle**.
The maximum configurable value is 30&nbsp;days.
@@ -192,10 +176,8 @@ The concurrent agent pools described above are licensing limits, not deployment
### Git providers
Coder Agents leverages your existing
[external authentication](../../../admin/external-auth.md) configuration
to power the in-chat diff viewer. Self-hosted GitHub Enterprise deployments
require additional configuration for this feature.
Coder Agents leverages your existing [external authentication](../../../admin/external-auth.md) configuration to power the in-chat diff viewer.
Self-hosted GitHub Enterprise deployments require additional configuration for this feature.
See [Git Providers](./git-providers.md) for details.
@@ -210,10 +192,8 @@ Refer to [Data Retention](./chat-retention.md) for details.
### Experiments
Administrators enable experimental features using the `--experiments` flag on
`coder server` (or the `CODER_EXPERIMENTS` environment variable). Once enabled,
runtime configuration for those features is available under **Admin settings** >
**AI** > **Coder Agents**.
Administrators enable experimental features using the `--experiments` flag on `coder server` (or the `CODER_EXPERIMENTS` environment variable).
Once enabled, runtime configuration for those features is available under **Admin settings** > **AI** > **Coder Agents**.
See the following pages for experiment-gated features:
@@ -230,40 +210,31 @@ We are continuing to invest in platform controls based on what feedback we get f
### Infrastructure-level enforcement
We believe that security-critical behaviors should not depend on the system
prompt. A system prompt can instruct an agent to "always format branch names like... ," but there is no guarantee the agent will comply every time.
We believe that security-critical behaviors should not depend on the system prompt.
A system prompt can instruct an agent to "always format branch names like... ," but there is no guarantee the agent will comply every time.
For controls that matter — network boundaries, git push targets, allowed
hostnames — we intend to enforce them at the infrastructure and network layer.
For controls that matter (network boundaries, git push targets, allowed hostnames), we intend to enforce them at the infrastructure and network layer.
Examples of what this looks like:
- **Network-restricted templates for agent workloads.** Because the AI comes
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.
- **Network-restricted templates for agent workloads.**
Because the AI comes 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.
## Why we take this approach
The common pattern in the industry today is that each developer installs and
configures their own coding agent inside their development environment. This
creates several problems for platform teams:
The common pattern in the industry today is that each developer installs and configures their own coding agent inside their development environment.
This creates several problems for platform teams:
- **No standardization.** Different developers use different agents with
different configurations. There is no unified way to enforce conventions or
improve the experience across the organization.
- **Security is ad-hoc.** If the agent runs inside the workspace, it has access
to whatever the workspace has access to — API keys, network endpoints,
credentials. Restricting this requires per-workspace configuration that is
difficult to maintain at scale.
- **Feedback is anecdotal.** Without centralized analytics, platform teams have
no way to know which models perform best, which prompts cause failures, or how
much agents are costing the organization.
- **Configuration is a developer burden.** Developers — especially those who
are not power users — should not need to think about which agent to install,
which API key to use, or how to configure a system prompt. They should
describe the work they want done.
- **No standardization.**
Different developers use different agents with different configurations.
There is no unified way to enforce conventions or improve the experience across the organization.
- **Security is ad-hoc.**
If the agent runs inside the workspace, it has access to whatever the workspace has access to (API keys, network endpoints, credentials).
Restricting this requires per-workspace configuration that is difficult to maintain at scale.
- **Feedback is anecdotal.**
Without centralized analytics, platform teams have no way to know which models perform best, which prompts cause failures, or how much agents are costing the organization.
- **Configuration is a developer burden.**
Developers (especially those who are not power users) should not need to think about which agent to install, which API key to use, or how to configure a system prompt.
They should describe the work they want done.
As models improve and the differences between agent harnesses continue to
shrink, we believe the leverage shifts toward user experience and platform-level controls: which
models to offer, how to enforce security, and how to use analytics to
continuously improve the development experience across the organization.
As models improve and the differences between agent harnesses continue to shrink, we believe the leverage shifts toward user experience and platform-level controls: which models to offer, how to enforce security, and how to use analytics to continuously improve the development experience across the organization.
@@ -2,18 +2,14 @@
title: MCP servers
---
Organization admins can register external MCP servers that provide additional
tools for agent chat sessions. Each organization has its own set of MCP
servers, and chats only offer servers from the chat's organization. Configured
servers are injected into or offered to users during chat depending on the
availability policy.
Organization admins can register external MCP servers that provide additional tools for agent chat sessions.
Each organization has its own set of MCP servers, and chats only offer servers from the chat's organization.
Configured servers are injected into or offered to users during chat depending on the availability policy.
This feature is accessible at **Admin settings** > **AI** > **Coder Agents** > **MCP servers**
(`/ai/settings/mcp-servers`). In multi-organization deployments, use the
organization picker to choose which organization's servers to manage. The
server list shows the picker when you can access more than one organization's
servers. The add and update views always show the target organization, as a
read-only field when only one organization is available.
This feature is accessible at **Admin settings** > **AI** > **Coder Agents** > **MCP servers** (`/ai/settings/mcp-servers`).
In multi-organization deployments, use the organization picker to choose which organization's servers to manage.
The server list shows the picker when you can access more than one organization's servers.
The add and update views always show the target organization, as a read-only field when only one organization is available.
## Add an MCP server
@@ -57,21 +53,21 @@ read-only field when only one organization is available.
## Authentication
Each MCP server uses one of five authentication modes. When you change the
auth type, fields from the previous type are automatically cleared.
Each MCP server uses one of five authentication modes.
When you change the auth type, fields from the previous type are automatically cleared.
OAuth2 client secrets, API keys, and custom headers are never returned in API responses.
Boolean flags indicate whether each value is set.
### None
No credentials are sent. Use this for servers that do not require
authentication.
No credentials are sent.
Use this for servers that do not require authentication.
### OAuth2
Per-user authorization. The administrator configures the OAuth2 provider, and
each user independently completes the authorization flow.
Per-user authorization.
The administrator configures the OAuth2 provider, and each user independently completes the authorization flow.
**Manual configuration** — provide all three fields together:
@@ -98,8 +94,9 @@ The value must be an absolute URI without a fragment or user information.
A manual configuration sends no `resource` parameter unless you set this field.
Leave it empty for providers that reject the parameter, such as Microsoft Entra ID.
**Auto-discovery** — leave `oauth2_client_id`, `oauth2_auth_url`, and
`oauth2_token_url` empty. The server attempts discovery in this order:
**Auto-discovery**:
leave `oauth2_client_id`, `oauth2_auth_url`, and `oauth2_token_url` empty.
The server attempts discovery in this order:
1. RFC 9728 — Protected Resource Metadata
1. RFC 8414 — Authorization Server Metadata
@@ -128,23 +125,20 @@ A static key sent as a header on every request.
### Custom headers
Arbitrary key-value header pairs sent on every request. At least one header
is required when this mode is selected.
Arbitrary key-value header pairs sent on every request.
At least one header is required when this mode is selected.
### User OIDC Identity
Forwards the calling user's OIDC access token (stored in
`user_links.oauth_access_token`) to the MCP server as an
`Authorization: Bearer <token>` header. The token is refreshed
transparently before each request if it has expired or is close to
expiring.
Forwards the calling user's OIDC access token (stored in `user_links.oauth_access_token`) to the MCP server as an `Authorization: Bearer <token>` header.
The token is refreshed transparently before each request if it has expired or is close to expiring.
No admin-configurable fields. No per-user connect step.
No admin-configurable fields.
No per-user connect step.
**Limitation**: this auth mode only works for users who authenticated to
Coder via OIDC. Users who logged in with password or GitHub will see
requests sent without an authorization header, and the upstream MCP
server is expected to respond with 401.
**Limitation**:
this auth mode only works for users who authenticated to Coder via OIDC.
Users who logged in with password or GitHub will see requests sent without an authorization header, and the upstream MCP server is expected to respond with 401.
## Tool governance
@@ -234,36 +228,28 @@ Enable it only for first-party or trusted internal MCP servers.
| OAuth2 disconnect | Token owner |
| Manage ACLs | Organization admin |
Disconnect only needs a valid session: users removed from the ACL or the
organization can still delete their stored token and revoke the provider
grant.
Disconnect only needs a valid session: users removed from the ACL or the organization can still delete their stored token and revoke the provider grant.
Members only see enabled servers in their own organizations. Sensitive fields
such as API keys and client secrets are redacted in API responses.
Members only see enabled servers in their own organizations.
Sensitive fields such as API keys and client secrets are redacted in API responses.
Users with access to an organization's MCP servers can open the **MCP servers**
settings page. Coder enables the edit controls for the users who can manage the
selected organization's servers.
Users with access to an organization's MCP servers can open the **MCP servers** settings page.
Coder enables the edit controls for the users who can manage the selected organization's servers.
Only deployment administrators can add or update a server that uses **User OIDC Identity** authentication.
Refer to [Organization scope](./organizations.md) for the organization scope of MCP servers and the upgrade behavior.
### Access control
Each server has a group and user ACL that controls which members can see and
use it. New servers grant read access to the organization's **Everyone** group,
so all members have access by default. Members with MCP server share permission
can open **Server actions** > **Manage permissions** to remove the Everyone
entry and grant specific groups or users instead. They can also manage the ACL
through the API
(`GET`/`PATCH /api/v2/organizations/{organization}/mcp-servers/{id}/acl`).
ACL management is available in all editions and does not require a Premium
license. ACL changes are recorded in the audit log.
Each server has a group and user ACL that controls which members can see and use it.
New servers grant read access to the organization's **Everyone** group, so all members have access by default.
Members with MCP server share permission can open **Server actions** > **Manage permissions** to remove the Everyone entry and grant specific groups or users instead.
They can also manage the ACL through the API (`GET`/`PATCH /api/v2/organizations/{organization}/mcp-servers/{id}/acl`).
ACL management is available in all editions and does not require a Premium license.
ACL changes are recorded in the audit log.
Revoking access stops a member from newly selecting the server in any chat,
but chats that already have the server selected keep using it, the same way
existing workspaces keep running after template access is revoked. To cut
off existing chats as well, disable or delete the server.
Revoking access stops a member from newly selecting the server in any chat, but chats that already have the server selected keep using it, the same way existing workspaces keep running after template access is revoked.
To cut off existing chats as well, disable or delete the server.
## Inline MCP servers (experimental)
@@ -117,9 +117,8 @@ You can add only the members and the groups of the organization that owns the mo
To change a model's access list, open **Model actions** > **Manage permissions** on the **Models** page.
Refer to [Manage model permissions](../models.md#manage-model-permissions) for the steps.
To change an MCP server's access list, open **Server actions** >
**Manage permissions** on the **MCP servers** page. Refer to
[Access control](./mcp-servers.md#access-control) for details.
To change an MCP server's access list, open **Server actions** > **Manage permissions** on the **MCP servers** page.
Refer to [Access control](./mcp-servers.md#access-control) for details.
You can also use the API:
@@ -8,18 +8,17 @@ Coder controls agent spend with AI Gateway budgets, and surfaces the resulting s
Coder Agents spend is controlled by AI Gateway budgets, which cap all AI Gateway usage (including Coder Agents chats) per user over the budget period.
- **Group budgets**: set a budget for a group from the group's settings page.
- **Group budgets**:
set a budget for a group from the group's settings page.
The deployment budget policy resolves which group budget applies when a user belongs to multiple budgeted groups, which defaults to the group with the highest budget.
- **Per-user overrides**: set a custom budget for an individual user, attributed to one of their groups.
- **Per-user overrides**:
set a custom budget for an individual user, attributed to one of their groups.
Per-user overrides take priority over group budgets.
The deployment flags `--ai-budget-policy` and `--ai-budget-period` currently
support only `highest` and `month`. `highest` selects the group with the
largest spend limit, and `month` resets spend at the start of each UTC
calendar month. A user who belongs to no budgeted group falls back to the
Everyone group, which has no budget unless one is set for it. There is no
deployment-wide budget amount, and a configured spend limit cannot exceed
$1,000,000 per member per period.
The deployment flags `--ai-budget-policy` and `--ai-budget-period` currently support only `highest` and `month`.
`highest` selects the group with the largest spend limit, and `month` resets spend at the start of each UTC calendar month.
A user who belongs to no budgeted group falls back to the Everyone group, which has no budget unless one is set for it.
There is no deployment-wide budget amount, and a configured spend limit cannot exceed $1,000,000 per member per period.
> [!IMPORTANT]
> Budget controls in the Coder UI, the group budget endpoints (`/api/v2/groups/{group}/ai/budget`), and the AI spend status and reporting endpoints all require the AI Gateway entitlement.
@@ -59,9 +58,12 @@ Spend is shown where it is actionable:
- **Admin settings** > **AI** > **User spend**: total and per-user AI Gateway spend for the selected organization and reporting period.
If you can also view AI sessions, you can filter it by provider, model, and client.
-->
- **Agents page and user menu**: the signed-in user's spend against their budget, as described previously.
- **Group settings**: each member's spend against the group's budget, for admins who can manage the group.
- **Chat summary panel**: the cost of one chat tree, on a chat's Summary tab.
- **Agents page and user menu**:
the signed-in user's spend against their budget, as described previously.
- **Group settings**:
each member's spend against the group's budget, for admins who can manage the group.
- **Chat summary panel**:
the cost of one chat tree, on a chat's Summary tab.
A subagent reports the total for its whole tree, including the chat that started it.
For organization spend exports, refer to [AI Gateway spend export](../../ai-gateway/cost-controls.md#spend-export).
@@ -8,8 +8,7 @@ The agent provisions one when missing tools, skills, MCP integrations, or contex
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.
Administrators can [restrict which templates the agent can use](#restrict-available-templates).
This guide covers best practices for creating templates that are discoverable
and useful to Coder Agents.
This guide covers best practices for creating templates that are discoverable and useful to Coder Agents.
## Restrict available templates
@@ -37,8 +36,7 @@ The agent's `list_templates` tool ranks matches by query relevance first, then b
It does not inspect the template's Terraform to understand what infrastructure is inside.
For the ranking details, refer to [list_templates](../tools.md#how-templates-are-ranked).
This means the template description is the single most important factor in
whether the agent picks the right template for a given task.
This means the template description is the single most important factor in whether the agent picks the right template for a given task.
### What to include
@@ -46,8 +44,7 @@ A good template description tells the agent:
- What language, framework, or stack the template is for.
- Which repository or service it targets, if applicable.
- What type of work it supports (e.g., backend services, frontend apps, data
pipelines).
- What type of work it supports (e.g., backend services, frontend apps, data pipelines).
### Examples
@@ -72,25 +69,17 @@ A good template description tells the agent:
### Template display names
Display names appear in the template selector and in the agent's tool output.
Use readable, descriptive names rather than slugs or internal codes. A display
name like "Python Backend (Payments)" is more useful to both humans and the
agent than `py-be-pay-v3`.
Use readable, descriptive names rather than slugs or internal codes.
A display name like "Python Backend (Payments)" is more useful to both humans and the agent than `py-be-pay-v3`.
### Put routing context near the top of the README
The short `description` also appears on the dashboard templates page, so it is
intentionally limited to fewer than 128 characters. When that is not enough
room to fully describe a template for the agent, put the most important routing
context at the top of the template's `README.md` body, immediately after any
frontmatter block.
The short `description` also appears on the dashboard templates page, so it is intentionally limited to fewer than 128 characters.
When that is not enough room to fully describe a template for the agent, put the most important routing context at the top of the template's `README.md` body, immediately after any frontmatter block.
The chat agent's template listing includes a bounded README excerpt (roughly the
first 1,000 characters), and template detail includes the README (up to roughly
8,000 characters). Both are reduced to plain text: frontmatter is stripped,
link text is kept while link URLs are dropped, images and badges are dropped
entirely, and code blocks and tables are preserved as text. Use the opening
section to explain when to choose this template, what it is *not* for, and the
specific stack or services it provides.
The chat agent's template listing includes a bounded README excerpt (roughly the first 1,000 characters), and template detail includes the README (up to roughly 8,000 characters).
Both are reduced to plain text: frontmatter is stripped, link text is kept while link URLs are dropped, images and badges are dropped entirely, and code blocks and tables are preserved as text.
Use the opening section to explain when to choose this template, what it is *not* for, and the specific stack or services it provides.
```md
---
@@ -107,41 +96,34 @@ cluster access and configurable CPU, memory, and persistent storage. It is not
intended for standalone VM or local Docker workflows.
```
The README is stored with the template version when you run
`coder templates push`, so updating it is part of your normal template
workflow. The short `description` still drives the initial template listing, so
keep it accurate and specific as well.
The README is stored with the template version when you run `coder templates push`, so updating it is part of your normal template workflow.
The short `description` still drives the initial template listing, so keep it accurate and specific as well.
## Create dedicated agent templates
Rather than reusing your standard interactive developer templates for agent
workloads, consider creating dedicated templates with configurations
appropriate for unattended, agent-driven work.
Rather than reusing your standard interactive developer templates for agent workloads, consider creating dedicated templates with configurations appropriate for unattended, agent-driven work.
Agent templates differ from developer templates in several ways:
- **No IDE tooling needed.** The agent connects via the workspace daemon's HTTP
API, not through VS Code or JetBrains. You can omit IDE-specific
configuration, extensions, and desktop tools.
- **Stricter network policies.** Agent workspaces typically need access to only
the control plane and your git provider. You can apply tighter egress rules
than you would for a developer who needs to browse documentation or access
additional services.
- **Reduced permissions.** Agent workspaces can use scoped credentials with
fewer permissions than a developer's interactive session.
- **No IDE tooling needed.**
The agent connects via the workspace daemon's HTTP API, not through VS Code or JetBrains.
You can omit IDE-specific configuration, extensions, and desktop tools.
- **Stricter network policies.**
Agent workspaces typically need access to only the control plane and your git provider.
You can apply tighter egress rules than you would for a developer who needs to browse documentation or access additional services.
- **Reduced permissions.**
Agent workspaces can use scoped credentials with fewer permissions than a developer's interactive session.
See [Creating templates](../../../admin/templates/creating-templates.md) for
step-by-step instructions on creating templates via the UI, CLI, or CI/CD.
See [Creating templates](../../../admin/templates/creating-templates.md) for step-by-step instructions on creating templates via the UI, CLI, or CI/CD.
## Configure network boundaries
The workspace is the network boundary for the agent. If you want to control
what the agent can access, control what the workspace can access.
The workspace is the network boundary for the agent.
If you want to control what the agent can access, control what the workspace can access.
This is a deliberate architectural advantage of running the agent loop in the
control plane. Because all AI functionality — LLM inference, tool dispatch,
chat state — lives in the control plane, agent workspaces do not need outbound
access to any LLM provider. The workspace only needs to reach:
This is a deliberate architectural advantage of running the agent loop in the control plane.
Because all AI functionality (LLM inference, tool dispatch, chat state) lives in the control plane, agent workspaces do not need outbound access to any LLM provider.
The workspace only needs to reach:
- **The Coder control plane** — required for the workspace daemon to function.
- **Your git provider** — required for push and pull operations.
@@ -150,82 +132,65 @@ Everything else can be blocked at the network level.
### Why network boundaries are more effective than process-level controls
Traditional approaches to restricting agent behavior — such as blocking
specific commands at the process level — are difficult to enforce reliably. An
agent executing arbitrary shell commands can find alternative paths to achieve
the same result (aliasing commands, writing scripts, using different tools).
Traditional approaches to restricting agent behavior (such as blocking specific commands at the process level) are difficult to enforce reliably.
An agent executing arbitrary shell commands can find alternative paths to achieve the same result (aliasing commands, writing scripts, using different tools).
Network-level boundaries are more robust because they operate below the process
layer. If the workspace cannot reach an external service, it does not matter
what command the agent runs — the connection simply fails. This provides a
firmer security guarantee than trying to restrict individual process behaviors.
Network-level boundaries are more robust because they operate below the process layer.
If the workspace cannot reach an external service, it does not matter what command the agent runs, because the connection simply fails.
This provides a firmer security guarantee than trying to restrict individual process behaviors.
See [Architecture](../architecture.md#workspaces-can-be-fully-network-isolated)
for more detail on the security model.
See [Architecture](../architecture.md#workspaces-can-be-fully-network-isolated) for more detail on the security model.
## Scope permissions and credentials
> [!WARNING]
> By default, agent workspaces inherit the same network access and
> permissions as any workspace the user creates manually. If your templates
> do not explicitly restrict outbound network access, the agent has full
> internet access from the workspace. Review the guidance below and in
> [Configure network boundaries](#configure-network-boundaries) to lock
> down agent workloads appropriately.
> By default, agent workspaces inherit the same network access and permissions as any workspace the user creates manually.
> If your templates do not explicitly restrict outbound network access, the agent has full internet access from the workspace.
> Review the guidance below and in [Configure network boundaries](#configure-network-boundaries) to lock down agent workloads appropriately.
The agent operates with the same identity and permissions as the user who
submitted the prompt. There is no privilege escalation — if a developer cannot
access a resource through the Coder dashboard, the agent cannot access it
either.
The agent operates with the same identity and permissions as the user who submitted the prompt.
There is no privilege escalation.
If a developer cannot access a resource through the Coder dashboard, the agent cannot access it either.
### External service credentials
When agent workspaces need access to external services (git providers, package
registries, artifact stores), configure credentials with the minimum scope
required:
When agent workspaces need access to external services (git providers, package registries, artifact stores), configure credentials with the minimum scope required:
- **Use separate tokens for agent templates.** Rather than sharing the same
broad-scope token used by developer workspaces, create a dedicated token with
only the permissions the agent needs (e.g., read/write access to specific
repositories, no admin access).
- **Configure external auth at the template level.** Use Coder's
[external authentication](../../../admin/external-auth.md) to provide scoped
git credentials. The agent uses the same external auth flow as any other
workspace, so credentials are managed centrally.
- **Avoid injecting long-lived secrets.** Prefer short-lived tokens or
credential helpers over static API keys baked into the template image.
- **Use separate tokens for agent templates.**
Rather than sharing the same broad-scope token used by developer workspaces, create a dedicated token with only the permissions the agent needs (e.g., read/write access to specific repositories, no admin access).
- **Configure external auth at the template level.**
Use Coder's [external authentication](../../../admin/external-auth.md) to provide scoped git credentials.
The agent uses the same external auth flow as any other workspace, so credentials are managed centrally.
- **Avoid injecting long-lived secrets.**
Prefer short-lived tokens or credential helpers over static API keys baked into the template image.
### Git identity
Every git operation the agent performs — commits, pushes, pull requests — is
attributed to the user who submitted the prompt. This happens through the
existing git authentication configured in your Coder deployment. There is no
shared bot account.
Every git operation the agent performs (commits, pushes, pull requests) is attributed to the user who submitted the prompt.
This happens through the existing git authentication configured in your Coder deployment.
There is no shared bot account.
Ensure your templates configure git with the appropriate author information so
that commits are properly attributed. The agent does not override git
configuration — it uses whatever is set in the workspace environment.
Ensure your templates configure git with the appropriate author information so that commits are properly attributed.
The agent does not override git configuration.
It uses whatever is set in the workspace environment.
## Design template parameters for automation
The agent can read template parameters — including their names, descriptions,
and defaults — and fill them in when creating a workspace. Well-designed
parameters help the agent provision the right infrastructure without human
intervention.
The agent can read template parameters (including their names, descriptions, and defaults) and fill them in when creating a workspace.
Well-designed parameters help the agent provision the right infrastructure without human intervention.
### Keep parameters simple
- **Use sensible defaults.** The agent performs best when most parameters have
reasonable defaults and only a few require explicit selection. A template
with ten required parameters and no defaults forces the agent to guess.
- **Minimize required parameters.** If a parameter is not essential for the
agent's use case, give it a default value or make it optional.
- **Use sensible defaults.**
The agent performs best when most parameters have reasonable defaults and only a few require explicit selection.
A template with ten required parameters and no defaults forces the agent to guess.
- **Minimize required parameters.**
If a parameter is not essential for the agent's use case, give it a default value or make it optional.
### Write descriptive parameter metadata
The agent reads `display_name` and `description` fields to understand what a
parameter controls. Treat these the same way you treat template descriptions —
be specific and use natural language.
The agent reads `display_name` and `description` fields to understand what a parameter controls.
Treat these the same way you treat template descriptions: be specific and use natural language.
```tf
data "coder_parameter" "region" {
@@ -237,47 +202,35 @@ data "coder_parameter" "region" {
}
```
A description like "AWS region" is less useful to the agent than one that
explains when to use each option.
A description like "AWS region" is less useful to the agent than one that explains when to use each option.
### Avoid opaque identifiers
Parameters with values like `ami-0abcdef1234567890` or `subnet-12345` are
difficult for the agent to reason about. Where possible, use human-readable
option labels or map opaque IDs to descriptive names using Terraform locals.
Parameters with values like `ami-0abcdef1234567890` or `subnet-12345` are difficult for the agent to reason about.
Where possible, use human-readable option labels or map opaque IDs to descriptive names using Terraform locals.
For full parameter reference — including types, validation, mutability, and
workspace presets — see
[Parameters](../../../admin/templates/extending-templates/parameters.md).
[Dynamic parameters](../../../admin/templates/extending-templates/dynamic-parameters.md)
add conditional form controls and identity-aware defaults for more advanced
use cases.
For full parameter reference (including types, validation, mutability, and workspace presets), see [Parameters](../../../admin/templates/extending-templates/parameters.md).
[Dynamic parameters](../../../admin/templates/extending-templates/dynamic-parameters.md) add conditional form controls and identity-aware defaults for more advanced use cases.
## Pre-install tools and dependencies
Agent workspaces should be ready to work immediately after provisioning. The
agent does not know how to install your organization's specific toolchain, and
time spent installing dependencies is time not spent on the task.
Agent workspaces should be ready to work immediately after provisioning.
The agent does not know how to install your organization's specific toolchain, and time spent installing dependencies is time not spent on the task.
### What to pre-install
- **Language runtimes and build tools** for the target stack (e.g., Go, Node,
Python, Maven).
- **Common CLI tools** the agent is likely to use: `git`, `curl`, `jq`, `make`,
`docker` (if applicable).
- **Project-specific dependencies.** If the template targets a specific
repository, consider pre-installing the project's dependencies or running the
setup script as part of workspace startup.
- **Git configuration.** Ensure `git` is configured with credentials and author
information so the agent can commit and push without additional setup.
- **Language runtimes and build tools** for the target stack (e.g., Go, Node, Python, Maven).
- **Common CLI tools** the agent is likely to use: `git`, `curl`, `jq`, `make`, `docker` (if applicable).
- **Project-specific dependencies.**
If the template targets a specific repository, consider pre-installing the project's dependencies or running the setup script as part of workspace startup.
- **Git configuration.**
Ensure `git` is configured with credentials and author information so the agent can commit and push without additional setup.
For guidance on building and maintaining workspace images, see
[Image management](../../../admin/templates/managing-templates/image-management.md).
For guidance on building and maintaining workspace images, see [Image management](../../../admin/templates/managing-templates/image-management.md).
### Set a meaningful working directory
If the template targets a specific repository, pre-clone it and set the
working directory so the agent starts in the right place:
If the template targets a specific repository, pre-clone it and set the working directory so the agent starts in the right place:
```tf
resource "coder_agent" "main" {
@@ -287,31 +240,23 @@ resource "coder_agent" "main" {
}
```
This avoids a round trip where the agent needs to figure out where the code
lives before it can begin working.
This avoids a round trip where the agent needs to figure out where the code lives before it can begin working.
## Use prebuilt workspaces to reduce provisioning time
Workspace provisioning is the primary source of latency when the agent begins a
task. Templates with complex infrastructure, large images, or lengthy startup
scripts can take minutes to provision — time where the developer is waiting
and the agent is idle.
Workspace provisioning is the primary source of latency when the agent begins a task.
Templates with complex infrastructure, large images, or lengthy startup scripts can take minutes to provision (time where the developer is waiting and the agent is idle).
[Prebuilt workspaces](../../../admin/templates/extending-templates/prebuilt-workspaces.md)
eliminate this delay by maintaining a pool of ready-to-use workspaces for
specific parameter presets. When the agent creates a workspace that matches a
preset, Coder assigns an already-running prebuilt workspace instead of
provisioning from scratch. The agent can begin working immediately.
[Prebuilt workspaces](../../../admin/templates/extending-templates/prebuilt-workspaces.md) eliminate this delay by maintaining a pool of ready-to-use workspaces for specific parameter presets.
When the agent creates a workspace that matches a preset, Coder assigns an already-running prebuilt workspace instead of provisioning from scratch.
The agent can begin working immediately.
## Checklist
Use this as a quick reference when creating or updating templates for Coder
Agents:
Use this as a quick reference when creating or updating templates for Coder Agents:
- Template has a specific, natural-language description that includes
language, framework, and target project or service.
- README opening section provides longer routing context when the short
description is not enough.
- Template has a specific, natural-language description that includes language, framework, and target project or service.
- README opening section provides longer routing context when the short description is not enough.
- Display name is readable and descriptive.
- Network egress is restricted to the control plane and git provider.
- External service credentials use minimal-scope tokens.
@@ -3,8 +3,8 @@ title: Virtual desktop
---
> [!NOTE]
> This feature is experimental. Pin a release before broad rollout and review
> the release notes before upgrading.
> This feature is experimental.
> Pin a release before broad rollout and review the release notes before upgrading.
## Enable the experiment
@@ -20,25 +20,21 @@ CODER_EXPERIMENTS=chat-virtual-desktop
## What it does
Lets agents drive a graphical desktop inside the workspace through
`spawn_agent` with `type=computer_use` (screenshots, mouse, keyboard).
Lets agents drive a graphical desktop inside the workspace through `spawn_agent` with `type=computer_use` (screenshots, mouse, keyboard).
## Configuration
Once the experiment is enabled, configure the computer-use provider under
**Admin settings** > **AI** > **Coder Agents** > **Deployment settings**.
Once the experiment is enabled, configure the computer-use provider under **Admin settings** > **AI** > **Coder Agents** > **Deployment settings**.
Use the **Virtual desktop** card.
Choose a **Computer use provider** (Anthropic or OpenAI). Virtual desktop also requires:
Choose a **Computer use provider** (Anthropic or OpenAI).
Virtual desktop also requires:
- The [portabledesktop](https://registry.coder.com/modules/coder/portabledesktop)
module installed in the workspace template.
- An API key for the selected provider configured under the **Providers**
sidebar item.
- The [portabledesktop](https://registry.coder.com/modules/coder/portabledesktop) module installed in the workspace template.
- An API key for the selected provider configured under the **Providers** sidebar item.
The Anthropic and OpenAI computer-use models are fixed by Coder per provider
and are not selectable from this UI. Anthropic is the default when no
provider is set.
The Anthropic and OpenAI computer-use models are fixed by Coder per provider and are not selectable from this UI.
Anthropic is the default when no provider is set.
The same configuration is available at:
+123 -172
View File
@@ -6,13 +6,9 @@ title: Migrate from the Tasks API to the Chats API
> Coder Tasks was deprecated in Coder v2.34 and has been removed, including the Tasks API (`/api/v2/tasks`).
> To read about Coder Tasks, use a previous version of the Coder documentation, from a release before v2.36.
The Tasks API (`/api/v2/tasks`) and the
[Chats API](../../reference/api/chats.md) (`/api/v2/chats`) serve similar
goals (programmatic access to AI-powered coding agents) but they differ
significantly in architecture, capabilities, and usage patterns.
The Tasks API (`/api/v2/tasks`) and the [Chats API](../../reference/api/chats.md) (`/api/v2/chats`) serve similar goals (programmatic access to AI-powered coding agents) but they differ significantly in architecture, capabilities, and usage patterns.
This guide walks you through updating your integrations from the Tasks API
to the Chats API.
This guide walks you through updating your integrations from the Tasks API to the Chats API.
## When to migrate
@@ -22,9 +18,8 @@ Coder Tasks has been removed, so requests to the Tasks API fail.
If your integrations still call the Tasks API, migrate to the Chats API and [Coder Agents](./index.md).
Coder Agents runs the agent loop in the Coder control plane rather than inside the workspace, and is the supported path going forward.
The two systems are not interchangeable. Tasks and Chats are separate
resources with separate APIs, so plan to update your integrations rather
than expecting a drop-in replacement.
The two systems are not interchangeable.
Tasks and Chats are separate resources with separate APIs, so plan to update your integrations rather than expecting a drop-in replacement.
## Key architectural differences
@@ -65,23 +60,22 @@ The table below maps each Tasks API endpoint to its Chats API equivalent.
### 1. Configure an LLM provider
With Tasks, LLM credentials are injected into the workspace as environment
variables (e.g. `ANTHROPIC_API_KEY`). With Coder Agents, credentials are
configured once in the control plane:
With Tasks, LLM credentials are injected into the workspace as environment variables (e.g. `ANTHROPIC_API_KEY`).
With Coder Agents, credentials are configured once in the control plane:
1. Navigate to **Admin settings** > **AI** and select **Providers**.
1. Add or update a provider with its credentials and upstream endpoint, then
save it.
1. Add or update a provider with its credentials and upstream endpoint, then save it.
1. Navigate to **Admin settings** > **AI** > **Models**.
1. Select the correct organization.
1. Add at least one model, and set it as the default.
You no longer pass API keys in template variables or workspace environment. See https://coder.com/docs/ai-coder/agents/getting-started for more information.
You no longer pass API keys in template variables or workspace environment.
See https://coder.com/docs/ai-coder/agents/getting-started for more information.
### 2. Update task creation calls
**Tasks API**. You specify the user, template version, and a prompt
string:
**Tasks API**.
You specify the user, template version, and a prompt string:
```sh
# Tasks API: create a task
@@ -94,8 +88,9 @@ curl -X POST https://coder.example.com/api/v2/tasks/me \
}'
```
**Chats API**. You send structured content parts. No template or user
path segment is required:
**Chats API**.
You send structured content parts.
No template or user path segment is required:
```sh
# Chats API: create a chat
@@ -112,24 +107,22 @@ curl -X POST https://coder.example.com/api/v2/chats \
Key differences:
- The `{user}` path parameter is removed. The authenticated user is
inferred from the session token.
- `organization_id` is required in the request body. The caller must be a
member of that organization.
- The prompt is now an array of `ChatInputPart` objects (supporting `text`,
`file`, and `file-reference` types) instead of a plain string.
- `template_version_id` and `template_version_preset_id` are removed. The
agent selects a template automatically based on the prompt and available
template descriptions. To pin to a specific workspace, pass
`workspace_id` instead.
- Optionally pass `model_config_id` to override the default model, or
`mcp_server_ids` to attach MCP servers.
- The `{user}` path parameter is removed.
The authenticated user is inferred from the session token.
- `organization_id` is required in the request body.
The caller must be a member of that organization.
- The prompt is now an array of `ChatInputPart` objects (supporting `text`, `file`, and `file-reference` types) instead of a plain string.
- `template_version_id` and `template_version_preset_id` are removed.
The agent selects a template automatically based on the prompt and available template descriptions.
To pin to a specific workspace, pass `workspace_id` instead.
- Optionally pass `model_config_id` to override the default model, or `mcp_server_ids` to attach MCP servers.
- Optionally pass `title` to set the chat's title.
A title you set is kept; automatic title generation runs only when `title` is omitted.
### 3. Update follow-up message calls
**Tasks API**. Follow-ups use the send endpoint with a plain string:
**Tasks API**.
Follow-ups use the send endpoint with a plain string:
```sh
# Tasks API: send input
@@ -139,7 +132,8 @@ curl -X POST https://coder.example.com/api/v2/tasks/me/my-task/send \
-d '{"input": "Now also update the integration tests"}'
```
**Chats API**. Follow-ups use the messages endpoint with content parts:
**Chats API**.
Follow-ups use the messages endpoint with content parts:
```sh
# Chats API: send a message
@@ -154,14 +148,14 @@ curl -X POST \
}'
```
The Chats API supports message queuing. If the agent is busy, the message
is queued automatically and delivered when the agent finishes its current
step. The response includes a `queued` field indicating whether the message
was delivered immediately or queued.
The Chats API supports message queuing.
If the agent is busy, the message is queued automatically and delivered when the agent finishes its current step.
The response includes a `queued` field indicating whether the message was delivered immediately or queued.
### 4. Switch from log polling to WebSocket streaming
**Tasks API**. You poll for logs:
**Tasks API**.
You poll for logs:
```sh
# Tasks API: get logs
@@ -169,14 +163,15 @@ curl https://coder.example.com/api/v2/tasks/me/my-task/logs \
-H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```
**Chats API**. You open a one-way WebSocket connection:
**Chats API**.
You open a one-way WebSocket connection:
```txt
GET wss://coder.example.com/api/v2/chats/{chat}/stream
```
The WebSocket sends JSON envelopes with a `type` field (`"ping"`,
`"data"`, or `"error"`). Data envelopes contain batches of events:
The WebSocket sends JSON envelopes with a `type` field (`"ping"`, `"data"`, or `"error"`).
Data envelopes contain batches of events:
| Event type | Description |
|----------------|---------------------------------------------------------|
@@ -187,13 +182,12 @@ The WebSocket sends JSON envelopes with a `type` field (`"ping"`,
| `retry` | The control plane is retrying a failed LLM call |
| `queue_update` | The queued message list changed |
Use `after_id` as a query parameter when reconnecting to skip messages the
client already has.
Use `after_id` as a query parameter when reconnecting to skip messages the client already has.
### 5. Update status handling
Task and chat statuses use different values. The Chats API status set is
defined in `codersdk.ChatStatus`:
Task and chat statuses use different values.
The Chats API status set is defined in `codersdk.ChatStatus`:
| Tasks API status | Chats API status | Notes |
|------------------|-------------------|---------------------------------------------------------------------------------------------------------------------|
@@ -206,14 +200,12 @@ defined in `codersdk.ChatStatus`:
| n/a | `interrupting` | An interrupt was requested and the agent is winding down the current run. |
The Chats API uses `waiting` as the default idle state (not `complete`).
A chat enters `waiting` when it is first created (before any message is
queued) and again whenever a run finishes or is interrupted, so treat
`waiting` as "the agent is not currently working" rather than only "the
agent just finished."
A chat enters `waiting` when it is first created (before any message is queued) and again whenever a run finishes or is interrupted, so treat `waiting` as "the agent is not currently working" rather than only "the agent just finished."
### 6. Replace delete with archive
The Tasks API uses `DELETE` to remove a task. The Chats API uses archiving:
The Tasks API uses `DELETE` to remove a task.
The Chats API uses archiving:
```diff
- curl -X DELETE https://coder.example.com/api/v2/tasks/me/my-task \
@@ -229,7 +221,8 @@ Archived chats can be restored by setting `archived` to `false`.
### 7. Replace pause/resume with interrupt and messaging
**Tasks API**. Pause and resume stop and start the workspace:
**Tasks API**.
Pause and resume stop and start the workspace:
```sh
# Tasks API
@@ -242,8 +235,9 @@ curl -X POST \
-H "Coder-Session-Token: $CODER_SESSION_TOKEN"
```
**Chats API**. Interrupt stops the current agent loop. Sending a new
message resumes processing:
**Chats API**.
Interrupt stops the current agent loop.
Sending a new message resumes processing:
```sh
# Chats API: interrupt
@@ -263,25 +257,16 @@ curl -X POST \
}'
```
In the Tasks API, pausing stops the workspace and frees compute. In the
Chats API, interrupt stops the agent loop in the control plane; the
workspace may remain running. The workspace lifecycle is managed
independently.
In the Tasks API, pausing stops the workspace and frees compute.
In the Chats API, interrupt stops the agent loop in the control plane; the workspace may remain running.
The workspace lifecycle is managed independently.
### 8. Update GitHub Actions integrations
If you use the
[Create Task Action](https://github.com/coder/create-task-action) GitHub
Action, replace it with the dedicated
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action).
It handles the API call, the GitHub user lookup, and the optional issue
comment, so most existing workflows can swap one `uses:` line and rename
a few inputs.
If you use the [Create Task Action](https://github.com/coder/create-task-action) GitHub Action, replace it with the dedicated [`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action).
It handles the API call, the GitHub user lookup, and the optional issue comment, so most existing workflows can swap one `uses:` line and rename a few inputs.
We are actively shipping new features for `create-agent-chat-action`, so
pin to a major version (for example `@v0`) and watch the
[releases](https://github.com/coder/create-agent-chat-action/releases) for
updates.
We are actively shipping new features for `create-agent-chat-action`, so pin to a major version (for example `@v0`) and watch the [releases](https://github.com/coder/create-agent-chat-action/releases) for updates.
```diff
# .github/workflows/triage-bug.yaml
@@ -322,18 +307,14 @@ jobs:
Key differences from the Tasks GHA:
- No `coder-template-name` or `coder-task-name-prefix`. The agent
auto-provisions a workspace; pass `workspace-id` if you want to pin to
an existing workspace instead.
- No `coder-template-name` or `coder-task-name-prefix`.
The agent auto-provisions a workspace; pass `workspace-id` if you want to pin to an existing workspace instead.
- The prompt input is renamed from `coder-task-prompt` to `chat-prompt`.
- LLM credentials are no longer passed through the template. They are
configured in the Coder control plane.
- LLM credentials are no longer passed through the template.
They are configured in the Coder control plane.
- No user mapping: the Tasks GHA's `github-user-id` input has no equivalent, because the chat is always owned by the user the `coder-token` belongs to and the Chats API has no owner override.
See the
[action README](https://github.com/coder/create-agent-chat-action#inputs)
for the full input and output reference, including the `existing-chat-id`
input for sending follow-up messages on a previous chat.
See the [action README](https://github.com/coder/create-agent-chat-action#inputs) for the full input and output reference, including the `existing-chat-id` input for sending follow-up messages on a previous chat.
## Template recommendations
@@ -342,62 +323,55 @@ input for sending follow-up messages on a previous chat.
these against their own deployment patterns before adopting them. -->
> [!NOTE]
> This section contains recommendations that may evolve as Coder Agents
> matures. Review these against your deployment requirements.
> This section contains recommendations that may evolve as Coder Agents matures.
> Review these against your deployment requirements.
With Coder Tasks, every task-capable template requires specific Terraform
resources (`coder_ai_task`, `coder_task`, agent modules, and LLM API
keys). With Coder Agents, templates no longer need any of these. The
agent runs in the control plane and treats the workspace as plain compute.
With Coder Tasks, every task-capable template requires specific Terraform resources (`coder_ai_task`, `coder_task`, agent modules, and LLM API keys).
With Coder Agents, templates no longer need any of these.
The agent runs in the control plane and treats the workspace as plain compute.
However, **we still recommend creating dedicated templates for agent
workloads** rather than reusing your standard developer templates
unchanged. The reasons are different from Tasks, but the principle holds:
However, **we still recommend creating dedicated templates for agent workloads** rather than reusing your standard developer templates unchanged.
The reasons are different from Tasks, but the principle holds:
### Why dedicated agent templates still matter
- **Network boundaries.** Agent workspaces inherit whatever network access
the template allows. Because the agent does not need outbound access to
LLM providers (that happens in the control plane), you can lock down
agent templates to only reach the Coder control plane and your git
provider. Standard developer templates typically allow broader access.
- **No IDE tooling overhead.** The agent connects via the workspace
daemon's HTTP API, not through VS Code or JetBrains. Removing IDE
extensions, desktop environments, and similar tooling from agent
templates reduces image size and startup time.
- **Scoped credentials.** Agent workloads may warrant more restrictive
credentials than interactive developer sessions. A dedicated template
lets you provide a separate, narrower-scoped git token or service
account without affecting your developers' workflow.
- **Cost control.** Agent workspaces can often use smaller compute
resources than developer workspaces since they don't need to run IDEs,
language servers, or other interactive tooling. A dedicated template lets
you right-size the infrastructure.
- **Network boundaries.**
Agent workspaces inherit whatever network access the template allows.
Because the agent does not need outbound access to LLM providers (that happens in the control plane), you can lock down agent templates to only reach the Coder control plane and your git provider.
Standard developer templates typically allow broader access.
- **No IDE tooling overhead.**
The agent connects via the workspace daemon's HTTP API, not through VS Code or JetBrains.
Removing IDE extensions, desktop environments, and similar tooling from agent templates reduces image size and startup time.
- **Scoped credentials.**
Agent workloads may warrant more restrictive credentials than interactive developer sessions.
A dedicated template lets you provide a separate, narrower-scoped git token or service account without affecting your developers' workflow.
- **Cost control.**
Agent workspaces can often use smaller compute resources than developer workspaces since they don't need to run IDEs, language servers, or other interactive tooling.
A dedicated template lets you right-size the infrastructure.
### What to include in agent templates
<!-- TODO: Expand this section with concrete Terraform examples once
template patterns stabilize. -->
- **Clear descriptions.** The agent selects templates by reading names and
descriptions. Include the target language, framework, repository, and
type of work. For example: *"Python backend services for the payments
repo. Includes Poetry, Python 3.12, and PostgreSQL."*
- **Pre-installed dependencies.** Language runtimes, build tools, `git`,
and project-specific dependencies should be baked into the image. Time
the agent spends installing tools is time not spent on the task.
- **Git configuration.** Ensure `git` is configured with credentials and
author information so the agent can commit and push without additional
setup.
- **Minimal parameters.** Use sensible defaults so the agent can provision
workspaces without guessing. Avoid required parameters with opaque
identifiers.
- **Clear descriptions.**
The agent selects templates by reading names and descriptions.
Include the target language, framework, repository, and type of work.
For example: *"Python backend services for the payments repo.
Includes Poetry, Python 3.12, and PostgreSQL."*
- **Pre-installed dependencies.**
Language runtimes, build tools, `git`, and project-specific dependencies should be baked into the image.
Time the agent spends installing tools is time not spent on the task.
- **Git configuration.**
Ensure `git` is configured with credentials and author information so the agent can commit and push without additional setup.
- **Minimal parameters.**
Use sensible defaults so the agent can provision workspaces without guessing.
Avoid required parameters with opaque identifiers.
### What to remove from migrated task templates
If you are converting an existing task template for use with Coder Agents,
you can safely remove the Tasks-specific Terraform resources. They are
unused when the chat is driven by the Chats API:
If you are converting an existing task template for use with Coder Agents, you can safely remove the Tasks-specific Terraform resources.
They are unused when the chat is driven by the Chats API:
```diff
terraform {
@@ -442,15 +416,12 @@ unused when the chat is driven by the Chats API:
> Remove the Tasks-specific Terraform when you upgrade.
> Tasks and Chats can no longer run side by side: Coder no longer injects `CODER_TASK_ID` or `CODER_TASK_PROMPT`, so builds of a template that keeps the `coder_task` data source can no longer populate it.
See
[Template Optimization](./platform-controls/template-optimization.md)
for the full guide on writing discoverable descriptions, configuring
network boundaries, scoping credentials, and pre-installing dependencies.
See [Template Optimization](./platform-controls/template-optimization.md) for the full guide on writing discoverable descriptions, configuring network boundaries, scoping credentials, and pre-installing dependencies.
### Pre-creating a workspace for deterministic results
Letting the agent pick a template and provision a workspace works well
for exploratory chats. If your workflow requires deterministic results like:
Letting the agent pick a template and provision a workspace works well for exploratory chats.
If your workflow requires deterministic results like:
- Automations
- Recurring processes
@@ -460,12 +431,10 @@ pre-create the workspace yourself and attach it when you create the chat.
The pattern is two API calls:
1. Create a workspace from a specific template via
[`POST /api/v2/users/{user}/workspaces`](../../reference/api/workspaces.md#create-user-workspace).
1. Create a workspace from a specific template via [`POST /api/v2/users/{user}/workspaces`](../../reference/api/workspaces.md#create-user-workspace).
You control the template, the version, and any rich parameters.
2. Create the chat with `workspace_id` set to the workspace you just
created. The agent runs against that workspace instead of selecting
one heuristically.
2. Create the chat with `workspace_id` set to the workspace you just created.
The agent runs against that workspace instead of selecting one heuristically.
```sh
# 1. Provision the workspace from the exact template you want.
@@ -491,17 +460,12 @@ curl -s -X POST https://coder.example.com/api/v2/chats \
}"
```
This pattern is the closest analogue to the Tasks API behavior of
`template_version_id` plus `coder-template-name`: you decide which
template runs, the agent decides what to do inside it. The same approach
works from the
[`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action)
GHA, which exposes the same pin via its `workspace-id` input.
This pattern is the closest analogue to the Tasks API behavior of `template_version_id` plus `coder-template-name`: you decide which template runs, the agent decides what to do inside it.
The same approach works from the [`coder/create-agent-chat-action`](https://github.com/coder/create-agent-chat-action) GHA, which exposes the same pin via its `workspace-id` input.
## How to test your migration
After completing the migration steps above, walk through these checks to
confirm the Chats API integration is working end-to-end.
After completing the migration steps above, walk through these checks to confirm the Chats API integration is working end-to-end.
### 1. Confirm LLM provider connectivity
@@ -512,8 +476,7 @@ curl -s https://coder.example.com/api/v2/organizations/$CODER_ORGANIZATION/chats
-H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '.models[].display_name'
```
If this returns an empty list or an error, revisit
[Step 1: Configure an LLM provider](#1-configure-an-llm-provider).
If this returns an empty list or an error, revisit [Step 1: Configure an LLM provider](#1-configure-an-llm-provider).
### 2. Create a chat and confirm the response
@@ -528,23 +491,21 @@ curl -s -X POST https://coder.example.com/api/v2/chats \
}' | jq '{id, status, title}'
```
You should receive a `Chat` object with `status` set to `"running"`,
since new chats begin processing immediately. Save the `id` for
subsequent steps.
You should receive a `Chat` object with `status` set to `"running"`, since new chats begin processing immediately.
Save the `id` for subsequent steps.
### 3. Stream the response
Open a WebSocket connection to verify the agent processes the prompt and
returns a response. Using [websocat](https://github.com/vi/websocat):
Open a WebSocket connection to verify the agent processes the prompt and returns a response.
Using [websocat](https://github.com/vi/websocat):
```sh
websocat -H "Coder-Session-Token: $CODER_SESSION_TOKEN" \
"wss://coder.example.com/api/v2/chats/$CHAT_ID/stream"
```
You should see JSON envelopes with `"type": "data"` containing
`message_part` and `status` events. The chat should eventually reach
`"waiting"` status, indicating the agent completed its response.
You should see JSON envelopes with `"type": "data"` containing `message_part` and `status` events.
The chat should eventually reach `"waiting"` status, indicating the agent completed its response.
### 4. Send a follow-up message
@@ -560,36 +521,28 @@ curl -s -X POST \
}' | jq '{queued}'
```
The response should include `"queued": false` (delivered immediately) or
`"queued": true` (agent was busy. The message is queued and will be
processed next).
The response should include `"queued": false` (delivered immediately) or `"queued": true` (agent was busy.
The message is queued and will be processed next).
### 5. Test workspace provisioning
Create a workspace from your converted agent template through the
standard Coder UI, then attach it to a new chat from the chat composer:
Create a workspace from your converted agent template through the standard Coder UI, then attach it to a new chat from the chat composer:
1. In the Coder dashboard, create a workspace from the agent template
you migrated.
1. In the Coder dashboard, create a workspace from the agent template you migrated.
2. Open **Agents** and start a new chat.
3. In the composer, use the workspace picker to attach the workspace you
just created.
4. Send a prompt that exercises the workspace, for example: *"List the
files in the root directory of this workspace."*
3. In the composer, use the workspace picker to attach the workspace you just created.
4. Send a prompt that exercises the workspace, for example: *"List the files in the root directory of this workspace."*
The response stream should show the agent invoking workspace tools (such
as `execute`) against the attached workspace. After the chat finishes,
verify the chat is bound to the workspace via the API:
The response stream should show the agent invoking workspace tools (such as `execute`) against the attached workspace.
After the chat finishes, verify the chat is bound to the workspace via the API:
```sh
curl -s "https://coder.example.com/api/v2/chats/$CHAT_ID" \
-H "Coder-Session-Token: $CODER_SESSION_TOKEN" | jq '{workspace_id, status}'
```
A `workspace_id` matching the workspace you attached confirms the chat
is driving that workspace end-to-end. Auto-provisioning from the chat
flow is also supported but is easier to verify once the manual-attach
path is working.
A `workspace_id` matching the workspace you attached confirms the chat is driving that workspace end-to-end.
Auto-provisioning from the chat flow is also supported but is easier to verify once the manual-attach path is working.
### 6. Verify interrupt works
@@ -640,16 +593,14 @@ Use this list to confirm each part of your integration:
- `POST /chats` creates a chat and returns a valid `Chat` object
- WebSocket stream at `/chats/{chat}/stream` delivers events
- Follow-up messages via `/chats/{chat}/messages` are accepted
- Chat attached to a workspace from the converted template runs
tools against that workspace
- Chat attached to a workspace from the converted template runs tools against that workspace
- `POST /chats/{chat}/interrupt` stops the agent and returns to `waiting`
- Archive and restore via `PATCH /chats/{chat}` works
- (If applicable) GitHub Actions workflow creates chats successfully
## Features available only in the Chats API
The Chats API includes capabilities that have no equivalent in the Tasks
API:
The Chats API includes capabilities that have no equivalent in the Tasks API:
| Feature | Description |
|--------------------------------------|-------------------------------------------------------------------------------------------------------|
@@ -669,8 +620,8 @@ API:
## Response schema changes
The Tasks API returns a `Task` object with workspace-centric fields. The
Chats API returns a `Chat` object with conversation-centric fields:
The Tasks API returns a `Task` object with workspace-centric fields.
The Chats API returns a `Chat` object with conversation-centric fields:
| Tasks API field | Chats API equivalent | Notes |
|--------------------|-----------------------------------------------|------------------------------------------------------------------|
+38 -71
View File
@@ -2,37 +2,30 @@
title: Tools
---
Coder Agents completes work by calling tools: structured functions the agent
invokes during a chat to gather context and take action, such as listing
templates, reading files, running commands, or creating a workspace.
Coder Agents completes work by calling tools: structured functions the agent invokes during a chat to gather context and take action, such as listing templates, reading files, running commands, or creating a workspace.
This page explains how tool calls work and documents the tools the agent uses
to select a template and create a workspace.
This page explains how tool calls work and documents the tools the agent uses to select a template and create a workspace.
## How tool calls work
Each turn of a conversation follows the same loop:
1. You send a message.
2. The model decides whether it needs a tool and calls it with structured
arguments. For example, `list_templates` with `{"query": "docker"}`.
3. Coder executes the tool in the control plane using your identity and
permissions, and returns a JSON result to the model.
4. The model uses the result to decide what to do next: call another tool or
reply to you.
2. The model decides whether it needs a tool and calls it with structured arguments.
For example, `list_templates` with `{"query": "docker"}`.
3. Coder executes the tool in the control plane using your identity and permissions, and returns a JSON result to the model.
4. The model uses the result to decide what to do next: call another tool or reply to you.
Tool calls and their results are visible in the chat timeline, so you can
always inspect what the agent did and why.
Tool calls and their results are visible in the chat timeline, so you can always inspect what the agent did and why.
Two properties hold for every built-in tool:
- **Your permissions apply.** Tools run with the chat owner's RBAC identity.
The agent cannot list templates or create workspaces that you could not
access yourself.
- **Results carry instructions.** Where a decision matters, the tool result
includes a `next_step` field containing a fixed instruction for the agent,
such as asking you to choose between similar templates. This keeps agent
behavior consistent without relying on long prompt rules.
- **Your permissions apply.**
Tools run with the chat owner's RBAC identity.
The agent cannot list templates or create workspaces that you could not access yourself.
- **Results carry instructions.**
Where a decision matters, the tool result includes a `next_step` field containing a fixed instruction for the agent, such as asking you to choose between similar templates.
This keeps agent behavior consistent without relying on long prompt rules.
## Workspace creation tools
@@ -52,10 +45,7 @@ Administrators can restrict which templates these tools can use with the switche
### list_templates
`list_templates` returns a ranked shortlist of the active, non-deprecated
templates in the chat's organization, so the agent can pick a template the
same way a colleague would: prefer what matches the request, what you already
use, and what the rest of the organization uses.
`list_templates` returns a ranked shortlist of the active, non-deprecated templates in the chat's organization, so the agent can pick a template the same way a colleague would: prefer what matches the request, what you already use, and what the rest of the organization uses.
#### Arguments
@@ -66,14 +56,12 @@ use, and what the rest of the organization uses.
#### How templates are ranked
Templates are ordered by query relevance first (when a query is provided),
then by an affinity score computed from your recent usage and organization
popularity. Name and ID break any remaining ties so the order is stable.
Templates are ordered by query relevance first (when a query is provided), then by an affinity score computed from your recent usage and organization popularity.
Name and ID break any remaining ties so the order is stable.
##### Query relevance tiers
When a query is provided, each template receives the highest tier that any
of its fields matches:
When a query is provided, each template receives the highest tier that any of its fields matches:
| Tier | Match |
|------|-----------------------------------------------------|
@@ -83,15 +71,13 @@ of its fields matches:
| 1 | The description contains the query |
| 0 | No match. The template is excluded from the results |
The description is checked only when neither the name nor the display name
matched. Matching is case-insensitive and ignores spaces, hyphens, and
underscores, so `python gpu` matches `python-gpu`. A higher tier always
outranks a lower tier, regardless of usage.
The description is checked only when neither the name nor the display name matched.
Matching is case-insensitive and ignores spaces, hyphens, and underscores, so `python gpu` matches `python-gpu`.
A higher tier always outranks a lower tier, regardless of usage.
##### Affinity score
Within a relevance tier, or when no query is given, templates are ordered by
an affinity score:
Within a relevance tier, or when no query is given, templates are ordered by an affinity score:
```txt
affinity = 10 x (active + 0.5 x deleted) x 0.5^(days_since_last_use / 14)
@@ -102,27 +88,18 @@ affinity = 10 x (active + 0.5 x deleted) x 0.5^(days_since_last_use / 14)
- `deleted`: your recently deleted workspaces used in the last 60&nbsp;days, counted at half the weight of active ones.
- `days_since_last_use`: days since you last used the template.
The personal term halves every 14&nbsp;days and is zero when you have no usage in the last 60&nbsp;days.
- `active_developers`: developers in the organization with an active
workspace on the template, excluding unclaimed prebuilt workspaces.
- `active_developers`: developers in the organization with an active workspace on the template, excluding unclaimed prebuilt workspaces.
Personal usage carries ten times the weight of organization popularity, and
popularity grows logarithmically so heavily used templates do not drown out
your own history. Each template is scored independently from its own
signals; one template's usage never affects another's score. The score is
internal and only determines ordering and the recommendation. The response
carries the raw evidence instead: `active_developers`,
`your_workspace_count`, and `last_used_by_you` appear on each template when
they are non-zero.
Personal usage carries ten times the weight of organization popularity, and popularity grows logarithmically so heavily used templates do not drown out your own history.
Each template is scored independently from its own signals; one template's usage never affects another's score.
The score is internal and only determines ordering and the recommendation.
The response carries the raw evidence instead: `active_developers`, `your_workspace_count`, and `last_used_by_you` appear on each template when they are non-zero.
#### Recommendation and next_step
Beyond the ranked list, the result tells the agent what to do next:
- `recommended_template_id` is present only when the top template is a clear
winner: it is the only available template, it matches the query at a
strictly higher tier than every other match, or its affinity score reaches
at least the score of two active developers and leads the runner-up by a
clear margin.
- `recommended_template_id` is present only when the top template is a clear winner: it is the only available template, it matches the query at a strictly higher tier than every other match, or its affinity score reaches at least the score of two active developers and leads the runner-up by a clear margin.
- `next_step` is always present and contains one of four fixed instructions:
| Situation | `next_step` instruction for the agent |
@@ -137,8 +114,8 @@ You can always override the recommendation by naming a template yourself.
#### Example
A user asks for "a workspace to debug a Docker image". The agent extracts a
search term and calls `list_templates` with:
A user asks for "a workspace to debug a Docker image".
The agent extracts a search term and calls `list_templates` with:
```json
{
@@ -146,9 +123,8 @@ search term and calls `list_templates` with:
}
```
The response lists matching templates best-first. Here `docker` is an exact
name match while `docker-gpu` is only a prefix match, so the top template is
a clear winner and is recommended:
The response lists matching templates best-first.
Here `docker` is an exact name match while `docker-gpu` is only a prefix match, so the top template is a clear winner and is recommended:
```json
{
@@ -176,29 +152,21 @@ a clear winner and is recommended:
}
```
The agent follows `next_step` and calls `create_workspace` with the
recommended template. Had the two templates tied (for example, both plain
substring matches with similar usage), the response would omit
`recommended_template_id` and `next_step` would instruct the agent to ask
you to choose.
The agent follows `next_step` and calls `create_workspace` with the recommended template.
Had the two templates tied (for example, both plain substring matches with similar usage), the response would omit `recommended_template_id` and `next_step` would instruct the agent to ask you to choose.
`next_page` is present only when more results exist.
### read_template
`read_template` reads one template's details: its configurable parameters
(name, type, default, options, and validation rules) and its presets,
including preset parameter values and whether prebuilt workspaces are
available for faster startup.
`read_template` reads one template's details: its configurable parameters (name, type, default, options, and validation rules) and its presets, including preset parameter values and whether prebuilt workspaces are available for faster startup.
The agent calls it only when needed, typically when a template has required
parameters or when a preset should be applied. For templates that work with
defaults, the agent skips straight to `create_workspace`.
The agent calls it only when needed, typically when a template has required parameters or when a preset should be applied.
For templates that work with defaults, the agent skips straight to `create_workspace`.
### create_workspace
`create_workspace` provisions a workspace from a template and waits for it to
become ready, then attaches it to the chat.
`create_workspace` provisions a workspace from a template and waits for it to become ready, then attaches it to the chat.
| Argument | Type | Description |
|---------------|--------|------------------------------------------------------------------------------------|
@@ -215,6 +183,5 @@ Guardrails:
Workspace readiness doesn't guarantee that skills, MCP tools, or context have finished loading.
The agent uses available capabilities rather than recreating the workspace to retry discovery.
It follows the `next_step` from `list_templates`, asking you to choose when no template is recommended.
- The tool is idempotent: if the chat already has a workspace building or
running, that workspace is returned instead of creating a duplicate.
- The tool is idempotent: if the chat already has a workspace building or running, that workspace is returned instead of creating a duplicate.
- Templates that do not allow Coder Agents are rejected.