Spaces:
Sleeping
Sleeping
File size: 2,994 Bytes
194aaa5 8b922e3 5d04207 194aaa5 5083221 194aaa5 6a9176f 5083221 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 194aaa5 6a9176f 5451b32 194aaa5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | import type { DocumentInfo, Message, Source } from '../types';
import { getAuthHeaders } from '../lib/auth';
export const API_URL = import.meta.env.VITE_API_URL ?? '/api';
export async function fetchDocuments(): Promise<DocumentInfo[]> {
const res = await fetch(`${API_URL}/documents`, {
headers: {
'Content-Type': 'application/json',
...getAuthHeaders(),
},
});
if (!res.ok) throw new Error('Failed to fetch documents');
return res.json();
}
export async function uploadDocument(file: File): Promise<void> {
const formData = new FormData();
formData.append('file', file);
const res = await fetch(`${API_URL}/documents/upload`, {
method: 'POST',
headers: {
...getAuthHeaders(),
},
body: formData,
});
if (!res.ok) {
const errData = await res.json().catch(() => ({}));
throw new Error(errData.detail || `Upload failed (${res.status})`);
}
}
export async function deleteDocument(id: string): Promise<void> {
const res = await fetch(`${API_URL}/documents/${id}`, {
method: 'DELETE',
headers: {
...getAuthHeaders(),
},
});
if (!res.ok) throw new Error('Failed to delete document');
}
export interface StreamChatPayload {
messages: Message[];
document_id: string | null;
}
export interface StreamChatCallbacks {
onChunk: (displayContent: string, sources: Source[] | undefined) => void;
onError: (message: string) => void;
}
export async function streamChat(
payload: StreamChatPayload,
callbacks: StreamChatCallbacks
): Promise<void> {
try {
const res = await fetch(`${API_URL}/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...getAuthHeaders(),
},
body: JSON.stringify(payload),
});
if (!res.ok) {
const errData = await res.json().catch(() => ({}));
throw new Error(errData.detail || `Chat request failed (${res.status})`);
}
if (!res.body) throw new Error('No response body for streaming');
const reader = res.body.getReader();
const decoder = new TextDecoder();
let streamedContent = '';
const delimiter = '\n__SOURCES__:';
while (true) {
const { value, done } = await reader.read();
if (done) break;
streamedContent += decoder.decode(value, { stream: true });
let displayContent = streamedContent;
let sources: Source[] | undefined = undefined;
if (streamedContent.includes(delimiter)) {
const parts = streamedContent.split(delimiter);
displayContent = parts[0];
try {
sources = JSON.parse(parts[1]);
} catch {
// Stream might be incomplete; wait for next chunk
}
}
callbacks.onChunk(displayContent, sources);
}
} catch (error: unknown) {
callbacks.onError(error instanceof Error ? error.message : 'Chat request failed');
}
} |