diff --git a/coderd/exp_chats.go b/coderd/exp_chats.go index 86713b8201..44d3ac3886 100644 --- a/coderd/exp_chats.go +++ b/coderd/exp_chats.go @@ -1830,6 +1830,20 @@ func (api *API) postChatMessages(rw http.ResponseWriter, r *http.Request) { } } + busyBehavior := chatd.SendMessageBusyBehaviorQueue + switch req.BusyBehavior { + case codersdk.ChatBusyBehaviorInterrupt: + busyBehavior = chatd.SendMessageBusyBehaviorInterrupt + case codersdk.ChatBusyBehaviorQueue, "": + // Default to queue. + default: + httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ + Message: "Invalid busy_behavior value.", + Detail: `Must be "queue" or "interrupt".`, + }) + return + } + sendResult, sendErr := api.chatDaemon.SendMessage( ctx, chatd.SendMessageOptions{ @@ -1837,7 +1851,7 @@ func (api *API) postChatMessages(rw http.ResponseWriter, r *http.Request) { CreatedBy: apiKey.UserID, Content: contentBlocks, ModelConfigID: req.ModelConfigID, - BusyBehavior: chatd.SendMessageBusyBehaviorQueue, + BusyBehavior: busyBehavior, MCPServerIDs: req.MCPServerIDs, }, ) diff --git a/codersdk/chats.go b/codersdk/chats.go index 1a4a865d08..f62a843553 100644 --- a/codersdk/chats.go +++ b/codersdk/chats.go @@ -369,11 +369,27 @@ type UpdateChatRequest struct { Labels *map[string]string `json:"labels,omitempty"` } +// ChatBusyBehavior controls what happens when a user sends a message +// while the chat is already processing. +type ChatBusyBehavior string + +const ( + // ChatBusyBehaviorQueue queues the message for processing after + // the current run finishes. + ChatBusyBehaviorQueue ChatBusyBehavior = "queue" + // ChatBusyBehaviorInterrupt queues the message and interrupts + // the active run. The partial assistant response is persisted + // before the queued message is promoted, preserving correct + // conversation order. + ChatBusyBehaviorInterrupt ChatBusyBehavior = "interrupt" +) + // CreateChatMessageRequest is the request to add a message to a chat. type CreateChatMessageRequest struct { - Content []ChatInputPart `json:"content"` - ModelConfigID *uuid.UUID `json:"model_config_id,omitempty" format:"uuid"` - MCPServerIDs *[]uuid.UUID `json:"mcp_server_ids,omitempty" format:"uuid"` + Content []ChatInputPart `json:"content"` + ModelConfigID *uuid.UUID `json:"model_config_id,omitempty" format:"uuid"` + MCPServerIDs *[]uuid.UUID `json:"mcp_server_ids,omitempty" format:"uuid"` + BusyBehavior ChatBusyBehavior `json:"busy_behavior,omitempty" enums:"queue,interrupt"` } // EditChatMessageRequest is the request to edit a user message in a chat. diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index f502de0395..0e657b5d14 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1215,6 +1215,11 @@ export interface Chat { readonly last_injected_context?: readonly ChatMessagePart[]; } +// From codersdk/chats.go +export type ChatBusyBehavior = "interrupt" | "queue"; + +export const ChatBusyBehaviors: ChatBusyBehavior[] = ["interrupt", "queue"]; + // From codersdk/chats.go /** * ChatCompactionThresholdKeyPrefix scopes per-model chat compaction @@ -2338,6 +2343,7 @@ export interface CreateChatMessageRequest { readonly content: readonly ChatInputPart[]; readonly model_config_id?: string; readonly mcp_server_ids?: string[]; + readonly busy_behavior?: ChatBusyBehavior; } // From codersdk/chats.go