Ojochegbeng commited on
Commit
7b0539d
·
verified ·
1 Parent(s): 13929ce

Delete qwen-embedding-service-docker.ts

Browse files
Files changed (1) hide show
  1. qwen-embedding-service-docker.ts +0 -209
qwen-embedding-service-docker.ts DELETED
@@ -1,209 +0,0 @@
1
- // Qwen Embedding Service using Docker-based Hugging Face Space
2
- // This version uses direct HTTP calls instead of Gradio client for better stability
3
-
4
- const QWEN_API_URL = process.env.QWEN_API_URL || 'https://your-username-qwen-embedding-api.hf.space';
5
-
6
- // Helper function to call Qwen Embeddings API via HTTP
7
- export async function generateQwenEmbeddings(texts: string[]): Promise<number[][]> {
8
- try {
9
- console.log(`Calling Qwen API for ${texts.length} texts...`);
10
-
11
- const response = await fetch(`${QWEN_API_URL}/api/predict`, {
12
- method: 'POST',
13
- headers: {
14
- 'Content-Type': 'application/json',
15
- },
16
- body: JSON.stringify({
17
- data: [texts] // Wrap in array for batch processing
18
- }),
19
- });
20
-
21
- if (!response.ok) {
22
- throw new Error(`HTTP error! status: ${response.status}`);
23
- }
24
-
25
- const data = await response.json();
26
-
27
- if (data.error) {
28
- throw new Error(`API Error: ${data.error}`);
29
- }
30
-
31
- // The response should be in the format: { data: [embeddings] }
32
- const embeddings = data.data[0];
33
-
34
- if (!Array.isArray(embeddings)) {
35
- throw new Error('Invalid embeddings format received from Qwen API');
36
- }
37
-
38
- // Validate embeddings
39
- for (let i = 0; i < embeddings.length; i++) {
40
- if (!Array.isArray(embeddings[i])) {
41
- throw new Error(`Embedding ${i} is not an array`);
42
- }
43
- if (embeddings[i].length === 0) {
44
- throw new Error(`Embedding ${i} is empty`);
45
- }
46
- }
47
-
48
- console.log(`Successfully generated ${embeddings.length} embeddings`);
49
- return embeddings;
50
-
51
- } catch (error) {
52
- console.error('Error calling Qwen embeddings API:', error);
53
- throw error;
54
- }
55
- }
56
-
57
- // Helper function to generate single embedding
58
- export async function generateSingleQwenEmbedding(text: string): Promise<number[]> {
59
- try {
60
- console.log('Calling Qwen API for single text...');
61
-
62
- const response = await fetch(`${QWEN_API_URL}/api/predict`, {
63
- method: 'POST',
64
- headers: {
65
- 'Content-Type': 'application/json',
66
- },
67
- body: JSON.stringify({
68
- data: [text] // Single text
69
- }),
70
- });
71
-
72
- if (!response.ok) {
73
- throw new Error(`HTTP error! status: ${response.status}`);
74
- }
75
-
76
- const data = await response.json();
77
-
78
- if (data.error) {
79
- throw new Error(`API Error: ${data.error}`);
80
- }
81
-
82
- // The response should be in the format: { data: [embedding] }
83
- const embedding = data.data[0];
84
-
85
- if (!Array.isArray(embedding)) {
86
- throw new Error('Invalid embedding format received from Qwen API');
87
- }
88
-
89
- if (embedding.length === 0) {
90
- throw new Error('Empty embedding received from Qwen API');
91
- }
92
-
93
- console.log('Successfully generated single embedding');
94
- return embedding;
95
-
96
- } catch (error) {
97
- console.error('Error calling Qwen single embedding API:', error);
98
- // Fallback to batch processing
99
- const embeddings = await generateQwenEmbeddings([text]);
100
- return embeddings[0];
101
- }
102
- }
103
-
104
- // Health check function
105
- export async function checkQwenAPIHealth(): Promise<boolean> {
106
- try {
107
- const response = await fetch(`${QWEN_API_URL}/health`, {
108
- method: 'GET',
109
- });
110
-
111
- if (!response.ok) {
112
- return false;
113
- }
114
-
115
- const data = await response.json();
116
- return data.status === 'healthy' && data.model_loaded === true;
117
-
118
- } catch (error) {
119
- console.error('Health check failed:', error);
120
- return false;
121
- }
122
- }
123
-
124
- // Retry mechanism for Qwen API
125
- async function generateQwenEmbeddingsWithRetry(texts: string[], maxRetries: number = 3): Promise<number[][]> {
126
- let lastError: Error | null = null;
127
-
128
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
129
- try {
130
- console.log(`Attempt ${attempt}/${maxRetries} to generate embeddings...`);
131
- return await generateQwenEmbeddings(texts);
132
- } catch (error) {
133
- lastError = error as Error;
134
- console.warn(`Attempt ${attempt} failed:`, error);
135
-
136
- if (attempt < maxRetries) {
137
- const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
138
- console.log(`Waiting ${delay}ms before retry...`);
139
- await new Promise(resolve => setTimeout(resolve, delay));
140
- }
141
- }
142
- }
143
-
144
- throw lastError || new Error('Qwen API failed after all retries');
145
- }
146
-
147
- // Fallback to Jina if Qwen fails
148
- export async function generateEmbeddingsWithFallback(texts: string[]): Promise<number[][]> {
149
- try {
150
- // Check API health first
151
- const isHealthy = await checkQwenAPIHealth();
152
- if (!isHealthy) {
153
- throw new Error('Qwen API is not healthy');
154
- }
155
-
156
- // Try Qwen first with retry
157
- return await generateQwenEmbeddingsWithRetry(texts);
158
- } catch (qwenError) {
159
- console.warn('Qwen API failed after retries, falling back to Jina:', qwenError);
160
-
161
- // Fallback to Jina
162
- const JINA_API_KEY = process.env.JINA_API_KEY;
163
- const JINA_EMBEDDINGS_MODEL = process.env.JINA_EMBEDDINGS_MODEL || 'jina-embeddings-v3';
164
-
165
- if (!JINA_API_KEY) {
166
- throw new Error('Both Qwen and Jina APIs failed. JINA_API_KEY not available for fallback.');
167
- }
168
-
169
- const response = await fetch('https://api.jina.ai/v1/embeddings', {
170
- method: 'POST',
171
- headers: {
172
- 'Content-Type': 'application/json',
173
- 'Authorization': `Bearer ${JINA_API_KEY}`,
174
- },
175
- body: JSON.stringify({
176
- model: JINA_EMBEDDINGS_MODEL,
177
- input: texts,
178
- }),
179
- });
180
-
181
- if (!response.ok) {
182
- const errorText = await response.text();
183
- throw new Error(`Jina API error: ${response.status} ${response.statusText} - ${errorText}`);
184
- }
185
-
186
- const data = await response.json();
187
- return data.data.map((item: any) => item.embedding);
188
- }
189
- }
190
-
191
- // Main function that uses Qwen with Jina fallback
192
- export async function generateEmbeddings(texts: string[]): Promise<number[][]> {
193
- // For single text, use the optimized single embedding endpoint
194
- if (texts.length === 1) {
195
- try {
196
- const embedding = await generateSingleQwenEmbedding(texts[0]);
197
- return [embedding];
198
- } catch (error) {
199
- console.warn('Single embedding failed, falling back to batch processing:', error);
200
- // Fall through to batch processing
201
- }
202
- }
203
-
204
- // Use batch processing with fallback
205
- return await generateEmbeddingsWithFallback(texts);
206
- }
207
-
208
- // Export the single embedding function for compatibility
209
- export const generateSingleEmbedding = generateSingleQwenEmbedding;