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

Update main.ts

Browse files
Files changed (1) hide show
  1. main.ts +15 -21
main.ts CHANGED
@@ -38,22 +38,15 @@ class GoogleAIService {
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,8 +122,8 @@ class GoogleAIService {
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,22 +456,19 @@ class GoogleAIService {
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,7 +495,7 @@ class GoogleAIService {
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,17 +591,22 @@ class OpenAICompatibleServer {
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,7 +619,6 @@ class OpenAICompatibleServer {
624
  }
625
  });
626
  }
627
-
628
  let responseText: string;
629
 
630
  // Routing logic based on keywords and content types
 
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
  }
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
  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
  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
  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
  }
620
  });
621
  }
 
622
  let responseText: string;
623
 
624
  // Routing logic based on keywords and content types