Spaces:
Paused
Paused
| /** | |
| * Example client for integrating with the Hono proxy from Next.js | |
| * Place this in your Next.js app at: lib/api-client.ts | |
| */ | |
| const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000/api'; | |
| export interface SearchResult { | |
| root: { | |
| children: Array<{ | |
| id: string; | |
| relevance: number; | |
| fields: { | |
| id: string; | |
| title: string; | |
| page_number: number; | |
| text: string; | |
| image: string; // base64 | |
| image_url: string; // Added by proxy | |
| full_image_url: string; // Added by proxy | |
| }; | |
| }>; | |
| }; | |
| } | |
| export interface ChatMessage { | |
| role: 'user' | 'assistant' | 'system'; | |
| content: string; | |
| } | |
| class ColPaliClient { | |
| private async fetchWithTimeout(url: string, options: RequestInit, timeout = 30000) { | |
| const controller = new AbortController(); | |
| const id = setTimeout(() => controller.abort(), timeout); | |
| try { | |
| const response = await fetch(url, { | |
| ...options, | |
| signal: controller.signal, | |
| }); | |
| return response; | |
| } finally { | |
| clearTimeout(id); | |
| } | |
| } | |
| async search(query: string, limit = 10): Promise<SearchResult> { | |
| const response = await this.fetchWithTimeout(`${API_URL}/search`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ query, limit }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`Search failed: ${response.statusText}`); | |
| } | |
| return response.json(); | |
| } | |
| async* chat(messages: ChatMessage[], context: string[] = []) { | |
| const response = await fetch(`${API_URL}/chat`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ messages, context }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`Chat failed: ${response.statusText}`); | |
| } | |
| const reader = response.body?.getReader(); | |
| if (!reader) throw new Error('No response body'); | |
| const decoder = new TextDecoder(); | |
| let buffer = ''; | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (done) break; | |
| buffer += decoder.decode(value, { stream: true }); | |
| const lines = buffer.split('\\n'); | |
| buffer = lines.pop() || ''; | |
| for (const line of lines) { | |
| if (line.startsWith('data: ')) { | |
| const data = line.slice(6); | |
| if (data === '[DONE]') return; | |
| try { | |
| const parsed = JSON.parse(data); | |
| yield parsed; | |
| } catch (e) { | |
| console.error('Failed to parse SSE data:', e); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| async getSimilarityMap(docId: string, query: string) { | |
| const response = await this.fetchWithTimeout(`${API_URL}/search/similarity-map`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ docId, query }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`Similarity map failed: ${response.statusText}`); | |
| } | |
| return response.json(); | |
| } | |
| getImageUrl(docId: string, type: 'thumbnail' | 'full' = 'thumbnail'): string { | |
| return `${API_URL}/search/image/${docId}/${type}`; | |
| } | |
| async checkHealth() { | |
| const response = await this.fetchWithTimeout(`${API_URL.replace('/api', '')}/health`, { | |
| method: 'GET', | |
| }, 5000); | |
| return response.json(); | |
| } | |
| } | |
| // Export singleton instance | |
| export const colpaliClient = new ColPaliClient(); | |
| // Usage examples: | |
| /* | |
| // In your Next.js component or API route: | |
| // Search | |
| const results = await colpaliClient.search('annual report 2023', 20); | |
| // Display images directly from proxy URLs | |
| results.root.children.forEach(hit => { | |
| const imageUrl = hit.fields.image_url; // Proxy URL for thumbnail | |
| const fullImageUrl = hit.fields.full_image_url; // Proxy URL for full image | |
| }); | |
| // Chat with streaming | |
| const messages = [{ role: 'user', content: 'What is the revenue?' }]; | |
| for await (const chunk of colpaliClient.chat(messages)) { | |
| console.log(chunk); | |
| } | |
| // Get image URL for direct use in <img> tags | |
| const imageUrl = colpaliClient.getImageUrl('doc123', 'thumbnail'); | |
| // Check system health | |
| const health = await colpaliClient.checkHealth(); | |
| */ |