mirror of
https://github.com/coder/coder.git
synced 2026-10-25 09:42:55 +08:00
feat: add file/image attachment support to chat input (#22604)
This change adds support for image attachments to chat via add button and clipboard paste. Files are stored in a new `chat_files` table and referenced by ID in message content. File data is resolved from storage at LLM dispatch time, keeping the message content column small. Upload validates MIME types via content type or content sniffing against an allowlist (png, jpeg, gif, webp). The retrieval endpoint serves files with immutable caching headers. On the frontend, uploads start eagerly on attach with a background fetch to pre-warm the browser HTTP cache so the timeline renders instantly after send.
This commit is contained in:
@@ -2296,6 +2296,23 @@ class ApiMethods {
|
||||
return response.data;
|
||||
};
|
||||
|
||||
uploadChatFile = async (
|
||||
file: File,
|
||||
organizationId: string,
|
||||
): Promise<TypesGen.UploadChatFileResponse> => {
|
||||
const response = await this.axios.post(
|
||||
`/api/experimental/chats/files?organization=${organizationId}`,
|
||||
file,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": file.type || "application/octet-stream",
|
||||
"Content-Disposition": `attachment; filename="${file.name}"`,
|
||||
},
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
getTemplateVersionLogs = async (
|
||||
versionId: string,
|
||||
): Promise<TypesGen.ProvisionerJobLog[]> => {
|
||||
|
||||
Generated
+12
-2
@@ -1120,12 +1120,13 @@ export interface ChatGitChange {
|
||||
export interface ChatInputPart {
|
||||
readonly type: ChatInputPartType;
|
||||
readonly text?: string;
|
||||
readonly file_id?: string;
|
||||
}
|
||||
|
||||
// From codersdk/chats.go
|
||||
export type ChatInputPartType = "text";
|
||||
export type ChatInputPartType = "file" | "text";
|
||||
|
||||
export const ChatInputPartTypes: ChatInputPartType[] = ["text"];
|
||||
export const ChatInputPartTypes: ChatInputPartType[] = ["file", "text"];
|
||||
|
||||
// From codersdk/chats.go
|
||||
/**
|
||||
@@ -1161,6 +1162,7 @@ export interface ChatMessagePart {
|
||||
readonly title?: string;
|
||||
readonly media_type?: string;
|
||||
readonly data?: string;
|
||||
readonly file_id?: string;
|
||||
}
|
||||
|
||||
// From codersdk/chats.go
|
||||
@@ -6556,6 +6558,14 @@ export interface UpdateWorkspaceTTLRequest {
|
||||
readonly ttl_ms: number | null;
|
||||
}
|
||||
|
||||
// From codersdk/chats.go
|
||||
/**
|
||||
* UploadChatFileResponse is the response from uploading a chat file.
|
||||
*/
|
||||
export interface UploadChatFileResponse {
|
||||
readonly id: string;
|
||||
}
|
||||
|
||||
// From codersdk/files.go
|
||||
/**
|
||||
* UploadResponse contains the hash to reference the uploaded file.
|
||||
|
||||
Reference in New Issue
Block a user