mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
co-authored by
Kyle Carberry
parent
c316d0a3e7
commit
34d9392e37
+20
-49
@@ -133,7 +133,6 @@ var (
|
||||
type CreateOptions struct {
|
||||
OwnerID uuid.UUID
|
||||
WorkspaceID uuid.NullUUID
|
||||
WorkspaceAgentID uuid.NullUUID
|
||||
ParentChatID uuid.NullUUID
|
||||
RootChatID uuid.NullUUID
|
||||
Title string
|
||||
@@ -212,7 +211,6 @@ func (p *Server) CreateChat(ctx context.Context, opts CreateOptions) (database.C
|
||||
insertedChat, err := tx.InsertChat(ctx, database.InsertChatParams{
|
||||
OwnerID: opts.OwnerID,
|
||||
WorkspaceID: opts.WorkspaceID,
|
||||
WorkspaceAgentID: opts.WorkspaceAgentID,
|
||||
ParentChatID: opts.ParentChatID,
|
||||
RootChatID: opts.RootChatID,
|
||||
LastModelConfigID: opts.ModelConfigID,
|
||||
@@ -1421,10 +1419,6 @@ func (p *Server) publishChatPubsubEvent(chat database.Chat, kind coderdpubsub.Ch
|
||||
if chat.WorkspaceID.Valid {
|
||||
sdkChat.WorkspaceID = &chat.WorkspaceID.UUID
|
||||
}
|
||||
if chat.WorkspaceAgentID.Valid {
|
||||
sdkChat.WorkspaceAgentID = &chat.WorkspaceAgentID.UUID
|
||||
}
|
||||
|
||||
event := coderdpubsub.ChatEvent{
|
||||
Kind: kind,
|
||||
Chat: sdkChat,
|
||||
@@ -1825,13 +1819,6 @@ func (p *Server) runChat(
|
||||
}()
|
||||
|
||||
currentChat := chat
|
||||
loadChatSnapshot := func(
|
||||
loadCtx context.Context,
|
||||
chatID uuid.UUID,
|
||||
) (database.Chat, error) {
|
||||
//nolint:gocritic // System context required to load chat snapshots for the stream.
|
||||
return p.db.GetChatByID(dbauthz.AsSystemRestricted(loadCtx), chatID)
|
||||
}
|
||||
var (
|
||||
chatStateMu sync.Mutex
|
||||
workspaceMu sync.Mutex
|
||||
@@ -1860,28 +1847,20 @@ func (p *Server) runChat(
|
||||
return nil, xerrors.New("workspace agent connector is not configured")
|
||||
}
|
||||
|
||||
if !chatSnapshot.WorkspaceAgentID.Valid {
|
||||
refreshedChat, refreshErr := refreshChatWorkspaceSnapshot(
|
||||
ctx,
|
||||
chatSnapshot,
|
||||
loadChatSnapshot,
|
||||
)
|
||||
if refreshErr != nil {
|
||||
return nil, refreshErr
|
||||
}
|
||||
if refreshedChat.WorkspaceAgentID.Valid {
|
||||
chatStateMu.Lock()
|
||||
currentChat = refreshedChat
|
||||
chatSnapshot = refreshedChat
|
||||
chatStateMu.Unlock()
|
||||
}
|
||||
if !chatSnapshot.WorkspaceID.Valid {
|
||||
return nil, xerrors.New("chat has no workspace")
|
||||
}
|
||||
|
||||
if !chatSnapshot.WorkspaceAgentID.Valid {
|
||||
//nolint:gocritic // System context needed to look up workspace agents.
|
||||
agents, err := p.db.GetWorkspaceAgentsInLatestBuildByWorkspaceID(
|
||||
dbauthz.AsSystemRestricted(ctx),
|
||||
chatSnapshot.WorkspaceID.UUID,
|
||||
)
|
||||
if err != nil || len(agents) == 0 {
|
||||
return nil, xerrors.New("chat has no workspace agent")
|
||||
}
|
||||
|
||||
agentConn, agentRelease, err := p.agentConnFn(ctx, chatSnapshot.WorkspaceAgentID.UUID)
|
||||
agentConn, agentRelease, err := p.agentConnFn(ctx, agents[0].ID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("connect to workspace agent: %w", err)
|
||||
}
|
||||
@@ -2376,23 +2355,6 @@ func usageNullInt64(value int64, valid bool) sql.NullInt64 {
|
||||
}
|
||||
}
|
||||
|
||||
func refreshChatWorkspaceSnapshot(
|
||||
ctx context.Context,
|
||||
chat database.Chat,
|
||||
loadChat func(context.Context, uuid.UUID) (database.Chat, error),
|
||||
) (database.Chat, error) {
|
||||
if chat.WorkspaceAgentID.Valid || loadChat == nil {
|
||||
return chat, nil
|
||||
}
|
||||
|
||||
refreshedChat, err := loadChat(ctx, chat.ID)
|
||||
if err != nil {
|
||||
return chat, xerrors.Errorf("reload chat workspace state: %w", err)
|
||||
}
|
||||
|
||||
return refreshedChat, nil
|
||||
}
|
||||
|
||||
// resolveInstructions returns the combined system instructions for the
|
||||
// workspace agent. It reads the home-level (~/.coder/AGENTS.md) and
|
||||
// working-directory-level (<pwd>/AGENTS.md) instruction files, combines
|
||||
@@ -2402,10 +2364,19 @@ func (p *Server) resolveInstructions(
|
||||
chat database.Chat,
|
||||
getWorkspaceConn func(context.Context) (workspacesdk.AgentConn, error),
|
||||
) string {
|
||||
if !chat.WorkspaceAgentID.Valid {
|
||||
if !chat.WorkspaceID.Valid {
|
||||
return ""
|
||||
}
|
||||
agentID := chat.WorkspaceAgentID.UUID
|
||||
|
||||
//nolint:gocritic // System context needed to look up workspace agents.
|
||||
agents, agentsErr := p.db.GetWorkspaceAgentsInLatestBuildByWorkspaceID(
|
||||
dbauthz.AsSystemRestricted(ctx),
|
||||
chat.WorkspaceID.UUID,
|
||||
)
|
||||
if agentsErr != nil || len(agents) == 0 {
|
||||
return ""
|
||||
}
|
||||
agentID := agents[0].ID
|
||||
|
||||
p.instructionCacheMu.Lock()
|
||||
cached, ok := p.instructionCache[agentID]
|
||||
|
||||
@@ -191,10 +191,6 @@ func CreateWorkspace(options CreateWorkspaceOptions) fantasy.AgentTool {
|
||||
UUID: workspace.ID,
|
||||
Valid: true,
|
||||
},
|
||||
WorkspaceAgentID: uuid.NullUUID{
|
||||
UUID: workspaceAgentID,
|
||||
Valid: workspaceAgentID != uuid.Nil,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -281,14 +277,15 @@ func checkExistingWorkspace(
|
||||
|
||||
case database.ProvisionerJobStatusSucceeded:
|
||||
// Build succeeded — check if agent is reachable.
|
||||
if chat.WorkspaceAgentID.Valid && agentConnFn != nil {
|
||||
agents, agentsErr := db.GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx, ws.ID)
|
||||
if agentsErr == nil && len(agents) > 0 && agentConnFn != nil {
|
||||
pingCtx, cancel := context.WithTimeout(
|
||||
ctx, agentPingTimeout,
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
conn, release, connErr := agentConnFn(
|
||||
pingCtx, chat.WorkspaceAgentID.UUID,
|
||||
pingCtx, agents[0].ID,
|
||||
)
|
||||
if connErr == nil {
|
||||
release()
|
||||
|
||||
@@ -240,9 +240,8 @@ func (p *Server) createChildSubagentChat(
|
||||
}
|
||||
|
||||
child, err := p.CreateChat(ctx, CreateOptions{
|
||||
OwnerID: parent.OwnerID,
|
||||
WorkspaceID: parent.WorkspaceID,
|
||||
WorkspaceAgentID: parent.WorkspaceAgentID,
|
||||
OwnerID: parent.OwnerID,
|
||||
WorkspaceID: parent.WorkspaceID,
|
||||
ParentChatID: uuid.NullUUID{
|
||||
UUID: parent.ID,
|
||||
Valid: true,
|
||||
|
||||
+1
-23
@@ -258,7 +258,6 @@ func (api *API) postChats(rw http.ResponseWriter, r *http.Request) {
|
||||
chat, err := api.chatDaemon.CreateChat(ctx, chatd.CreateOptions{
|
||||
OwnerID: apiKey.UserID,
|
||||
WorkspaceID: workspaceSelection.WorkspaceID,
|
||||
WorkspaceAgentID: workspaceSelection.WorkspaceAgentID,
|
||||
Title: title,
|
||||
ModelConfigID: modelConfigID,
|
||||
SystemPrompt: defaultChatSystemPrompt(),
|
||||
@@ -1854,8 +1853,7 @@ func parseGitHubPullRequestURL(raw string) (githubPullRequestRef, bool) {
|
||||
}
|
||||
|
||||
type createChatWorkspaceSelection struct {
|
||||
WorkspaceID uuid.NullUUID
|
||||
WorkspaceAgentID uuid.NullUUID
|
||||
WorkspaceID uuid.NullUUID
|
||||
}
|
||||
|
||||
func (api *API) validateCreateChatWorkspaceSelection(
|
||||
@@ -1888,23 +1886,6 @@ func (api *API) validateCreateChatWorkspaceSelection(
|
||||
Valid: true,
|
||||
}
|
||||
|
||||
workspaceAgents, err := api.Database.GetWorkspaceAgentsInLatestBuildByWorkspaceID(
|
||||
ctx,
|
||||
workspace.ID,
|
||||
)
|
||||
if err != nil {
|
||||
return selection, http.StatusInternalServerError, &codersdk.Response{
|
||||
Message: "Failed to get workspace agents.",
|
||||
Detail: err.Error(),
|
||||
}
|
||||
}
|
||||
if len(workspaceAgents) > 0 {
|
||||
selection.WorkspaceAgentID = uuid.NullUUID{
|
||||
UUID: workspaceAgents[0].ID,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
return selection, 0, nil
|
||||
}
|
||||
|
||||
@@ -2081,9 +2062,6 @@ func convertChat(c database.Chat, diffStatus *database.ChatDiffStatus) codersdk.
|
||||
if c.WorkspaceID.Valid {
|
||||
chat.WorkspaceID = &c.WorkspaceID.UUID
|
||||
}
|
||||
if c.WorkspaceAgentID.Valid {
|
||||
chat.WorkspaceAgentID = &c.WorkspaceAgentID.UUID
|
||||
}
|
||||
if diffStatus != nil {
|
||||
convertedDiffStatus := convertChatDiffStatus(c.ID, diffStatus)
|
||||
chat.DiffStatus = &convertedDiffStatus
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -694,9 +694,8 @@ func (s *MethodTestSuite) TestChats() {
|
||||
s.Run("UpdateChatWorkspace", s.Mocked(func(dbm *dbmock.MockStore, faker *gofakeit.Faker, check *expects) {
|
||||
chat := testutil.Fake(s.T(), faker, database.Chat{})
|
||||
arg := database.UpdateChatWorkspaceParams{
|
||||
ID: chat.ID,
|
||||
WorkspaceID: uuid.NullUUID{UUID: uuid.New(), Valid: true},
|
||||
WorkspaceAgentID: uuid.NullUUID{UUID: uuid.New(), Valid: true},
|
||||
ID: chat.ID,
|
||||
WorkspaceID: uuid.NullUUID{UUID: uuid.New(), Valid: true},
|
||||
}
|
||||
updatedChat := testutil.Fake(s.T(), faker, database.Chat{ID: chat.ID})
|
||||
dbm.EXPECT().GetChatByID(gomock.Any(), chat.ID).Return(chat, nil).AnyTimes()
|
||||
|
||||
Generated
-4
@@ -1263,7 +1263,6 @@ CREATE TABLE chats (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
owner_id uuid NOT NULL,
|
||||
workspace_id uuid,
|
||||
workspace_agent_id uuid,
|
||||
title text DEFAULT 'New Chat'::text NOT NULL,
|
||||
status chat_status DEFAULT 'waiting'::chat_status NOT NULL,
|
||||
worker_id uuid,
|
||||
@@ -3790,9 +3789,6 @@ ALTER TABLE ONLY chats
|
||||
ALTER TABLE ONLY chats
|
||||
ADD CONSTRAINT chats_root_chat_id_fkey FOREIGN KEY (root_chat_id) REFERENCES chats(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY chats
|
||||
ADD CONSTRAINT chats_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY chats
|
||||
ADD CONSTRAINT chats_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ const (
|
||||
ForeignKeyChatsOwnerID ForeignKeyConstraint = "chats_owner_id_fkey" // ALTER TABLE ONLY chats ADD CONSTRAINT chats_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
ForeignKeyChatsParentChatID ForeignKeyConstraint = "chats_parent_chat_id_fkey" // ALTER TABLE ONLY chats ADD CONSTRAINT chats_parent_chat_id_fkey FOREIGN KEY (parent_chat_id) REFERENCES chats(id) ON DELETE SET NULL;
|
||||
ForeignKeyChatsRootChatID ForeignKeyConstraint = "chats_root_chat_id_fkey" // ALTER TABLE ONLY chats ADD CONSTRAINT chats_root_chat_id_fkey FOREIGN KEY (root_chat_id) REFERENCES chats(id) ON DELETE SET NULL;
|
||||
ForeignKeyChatsWorkspaceAgentID ForeignKeyConstraint = "chats_workspace_agent_id_fkey" // ALTER TABLE ONLY chats ADD CONSTRAINT chats_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE SET NULL;
|
||||
ForeignKeyChatsWorkspaceID ForeignKeyConstraint = "chats_workspace_id_fkey" // ALTER TABLE ONLY chats ADD CONSTRAINT chats_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE SET NULL;
|
||||
ForeignKeyConnectionLogsOrganizationID ForeignKeyConstraint = "connection_logs_organization_id_fkey" // ALTER TABLE ONLY connection_logs ADD CONSTRAINT connection_logs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
ForeignKeyConnectionLogsWorkspaceID ForeignKeyConstraint = "connection_logs_workspace_id_fkey" // ALTER TABLE ONLY connection_logs ADD CONSTRAINT connection_logs_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE chats ADD COLUMN workspace_agent_id UUID REFERENCES workspace_agents(id) ON DELETE SET NULL;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE chats DROP COLUMN workspace_agent_id;
|
||||
@@ -3889,7 +3889,6 @@ type Chat struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
WorkspaceID uuid.NullUUID `db:"workspace_id" json:"workspace_id"`
|
||||
WorkspaceAgentID uuid.NullUUID `db:"workspace_agent_id" json:"workspace_agent_id"`
|
||||
Title string `db:"title" json:"title"`
|
||||
Status ChatStatus `db:"status" json:"status"`
|
||||
WorkerID uuid.NullUUID `db:"worker_id" json:"worker_id"`
|
||||
|
||||
@@ -2842,7 +2842,7 @@ WHERE
|
||||
1
|
||||
)
|
||||
RETURNING
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
`
|
||||
|
||||
type AcquireChatParams struct {
|
||||
@@ -2859,7 +2859,6 @@ func (q *sqlQuerier) AcquireChat(ctx context.Context, arg AcquireChatParams) (Ch
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -2940,7 +2939,7 @@ func (q *sqlQuerier) DeleteChatQueuedMessage(ctx context.Context, arg DeleteChat
|
||||
|
||||
const getChatByID = `-- name: GetChatByID :one
|
||||
SELECT
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
FROM
|
||||
chats
|
||||
WHERE
|
||||
@@ -2954,7 +2953,6 @@ func (q *sqlQuerier) GetChatByID(ctx context.Context, id uuid.UUID) (Chat, error
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -2972,7 +2970,7 @@ func (q *sqlQuerier) GetChatByID(ctx context.Context, id uuid.UUID) (Chat, error
|
||||
}
|
||||
|
||||
const getChatByIDForUpdate = `-- name: GetChatByIDForUpdate :one
|
||||
SELECT id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error FROM chats WHERE id = $1::uuid FOR UPDATE
|
||||
SELECT id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error FROM chats WHERE id = $1::uuid FOR UPDATE
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetChatByIDForUpdate(ctx context.Context, id uuid.UUID) (Chat, error) {
|
||||
@@ -2982,7 +2980,6 @@ func (q *sqlQuerier) GetChatByIDForUpdate(ctx context.Context, id uuid.UUID) (Ch
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3291,7 +3288,7 @@ func (q *sqlQuerier) GetChatQueuedMessages(ctx context.Context, chatID uuid.UUID
|
||||
|
||||
const getChatsByOwnerID = `-- name: GetChatsByOwnerID :many
|
||||
SELECT
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
FROM
|
||||
chats
|
||||
WHERE
|
||||
@@ -3314,7 +3311,6 @@ func (q *sqlQuerier) GetChatsByOwnerID(ctx context.Context, ownerID uuid.UUID) (
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3343,7 +3339,7 @@ func (q *sqlQuerier) GetChatsByOwnerID(ctx context.Context, ownerID uuid.UUID) (
|
||||
|
||||
const getStaleChats = `-- name: GetStaleChats :many
|
||||
SELECT
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
FROM
|
||||
chats
|
||||
WHERE
|
||||
@@ -3366,7 +3362,6 @@ func (q *sqlQuerier) GetStaleChats(ctx context.Context, staleThreshold time.Time
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3397,7 +3392,6 @@ const insertChat = `-- name: InsertChat :one
|
||||
INSERT INTO chats (
|
||||
owner_id,
|
||||
workspace_id,
|
||||
workspace_agent_id,
|
||||
parent_chat_id,
|
||||
root_chat_id,
|
||||
last_model_config_id,
|
||||
@@ -3408,17 +3402,15 @@ INSERT INTO chats (
|
||||
$3::uuid,
|
||||
$4::uuid,
|
||||
$5::uuid,
|
||||
$6::uuid,
|
||||
$7::text
|
||||
$6::text
|
||||
)
|
||||
RETURNING
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
`
|
||||
|
||||
type InsertChatParams struct {
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
WorkspaceID uuid.NullUUID `db:"workspace_id" json:"workspace_id"`
|
||||
WorkspaceAgentID uuid.NullUUID `db:"workspace_agent_id" json:"workspace_agent_id"`
|
||||
ParentChatID uuid.NullUUID `db:"parent_chat_id" json:"parent_chat_id"`
|
||||
RootChatID uuid.NullUUID `db:"root_chat_id" json:"root_chat_id"`
|
||||
LastModelConfigID uuid.UUID `db:"last_model_config_id" json:"last_model_config_id"`
|
||||
@@ -3429,7 +3421,6 @@ func (q *sqlQuerier) InsertChat(ctx context.Context, arg InsertChatParams) (Chat
|
||||
row := q.db.QueryRowContext(ctx, insertChat,
|
||||
arg.OwnerID,
|
||||
arg.WorkspaceID,
|
||||
arg.WorkspaceAgentID,
|
||||
arg.ParentChatID,
|
||||
arg.RootChatID,
|
||||
arg.LastModelConfigID,
|
||||
@@ -3440,7 +3431,6 @@ func (q *sqlQuerier) InsertChat(ctx context.Context, arg InsertChatParams) (Chat
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3578,7 +3568,7 @@ func (q *sqlQuerier) InsertChatQueuedMessage(ctx context.Context, arg InsertChat
|
||||
|
||||
const listChatsByRootID = `-- name: ListChatsByRootID :many
|
||||
SELECT
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
FROM
|
||||
chats
|
||||
WHERE
|
||||
@@ -3600,7 +3590,6 @@ func (q *sqlQuerier) ListChatsByRootID(ctx context.Context, rootChatID uuid.UUID
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3629,7 +3618,7 @@ func (q *sqlQuerier) ListChatsByRootID(ctx context.Context, rootChatID uuid.UUID
|
||||
|
||||
const listChildChatsByParentID = `-- name: ListChildChatsByParentID :many
|
||||
SELECT
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
FROM
|
||||
chats
|
||||
WHERE
|
||||
@@ -3651,7 +3640,6 @@ func (q *sqlQuerier) ListChildChatsByParentID(ctx context.Context, parentChatID
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3719,7 +3707,7 @@ SET
|
||||
WHERE
|
||||
id = $2::uuid
|
||||
RETURNING
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
`
|
||||
|
||||
type UpdateChatByIDParams struct {
|
||||
@@ -3734,7 +3722,6 @@ func (q *sqlQuerier) UpdateChatByID(ctx context.Context, arg UpdateChatByIDParam
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3831,7 +3818,7 @@ SET
|
||||
WHERE
|
||||
id = $6::uuid
|
||||
RETURNING
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
`
|
||||
|
||||
type UpdateChatStatusParams struct {
|
||||
@@ -3857,7 +3844,6 @@ func (q *sqlQuerier) UpdateChatStatus(ctx context.Context, arg UpdateChatStatusP
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
@@ -3879,28 +3865,25 @@ UPDATE
|
||||
chats
|
||||
SET
|
||||
workspace_id = $1::uuid,
|
||||
workspace_agent_id = $2::uuid,
|
||||
updated_at = NOW()
|
||||
WHERE
|
||||
id = $3::uuid
|
||||
id = $2::uuid
|
||||
RETURNING
|
||||
id, owner_id, workspace_id, workspace_agent_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
id, owner_id, workspace_id, title, status, worker_id, started_at, heartbeat_at, created_at, updated_at, parent_chat_id, root_chat_id, last_model_config_id, archived, last_error
|
||||
`
|
||||
|
||||
type UpdateChatWorkspaceParams struct {
|
||||
WorkspaceID uuid.NullUUID `db:"workspace_id" json:"workspace_id"`
|
||||
WorkspaceAgentID uuid.NullUUID `db:"workspace_agent_id" json:"workspace_agent_id"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
WorkspaceID uuid.NullUUID `db:"workspace_id" json:"workspace_id"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateChatWorkspace(ctx context.Context, arg UpdateChatWorkspaceParams) (Chat, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateChatWorkspace, arg.WorkspaceID, arg.WorkspaceAgentID, arg.ID)
|
||||
row := q.db.QueryRowContext(ctx, updateChatWorkspace, arg.WorkspaceID, arg.ID)
|
||||
var i Chat
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.OwnerID,
|
||||
&i.WorkspaceID,
|
||||
&i.WorkspaceAgentID,
|
||||
&i.Title,
|
||||
&i.Status,
|
||||
&i.WorkerID,
|
||||
|
||||
@@ -136,7 +136,6 @@ ORDER BY
|
||||
INSERT INTO chats (
|
||||
owner_id,
|
||||
workspace_id,
|
||||
workspace_agent_id,
|
||||
parent_chat_id,
|
||||
root_chat_id,
|
||||
last_model_config_id,
|
||||
@@ -144,7 +143,6 @@ INSERT INTO chats (
|
||||
) VALUES (
|
||||
@owner_id::uuid,
|
||||
sqlc.narg('workspace_id')::uuid,
|
||||
sqlc.narg('workspace_agent_id')::uuid,
|
||||
sqlc.narg('parent_chat_id')::uuid,
|
||||
sqlc.narg('root_chat_id')::uuid,
|
||||
@last_model_config_id::uuid,
|
||||
@@ -222,7 +220,6 @@ UPDATE
|
||||
chats
|
||||
SET
|
||||
workspace_id = sqlc.narg('workspace_id')::uuid,
|
||||
workspace_agent_id = sqlc.narg('workspace_agent_id')::uuid,
|
||||
updated_at = NOW()
|
||||
WHERE
|
||||
id = @id::uuid
|
||||
|
||||
@@ -64,7 +64,6 @@ func TestChatParam(t *testing.T) {
|
||||
chat, err := db.InsertChat(context.Background(), database.InsertChatParams{
|
||||
OwnerID: ownerID,
|
||||
WorkspaceID: uuid.NullUUID{},
|
||||
WorkspaceAgentID: uuid.NullUUID{},
|
||||
ParentChatID: uuid.NullUUID{},
|
||||
RootChatID: uuid.NullUUID{},
|
||||
LastModelConfigID: modelConfig.ID,
|
||||
|
||||
@@ -32,7 +32,6 @@ type Chat struct {
|
||||
ID uuid.UUID `json:"id" format:"uuid"`
|
||||
OwnerID uuid.UUID `json:"owner_id" format:"uuid"`
|
||||
WorkspaceID *uuid.UUID `json:"workspace_id,omitempty" format:"uuid"`
|
||||
WorkspaceAgentID *uuid.UUID `json:"workspace_agent_id,omitempty" format:"uuid"`
|
||||
ParentChatID *uuid.UUID `json:"parent_chat_id,omitempty" format:"uuid"`
|
||||
RootChatID *uuid.UUID `json:"root_chat_id,omitempty" format:"uuid"`
|
||||
LastModelConfigID uuid.UUID `json:"last_model_config_id" format:"uuid"`
|
||||
|
||||
Generated
-1
@@ -1054,7 +1054,6 @@ export interface Chat {
|
||||
readonly id: string;
|
||||
readonly owner_id: string;
|
||||
readonly workspace_id?: string;
|
||||
readonly workspace_agent_id?: string;
|
||||
readonly parent_chat_id?: string;
|
||||
readonly root_chat_id?: string;
|
||||
readonly last_model_config_id: string;
|
||||
|
||||
@@ -117,7 +117,6 @@ const mockModelCatalog: TypesGen.ChatModelsResponse = {
|
||||
const baseChatFields = {
|
||||
owner_id: "owner-id",
|
||||
workspace_id: mockWorkspace.id,
|
||||
workspace_agent_id: mockWorkspaceAgent.id,
|
||||
last_model_config_id: "model-config-1",
|
||||
created_at: "2026-02-18T00:00:00.000Z",
|
||||
updated_at: "2026-02-18T00:00:00.000Z",
|
||||
|
||||
@@ -494,7 +494,6 @@ const AgentDetail: FC = () => {
|
||||
});
|
||||
const chatsQuery = useQuery(chats());
|
||||
const workspaceId = chatQuery.data?.chat?.workspace_id;
|
||||
const workspaceAgentId = chatQuery.data?.chat?.workspace_agent_id;
|
||||
const workspaceQuery = useQuery({
|
||||
...workspaceById(workspaceId ?? ""),
|
||||
enabled: Boolean(workspaceId),
|
||||
@@ -507,7 +506,7 @@ const AgentDetail: FC = () => {
|
||||
const chatModelConfigsQuery = useQuery(chatModelConfigs());
|
||||
const hasDiffStatus = Boolean(diffStatusQuery.data?.url);
|
||||
const workspace = workspaceQuery.data;
|
||||
const workspaceAgent = getWorkspaceAgent(workspace, workspaceAgentId);
|
||||
const workspaceAgent = getWorkspaceAgent(workspace, undefined);
|
||||
const chatData = chatQuery.data;
|
||||
const chatRecord = chatData?.chat;
|
||||
const chatMessages = chatData?.messages;
|
||||
|
||||
Reference in New Issue
Block a user