chore(db): remove workspace_agent_id from chats table (#22442)

## Summary

Remove the `workspace_agent_id` column from the `chats` table and
dynamically look up the first workspace agent instead.

## Problem

When a workspace is stopped and restarted, the workspace agent gets a
new ID. The `workspace_agent_id` stored on the chat at creation time
becomes stale, making the agent unreachable. This caused chats to break
after workspace restarts.

## Solution

Instead of persisting the agent ID, dynamically look up the first agent
from the workspace's latest build via
`GetWorkspaceAgentsInLatestBuildByWorkspaceID` whenever an agent
connection is needed. The `workspace_id` on the chat remains stable
across restarts.

This behavior may be refined later (e.g., agent selection heuristics),
but picking the first agent resolves the immediate breakage.

## Changes

- **Migration 000425**: Drop `workspace_agent_id` column from `chats`
- **SQL queries**: Remove `workspace_agent_id` from `InsertChat` and
`UpdateChatWorkspace`
- **chatd.go**: `getWorkspaceConn` and `resolveInstructions` now look up
agents dynamically from workspace ID
- **chatd.go**: Remove `refreshChatWorkspaceSnapshot` (no longer needed)
- **createworkspace.go**: Stop persisting agent ID when associating
workspace with chat
- **subagent.go**: Stop passing agent ID to child chats
- **SDK/frontend**: Remove `WorkspaceAgentID` / `workspace_agent_id`
from Chat type

---------

Co-authored-by: Kyle Carberry <kylecarbs@gmail.com>
This commit is contained in:
Kyle Carberry
2026-02-28 16:46:51 -05:00
committed by GitHub
co-authored by Kyle Carberry
parent c316d0a3e7
commit 34d9392e37
18 changed files with 47 additions and 136 deletions
-4
View File
@@ -77,7 +77,6 @@ func TestPostChats(t *testing.T) {
require.NotZero(t, chat.CreatedAt)
require.NotZero(t, chat.UpdatedAt)
require.Nil(t, chat.WorkspaceID)
require.Nil(t, chat.WorkspaceAgentID)
require.NotNil(t, chat.RootChatID)
require.Equal(t, chat.ID, *chat.RootChatID)
@@ -206,8 +205,6 @@ func TestPostChats(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, chat.WorkspaceID)
require.Equal(t, workspaceBuild.Workspace.ID, *chat.WorkspaceID)
require.NotNil(t, chat.WorkspaceAgentID)
require.Equal(t, workspaceBuild.Agents[0].ID, *chat.WorkspaceAgentID)
require.Equal(t, modelConfig.ID, chat.LastModelConfigID)
})
@@ -342,7 +339,6 @@ func TestListChats(t *testing.T) {
require.NotZero(t, chat.UpdatedAt)
require.Nil(t, chat.ParentChatID)
require.Nil(t, chat.WorkspaceID)
require.Nil(t, chat.WorkspaceAgentID)
require.NotNil(t, chat.RootChatID)
require.Equal(t, chat.ID, *chat.RootChatID)
require.NotNil(t, chat.DiffStatus)