Skip to content

feat(chatd): add start_workspace tool to agent flow#22646

Merged
kylecarbs merged 6 commits intomainfrom
chat-start-workspace-tool
Mar 5, 2026
Merged

feat(chatd): add start_workspace tool to agent flow#22646
kylecarbs merged 6 commits intomainfrom
chat-start-workspace-tool

Conversation

@kylecarbs
Copy link
Member

Summary

When a chat's workspace is stopped, the LLM previously had no way to start it — create_workspace would either create a duplicate workspace or fail. This adds a dedicated start_workspace tool to the agent flow.

Changes

New: start_workspace tool (coderd/chatd/chattool/startworkspace.go)

  • Detects if the chat's workspace is stopped and starts it via a new build with transition=start
  • Reuses the existing waitForBuild and waitForAgent helpers (shared logic)
  • Shares the workspace mutex with create_workspace to prevent races
  • Idempotent: returns immediately if the workspace is already running or building
  • Returns a no_agent / not_ready status if the agent isn't available yet (non-fatal)

Updated: create_workspace stopped-workspace hint

  • checkExistingWorkspace now returns a stopped status with message "use start_workspace to start it" when it detects the chat's workspace is stopped, instead of falling through to create a new workspace

Wiring

  • chatd.Config / chatd.Server: new StartWorkspace / startWorkspaceFn field
  • coderd/chats.go: new chatStartWorkspace method that calls postWorkspaceBuildsInternal with proper RBAC context
  • coderd/coderd.go: passes chatStartWorkspace into chatd config
  • Tool registered alongside create_workspace for root chats only (not subagents)

Tests (startworkspace_test.go)

  • NoWorkspace: error when chat has no workspace
  • AlreadyRunning: idempotent return for workspace with successful start build
  • StoppedWorkspace: verifies StartFn is called, build is waited on, and success response returned

When a chat's workspace is stopped, the LLM previously had no way to
start it — create_workspace would either create a duplicate workspace
or fail silently. This change adds a dedicated start_workspace tool
that:

- Detects if the chat's workspace is stopped and starts it via a new
  build with transition=start
- Reuses the existing waitForBuild and waitForAgent helpers for the
  shared build-polling and agent-connectivity logic
- Shares the workspace mutex with create_workspace to prevent races
- Is idempotent: returns immediately if the workspace is already
  running or building

Additionally, create_workspace's checkExistingWorkspace now returns a
'stopped' hint when it finds a stopped workspace, guiding the LLM to
use start_workspace instead of creating a new workspace.

Files changed:
- coderd/chatd/chattool/startworkspace.go (new)
- coderd/chatd/chattool/startworkspace_test.go (new)
- coderd/chatd/chattool/createworkspace.go (stopped hint)
- coderd/chatd/chatd.go (wire tool)
- coderd/chats.go (chatStartWorkspace)
- coderd/coderd.go (wire config)
@coder-tasks
Copy link
Contributor

coder-tasks bot commented Mar 5, 2026

Documentation Check

Updates Needed

  • docs/ai-coder/agents/index.md - Add start_workspace to the "Built-in tools" table (currently missing; create_workspace is listed but start_workspace is not)
  • docs/ai-coder/agents/architecture.md - Add start_workspace to the "Platform tools" table alongside create_workspace

Automated review via Coder Tasks

@kylecarbs kylecarbs requested a review from johnstcn March 5, 2026 12:41
Comment on lines +75 to +99
tpl := dbgen.Template(t, db, database.Template{
OrganizationID: org.ID,
CreatedBy: user.ID,
})
tv := dbgen.TemplateVersion(t, db, database.TemplateVersion{
OrganizationID: org.ID,
TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true},
CreatedBy: user.ID,
})
ws := dbgen.Workspace(t, db, database.WorkspaceTable{
OwnerID: user.ID,
OrganizationID: org.ID,
TemplateID: tpl.ID,
})
job := dbgen.ProvisionerJob(t, db, nil, database.ProvisionerJob{
OrganizationID: org.ID,
CompletedAt: sql.NullTime{Time: dbtestutil.NowInDefaultTimezone(), Valid: true},
})
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
WorkspaceID: ws.ID,
TemplateVersionID: tv.ID,
JobID: job.ID,
Transition: database.WorkspaceTransitionStart,
BuildNumber: 1,
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +32 to +33
//nolint:gocritic // Unit test needs system context for DB seeding.
ctx = dbauthz.AsSystemRestricted(ctx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not actually sure this is the case, looking at dbtestutil.NewDB.

- Add TestStartWorkspaceTool_EndToEnd in chatd_test.go: creates a
  workspace, stops it, then verifies the start_workspace tool starts
  it via a mock LLM chat flow.
- Refactor startworkspace_test.go per review feedback:
  - Replace manual dbgen.ProvisionerJob + dbgen.WorkspaceBuild with
    dbfake.WorkspaceBuild builder.
  - Remove unnecessary dbauthz.AsSystemRestricted since dbtestutil.NewDB
    returns an unwrapped database.Store.
After merging main, waitForAgent was renamed to waitForAgentReady
with a new signature (returns map[string]any instead of error).
Update waitForAgentAndRespond to use the new API.
The test does create+stop+start which involves more provisioner
round-trips and agent connectivity checks. WaitSuperLong (60s)
gives sufficient headroom vs WaitLong (25s).
The echo provisioner creates new agent rows per build, so the
agenttest.New agent (connected to build 1's agent row) cannot
serve build 3's agent row after stop/start. This caused
waitForAgentReady to retry for 2 min, exceeding the test timeout.

The start_workspace tool handles the no-agent case gracefully
(returns started=true with agent_status=no_agent), so the test
still validates the core start-workspace flow end-to-end.
@kylecarbs kylecarbs enabled auto-merge (squash) March 5, 2026 15:16
@kylecarbs kylecarbs merged commit 6520159 into main Mar 5, 2026
24 checks passed
@kylecarbs kylecarbs deleted the chat-start-workspace-tool branch March 5, 2026 15:34
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants