xt8 commited on
Commit
14886ca
·
verified ·
1 Parent(s): c05651a

Update main.ts

Browse files
Files changed (1) hide show
  1. main.ts +21 -15
main.ts CHANGED
@@ -38,15 +38,22 @@ class GoogleAIService {
38
 
39
  constructor() {
40
  this.apiKeys = [];
41
- this.apiKeys = Deno.env.get(`GOOGLE_AI_KEYS`).split(',').map(s => s.trim());
 
 
 
 
 
 
 
 
42
  if (this.apiKeys.length === 0) {
43
- throw new Error("No Google AI API keys found in environment variables (e.g., GOOGLE_AI_KEYS)");
44
  }
45
  }
46
 
47
  private getNextApiKey(): string {
48
  const key = this.apiKeys[this.currentKeyIndex];
49
- console.log(key)
50
  this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length;
51
  return key;
52
  }
@@ -122,8 +129,8 @@ class GoogleAIService {
122
  }
123
 
124
  public isVisionModel = (modelName: string): boolean => modelName.toLowerCase().includes('vision') || modelName.toLowerCase().includes('pro');
125
- public isImageGenerationModel = (modelName: string): boolean => modelName.includes('image') || modelName === 'gemini-2.0-flash-preview-image-generation' || modelName === 'gemini-2.5-flash-image-preview';
126
- public isImageEditingModel = (modelName: string): boolean => modelName.includes('image') || modelName === 'gemini-2.0-flash-preview-image-generation' || modelName === 'gemini-2.5-flash-image-preview';
127
  public isDocumentModel = (modelName: string): boolean => modelName.toLowerCase().includes('gemini-1.5') || modelName.toLowerCase().includes('pro') || modelName.toLowerCase().includes('flash');
128
  public isTTSModel = (modelName: string): boolean => modelName.toLowerCase().includes('tts');
129
 
@@ -456,19 +463,22 @@ class GoogleAIService {
456
  tools: [{ googleSearch: {} }],
457
  generationConfig: { temperature: 0.7, maxOutputTokens: maxTokens || 8192 }
458
  };
 
459
  const response = await fetch(
460
  `https://generativelanguage.googleapis.com/v1beta/${fullModelName}:generateContent?key=${apiKey}`,
461
  { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }
462
  );
 
463
  if (!response.ok) {
464
  console.warn(`Google Search API failed: ${response.status}, trying alternative.`);
465
  return await this.generateContentWithSearchPrompt(messages, modelName, maxTokens);
466
  }
 
467
  const data = await response.json();
468
  if (!data.candidates || data.candidates.length === 0) {
469
  return await this.generateContentWithSearchPrompt(messages, modelName, maxTokens);
470
  }
471
-
472
  const candidate = data.candidates[0];
473
  if (candidate.finishReason === "SAFETY") {
474
  throw new Error("Response blocked due to safety filters");
@@ -495,7 +505,7 @@ class GoogleAIService {
495
  const result = await this.generateOrEditImageWithGemini(prompt, modelName, inputImage);
496
  let response = "";
497
  if (result.text) response += result.text + "\\\\n\\\\n";
498
- if (result.imageUrl) response += `![image](${result.imageUrl})`;
499
  return response || `Image processing complete.`;
500
  } catch (error) {
501
  return `Image processing failed: ${error.message}`;
@@ -591,22 +601,17 @@ class OpenAICompatibleServer {
591
  const stream = body.stream || false;
592
  const maxTokens = body.max_tokens || 1048576;
593
  console.log(`Request for model: ${requestedModel}, stream: ${stream}, max_tokens: ${maxTokens}`);
 
594
  const lastMessage = body.messages[body.messages.length - 1];
595
  const content = typeof lastMessage.content === "string"
596
  ? lastMessage.content
597
  : (Array.isArray(lastMessage.content) ? lastMessage.content.map(p => p.text || "").join(" ") : "");
598
- if (content == 'ping'){
599
- const responsePayload = {
600
- id: `chatcmpl-${Date.now()}`, object: "chat.completion", created: Math.floor(Date.now() / 1000), model: requestedModel,
601
- choices: [{ index: 0, message: { role: "assistant", content: "pong" }, finish_reason: "stop" }],
602
- usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 }
603
- };
604
- return new Response(JSON.stringify(responsePayload), { headers: { "Content-Type": "application/json" } });
605
- }
606
  const hasDocument = body.messages.some(msg =>
607
  Array.isArray(msg.content) &&
608
  msg.content.some(part => part.type === "document" || this.isDocumentContent(part.document?.url))
609
  );
 
610
  const hasImages = body.messages.some(msg => Array.isArray(msg.content) && msg.content.some(part => part.type === "image_url"));
611
 
612
  let inputImages: any[] = [];
@@ -619,6 +624,7 @@ class OpenAICompatibleServer {
619
  }
620
  });
621
  }
 
622
  let responseText: string;
623
 
624
  // Routing logic based on keywords and content types
 
38
 
39
  constructor() {
40
  this.apiKeys = [];
41
+ let i = 1;
42
+ while (true) {
43
+ const key = Deno.env.get(`GOOGLE_AI_KEY_${i}`) ||
44
+ (i === 1 ? Deno.env.get("GOOGLE_AI_KEY") : null);
45
+ if (!key) break;
46
+ this.apiKeys.push(key);
47
+ i++;
48
+ }
49
+
50
  if (this.apiKeys.length === 0) {
51
+ throw new Error("No Google AI API keys found in environment variables (e.g., GOOGLE_AI_KEY_1, GOOGLE_AI_KEY)");
52
  }
53
  }
54
 
55
  private getNextApiKey(): string {
56
  const key = this.apiKeys[this.currentKeyIndex];
 
57
  this.currentKeyIndex = (this.currentKeyIndex + 1) % this.apiKeys.length;
58
  return key;
59
  }
 
129
  }
130
 
131
  public isVisionModel = (modelName: string): boolean => modelName.toLowerCase().includes('vision') || modelName.toLowerCase().includes('pro');
132
+ public isImageGenerationModel = (modelName: string): boolean => modelName.includes('image-generation') || modelName === 'gemini-2.0-flash-preview-image-generation';
133
+ public isImageEditingModel = (modelName: string): boolean => modelName.includes('image-generation') || modelName === 'gemini-2.0-flash-preview-image-generation';
134
  public isDocumentModel = (modelName: string): boolean => modelName.toLowerCase().includes('gemini-1.5') || modelName.toLowerCase().includes('pro') || modelName.toLowerCase().includes('flash');
135
  public isTTSModel = (modelName: string): boolean => modelName.toLowerCase().includes('tts');
136
 
 
463
  tools: [{ googleSearch: {} }],
464
  generationConfig: { temperature: 0.7, maxOutputTokens: maxTokens || 8192 }
465
  };
466
+
467
  const response = await fetch(
468
  `https://generativelanguage.googleapis.com/v1beta/${fullModelName}:generateContent?key=${apiKey}`,
469
  { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }
470
  );
471
+
472
  if (!response.ok) {
473
  console.warn(`Google Search API failed: ${response.status}, trying alternative.`);
474
  return await this.generateContentWithSearchPrompt(messages, modelName, maxTokens);
475
  }
476
+
477
  const data = await response.json();
478
  if (!data.candidates || data.candidates.length === 0) {
479
  return await this.generateContentWithSearchPrompt(messages, modelName, maxTokens);
480
  }
481
+
482
  const candidate = data.candidates[0];
483
  if (candidate.finishReason === "SAFETY") {
484
  throw new Error("Response blocked due to safety filters");
 
505
  const result = await this.generateOrEditImageWithGemini(prompt, modelName, inputImage);
506
  let response = "";
507
  if (result.text) response += result.text + "\\\\n\\\\n";
508
+ if (result.imageUrl) response += `${inputImage ? 'Edited' : 'Generated'} image:\\\\n${result.imageUrl}`;
509
  return response || `Image processing complete.`;
510
  } catch (error) {
511
  return `Image processing failed: ${error.message}`;
 
601
  const stream = body.stream || false;
602
  const maxTokens = body.max_tokens || 1048576;
603
  console.log(`Request for model: ${requestedModel}, stream: ${stream}, max_tokens: ${maxTokens}`);
604
+
605
  const lastMessage = body.messages[body.messages.length - 1];
606
  const content = typeof lastMessage.content === "string"
607
  ? lastMessage.content
608
  : (Array.isArray(lastMessage.content) ? lastMessage.content.map(p => p.text || "").join(" ") : "");
609
+
 
 
 
 
 
 
 
610
  const hasDocument = body.messages.some(msg =>
611
  Array.isArray(msg.content) &&
612
  msg.content.some(part => part.type === "document" || this.isDocumentContent(part.document?.url))
613
  );
614
+
615
  const hasImages = body.messages.some(msg => Array.isArray(msg.content) && msg.content.some(part => part.type === "image_url"));
616
 
617
  let inputImages: any[] = [];
 
624
  }
625
  });
626
  }
627
+
628
  let responseText: string;
629
 
630
  // Routing logic based on keywords and content types