返回 AiToEarn
ai-log.schema.ts
根目录 / project / aitoearn-backend / libs / mongodb / src / schemas / ai-log.schema.ts
1 import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
2 import { UserType } from '@yikart/common'
3 import { AiLogChannel, AiLogStatus, AiLogType } from '../enums'
4 import { DEFAULT_SCHEMA_OPTIONS } from '../mongodb.constants'
5 import { WithTimestampSchema } from './timestamp.schema'
6
7 export interface AiLogExtraFields { [key: string]: any }
8
9 type AiLogObject<T extends object = Record<string, never>> = T & AiLogExtraFields
10
11 type AiLogUsage = AiLogObject<{
12 input_tokens?: number
13 output_tokens?: number
14 total_tokens?: number
15 promptTokenCount?: number
16 candidatesTokenCount?: number
17 totalTokenCount?: number
18 inputTokenDetails?: Record<string, unknown>
19 outputTokenDetails?: Record<string, unknown>
20 }>
21
22 type AiLogChatMessagePart = AiLogObject<{
23 type: string
24 text?: string
25 image_url?: AiLogObject<{
26 url: string
27 detail?: string
28 }>
29 }>
30
31 type AiLogChatMessage = AiLogObject<{
32 role: string
33 content: string | AiLogChatMessagePart[]
34 }>
35
36 export type AiLogImageResult = AiLogObject<{
37 url?: string
38 b64_json?: string
39 revised_prompt?: string
40 }>
41
42 type AiLogVideoTool = AiLogObject<{
43 type: string
44 }>
45
46 type AiLogVideoContentItem = AiLogObject<{
47 type: string
48 text?: string
49 role?: string
50 image_url?: AiLogObject<{ url: string }>
51 video_url?: AiLogObject<{ url: string }>
52 audio_url?: AiLogObject<{ url: string }>
53 }>
54
55 type AiLogDraftPlan = AiLogObject<{
56 title?: string
57 description?: string
58 topics?: string[]
59 videoPrompt?: string
60 imagePrompts?: string[]
61 }>
62
63 type AiLogImageExecution = AiLogObject<{
64 referenceHandling?: string
65 resolvedSize?: string
66 }>
67
68 type AiLogVideoError = string | AiLogObject<{
69 code?: string
70 message?: string
71 }>
72
73 export type ChatAiLogRequest = AiLogObject<{
74 model: string
75 messages: AiLogChatMessage[]
76 temperature?: number
77 maxTokens?: number
78 maxCompletionTokens?: number
79 modalities?: string[]
80 topP?: number
81 modelKwargs?: Record<string, unknown>
82 }>
83
84 export type ChatAiLogResponse = AiLogObject<{
85 model: string
86 created?: number
87 choices?: unknown[]
88 usage?: AiLogUsage
89 }>
90
91 export type ImageAiLogRequest = AiLogObject<{
92 prompt: string
93 model?: string
94 content?: string
95 image?: string | string[]
96 imageUrls?: string[]
97 imageSize?: string
98 aspectRatio?: string
99 referenceImageUrl?: string
100 mask?: string
101 n?: number
102 quality?: string
103 response_format?: 'url' | 'b64_json'
104 size?: string
105 style?: string
106 user?: string
107 }>
108
109 export type ImageAiLogResponse = AiLogObject<{
110 created?: number
111 data?: AiLogImageResult[]
112 list?: AiLogImageResult[]
113 images?: AiLogImageResult[]
114 image?: string
115 imageUrl?: string
116 usage?: AiLogUsage
117 }>
118
119 export type UserVideoGenerationAiLogRequest = AiLogObject<{
120 model: string
121 prompt: string
122 groupId?: string
123 image?: string | string[]
124 image_tail?: string
125 video_url?: string
126 images?: string[]
127 videos?: string[]
128 audios?: string[]
129 mode?: string
130 size?: string
131 resolution?: string
132 ratio?: string
133 duration?: number
134 seed?: number
135 watermark?: boolean
136 tools?: AiLogVideoTool[]
137 metadata?: Record<string, unknown>
138 }>
139
140 export type VolcengineVideoAiLogRequest = AiLogObject<{
141 model: string
142 content: AiLogVideoContentItem[]
143 return_last_frame?: boolean
144 resolution?: string
145 ratio?: string
146 duration?: number
147 seed?: number
148 watermark?: boolean
149 tools?: AiLogVideoTool[]
150 groupId?: string
151 }>
152
153 type OpenAIVideoAiLogRequestBase = AiLogObject<{
154 prompt: string
155 input_reference?: string
156 groupId?: string
157 }>
158
159 export type OpenAIVideoAiLogRequest = OpenAIVideoAiLogRequestBase & {
160 model?: string
161 seconds?: string
162 size?: string
163 }
164
165 export type OpenAIRemixVideoAiLogRequest = OpenAIVideoAiLogRequestBase & {
166 remixed_from_video_id: string
167 }
168
169 export type GrokVideoAiLogRequest = AiLogObject<{
170 model: string
171 prompt: string
172 duration?: number
173 aspectRatio?: string
174 resolution?: string
175 image?: string
176 referenceImages?: string[]
177 videoUrl?: string
178 groupId?: string
179 }>
180
181 export type DashscopeVideoAiLogRequest = AiLogObject<{
182 model: string
183 providerModel?: string
184 mode?: string
185 prompt: string
186 images?: string[]
187 videoUrl?: string
188 resolution?: string
189 ratio?: string
190 duration?: number
191 watermark?: boolean
192 seed?: number
193 groupId?: string
194 }>
195 export type RelayVideoAiLogRequest = AiLogObject<{
196 model: string
197 prompt: string
198 groupId?: string
199 image?: string | string[]
200 image_tail?: string
201 video_url?: string
202 images?: string[]
203 videos?: string[]
204 audios?: string[]
205 mode?: string
206 size?: string
207 resolution?: string
208 ratio?: string
209 duration?: number
210 seed?: number
211 watermark?: boolean
212 tools?: Array<{ type: string }>
213 metadata?: Record<string, unknown>
214 source?: string
215 }>
216
217 export type VideoAiLogRequest
218 = | UserVideoGenerationAiLogRequest
219 | VolcengineVideoAiLogRequest
220 | OpenAIVideoAiLogRequest
221 | OpenAIRemixVideoAiLogRequest
222 | GrokVideoAiLogRequest
223 | DashscopeVideoAiLogRequest
224 | RelayVideoAiLogRequest
225
226 export type VideoAiLogResponse = AiLogObject<{
227 id?: string
228 name?: string
229 status?: string | AiLogStatus
230 done?: boolean
231 createdAt?: Date
232 completedAt?: Date | null
233 model?: string
234 prompt?: string
235 url?: string
236 video_url?: string
237 videoUrl?: string
238 content?: AiLogObject<{
239 video_url?: string
240 last_frame_url?: string
241 }>
242 generatedVideos?: Array<AiLogObject<{
243 url: string
244 gcsUrl: string | null
245 }>>
246 response?: AiLogObject<{
247 generatedVideos?: Array<AiLogObject<{
248 video?: AiLogExtraFields
249 }>>
250 }>
251 error?: AiLogVideoError
252 mediaId?: string
253 coverUrl?: string
254 groupId?: string
255 }>
256
257 type VideoDraftGenerationAiLogRequest = AiLogObject<{
258 groupId: string
259 version: 'v2'
260 model: string
261 duration?: number
262 aspectRatio?: string
263 prompt?: string
264 captionPrompt?: string
265 imageUrls?: string[]
266 videoUrls?: string[]
267 draftType?: string
268 plannerModel?: string
269 imageExecution?: AiLogImageExecution
270 }>
271
272 type ImageTextDraftGenerationAiLogRequest = AiLogObject<{
273 groupId: string
274 version: 'v2-image-text'
275 imageModel: string
276 imageCount?: number
277 imageSize?: string
278 aspectRatio?: string
279 prompt: string
280 imageUrls?: string[]
281 draftType?: string
282 plannerModel?: string
283 imageExecution?: AiLogImageExecution
284 }>
285
286 export type DraftGenerationAiLogRequest
287 = | VideoDraftGenerationAiLogRequest
288 | ImageTextDraftGenerationAiLogRequest
289
290 export type DraftGenerationAiLogResponse = AiLogObject<{
291 materialId?: string
292 mediaId?: string
293 mediaIds?: string[]
294 title?: string
295 description?: string
296 topics?: string[]
297 videoUrl?: string
298 coverUrl?: string
299 imageUrls?: string[]
300 requestedImageCount?: number
301 generatedImageCount?: number
302 imageGenerationErrors?: AiLogExtraFields[]
303 plan?: AiLogDraftPlan
304 }>
305
306 export type AideoAiLogRequest = AiLogObject<{
307 spaceName?: string
308 prompt?: string
309 skillType?: string
310 skillParams?: Record<string, unknown>
311 multiInputs?: unknown[]
312 vids?: string[]
313 dramaScriptTaskId?: string
314 recapText?: string
315 speakerConfig?: Record<string, unknown>
316 isEraseSubtitle?: boolean
317 fontConfig?: Record<string, unknown>
318 recapStyle?: string
319 recapTextSpeed?: number
320 recapTextLength?: number
321 pauseTime?: number
322 allowRepeatMatch?: boolean
323 }>
324
325 export type AideoAiLogResponse = AiLogObject<{
326 taskId?: string
327 dramaScriptTaskId?: string
328 status?: string
329 Status?: string
330 SkillType?: string
331 SkillParams?: Record<string, unknown>
332 ApiResponses?: Array<AiLogObject<{
333 Error?: AiLogObject<{
334 Code?: string
335 Message?: string
336 }>
337 }>>
338 outputVid?: string
339 outputUrl?: string
340 errorMessage?: string
341 error?: AiLogExtraFields
342 }>
343
344 export type VideoEditAiLogRequest = AiLogObject<{
345 Canvas: Record<string, unknown>
346 Output: Record<string, unknown>
347 tracksCount: number
348 }>
349
350 export type VideoEditAiLogResponse = AiLogObject<{
351 outputUrl?: string
352 outputVid?: string
353 error?: string | AiLogExtraFields
354 }>
355
356 export type AgentAiLogRequest = AiLogObject<{
357 materialId?: string
358 platforms?: string[]
359 configOnly?: boolean
360 imageCount?: number
361 videoUrl?: string
362 }>
363
364 export type AgentAiLogResponse = AiLogObject<{
365 modelUsage?: Record<string, unknown>
366 taskResult?: unknown
367 title?: string
368 description?: string
369 topics?: string[]
370 }>
371
372 export type StyleTransferAiLogRequest = AiLogObject<{
373 videoInput: string
374 style?: string
375 resolution?: string
376 vid?: string
377 }>
378
379 export type StyleTransferAiLogResponse = AiLogObject<{
380 taskId?: string
381 outputVid?: string
382 outputUrl?: string
383 duration?: number
384 resolution?: string
385 price?: number
386 }>
387
388 export type CardAiLogRequest = AiLogExtraFields
389 export type CardAiLogResponse = AiLogExtraFields
390
391 export type CrawlerAiLogRequest = AiLogObject<{
392 userId: string
393 link: string
394 }>
395
396 export type CrawlerAiLogResponse = AiLogObject<{
397 status?: string
398 result?: Record<string, unknown>
399 error?: string
400 uploadMediaList?: unknown[]
401 }>
402
403 export interface AiLogRequestByTypeMap {
404 [AiLogType.Chat]: ChatAiLogRequest
405 [AiLogType.Image]: ImageAiLogRequest
406 [AiLogType.Card]: CardAiLogRequest
407 [AiLogType.Video]: VideoAiLogRequest
408 [AiLogType.Agent]: AgentAiLogRequest
409 [AiLogType.Aideo]: AideoAiLogRequest
410 [AiLogType.Crawler]: CrawlerAiLogRequest
411 [AiLogType.StyleTransfer]: StyleTransferAiLogRequest
412 [AiLogType.VideoEdit]: VideoEditAiLogRequest
413 [AiLogType.DraftGeneration]: DraftGenerationAiLogRequest
414 }
415
416 export interface AiLogResponseByTypeMap {
417 [AiLogType.Chat]: ChatAiLogResponse
418 [AiLogType.Image]: ImageAiLogResponse
419 [AiLogType.Card]: CardAiLogResponse
420 [AiLogType.Video]: VideoAiLogResponse
421 [AiLogType.Agent]: AgentAiLogResponse
422 [AiLogType.Aideo]: AideoAiLogResponse
423 [AiLogType.Crawler]: CrawlerAiLogResponse
424 [AiLogType.StyleTransfer]: StyleTransferAiLogResponse
425 [AiLogType.VideoEdit]: VideoEditAiLogResponse
426 [AiLogType.DraftGeneration]: DraftGenerationAiLogResponse
427 }
428
429 export type AiLogRequest = AiLogRequestByTypeMap[keyof AiLogRequestByTypeMap]
430 export type AiLogResponse = AiLogResponseByTypeMap[keyof AiLogResponseByTypeMap]
431 export type AiLogRequestByType<T extends AiLogType> = AiLogRequestByTypeMap[T]
432 export type AiLogResponseByType<T extends AiLogType> = AiLogResponseByTypeMap[T]
433
434 @Schema({ ...DEFAULT_SCHEMA_OPTIONS, collection: 'aiLogs' })
435 export class AiLog extends WithTimestampSchema {
436 id: string
437
438 @Prop({
439 required: true,
440 index: true,
441 })
442 userId: string
443
444 @Prop({
445 required: true,
446 enum: UserType,
447 })
448 userType: UserType
449
450 @Prop({
451 required: false,
452 index: true,
453 })
454 taskId?: string
455
456 @Prop({
457 required: true,
458 enum: AiLogType,
459 })
460 type: AiLogType
461
462 @Prop({
463 required: true,
464 })
465 model: string
466
467 @Prop({
468 required: true,
469 enum: AiLogChannel,
470 })
471 channel: AiLogChannel
472
473 @Prop({
474 required: false,
475 })
476 action?: string
477
478 @Prop({
479 required: true,
480 enum: AiLogStatus,
481 })
482 status: AiLogStatus
483
484 @Prop({
485 required: true,
486 type: Date,
487 })
488 startedAt: Date
489
490 @Prop({
491 required: false,
492 })
493 duration?: number
494
495 @Prop({
496 required: true,
497 type: Object,
498 })
499 request: AiLogRequest
500
501 @Prop({
502 required: false,
503 type: Object,
504 })
505 response?: AiLogResponse
506
507 @Prop({
508 required: false,
509 type: Object,
510 })
511 errorMessage?: string
512 }
513
514 export type TypedAiLog<T extends AiLogType> = Omit<AiLog, 'type' | 'request' | 'response'> & {
515 type: T
516 request: AiLogRequestByType<T>
517 response?: AiLogResponseByType<T>
518 }
519
520 export const AiLogSchema = SchemaFactory.createForClass(AiLog)
521 AiLogSchema.index({ type: 1, status: 1, channel: 1, createdAt: -1 })
522 AiLogSchema.index({ userId: 1, type: 1, userType: 1, createdAt: -1 })
523 AiLogSchema.index({ status: 1, createdAt: -1 })
524 AiLogSchema.index({ status: 1, startedAt: 1 })
525
525 lines TYPESCRIPT