@drax/ai-back 3.51.1 → 3.52.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/models/AILogModel.js +1 -0
- package/dist/providers/ai/AbstractAiProvider.js +90 -0
- package/dist/providers/ai/DeepSeekAiProvider.js +1 -7
- package/dist/providers/ai/GoogleAiProvider.js +3 -80
- package/dist/providers/ai/OllamaAiProvider.js +3 -80
- package/dist/providers/ai/OpenAiProvider.js +4 -81
- package/dist/repository/sqlite/AILogSqliteRepository.js +1 -0
- package/dist/routes/AILogRoutes.js +5 -5
- package/dist/schemas/AILogSchema.js +4 -1
- package/package.json +3 -3
- package/src/models/AILogModel.ts +1 -0
- package/src/providers/ai/AbstractAiProvider.ts +129 -0
- package/src/providers/ai/DeepSeekAiProvider.ts +1 -20
- package/src/providers/ai/GoogleAiProvider.ts +4 -116
- package/src/providers/ai/OllamaAiProvider.ts +4 -116
- package/src/providers/ai/OpenAiProvider.ts +5 -117
- package/src/repository/sqlite/AILogSqliteRepository.ts +1 -1
- package/src/routes/AILogRoutes.ts +14 -14
- package/src/schemas/AILogSchema.ts +4 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/types/models/AILogModel.d.ts.map +1 -1
- package/types/providers/ai/AbstractAiProvider.d.ts +29 -0
- package/types/providers/ai/AbstractAiProvider.d.ts.map +1 -0
- package/types/providers/ai/DeepSeekAiProvider.d.ts +0 -14
- package/types/providers/ai/DeepSeekAiProvider.d.ts.map +1 -1
- package/types/providers/ai/GoogleAiProvider.d.ts +3 -31
- package/types/providers/ai/GoogleAiProvider.d.ts.map +1 -1
- package/types/providers/ai/OllamaAiProvider.d.ts +3 -31
- package/types/providers/ai/OllamaAiProvider.d.ts.map +1 -1
- package/types/providers/ai/OpenAiProvider.d.ts +4 -32
- package/types/providers/ai/OpenAiProvider.d.ts.map +1 -1
- package/types/repository/sqlite/AILogSqliteRepository.d.ts.map +1 -1
- package/types/schemas/AILogSchema.d.ts +4 -0
- package/types/schemas/AILogSchema.d.ts.map +1 -1
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
-
import type {IAILogBase} from "@drax/ai-share";
|
|
3
|
-
import type {IPromptParams} from "../../interfaces/IAIProvider.js";
|
|
4
2
|
import type {AILogService} from "../../services/AILogService.js";
|
|
5
3
|
import OpenAiProvider from "./OpenAiProvider.js";
|
|
6
4
|
|
|
@@ -15,7 +13,7 @@ class DeepSeekAiProvider extends OpenAiProvider{
|
|
|
15
13
|
throw new Error("DeepSeek model required")
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
super(apiKey, model, visionModel, aiLogService)
|
|
16
|
+
super(apiKey, model, visionModel, aiLogService, "deepseek")
|
|
19
17
|
|
|
20
18
|
if (!baseUrl) {
|
|
21
19
|
throw new Error("DeepSeek baseUrl required")
|
|
@@ -35,23 +33,6 @@ class DeepSeekAiProvider extends OpenAiProvider{
|
|
|
35
33
|
return this._client
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
protected buildLogPayload(input: IPromptParams, params: {
|
|
39
|
-
model: string,
|
|
40
|
-
systemPrompt: string,
|
|
41
|
-
startedAt: Date,
|
|
42
|
-
endedAt?: Date,
|
|
43
|
-
inputTokens?: number,
|
|
44
|
-
outputTokens?: number,
|
|
45
|
-
tokens?: number,
|
|
46
|
-
output?: unknown,
|
|
47
|
-
success: boolean,
|
|
48
|
-
errorMessage?: string,
|
|
49
|
-
}): IAILogBase {
|
|
50
|
-
return {
|
|
51
|
-
...super.buildLogPayload(input, params),
|
|
52
|
-
provider: "deepseek",
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
36
|
}
|
|
56
37
|
|
|
57
38
|
export default DeepSeekAiProvider
|
|
@@ -8,7 +8,6 @@ import type {
|
|
|
8
8
|
} from "@google/genai";
|
|
9
9
|
import {toJSONSchema} from "zod";
|
|
10
10
|
import type {
|
|
11
|
-
IAIProvider,
|
|
12
11
|
IPromptContentPart,
|
|
13
12
|
IPromptMessage,
|
|
14
13
|
IPromptParams,
|
|
@@ -16,15 +15,14 @@ import type {
|
|
|
16
15
|
IPromptTool
|
|
17
16
|
} from "../../interfaces/IAIProvider.js";
|
|
18
17
|
import type {AILogService} from "../../services/AILogService.js";
|
|
19
|
-
import type {IAILogBase} from "@drax/ai-share";
|
|
20
18
|
import PromptAudioService from "../../services/PromptAudioService.js";
|
|
19
|
+
import AbstractAiProvider from "./AbstractAiProvider.js";
|
|
21
20
|
|
|
22
|
-
class GoogleAiProvider
|
|
21
|
+
class GoogleAiProvider extends AbstractAiProvider{
|
|
23
22
|
protected _apiKey: string
|
|
24
23
|
protected _model: any
|
|
25
24
|
protected _visionModel?: string
|
|
26
25
|
protected _client: GoogleGenAI | undefined
|
|
27
|
-
protected _aiLogService?: AILogService
|
|
28
26
|
|
|
29
27
|
constructor(apiKey: string, model: string, visionModel?: string, aiLogService?: AILogService) {
|
|
30
28
|
|
|
@@ -35,10 +33,11 @@ class GoogleAiProvider implements IAIProvider{
|
|
|
35
33
|
throw new Error("Google AI model required")
|
|
36
34
|
}
|
|
37
35
|
|
|
36
|
+
super("googleai", aiLogService)
|
|
37
|
+
|
|
38
38
|
this._apiKey = apiKey
|
|
39
39
|
this._model = model
|
|
40
40
|
this._visionModel = visionModel
|
|
41
|
-
this._aiLogService = aiLogService
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
get model(){
|
|
@@ -169,117 +168,6 @@ class GoogleAiProvider implements IAIProvider{
|
|
|
169
168
|
})
|
|
170
169
|
}
|
|
171
170
|
|
|
172
|
-
protected hasImageInput(input: IPromptParams){
|
|
173
|
-
if(input.userImages && input.userImages.length > 0){
|
|
174
|
-
return true
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if(input.userContent?.some(part => part.type === 'image')){
|
|
178
|
-
return true
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return input.history?.some(message =>
|
|
182
|
-
Array.isArray(message.content) && message.content.some(part => part.type === 'image')
|
|
183
|
-
) ?? false
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
protected serializePromptInput(input: IPromptParams, systemPrompt: string){
|
|
187
|
-
return JSON.stringify({
|
|
188
|
-
systemPrompt,
|
|
189
|
-
history: input.history,
|
|
190
|
-
userInput: input.userInput,
|
|
191
|
-
userContent: input.userContent,
|
|
192
|
-
memory: input.memory,
|
|
193
|
-
knowledgeBase: input.knowledgeBase,
|
|
194
|
-
tools: input.tools?.map(tool => ({
|
|
195
|
-
name: tool.name,
|
|
196
|
-
description: tool.description,
|
|
197
|
-
parameters: tool.parameters,
|
|
198
|
-
})),
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
protected serializePromptOutput(output: unknown){
|
|
203
|
-
if (typeof output === "string") {
|
|
204
|
-
return output
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
if (output === null || output === undefined) {
|
|
208
|
-
return undefined
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return JSON.stringify(output)
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
protected buildLogPayload(input: IPromptParams, params: {
|
|
215
|
-
model: string,
|
|
216
|
-
systemPrompt: string,
|
|
217
|
-
startedAt: Date,
|
|
218
|
-
endedAt?: Date,
|
|
219
|
-
inputTokens?: number,
|
|
220
|
-
outputTokens?: number,
|
|
221
|
-
tokens?: number,
|
|
222
|
-
output?: unknown,
|
|
223
|
-
success: boolean,
|
|
224
|
-
errorMessage?: string,
|
|
225
|
-
}): IAILogBase {
|
|
226
|
-
return {
|
|
227
|
-
provider: "googleai",
|
|
228
|
-
model: params.model,
|
|
229
|
-
operationTitle: input.operationTitle,
|
|
230
|
-
operationGroup: input.operationGroup,
|
|
231
|
-
ip: input.ip,
|
|
232
|
-
userAgent: input.userAgent,
|
|
233
|
-
input: this.serializePromptInput(input, params.systemPrompt),
|
|
234
|
-
inputImages: input.userImages?.map(image => ({
|
|
235
|
-
url: image.url,
|
|
236
|
-
})) ?? input.userContent
|
|
237
|
-
?.filter(part => part.type === "image")
|
|
238
|
-
.map(part => ({
|
|
239
|
-
url: part.imageUrl,
|
|
240
|
-
})),
|
|
241
|
-
inputFiles: input.inputFiles,
|
|
242
|
-
inputTokens: params.inputTokens,
|
|
243
|
-
outputTokens: params.outputTokens,
|
|
244
|
-
tokens: params.tokens,
|
|
245
|
-
startedAt: params.startedAt,
|
|
246
|
-
endedAt: params.endedAt,
|
|
247
|
-
responseTime: params.endedAt ? `${params.endedAt.getTime() - params.startedAt.getTime()}ms` : undefined,
|
|
248
|
-
output: this.serializePromptOutput(params.output),
|
|
249
|
-
success: params.success,
|
|
250
|
-
errorMessage: params.errorMessage,
|
|
251
|
-
tenant: input.tenant,
|
|
252
|
-
user: input.user,
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
protected async registerPromptLog(input: IPromptParams, params: {
|
|
257
|
-
model: string,
|
|
258
|
-
systemPrompt: string,
|
|
259
|
-
startedAt: Date,
|
|
260
|
-
endedAt?: Date,
|
|
261
|
-
inputTokens?: number,
|
|
262
|
-
outputTokens?: number,
|
|
263
|
-
tokens?: number,
|
|
264
|
-
output?: unknown,
|
|
265
|
-
success: boolean,
|
|
266
|
-
errorMessage?: string,
|
|
267
|
-
}){
|
|
268
|
-
if(!this._aiLogService){
|
|
269
|
-
return
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
try{
|
|
273
|
-
await this._aiLogService.create(this.buildLogPayload(input, params))
|
|
274
|
-
}catch(e: any){
|
|
275
|
-
console.error("Error registerPromptLog", {
|
|
276
|
-
name: e?.name,
|
|
277
|
-
message: e?.message,
|
|
278
|
-
stack: e?.stack,
|
|
279
|
-
})
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
171
|
async generateEmbedding({text, model="text-embedding-004"}: {text:string,model?:string }): Promise<number[]> {
|
|
284
172
|
const response = await this.client.models.embedContent({
|
|
285
173
|
model,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {toJSONSchema} from "zod";
|
|
2
2
|
import type {
|
|
3
|
-
IAIProvider,
|
|
4
3
|
IPromptContentPart,
|
|
5
4
|
IPromptMessage,
|
|
6
5
|
IPromptParams,
|
|
@@ -8,8 +7,8 @@ import type {
|
|
|
8
7
|
IPromptTool
|
|
9
8
|
} from "../../interfaces/IAIProvider.js";
|
|
10
9
|
import type {AILogService} from "../../services/AILogService.js";
|
|
11
|
-
import type {IAILogBase} from "@drax/ai-share";
|
|
12
10
|
import PromptAudioService from "../../services/PromptAudioService.js";
|
|
11
|
+
import AbstractAiProvider from "./AbstractAiProvider.js";
|
|
13
12
|
|
|
14
13
|
type OllamaMessage = {
|
|
15
14
|
role: "system" | "user" | "assistant" | "tool",
|
|
@@ -25,12 +24,11 @@ type OllamaToolCall = {
|
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
class OllamaAiProvider
|
|
27
|
+
class OllamaAiProvider extends AbstractAiProvider{
|
|
29
28
|
protected _baseUrl: string
|
|
30
29
|
protected _model: string
|
|
31
30
|
protected _visionModel?: string
|
|
32
31
|
protected _embeddingModel?: string
|
|
33
|
-
protected _aiLogService?: AILogService
|
|
34
32
|
|
|
35
33
|
constructor(baseUrl: string, model: string, visionModel?: string, embeddingModel?: string, aiLogService?: AILogService) {
|
|
36
34
|
|
|
@@ -41,11 +39,12 @@ class OllamaAiProvider implements IAIProvider{
|
|
|
41
39
|
throw new Error("Ollama AI model required")
|
|
42
40
|
}
|
|
43
41
|
|
|
42
|
+
super("ollamaai", aiLogService)
|
|
43
|
+
|
|
44
44
|
this._baseUrl = baseUrl.replace(/\/+$/, "")
|
|
45
45
|
this._model = model
|
|
46
46
|
this._visionModel = visionModel
|
|
47
47
|
this._embeddingModel = embeddingModel
|
|
48
|
-
this._aiLogService = aiLogService
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
get model(){
|
|
@@ -154,117 +153,6 @@ class OllamaAiProvider implements IAIProvider{
|
|
|
154
153
|
return messages
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
protected hasImageInput(input: IPromptParams){
|
|
158
|
-
if(input.userImages && input.userImages.length > 0){
|
|
159
|
-
return true
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if(input.userContent?.some(part => part.type === 'image')){
|
|
163
|
-
return true
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return input.history?.some(message =>
|
|
167
|
-
Array.isArray(message.content) && message.content.some(part => part.type === 'image')
|
|
168
|
-
) ?? false
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
protected serializePromptInput(input: IPromptParams, systemPrompt: string){
|
|
172
|
-
return JSON.stringify({
|
|
173
|
-
systemPrompt,
|
|
174
|
-
history: input.history,
|
|
175
|
-
userInput: input.userInput,
|
|
176
|
-
userContent: input.userContent,
|
|
177
|
-
memory: input.memory,
|
|
178
|
-
knowledgeBase: input.knowledgeBase,
|
|
179
|
-
tools: input.tools?.map(tool => ({
|
|
180
|
-
name: tool.name,
|
|
181
|
-
description: tool.description,
|
|
182
|
-
parameters: tool.parameters,
|
|
183
|
-
})),
|
|
184
|
-
})
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
protected serializePromptOutput(output: unknown){
|
|
188
|
-
if (typeof output === "string") {
|
|
189
|
-
return output
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (output === null || output === undefined) {
|
|
193
|
-
return undefined
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return JSON.stringify(output)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
protected buildLogPayload(input: IPromptParams, params: {
|
|
200
|
-
model: string,
|
|
201
|
-
systemPrompt: string,
|
|
202
|
-
startedAt: Date,
|
|
203
|
-
endedAt?: Date,
|
|
204
|
-
inputTokens?: number,
|
|
205
|
-
outputTokens?: number,
|
|
206
|
-
tokens?: number,
|
|
207
|
-
output?: unknown,
|
|
208
|
-
success: boolean,
|
|
209
|
-
errorMessage?: string,
|
|
210
|
-
}): IAILogBase {
|
|
211
|
-
return {
|
|
212
|
-
provider: "ollamaai",
|
|
213
|
-
model: params.model,
|
|
214
|
-
operationTitle: input.operationTitle,
|
|
215
|
-
operationGroup: input.operationGroup,
|
|
216
|
-
ip: input.ip,
|
|
217
|
-
userAgent: input.userAgent,
|
|
218
|
-
input: this.serializePromptInput(input, params.systemPrompt),
|
|
219
|
-
inputImages: input.userImages?.map(image => ({
|
|
220
|
-
url: image.url,
|
|
221
|
-
})) ?? input.userContent
|
|
222
|
-
?.filter(part => part.type === "image")
|
|
223
|
-
.map(part => ({
|
|
224
|
-
url: part.imageUrl,
|
|
225
|
-
})),
|
|
226
|
-
inputFiles: input.inputFiles,
|
|
227
|
-
inputTokens: params.inputTokens,
|
|
228
|
-
outputTokens: params.outputTokens,
|
|
229
|
-
tokens: params.tokens,
|
|
230
|
-
startedAt: params.startedAt,
|
|
231
|
-
endedAt: params.endedAt,
|
|
232
|
-
responseTime: params.endedAt ? `${params.endedAt.getTime() - params.startedAt.getTime()}ms` : undefined,
|
|
233
|
-
output: this.serializePromptOutput(params.output),
|
|
234
|
-
success: params.success,
|
|
235
|
-
errorMessage: params.errorMessage,
|
|
236
|
-
tenant: input.tenant,
|
|
237
|
-
user: input.user,
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
protected async registerPromptLog(input: IPromptParams, params: {
|
|
242
|
-
model: string,
|
|
243
|
-
systemPrompt: string,
|
|
244
|
-
startedAt: Date,
|
|
245
|
-
endedAt?: Date,
|
|
246
|
-
inputTokens?: number,
|
|
247
|
-
outputTokens?: number,
|
|
248
|
-
tokens?: number,
|
|
249
|
-
output?: unknown,
|
|
250
|
-
success: boolean,
|
|
251
|
-
errorMessage?: string,
|
|
252
|
-
}){
|
|
253
|
-
if(!this._aiLogService){
|
|
254
|
-
return
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
try{
|
|
258
|
-
await this._aiLogService.create(this.buildLogPayload(input, params))
|
|
259
|
-
}catch(e: any){
|
|
260
|
-
console.error("Error registerPromptLog", {
|
|
261
|
-
name: e?.name,
|
|
262
|
-
message: e?.message,
|
|
263
|
-
stack: e?.stack,
|
|
264
|
-
})
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
156
|
async generateEmbedding({text, model}: {text:string, model?:string }): Promise<number[]> {
|
|
269
157
|
const response = await this.post<any>("/api/embed", {
|
|
270
158
|
model: model ?? this.embeddingModel,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
2
|
import { zodResponseFormat } from "openai/helpers/zod";
|
|
3
3
|
import type {
|
|
4
|
-
IAIProvider,
|
|
5
4
|
IPromptContentPart,
|
|
6
5
|
IPromptMessage,
|
|
7
6
|
IPromptParams,
|
|
@@ -9,17 +8,16 @@ import type {
|
|
|
9
8
|
IPromptTool
|
|
10
9
|
} from "../../interfaces/IAIProvider.js";
|
|
11
10
|
import type {AILogService} from "../../services/AILogService.js";
|
|
12
|
-
import type {IAILogBase} from "@drax/ai-share";
|
|
13
11
|
import PromptAudioService from "../../services/PromptAudioService.js";
|
|
12
|
+
import AbstractAiProvider from "./AbstractAiProvider.js";
|
|
14
13
|
|
|
15
|
-
class OpenAiProvider
|
|
14
|
+
class OpenAiProvider extends AbstractAiProvider{
|
|
16
15
|
protected _apiKey: string
|
|
17
16
|
protected _model: any
|
|
18
17
|
protected _visionModel?: string
|
|
19
18
|
protected _client: any
|
|
20
|
-
protected _aiLogService?: AILogService
|
|
21
19
|
|
|
22
|
-
constructor(apiKey: string, model: string, visionModel?: string, aiLogService?: AILogService) {
|
|
20
|
+
constructor(apiKey: string, model: string, visionModel?: string, aiLogService?: AILogService, providerName: string = "openai") {
|
|
23
21
|
|
|
24
22
|
if (!apiKey) {
|
|
25
23
|
throw new Error("OpenAI apiKey required")
|
|
@@ -28,10 +26,11 @@ class OpenAiProvider implements IAIProvider{
|
|
|
28
26
|
throw new Error("OpenAI model required")
|
|
29
27
|
}
|
|
30
28
|
|
|
29
|
+
super(providerName, aiLogService)
|
|
30
|
+
|
|
31
31
|
this._apiKey = apiKey
|
|
32
32
|
this._model = model
|
|
33
33
|
this._visionModel = visionModel
|
|
34
|
-
this._aiLogService = aiLogService
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
get model(){
|
|
@@ -109,117 +108,6 @@ class OpenAiProvider implements IAIProvider{
|
|
|
109
108
|
}))
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
protected hasImageInput(input: IPromptParams){
|
|
113
|
-
if(input.userImages && input.userImages.length > 0){
|
|
114
|
-
return true
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if(input.userContent?.some(part => part.type === 'image')){
|
|
118
|
-
return true
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return input.history?.some(message =>
|
|
122
|
-
Array.isArray(message.content) && message.content.some(part => part.type === 'image')
|
|
123
|
-
) ?? false
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
protected serializePromptInput(input: IPromptParams, systemPrompt: string){
|
|
127
|
-
return JSON.stringify({
|
|
128
|
-
systemPrompt,
|
|
129
|
-
history: input.history,
|
|
130
|
-
userInput: input.userInput,
|
|
131
|
-
userContent: input.userContent,
|
|
132
|
-
memory: input.memory,
|
|
133
|
-
knowledgeBase: input.knowledgeBase,
|
|
134
|
-
tools: input.tools?.map(tool => ({
|
|
135
|
-
name: tool.name,
|
|
136
|
-
description: tool.description,
|
|
137
|
-
parameters: tool.parameters,
|
|
138
|
-
})),
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
protected serializePromptOutput(output: unknown){
|
|
143
|
-
if (typeof output === "string") {
|
|
144
|
-
return output
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (output === null || output === undefined) {
|
|
148
|
-
return undefined
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return JSON.stringify(output)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
protected buildLogPayload(input: IPromptParams, params: {
|
|
155
|
-
model: string,
|
|
156
|
-
systemPrompt: string,
|
|
157
|
-
startedAt: Date,
|
|
158
|
-
endedAt?: Date,
|
|
159
|
-
inputTokens?: number,
|
|
160
|
-
outputTokens?: number,
|
|
161
|
-
tokens?: number,
|
|
162
|
-
output?: unknown,
|
|
163
|
-
success: boolean,
|
|
164
|
-
errorMessage?: string,
|
|
165
|
-
}): IAILogBase {
|
|
166
|
-
return {
|
|
167
|
-
provider: "openai",
|
|
168
|
-
model: params.model,
|
|
169
|
-
operationTitle: input.operationTitle,
|
|
170
|
-
operationGroup: input.operationGroup,
|
|
171
|
-
ip: input.ip,
|
|
172
|
-
userAgent: input.userAgent,
|
|
173
|
-
input: this.serializePromptInput(input, params.systemPrompt),
|
|
174
|
-
inputImages: input.userImages?.map(image => ({
|
|
175
|
-
url: image.url,
|
|
176
|
-
})) ?? input.userContent
|
|
177
|
-
?.filter(part => part.type === "image")
|
|
178
|
-
.map(part => ({
|
|
179
|
-
url: part.imageUrl,
|
|
180
|
-
})),
|
|
181
|
-
inputFiles: input.inputFiles,
|
|
182
|
-
inputTokens: params.inputTokens,
|
|
183
|
-
outputTokens: params.outputTokens,
|
|
184
|
-
tokens: params.tokens,
|
|
185
|
-
startedAt: params.startedAt,
|
|
186
|
-
endedAt: params.endedAt,
|
|
187
|
-
responseTime: params.endedAt ? `${params.endedAt.getTime() - params.startedAt.getTime()}ms` : undefined,
|
|
188
|
-
output: this.serializePromptOutput(params.output),
|
|
189
|
-
success: params.success,
|
|
190
|
-
errorMessage: params.errorMessage,
|
|
191
|
-
tenant: input.tenant,
|
|
192
|
-
user: input.user,
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
protected async registerPromptLog(input: IPromptParams, params: {
|
|
197
|
-
model: string,
|
|
198
|
-
systemPrompt: string,
|
|
199
|
-
startedAt: Date,
|
|
200
|
-
endedAt?: Date,
|
|
201
|
-
inputTokens?: number,
|
|
202
|
-
outputTokens?: number,
|
|
203
|
-
tokens?: number,
|
|
204
|
-
output?: unknown,
|
|
205
|
-
success: boolean,
|
|
206
|
-
errorMessage?: string,
|
|
207
|
-
}){
|
|
208
|
-
if(!this._aiLogService){
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
try{
|
|
213
|
-
await this._aiLogService.create(this.buildLogPayload(input, params))
|
|
214
|
-
}catch(e: any){
|
|
215
|
-
console.error("Error registerPromptLog", {
|
|
216
|
-
name: e?.name,
|
|
217
|
-
message: e?.message,
|
|
218
|
-
stack: e?.stack,
|
|
219
|
-
})
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
111
|
async generateEmbedding({text, model="text-embedding-ada-002"}: {text:string,model:string }): Promise<number[]> {
|
|
224
112
|
const response = await this.client.embeddings.create({
|
|
225
113
|
model: model,
|
|
@@ -37,6 +37,7 @@ class AILogSqliteRepository extends AbstractSqliteRepository<IAILog, IAILogBase,
|
|
|
37
37
|
{name: "startedAt", type: "TEXT", unique: false, primary: false},
|
|
38
38
|
{name: "endedAt", type: "TEXT", unique: false, primary: false},
|
|
39
39
|
{name: "responseTime", type: "TEXT", unique: false, primary: false},
|
|
40
|
+
{name: "responseTimeMS", type: "REAL", unique: false, primary: false},
|
|
40
41
|
{name: "output", type: "TEXT", unique: false, primary: false},
|
|
41
42
|
{name: "success", type: "TEXT", unique: false, primary: false},
|
|
42
43
|
{name: "statusCode", type: "INTEGER", unique: false, primary: false},
|
|
@@ -50,4 +51,3 @@ class AILogSqliteRepository extends AbstractSqliteRepository<IAILog, IAILogBase,
|
|
|
50
51
|
|
|
51
52
|
export default AILogSqliteRepository
|
|
52
53
|
export {AILogSqliteRepository}
|
|
53
|
-
|
|
@@ -9,29 +9,29 @@ async function AILogFastifyRoutes(fastify, options) {
|
|
|
9
9
|
const schemas = new CrudSchemaBuilder(AILogSchema, AILogBaseSchema,AILogBaseSchema, 'AILog', 'openapi-3.0', ['ai']);
|
|
10
10
|
|
|
11
11
|
fastify.get('/api/ailog', {schema: schemas.paginateSchema}, (req,rep) => controller.paginate(req,rep))
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
fastify.get('/api/ailog/find', {schema: schemas.findSchema}, (req,rep) => controller.find(req,rep))
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
fastify.get('/api/ailog/search', {schema: schemas.searchSchema}, (req,rep) => controller.search(req,rep))
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
fastify.get('/api/ailog/:id', {schema: schemas.findByIdSchema}, (req,rep) => controller.findById(req,rep))
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
fastify.get('/api/ailog/find-one', {schema: schemas.findOneSchema}, (req,rep) => controller.findOne(req,rep))
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
fastify.get('/api/ailog/group-by', {schema: schemas.groupBySchema}, (req,rep) => controller.groupBy(req,rep))
|
|
22
22
|
|
|
23
|
-
fastify.post('/api/ailog', {schema: schemas.createSchema}, (req,rep) =>controller.create(req,rep))
|
|
23
|
+
// fastify.post('/api/ailog', {schema: schemas.createSchema}, (req,rep) =>controller.create(req,rep))
|
|
24
24
|
|
|
25
|
-
fastify.put('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.update(req,rep))
|
|
26
|
-
|
|
27
|
-
fastify.patch('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.updatePartial(req,rep))
|
|
25
|
+
// fastify.put('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.update(req,rep))
|
|
26
|
+
|
|
27
|
+
// fastify.patch('/api/ailog/:id', {schema: schemas.updateSchema}, (req,rep) =>controller.updatePartial(req,rep))
|
|
28
|
+
|
|
29
|
+
// fastify.delete('/api/ailog/:id', {schema: schemas.deleteSchema}, (req,rep) =>controller.delete(req,rep))
|
|
28
30
|
|
|
29
|
-
fastify.delete('/api/ailog/:id', {schema: schemas.deleteSchema}, (req,rep) =>controller.delete(req,rep))
|
|
30
|
-
|
|
31
31
|
fastify.get('/api/ailog/export', (req,rep) =>controller.export(req,rep))
|
|
32
|
-
|
|
33
|
-
fastify.post('/api/ailog/import', (req,rep) => controller.import(req,rep))
|
|
34
|
-
|
|
32
|
+
|
|
33
|
+
// fastify.post('/api/ailog/import', (req,rep) => controller.import(req,rep))
|
|
34
|
+
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export default AILogFastifyRoutes;
|
|
@@ -33,6 +33,7 @@ const AILogBaseSchema = z.object({
|
|
|
33
33
|
startedAt: z.coerce.date().nullable().optional(),
|
|
34
34
|
endedAt: z.coerce.date().nullable().optional(),
|
|
35
35
|
responseTime: z.string().optional(),
|
|
36
|
+
responseTimeMS: z.number().nullable().optional(),
|
|
36
37
|
output: z.string().optional(),
|
|
37
38
|
success: z.boolean().optional(),
|
|
38
39
|
statusCode: z.number().nullable().optional(),
|
|
@@ -45,7 +46,9 @@ const AILogSchema = AILogBaseSchema
|
|
|
45
46
|
.extend({
|
|
46
47
|
_id: z.coerce.string(),
|
|
47
48
|
tenant: z.object({_id: z.coerce.string(), name: z.string()}).nullable().optional(),
|
|
48
|
-
user: z.object({_id: z.coerce.string(), username: z.string()}).nullable().optional()
|
|
49
|
+
user: z.object({_id: z.coerce.string(), username: z.string()}).nullable().optional(),
|
|
50
|
+
createdAt: z.coerce.date().nullable().optional(),
|
|
51
|
+
updatedAt: z.coerce.date().nullable().optional(),
|
|
49
52
|
})
|
|
50
53
|
|
|
51
54
|
export default AILogSchema;
|