feat: add database tables and API routes for agentic chat feature (#17570)

Backend portion of experimental `AgenticChat` feature:
- Adds database tables for chats and chat messages
- Adds functionality to stream messages from LLM providers using
`kylecarbs/aisdk-go`
- Adds API routes with relevant functionality (list, create, update
chats, insert chat message)
- Adds experiment `codersdk.AgenticChat`

---------

Co-authored-by: Kyle Carberry <kyle@carberry.com>
This commit is contained in:
Cian Johnston
2025-05-02 17:29:57 +01:00
committed by GitHub
parent 64b9bc1ca4
commit 544259b809
45 changed files with 4264 additions and 16 deletions

592
coderd/apidoc/docs.go generated
View File

@ -343,6 +343,173 @@ const docTemplate = `{
}
}
},
"/chats": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "List chats",
"operationId": "list-chats",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Chat"
}
}
}
}
},
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "Create a chat",
"operationId": "create-a-chat",
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/codersdk.Chat"
}
}
}
}
},
"/chats/{chat}": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "Get a chat",
"operationId": "get-a-chat",
"parameters": [
{
"type": "string",
"description": "Chat ID",
"name": "chat",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.Chat"
}
}
}
}
},
"/chats/{chat}/messages": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "Get chat messages",
"operationId": "get-chat-messages",
"parameters": [
{
"type": "string",
"description": "Chat ID",
"name": "chat",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.Message"
}
}
}
}
},
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Chat"
],
"summary": "Create a chat message",
"operationId": "create-a-chat-message",
"parameters": [
{
"type": "string",
"description": "Chat ID",
"name": "chat",
"in": "path",
"required": true
},
{
"description": "Request body",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/codersdk.CreateChatMessageRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {}
}
}
}
}
},
"/csp/reports": {
"post": {
"security": [
@ -659,6 +826,31 @@ const docTemplate = `{
}
}
},
"/deployment/llms": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"General"
],
"summary": "Get language models",
"operationId": "get-language-models",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.LanguageModelConfig"
}
}
}
}
},
"/deployment/ssh": {
"get": {
"security": [
@ -10297,6 +10489,190 @@ const docTemplate = `{
}
}
},
"aisdk.Attachment": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
},
"name": {
"type": "string"
},
"url": {
"type": "string"
}
}
},
"aisdk.Message": {
"type": "object",
"properties": {
"annotations": {
"type": "array",
"items": {}
},
"content": {
"type": "string"
},
"createdAt": {
"type": "array",
"items": {
"type": "integer"
}
},
"experimental_attachments": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.Attachment"
}
},
"id": {
"type": "string"
},
"parts": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.Part"
}
},
"role": {
"type": "string"
}
}
},
"aisdk.Part": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "integer"
}
},
"details": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.ReasoningDetail"
}
},
"mimeType": {
"description": "Type: \"file\"",
"type": "string"
},
"reasoning": {
"description": "Type: \"reasoning\"",
"type": "string"
},
"source": {
"description": "Type: \"source\"",
"allOf": [
{
"$ref": "#/definitions/aisdk.SourceInfo"
}
]
},
"text": {
"description": "Type: \"text\"",
"type": "string"
},
"toolInvocation": {
"description": "Type: \"tool-invocation\"",
"allOf": [
{
"$ref": "#/definitions/aisdk.ToolInvocation"
}
]
},
"type": {
"$ref": "#/definitions/aisdk.PartType"
}
}
},
"aisdk.PartType": {
"type": "string",
"enum": [
"text",
"reasoning",
"tool-invocation",
"source",
"file",
"step-start"
],
"x-enum-varnames": [
"PartTypeText",
"PartTypeReasoning",
"PartTypeToolInvocation",
"PartTypeSource",
"PartTypeFile",
"PartTypeStepStart"
]
},
"aisdk.ReasoningDetail": {
"type": "object",
"properties": {
"data": {
"type": "string"
},
"signature": {
"type": "string"
},
"text": {
"type": "string"
},
"type": {
"type": "string"
}
}
},
"aisdk.SourceInfo": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
},
"data": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": {}
},
"uri": {
"type": "string"
}
}
},
"aisdk.ToolInvocation": {
"type": "object",
"properties": {
"args": {},
"result": {},
"state": {
"$ref": "#/definitions/aisdk.ToolInvocationState"
},
"step": {
"type": "integer"
},
"toolCallId": {
"type": "string"
},
"toolName": {
"type": "string"
}
}
},
"aisdk.ToolInvocationState": {
"type": "string",
"enum": [
"call",
"partial-call",
"result"
],
"x-enum-varnames": [
"ToolInvocationStateCall",
"ToolInvocationStatePartialCall",
"ToolInvocationStateResult"
]
},
"coderd.SCIMUser": {
"type": "object",
"properties": {
@ -10388,6 +10764,37 @@ const docTemplate = `{
}
}
},
"codersdk.AIConfig": {
"type": "object",
"properties": {
"providers": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.AIProviderConfig"
}
}
}
},
"codersdk.AIProviderConfig": {
"type": "object",
"properties": {
"base_url": {
"description": "BaseURL is the base URL to use for the API provider.",
"type": "string"
},
"models": {
"description": "Models is the list of models to use for the API provider.",
"type": "array",
"items": {
"type": "string"
}
},
"type": {
"description": "Type is the type of the API provider.",
"type": "string"
}
}
},
"codersdk.APIKey": {
"type": "object",
"required": [
@ -10973,6 +11380,62 @@ const docTemplate = `{
}
}
},
"codersdk.Chat": {
"type": "object",
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
},
"id": {
"type": "string",
"format": "uuid"
},
"title": {
"type": "string"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"codersdk.ChatMessage": {
"type": "object",
"properties": {
"annotations": {
"type": "array",
"items": {}
},
"content": {
"type": "string"
},
"createdAt": {
"type": "array",
"items": {
"type": "integer"
}
},
"experimental_attachments": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.Attachment"
}
},
"id": {
"type": "string"
},
"parts": {
"type": "array",
"items": {
"$ref": "#/definitions/aisdk.Part"
}
},
"role": {
"type": "string"
}
}
},
"codersdk.ConnectionLatency": {
"type": "object",
"properties": {
@ -11006,6 +11469,20 @@ const docTemplate = `{
}
}
},
"codersdk.CreateChatMessageRequest": {
"type": "object",
"properties": {
"message": {
"$ref": "#/definitions/codersdk.ChatMessage"
},
"model": {
"type": "string"
},
"thinking": {
"type": "boolean"
}
}
},
"codersdk.CreateFirstUserRequest": {
"type": "object",
"required": [
@ -11293,7 +11770,73 @@ const docTemplate = `{
}
},
"codersdk.CreateTestAuditLogRequest": {
"type": "object"
"type": "object",
"properties": {
"action": {
"enum": [
"create",
"write",
"delete",
"start",
"stop"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.AuditAction"
}
]
},
"additional_fields": {
"type": "array",
"items": {
"type": "integer"
}
},
"build_reason": {
"enum": [
"autostart",
"autostop",
"initiator"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.BuildReason"
}
]
},
"organization_id": {
"type": "string",
"format": "uuid"
},
"request_id": {
"type": "string",
"format": "uuid"
},
"resource_id": {
"type": "string",
"format": "uuid"
},
"resource_type": {
"enum": [
"template",
"template_version",
"user",
"workspace",
"workspace_build",
"git_ssh_key",
"auditable_group"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ResourceType"
}
]
},
"time": {
"type": "string",
"format": "date-time"
}
}
},
"codersdk.CreateTokenRequest": {
"type": "object",
@ -11742,6 +12285,9 @@ const docTemplate = `{
"agent_stat_refresh_interval": {
"type": "integer"
},
"ai": {
"$ref": "#/definitions/serpent.Struct-codersdk_AIConfig"
},
"allow_workspace_renames": {
"type": "boolean"
},
@ -12009,9 +12555,11 @@ const docTemplate = `{
"workspace-usage",
"web-push",
"dynamic-parameters",
"workspace-prebuilds"
"workspace-prebuilds",
"agentic-chat"
],
"x-enum-comments": {
"ExperimentAgenticChat": "Enables the new agentic AI chat feature.",
"ExperimentAutoFillParameters": "This should not be taken out of experiments until we have redesigned the feature.",
"ExperimentDynamicParameters": "Enables dynamic parameters when creating a workspace.",
"ExperimentExample": "This isn't used for anything.",
@ -12027,7 +12575,8 @@ const docTemplate = `{
"ExperimentWorkspaceUsage",
"ExperimentWebPush",
"ExperimentDynamicParameters",
"ExperimentWorkspacePrebuilds"
"ExperimentWorkspacePrebuilds",
"ExperimentAgenticChat"
]
},
"codersdk.ExternalAuth": {
@ -12538,6 +13087,33 @@ const docTemplate = `{
"RequiredTemplateVariables"
]
},
"codersdk.LanguageModel": {
"type": "object",
"properties": {
"display_name": {
"type": "string"
},
"id": {
"description": "ID is used by the provider to identify the LLM.",
"type": "string"
},
"provider": {
"description": "Provider is the provider of the LLM. e.g. openai, anthropic, etc.",
"type": "string"
}
}
},
"codersdk.LanguageModelConfig": {
"type": "object",
"properties": {
"models": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.LanguageModel"
}
}
}
},
"codersdk.License": {
"type": "object",
"properties": {
@ -14272,6 +14848,7 @@ const docTemplate = `{
"assign_org_role",
"assign_role",
"audit_log",
"chat",
"crypto_key",
"debug_info",
"deployment_config",
@ -14310,6 +14887,7 @@ const docTemplate = `{
"ResourceAssignOrgRole",
"ResourceAssignRole",
"ResourceAuditLog",
"ResourceChat",
"ResourceCryptoKey",
"ResourceDebugInfo",
"ResourceDeploymentConfig",
@ -18250,6 +18828,14 @@ const docTemplate = `{
}
}
},
"serpent.Struct-codersdk_AIConfig": {
"type": "object",
"properties": {
"value": {
"$ref": "#/definitions/codersdk.AIConfig"
}
}
},
"serpent.URL": {
"type": "object",
"properties": {