@drax/ai-back 3.31.0 → 3.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/GoogleAiConfig.js +9 -0
- package/dist/factory/AiProviderFactory.js +8 -3
- package/dist/factory/GoogleAiProviderFactory.js +14 -0
- package/dist/index.js +4 -1
- package/dist/providers/GoogleAiProvider.js +367 -0
- package/dist/tools/BuilderTool.js +9 -0
- package/package.json +5 -3
- package/src/config/GoogleAiConfig.ts +14 -0
- package/src/factory/AiProviderFactory.ts +8 -5
- package/src/factory/GoogleAiProviderFactory.ts +26 -0
- package/src/index.ts +6 -0
- package/src/providers/GoogleAiProvider.ts +489 -0
- package/src/tools/BuilderTool.ts +12 -0
- package/test/GoogleAiProvider.test.ts +211 -0
- package/test/ToolBuilder.test.ts +48 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/types/config/GoogleAiConfig.d.ts +9 -0
- package/types/config/GoogleAiConfig.d.ts.map +1 -0
- package/types/factory/AiProviderFactory.d.ts.map +1 -1
- package/types/factory/GoogleAiProviderFactory.d.ts +8 -0
- package/types/factory/GoogleAiProviderFactory.d.ts.map +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/providers/GoogleAiProvider.d.ts +63 -0
- package/types/providers/GoogleAiProvider.d.ts.map +1 -0
- package/types/tools/BuilderTool.d.ts.map +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var GoogleAiConfig;
|
|
2
|
+
(function (GoogleAiConfig) {
|
|
3
|
+
GoogleAiConfig["GoogleAiApiKey"] = "GOOGLE_AI_API_KEY";
|
|
4
|
+
GoogleAiConfig["GoogleApiKey"] = "GOOGLE_API_KEY";
|
|
5
|
+
GoogleAiConfig["GoogleAiModel"] = "GOOGLE_AI_MODEL";
|
|
6
|
+
GoogleAiConfig["GoogleAiVisionModel"] = "GOOGLE_AI_VISION_MODEL";
|
|
7
|
+
})(GoogleAiConfig || (GoogleAiConfig = {}));
|
|
8
|
+
export default GoogleAiConfig;
|
|
9
|
+
export { GoogleAiConfig };
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import OpenAiProviderFactory from "./OpenAiProviderFactory.js";
|
|
2
|
+
import GoogleAiProviderFactory from "./GoogleAiProviderFactory.js";
|
|
2
3
|
class AiProviderFactory {
|
|
3
4
|
static instance(provider = 'OpenAi') {
|
|
4
|
-
if (!AiProviderFactory.
|
|
5
|
+
if (!AiProviderFactory.singletons[provider]) {
|
|
5
6
|
switch (provider) {
|
|
6
7
|
case 'OpenAi':
|
|
7
|
-
AiProviderFactory.
|
|
8
|
+
AiProviderFactory.singletons[provider] = OpenAiProviderFactory.instance();
|
|
9
|
+
break;
|
|
10
|
+
case 'GoogleAi':
|
|
11
|
+
AiProviderFactory.singletons[provider] = GoogleAiProviderFactory.instance();
|
|
8
12
|
break;
|
|
9
13
|
default:
|
|
10
14
|
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
|
-
return AiProviderFactory.
|
|
17
|
+
return AiProviderFactory.singletons[provider];
|
|
14
18
|
}
|
|
15
19
|
}
|
|
20
|
+
AiProviderFactory.singletons = {};
|
|
16
21
|
export default AiProviderFactory;
|
|
17
22
|
export { AiProviderFactory };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DraxConfig } from "@drax/common-back";
|
|
2
|
+
import GoogleAiConfig from "../config/GoogleAiConfig.js";
|
|
3
|
+
import GoogleAiProvider from "../providers/GoogleAiProvider.js";
|
|
4
|
+
import AILogServiceFactory from "./services/AILogServiceFactory.js";
|
|
5
|
+
class GoogleAiProviderFactory {
|
|
6
|
+
static instance() {
|
|
7
|
+
if (!GoogleAiProviderFactory.singleton) {
|
|
8
|
+
GoogleAiProviderFactory.singleton = new GoogleAiProvider(DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiApiKey) ?? DraxConfig.getOrLoad(GoogleAiConfig.GoogleApiKey), DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiModel), DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiVisionModel), AILogServiceFactory.instance);
|
|
9
|
+
}
|
|
10
|
+
return GoogleAiProviderFactory.singleton;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export default GoogleAiProviderFactory;
|
|
14
|
+
export { GoogleAiProviderFactory };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { OpenAiConfig } from "./config/OpenAiConfig.js";
|
|
2
|
+
import { GoogleAiConfig } from "./config/GoogleAiConfig.js";
|
|
2
3
|
import { AILogSchema, AILogBaseSchema } from "./schemas/AILogSchema.js";
|
|
3
4
|
import AILogModel from "./models/AILogModel.js";
|
|
4
5
|
import AILogMongoRepository from "./repository/mongo/AILogMongoRepository.js";
|
|
5
6
|
import AILogSqliteRepository from "./repository/sqlite/AILogSqliteRepository.js";
|
|
6
7
|
import { OpenAiProviderFactory } from "./factory/OpenAiProviderFactory.js";
|
|
8
|
+
import { GoogleAiProviderFactory } from "./factory/GoogleAiProviderFactory.js";
|
|
7
9
|
import { AiProviderFactory } from "./factory/AiProviderFactory.js";
|
|
8
10
|
import AILogServiceFactory from "./factory/services/AILogServiceFactory.js";
|
|
9
11
|
import { OpenAiProvider } from "./providers/OpenAiProvider.js";
|
|
12
|
+
import { GoogleAiProvider } from "./providers/GoogleAiProvider.js";
|
|
10
13
|
import { BuilderTool } from "./tools/BuilderTool.js";
|
|
11
14
|
import { KnowledgeService } from "./services/KnowledgeService.js";
|
|
12
15
|
import { AILogService } from "./services/AILogService.js";
|
|
@@ -24,7 +27,7 @@ import AIRoutes from "./routes/AIRoutes.js";
|
|
|
24
27
|
import DraxAgentRoutes from "./routes/DraxAgentRoutes.js";
|
|
25
28
|
import AgentSessionRoutes from "./routes/AgentSessionRoutes.js";
|
|
26
29
|
import { DraxAgent } from "./agents/DraxAgent.js";
|
|
27
|
-
export { OpenAiConfig, AILogSchema, AILogBaseSchema, AILogModel, AILogMongoRepository, AILogSqliteRepository, OpenAiProviderFactory, AiProviderFactory, AILogServiceFactory, OpenAiProvider, BuilderTool,
|
|
30
|
+
export { OpenAiConfig, GoogleAiConfig, AILogSchema, AILogBaseSchema, AILogModel, AILogMongoRepository, AILogSqliteRepository, OpenAiProviderFactory, GoogleAiProviderFactory, AiProviderFactory, AILogServiceFactory, OpenAiProvider, GoogleAiProvider, BuilderTool,
|
|
28
31
|
//Service
|
|
29
32
|
KnowledgeService, AILogService,
|
|
30
33
|
//Permissions
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { GoogleGenAI } from "@google/genai";
|
|
2
|
+
import { toJSONSchema } from "zod";
|
|
3
|
+
class GoogleAiProvider {
|
|
4
|
+
constructor(apiKey, model, visionModel, aiLogService) {
|
|
5
|
+
if (!apiKey) {
|
|
6
|
+
throw new Error("Google AI apiKey required");
|
|
7
|
+
}
|
|
8
|
+
if (!model) {
|
|
9
|
+
throw new Error("Google AI model required");
|
|
10
|
+
}
|
|
11
|
+
this._apiKey = apiKey;
|
|
12
|
+
this._model = model;
|
|
13
|
+
this._visionModel = visionModel;
|
|
14
|
+
this._aiLogService = aiLogService;
|
|
15
|
+
}
|
|
16
|
+
get model() {
|
|
17
|
+
if (!this._model) {
|
|
18
|
+
throw new Error("Google AI model not found");
|
|
19
|
+
}
|
|
20
|
+
return this._model;
|
|
21
|
+
}
|
|
22
|
+
get client() {
|
|
23
|
+
if (!this._client) {
|
|
24
|
+
this._client = new GoogleGenAI({
|
|
25
|
+
apiKey: this._apiKey,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return this._client;
|
|
29
|
+
}
|
|
30
|
+
get visionModel() {
|
|
31
|
+
return this._visionModel;
|
|
32
|
+
}
|
|
33
|
+
buildUserContent(input) {
|
|
34
|
+
if (input.userContent && input.userContent.length > 0) {
|
|
35
|
+
return this.mapContentParts(input.userContent);
|
|
36
|
+
}
|
|
37
|
+
if (input.userImages && input.userImages.length > 0) {
|
|
38
|
+
const content = [];
|
|
39
|
+
if (input.userInput) {
|
|
40
|
+
content.push({ text: input.userInput });
|
|
41
|
+
}
|
|
42
|
+
content.push(...input.userImages.map(image => this.mapImageUrl(image.url)));
|
|
43
|
+
return content;
|
|
44
|
+
}
|
|
45
|
+
return input.userInput ? [{ text: input.userInput }] : [{ text: "" }];
|
|
46
|
+
}
|
|
47
|
+
mapContentParts(content) {
|
|
48
|
+
return content.map(part => {
|
|
49
|
+
if (part.type === 'text') {
|
|
50
|
+
return {
|
|
51
|
+
text: part.text
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return this.mapImageUrl(part.imageUrl);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
mapImageUrl(url) {
|
|
58
|
+
const dataUrlMatch = url.match(/^data:([^;,]+);base64,(.+)$/);
|
|
59
|
+
if (dataUrlMatch) {
|
|
60
|
+
return {
|
|
61
|
+
inlineData: {
|
|
62
|
+
mimeType: dataUrlMatch[1],
|
|
63
|
+
data: dataUrlMatch[2],
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
fileData: {
|
|
69
|
+
fileUri: url,
|
|
70
|
+
mimeType: this.inferImageMimeType(url),
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
inferImageMimeType(url) {
|
|
75
|
+
const normalizedUrl = url.split("?")[0].toLowerCase();
|
|
76
|
+
if (normalizedUrl.endsWith(".png")) {
|
|
77
|
+
return "image/png";
|
|
78
|
+
}
|
|
79
|
+
if (normalizedUrl.endsWith(".webp")) {
|
|
80
|
+
return "image/webp";
|
|
81
|
+
}
|
|
82
|
+
if (normalizedUrl.endsWith(".gif")) {
|
|
83
|
+
return "image/gif";
|
|
84
|
+
}
|
|
85
|
+
if (normalizedUrl.endsWith(".bmp")) {
|
|
86
|
+
return "image/bmp";
|
|
87
|
+
}
|
|
88
|
+
if (normalizedUrl.endsWith(".heic")) {
|
|
89
|
+
return "image/heic";
|
|
90
|
+
}
|
|
91
|
+
if (normalizedUrl.endsWith(".heif")) {
|
|
92
|
+
return "image/heif";
|
|
93
|
+
}
|
|
94
|
+
return "image/jpeg";
|
|
95
|
+
}
|
|
96
|
+
mapHistory(history = []) {
|
|
97
|
+
return history.map(message => {
|
|
98
|
+
const parts = typeof message.content === 'string'
|
|
99
|
+
? [{ text: message.content }]
|
|
100
|
+
: this.mapContentParts(message.content);
|
|
101
|
+
if (message.role === "assistant") {
|
|
102
|
+
return {
|
|
103
|
+
role: "model",
|
|
104
|
+
parts,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (message.role === "system") {
|
|
108
|
+
return {
|
|
109
|
+
role: "user",
|
|
110
|
+
parts: [
|
|
111
|
+
{ text: "[SYSTEM]" },
|
|
112
|
+
...parts,
|
|
113
|
+
],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
role: "user",
|
|
118
|
+
parts,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
hasImageInput(input) {
|
|
123
|
+
if (input.userImages && input.userImages.length > 0) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
if (input.userContent?.some(part => part.type === 'image')) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
return input.history?.some(message => Array.isArray(message.content) && message.content.some(part => part.type === 'image')) ?? false;
|
|
130
|
+
}
|
|
131
|
+
serializePromptInput(input, systemPrompt) {
|
|
132
|
+
return JSON.stringify({
|
|
133
|
+
systemPrompt,
|
|
134
|
+
history: input.history,
|
|
135
|
+
userInput: input.userInput,
|
|
136
|
+
userContent: input.userContent,
|
|
137
|
+
memory: input.memory,
|
|
138
|
+
knowledgeBase: input.knowledgeBase,
|
|
139
|
+
tools: input.tools?.map(tool => ({
|
|
140
|
+
name: tool.name,
|
|
141
|
+
description: tool.description,
|
|
142
|
+
parameters: tool.parameters,
|
|
143
|
+
})),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
serializePromptOutput(output) {
|
|
147
|
+
if (typeof output === "string") {
|
|
148
|
+
return output;
|
|
149
|
+
}
|
|
150
|
+
if (output === null || output === undefined) {
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
return JSON.stringify(output);
|
|
154
|
+
}
|
|
155
|
+
buildLogPayload(input, params) {
|
|
156
|
+
return {
|
|
157
|
+
provider: "googleai",
|
|
158
|
+
model: params.model,
|
|
159
|
+
operationTitle: input.operationTitle,
|
|
160
|
+
operationGroup: input.operationGroup,
|
|
161
|
+
ip: input.ip,
|
|
162
|
+
userAgent: input.userAgent,
|
|
163
|
+
input: this.serializePromptInput(input, params.systemPrompt),
|
|
164
|
+
inputImages: input.userImages?.map(image => ({
|
|
165
|
+
url: image.url,
|
|
166
|
+
})) ?? input.userContent
|
|
167
|
+
?.filter(part => part.type === "image")
|
|
168
|
+
.map(part => ({
|
|
169
|
+
url: part.imageUrl,
|
|
170
|
+
})),
|
|
171
|
+
inputFiles: input.inputFiles,
|
|
172
|
+
inputTokens: params.inputTokens,
|
|
173
|
+
outputTokens: params.outputTokens,
|
|
174
|
+
tokens: params.tokens,
|
|
175
|
+
startedAt: params.startedAt,
|
|
176
|
+
endedAt: params.endedAt,
|
|
177
|
+
responseTime: params.endedAt ? `${params.endedAt.getTime() - params.startedAt.getTime()}ms` : undefined,
|
|
178
|
+
output: this.serializePromptOutput(params.output),
|
|
179
|
+
success: params.success,
|
|
180
|
+
errorMessage: params.errorMessage,
|
|
181
|
+
tenant: input.tenant,
|
|
182
|
+
user: input.user,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
async registerPromptLog(input, params) {
|
|
186
|
+
if (!this._aiLogService) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
await this._aiLogService.create(this.buildLogPayload(input, params));
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
console.error("Error registerPromptLog", {
|
|
194
|
+
name: e?.name,
|
|
195
|
+
message: e?.message,
|
|
196
|
+
stack: e?.stack,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async generateEmbedding({ text, model = "text-embedding-004" }) {
|
|
201
|
+
const response = await this.client.models.embedContent({
|
|
202
|
+
model,
|
|
203
|
+
contents: text,
|
|
204
|
+
});
|
|
205
|
+
return response.embeddings?.[0]?.values ?? [];
|
|
206
|
+
}
|
|
207
|
+
mapTools(tools = []) {
|
|
208
|
+
if (tools.length === 0) {
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
return [{
|
|
212
|
+
functionDeclarations: tools.map(tool => ({
|
|
213
|
+
name: tool.name,
|
|
214
|
+
description: tool.description,
|
|
215
|
+
parametersJsonSchema: tool.parameters ?? {
|
|
216
|
+
type: "object",
|
|
217
|
+
properties: {},
|
|
218
|
+
additionalProperties: false,
|
|
219
|
+
},
|
|
220
|
+
}))
|
|
221
|
+
}];
|
|
222
|
+
}
|
|
223
|
+
buildResponseConfig(input, systemPrompt) {
|
|
224
|
+
const config = {
|
|
225
|
+
systemInstruction: systemPrompt,
|
|
226
|
+
};
|
|
227
|
+
const responseJsonSchema = this.normalizeResponseJsonSchema(input);
|
|
228
|
+
if (responseJsonSchema) {
|
|
229
|
+
config.responseMimeType = "application/json";
|
|
230
|
+
config.responseJsonSchema = responseJsonSchema;
|
|
231
|
+
}
|
|
232
|
+
if (input.tools && input.tools.length > 0) {
|
|
233
|
+
config.tools = this.mapTools(input.tools);
|
|
234
|
+
}
|
|
235
|
+
return config;
|
|
236
|
+
}
|
|
237
|
+
normalizeResponseJsonSchema(input) {
|
|
238
|
+
if (input.zodSchema) {
|
|
239
|
+
return toJSONSchema(input.zodSchema, {
|
|
240
|
+
target: "draft-7",
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (!input.jsonSchema) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
const jsonSchema = input.jsonSchema;
|
|
247
|
+
if (jsonSchema.type === "json_schema" && jsonSchema.json_schema?.schema) {
|
|
248
|
+
return jsonSchema.json_schema.schema;
|
|
249
|
+
}
|
|
250
|
+
return jsonSchema;
|
|
251
|
+
}
|
|
252
|
+
async buildToolResponseParts(functionCalls = [], tools = []) {
|
|
253
|
+
const parts = [];
|
|
254
|
+
for (const functionCall of functionCalls) {
|
|
255
|
+
const toolName = functionCall.name;
|
|
256
|
+
const tool = tools.find(t => t.name === toolName);
|
|
257
|
+
if (!tool) {
|
|
258
|
+
throw new Error(`Tool not found: ${toolName}`);
|
|
259
|
+
}
|
|
260
|
+
const output = await tool.execute(functionCall.args ?? {});
|
|
261
|
+
parts.push({
|
|
262
|
+
functionResponse: {
|
|
263
|
+
id: functionCall.id,
|
|
264
|
+
name: toolName,
|
|
265
|
+
response: {
|
|
266
|
+
output,
|
|
267
|
+
},
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
return parts;
|
|
272
|
+
}
|
|
273
|
+
buildModelFunctionCallContent(functionCalls = []) {
|
|
274
|
+
return {
|
|
275
|
+
role: "model",
|
|
276
|
+
parts: functionCalls.map(functionCall => ({
|
|
277
|
+
functionCall,
|
|
278
|
+
}))
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
async prompt(input) {
|
|
282
|
+
if (!input.systemPrompt) {
|
|
283
|
+
throw new Error("systemPrompt required");
|
|
284
|
+
}
|
|
285
|
+
let systemPrompt = input.systemPrompt;
|
|
286
|
+
if (input.memory && input.memory.length > 0) {
|
|
287
|
+
systemPrompt += `\n\n ${input.memoryHeader ?? '[MEMORIA]'}\n ${input.memory.map(m => `${m.key}: ${m.value}`).join('\n')}`;
|
|
288
|
+
}
|
|
289
|
+
if (input.knowledgeBase && input.knowledgeBase.length > 0) {
|
|
290
|
+
systemPrompt += `\n\n${input.knowledgeBaseHeader ?? '[BASE DE CONOCIMIENTO]'}\n ${input.knowledgeBase.join('\n')}`;
|
|
291
|
+
}
|
|
292
|
+
const userInput = this.buildUserContent(input);
|
|
293
|
+
const model = input.model ?? (this.hasImageInput(input) ? this.visionModel ?? this.model : this.model);
|
|
294
|
+
const startedAt = new Date();
|
|
295
|
+
const startTime = performance.now();
|
|
296
|
+
let tokens = 0;
|
|
297
|
+
let inputTokens = 0;
|
|
298
|
+
let outputTokens = 0;
|
|
299
|
+
try {
|
|
300
|
+
const contents = [
|
|
301
|
+
...this.mapHistory(input.history),
|
|
302
|
+
{ role: 'user', parts: userInput },
|
|
303
|
+
];
|
|
304
|
+
const tools = input.tools ?? [];
|
|
305
|
+
const maxIterations = input.toolMaxIterations ?? 5;
|
|
306
|
+
let output;
|
|
307
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
308
|
+
const response = await this.client.models.generateContent({
|
|
309
|
+
model,
|
|
310
|
+
contents,
|
|
311
|
+
config: this.buildResponseConfig(input, systemPrompt),
|
|
312
|
+
});
|
|
313
|
+
tokens += response.usageMetadata?.totalTokenCount ?? 0;
|
|
314
|
+
inputTokens += response.usageMetadata?.promptTokenCount ?? 0;
|
|
315
|
+
outputTokens += response.usageMetadata?.candidatesTokenCount ?? 0;
|
|
316
|
+
const functionCalls = response.functionCalls ?? [];
|
|
317
|
+
if (functionCalls.length === 0) {
|
|
318
|
+
output = response.text;
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
contents.push(response.candidates?.[0]?.content ?? this.buildModelFunctionCallContent(functionCalls));
|
|
322
|
+
contents.push({
|
|
323
|
+
role: "user",
|
|
324
|
+
parts: await this.buildToolResponseParts(functionCalls, tools),
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (output === undefined) {
|
|
328
|
+
throw new Error(`Tool max iterations reached: ${maxIterations}`);
|
|
329
|
+
}
|
|
330
|
+
const endTime = performance.now();
|
|
331
|
+
const time = endTime - startTime;
|
|
332
|
+
const endedAt = new Date();
|
|
333
|
+
await this.registerPromptLog(input, {
|
|
334
|
+
model,
|
|
335
|
+
systemPrompt,
|
|
336
|
+
startedAt,
|
|
337
|
+
endedAt,
|
|
338
|
+
inputTokens,
|
|
339
|
+
outputTokens,
|
|
340
|
+
tokens,
|
|
341
|
+
output,
|
|
342
|
+
success: true,
|
|
343
|
+
});
|
|
344
|
+
return {
|
|
345
|
+
output,
|
|
346
|
+
tokens,
|
|
347
|
+
inputTokens,
|
|
348
|
+
outputTokens,
|
|
349
|
+
time
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
catch (e) {
|
|
353
|
+
const endedAt = new Date();
|
|
354
|
+
await this.registerPromptLog(input, {
|
|
355
|
+
model,
|
|
356
|
+
systemPrompt,
|
|
357
|
+
startedAt,
|
|
358
|
+
endedAt,
|
|
359
|
+
success: false,
|
|
360
|
+
errorMessage: e?.message,
|
|
361
|
+
});
|
|
362
|
+
throw e;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
export default GoogleAiProvider;
|
|
367
|
+
export { GoogleAiProvider };
|
|
@@ -224,6 +224,15 @@ class BuilderTool {
|
|
|
224
224
|
if (typeof f?.unwrap === "function" && typeName === "ZodNullable") {
|
|
225
225
|
return this.fieldAdapter(f.unwrap()).nullable();
|
|
226
226
|
}
|
|
227
|
+
if (typeof f?.unwrap === "function" && typeName === "ZodDefault") {
|
|
228
|
+
return this.fieldAdapter(f.unwrap()).default(f.def.defaultValue);
|
|
229
|
+
}
|
|
230
|
+
if (typeof f?.unwrap === "function" && typeName === "ZodCatch") {
|
|
231
|
+
return this.fieldAdapter(f.unwrap()).catch(f.def.catchValue);
|
|
232
|
+
}
|
|
233
|
+
if (typeof f?.unwrap === "function" && typeName === "ZodReadonly") {
|
|
234
|
+
return this.fieldAdapter(f.unwrap()).readonly();
|
|
235
|
+
}
|
|
227
236
|
if (typeName === "ZodArray" && f?.element) {
|
|
228
237
|
return z.array(this.fieldAdapter(f.element));
|
|
229
238
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "3.
|
|
6
|
+
"version": "3.33.0",
|
|
7
7
|
"description": "Ai utils",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@drax/ai-share": "^3.31.0",
|
|
22
|
-
"@drax/crud-back": "^3.
|
|
22
|
+
"@drax/crud-back": "^3.32.0",
|
|
23
23
|
"mongoose": "^8.23.0",
|
|
24
24
|
"mongoose-paginate-v2": "^1.8.3"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
+
"@google/genai": "^1.52.0",
|
|
27
28
|
"jsdom": "^26.0.0",
|
|
28
29
|
"office-text-extractor": "^3.0.3",
|
|
29
30
|
"openai": "^6.0.0",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
}
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
39
|
+
"@google/genai": "^1.52.0",
|
|
38
40
|
"@types/node": "^25.2.3",
|
|
39
41
|
"jsdom": "^26.0.0",
|
|
40
42
|
"office-text-extractor": "^3.0.3",
|
|
@@ -44,5 +46,5 @@
|
|
|
44
46
|
"typescript": "^5.9.3",
|
|
45
47
|
"vitest": "^3.0.8"
|
|
46
48
|
},
|
|
47
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "e914874dd8474ca01a898be89423a85c7fabaee6"
|
|
48
50
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
enum GoogleAiConfig {
|
|
3
|
+
|
|
4
|
+
GoogleAiApiKey = "GOOGLE_AI_API_KEY",
|
|
5
|
+
GoogleApiKey = "GOOGLE_API_KEY",
|
|
6
|
+
GoogleAiModel = "GOOGLE_AI_MODEL",
|
|
7
|
+
GoogleAiVisionModel = "GOOGLE_AI_VISION_MODEL",
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export default GoogleAiConfig;
|
|
13
|
+
|
|
14
|
+
export {GoogleAiConfig}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import type {IAIProvider} from "../interfaces/IAIProvider"
|
|
2
2
|
import OpenAiProviderFactory from "./OpenAiProviderFactory.js";
|
|
3
|
+
import GoogleAiProviderFactory from "./GoogleAiProviderFactory.js";
|
|
3
4
|
|
|
4
5
|
class AiProviderFactory {
|
|
5
|
-
private static
|
|
6
|
+
private static singletons: Record<string, IAIProvider> = {};
|
|
6
7
|
|
|
7
8
|
public static instance(provider: string = 'OpenAi'): IAIProvider {
|
|
8
|
-
if (!AiProviderFactory.
|
|
9
|
+
if (!AiProviderFactory.singletons[provider]) {
|
|
9
10
|
switch (provider) {
|
|
10
11
|
case 'OpenAi':
|
|
11
|
-
AiProviderFactory.
|
|
12
|
+
AiProviderFactory.singletons[provider] = OpenAiProviderFactory.instance()
|
|
13
|
+
break;
|
|
14
|
+
case 'GoogleAi':
|
|
15
|
+
AiProviderFactory.singletons[provider] = GoogleAiProviderFactory.instance()
|
|
12
16
|
break;
|
|
13
17
|
default:
|
|
14
18
|
throw new Error(`Unsupported AI provider: ${provider}`);
|
|
15
19
|
}
|
|
16
20
|
}
|
|
17
|
-
return AiProviderFactory.
|
|
21
|
+
return AiProviderFactory.singletons[provider];
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -22,4 +26,3 @@ export default AiProviderFactory
|
|
|
22
26
|
export {
|
|
23
27
|
AiProviderFactory
|
|
24
28
|
}
|
|
25
|
-
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {DraxConfig} from "@drax/common-back";
|
|
2
|
+
import GoogleAiConfig from "../config/GoogleAiConfig.js";
|
|
3
|
+
import type {IAIProvider} from "../interfaces/IAIProvider"
|
|
4
|
+
import GoogleAiProvider from "../providers/GoogleAiProvider.js";
|
|
5
|
+
import AILogServiceFactory from "./services/AILogServiceFactory.js";
|
|
6
|
+
|
|
7
|
+
class GoogleAiProviderFactory {
|
|
8
|
+
private static singleton: IAIProvider;
|
|
9
|
+
|
|
10
|
+
public static instance(): IAIProvider {
|
|
11
|
+
if (!GoogleAiProviderFactory.singleton) {
|
|
12
|
+
GoogleAiProviderFactory.singleton = new GoogleAiProvider(
|
|
13
|
+
DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiApiKey) ?? DraxConfig.getOrLoad(GoogleAiConfig.GoogleApiKey),
|
|
14
|
+
DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiModel),
|
|
15
|
+
DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiVisionModel),
|
|
16
|
+
AILogServiceFactory.instance
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
return GoogleAiProviderFactory.singleton;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default GoogleAiProviderFactory
|
|
24
|
+
export {
|
|
25
|
+
GoogleAiProviderFactory
|
|
26
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import {OpenAiConfig} from "./config/OpenAiConfig.js";
|
|
2
|
+
import {GoogleAiConfig} from "./config/GoogleAiConfig.js";
|
|
2
3
|
import {AILogSchema, AILogBaseSchema} from "./schemas/AILogSchema.js";
|
|
3
4
|
import AILogModel from "./models/AILogModel.js";
|
|
4
5
|
import AILogMongoRepository from "./repository/mongo/AILogMongoRepository.js";
|
|
5
6
|
import AILogSqliteRepository from "./repository/sqlite/AILogSqliteRepository.js";
|
|
6
7
|
import {OpenAiProviderFactory} from "./factory/OpenAiProviderFactory.js";
|
|
8
|
+
import {GoogleAiProviderFactory} from "./factory/GoogleAiProviderFactory.js";
|
|
7
9
|
import {AiProviderFactory} from "./factory/AiProviderFactory.js";
|
|
8
10
|
import AILogServiceFactory from "./factory/services/AILogServiceFactory.js";
|
|
9
11
|
import {OpenAiProvider} from "./providers/OpenAiProvider.js";
|
|
12
|
+
import {GoogleAiProvider} from "./providers/GoogleAiProvider.js";
|
|
10
13
|
import {BuilderTool} from "./tools/BuilderTool.js";
|
|
11
14
|
import {KnowledgeService} from "./services/KnowledgeService.js";
|
|
12
15
|
import {AILogService} from "./services/AILogService.js";
|
|
@@ -95,15 +98,18 @@ export type {
|
|
|
95
98
|
|
|
96
99
|
export {
|
|
97
100
|
OpenAiConfig,
|
|
101
|
+
GoogleAiConfig,
|
|
98
102
|
AILogSchema,
|
|
99
103
|
AILogBaseSchema,
|
|
100
104
|
AILogModel,
|
|
101
105
|
AILogMongoRepository,
|
|
102
106
|
AILogSqliteRepository,
|
|
103
107
|
OpenAiProviderFactory,
|
|
108
|
+
GoogleAiProviderFactory,
|
|
104
109
|
AiProviderFactory,
|
|
105
110
|
AILogServiceFactory,
|
|
106
111
|
OpenAiProvider,
|
|
112
|
+
GoogleAiProvider,
|
|
107
113
|
BuilderTool,
|
|
108
114
|
//Service
|
|
109
115
|
KnowledgeService,
|