This commit is contained in:
2026-04-16 17:21:48 +03:00
parent c8fa4c442d
commit c8e7e4e927
116 changed files with 3720 additions and 4197 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
import { registerAs } from '@nestjs/config';
import { registerAs } from "@nestjs/config";
export const geminiConfig = registerAs('gemini', () => ({
enabled: process.env.ENABLE_GEMINI === 'true',
export const geminiConfig = registerAs("gemini", () => ({
enabled: process.env.ENABLE_GEMINI === "true",
apiKey: process.env.GOOGLE_API_KEY,
defaultModel: process.env.GEMINI_MODEL || 'gemini-2.5-flash',
defaultModel: process.env.GEMINI_MODEL || "gemini-2.5-flash",
}));
+4 -4
View File
@@ -1,7 +1,7 @@
import { Module, Global } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GeminiService } from './gemini.service';
import { geminiConfig } from './gemini.config';
import { Module, Global } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { GeminiService } from "./gemini.service";
import { geminiConfig } from "./gemini.config";
/**
* Gemini AI Module
+27 -27
View File
@@ -1,6 +1,6 @@
import { Injectable, OnModuleInit, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { GoogleGenAI } from '@google/genai';
import { Injectable, OnModuleInit, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { GoogleGenAI } from "@google/genai";
export interface GeminiGenerateOptions {
model?: string;
@@ -10,7 +10,7 @@ export interface GeminiGenerateOptions {
}
export interface GeminiChatMessage {
role: 'user' | 'model';
role: "user" | "model";
content: string;
}
@@ -48,34 +48,34 @@ export class GeminiService implements OnModuleInit {
private defaultModel: string;
constructor(private readonly configService: ConfigService) {
this.isEnabled = this.configService.get<boolean>('gemini.enabled', false);
this.isEnabled = this.configService.get<boolean>("gemini.enabled", false);
this.defaultModel = this.configService.get<string>(
'gemini.defaultModel',
'gemini-2.5-flash',
"gemini.defaultModel",
"gemini-2.5-flash",
);
}
onModuleInit() {
if (!this.isEnabled) {
this.logger.log(
'Gemini AI is disabled. Set ENABLE_GEMINI=true to enable.',
"Gemini AI is disabled. Set ENABLE_GEMINI=true to enable.",
);
return;
}
const apiKey = this.configService.get<string>('gemini.apiKey');
const apiKey = this.configService.get<string>("gemini.apiKey");
if (!apiKey) {
this.logger.warn(
'GOOGLE_API_KEY is not set. Gemini features will not work.',
"GOOGLE_API_KEY is not set. Gemini features will not work.",
);
return;
}
try {
this.client = new GoogleGenAI({ apiKey });
this.logger.log('✅ Gemini AI initialized successfully');
this.logger.log("✅ Gemini AI initialized successfully");
} catch (error) {
this.logger.error('Failed to initialize Gemini AI', error);
this.logger.error("Failed to initialize Gemini AI", error);
}
}
@@ -98,7 +98,7 @@ export class GeminiService implements OnModuleInit {
options: GeminiGenerateOptions = {},
): Promise<{ text: string; usage?: any }> {
if (!this.isAvailable()) {
throw new Error('Gemini AI is not available. Check your configuration.');
throw new Error("Gemini AI is not available. Check your configuration.");
}
const model = options.model || this.defaultModel;
@@ -109,17 +109,17 @@ export class GeminiService implements OnModuleInit {
// Add system prompt if provided
if (options.systemPrompt) {
contents.push({
role: 'user',
role: "user",
parts: [{ text: options.systemPrompt }],
});
contents.push({
role: 'model',
parts: [{ text: 'Understood. I will follow these instructions.' }],
role: "model",
parts: [{ text: "Understood. I will follow these instructions." }],
});
}
contents.push({
role: 'user',
role: "user",
parts: [{ text: prompt }],
});
@@ -133,11 +133,11 @@ export class GeminiService implements OnModuleInit {
});
return {
text: (response.text || '').trim(),
text: (response.text || "").trim(),
usage: response.usageMetadata,
};
} catch (error) {
this.logger.error('Gemini generation failed', error);
this.logger.error("Gemini generation failed", error);
throw error;
}
}
@@ -154,7 +154,7 @@ export class GeminiService implements OnModuleInit {
options: GeminiGenerateOptions = {},
): Promise<{ text: string; usage?: any }> {
if (!this.isAvailable()) {
throw new Error('Gemini AI is not available. Check your configuration.');
throw new Error("Gemini AI is not available. Check your configuration.");
}
const model = options.model || this.defaultModel;
@@ -169,12 +169,12 @@ export class GeminiService implements OnModuleInit {
if (options.systemPrompt) {
contents.unshift(
{
role: 'user',
role: "user",
parts: [{ text: options.systemPrompt }],
},
{
role: 'model',
parts: [{ text: 'Understood. I will follow these instructions.' }],
role: "model",
parts: [{ text: "Understood. I will follow these instructions." }],
},
);
}
@@ -189,11 +189,11 @@ export class GeminiService implements OnModuleInit {
});
return {
text: (response.text || '').trim(),
text: (response.text || "").trim(),
usage: response.usageMetadata,
};
} catch (error) {
this.logger.error('Gemini chat failed', error);
this.logger.error("Gemini chat failed", error);
throw error;
}
}
@@ -233,8 +233,8 @@ IMPORTANT: Only output valid JSON, no markdown code blocks or other text.`;
const data = JSON.parse(jsonStr) as T;
return { data, usage: response.usage };
} catch (error) {
this.logger.error('Failed to parse JSON response', error);
throw new Error('Failed to parse AI response as JSON');
this.logger.error("Failed to parse JSON response", error);
throw new Error("Failed to parse AI response as JSON");
}
}
}
+3 -3
View File
@@ -1,3 +1,3 @@
export * from './gemini.module';
export * from './gemini.service';
export * from './gemini.config';
export * from "./gemini.module";
export * from "./gemini.service";
export * from "./gemini.config";