feat: treeview with folders, toolbar, file attachments in chat

This commit is contained in:
Agent Zero
2026-07-17 09:21:40 +02:00
parent 9a29206190
commit 202d80c750
4 changed files with 349 additions and 57 deletions
+51 -1
View File
@@ -61,6 +61,14 @@ export interface AIAgent {
updated_at?: string;
}
export interface ChatFolder {
id: string;
name: string;
parent_id: string | null;
user_id: string;
created_at?: string;
}
export interface ChatSession {
id: string;
user_id: string;
@@ -68,6 +76,7 @@ export interface ChatSession {
title: string;
is_pinned: boolean;
is_sidebar: boolean;
folder_id: string | null;
created_at?: string;
updated_at?: string;
}
@@ -84,6 +93,15 @@ export interface ChatMessage {
created_at?: string;
}
export interface ChatAttachment {
id: string;
message_id: string | null;
session_id: string;
filename: string;
mime_type: string;
size_bytes: number;
}
export interface AITool {
name: string;
description: string;
@@ -126,11 +144,18 @@ export const deleteAgent = (id: string) => apiDelete(`/ai/agents/${id}`);
export const fetchTools = () => apiGet<AITool[]>('/ai/tools');
// ─── Folders ───
export const fetchFolders = () => apiGet<ChatFolder[]>('/ai/folders');
export const createFolder = (data: { name: string; parent_id?: string }) => apiPost<ChatFolder>('/ai/folders', data);
export const updateFolder = (id: string, data: Partial<ChatFolder>) => apiPut<ChatFolder>(`/ai/folders/${id}`, data);
export const deleteFolder = (id: string) => apiDelete(`/ai/folders/${id}`);
// ─── Sessions ───
export const fetchSessions = (isSidebar?: boolean) =>
apiGet<ChatSession[]>('/ai/sessions', { params: isSidebar !== undefined ? { is_sidebar: isSidebar } : {} });
export const createSession = (data: { title?: string; agent_id?: string; is_sidebar?: boolean }) =>
export const createSession = (data: { title?: string; agent_id?: string; is_sidebar?: boolean; folder_id?: string }) =>
apiPost<ChatSession>('/ai/sessions', data);
export const updateSession = (id: string, data: Partial<ChatSession>) =>
apiPut<ChatSession>(`/ai/sessions/${id}`, data);
@@ -141,6 +166,31 @@ export const deleteSession = (id: string) => apiDelete(`/ai/sessions/${id}`);
export const fetchMessages = (sessionId: string) =>
apiGet<ChatMessage[]>(`/ai/sessions/${sessionId}/messages`);
// ─── Attachments ───
export const fetchAttachments = (sessionId: string) =>
apiGet<ChatAttachment[]>(`/ai/sessions/${sessionId}/attachments`);
export async function uploadAttachment(sessionId: string, file: File): Promise<ChatAttachment> {
const formData = new FormData();
formData.append('file', file);
const csrfToken = sessionStorage.getItem('leocrm_csrf_token');
const response = await fetch(`/api/v1/ai/sessions/${sessionId}/attachments`, {
method: 'POST',
headers: {
...(csrfToken ? { 'X-CSRF-Token': csrfToken } : {}),
},
credentials: 'include',
body: formData,
});
if (!response.ok) throw new Error(`Upload failed: ${response.status}`);
return response.json();
}
export function getAttachmentDownloadUrl(attachmentId: string): string {
return `/api/v1/ai/attachments/${attachmentId}/download`;
}
// ─── Streaming Chat ───
export interface StreamEvent {