Spaces:
Running
Running
/** | |
* 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(); | |
*/ |