返回 AiToEarn
agent.vo.ts
1 import { AccountType, createPaginationVo, createZodDto } from '@yikart/common'
2 import { ContentGenerationTaskStatus } from '@yikart/mongodb'
3 import { z } from 'zod'
4
5 export enum AgentMessageType {
6 Assistant = 'assistant',
7 User = 'user',
8 Result = 'result',
9 System = 'system',
10 StreamEvent = 'stream_event',
11 ToolProgress = 'tool_progress',
12 AuthStatus = 'auth_status',
13 KeepAlive = 'keep_alive',
14 Init = 'init',
15 Complete = 'complete',
16 TitleUpdated = 'title_updated',
17 Error = 'error',
18 }
19
20 export const ContentGenerationMediaVoSchema = z.object({
21 type: z.enum(['IMAGE', 'VIDEO']),
22 url: z.string(),
23 thumbUrl: z.string().optional(),
24 prompt: z.string().optional(),
25 })
26 export class ContentGenerationMediaVo extends createZodDto(ContentGenerationMediaVoSchema) { }
27
28 // MediaOnly result schema (single object only)
29 const MediaOnlyBaseSchema = z.object({
30 type: z.literal('mediaOnly'),
31 medias: z.array(ContentGenerationMediaVoSchema),
32 })
33
34 const MediaOnlyNoneActionSchema = MediaOnlyBaseSchema.extend({
35 action: z.literal('none'),
36 })
37
38 const MediaOnlyNavigateToMediaActionSchema = MediaOnlyBaseSchema.extend({
39 action: z.literal('navigateToMedia'),
40 mediaId: z.string(),
41 groupId: z.string(),
42 })
43
44 const MediaOnlyResultSchema = z.discriminatedUnion('action', [
45 MediaOnlyNoneActionSchema,
46 MediaOnlyNavigateToMediaActionSchema,
47 ])
48
49 // FullContent result schema (array only)
50 // Base fields for each array element
51 const FullContentElementBaseSchema = z.object({
52 type: z.literal('fullContent'),
53 title: z.string(),
54 description: z.string(),
55 tags: z.array(z.string()),
56 medias: z.array(ContentGenerationMediaVoSchema),
57 })
58
59 // Action: none (platform not needed)
60 const FullContentNoneActionSchema = FullContentElementBaseSchema.extend({
61 action: z.literal('none'),
62 platform: z.enum(AccountType).optional(),
63 flowId: z.string().optional(),
64 })
65
66 // Action: navigateToDraft (platform not needed)
67 const FullContentNavigateToDraftActionSchema = FullContentElementBaseSchema.extend({
68 action: z.literal('navigateToDraft'),
69 groupId: z.string(),
70 platform: z.enum(AccountType).optional(),
71 })
72
73 // Action: navigateToMedia (platform not needed)
74 const FullContentNavigateToMediaActionSchema = FullContentElementBaseSchema.extend({
75 action: z.literal('navigateToMedia'),
76 mediaId: z.string(),
77 groupId: z.string(),
78 platform: z.enum(AccountType).optional(),
79 })
80
81 // Action: createChannel (platform required)
82 const FullContentCreateChannelActionSchema = FullContentElementBaseSchema.extend({
83 action: z.literal('createChannel'),
84 platform: z.enum(AccountType), // required
85 errorMessage: z.string().optional(),
86 })
87
88 // Action: updateChannel (platform required)
89 const FullContentUpdateChannelActionSchema = FullContentElementBaseSchema.extend({
90 action: z.literal('updateChannel'),
91 platform: z.enum(AccountType), // required
92 accountId: z.string().optional(),
93 errorMessage: z.string().optional(),
94 })
95
96 // Action: navigateToPublish (platform required)
97 const FullContentNavigateToPublishActionSchema = FullContentElementBaseSchema.extend({
98 action: z.literal('navigateToPublish'),
99 platform: z.enum(AccountType), // required
100 accountId: z.string().optional(),
101 publishTime: z.iso.datetime().optional(),
102 topics: z.array(z.string()).optional(),
103 errorMessage: z.string().optional(),
104 })
105
106 // FullContent single element union
107 const FullContentElementSchema = z.discriminatedUnion('action', [
108 FullContentNoneActionSchema,
109 FullContentNavigateToDraftActionSchema,
110 FullContentNavigateToMediaActionSchema,
111 FullContentCreateChannelActionSchema,
112 FullContentUpdateChannelActionSchema,
113 FullContentNavigateToPublishActionSchema,
114 ])
115
116 // FullContent result is an array (minimum 1 element)
117 const FullContentResultSchema = z.array(FullContentElementSchema).min(1)
118
119 // Final union: mediaOnly (single object) OR fullContent (array)
120 export const ContentGenerationTaskResultUnionSchema = z.union([
121 MediaOnlyResultSchema,
122 FullContentResultSchema,
123 ])
124
125 export const ContentGenerationTaskResultSchema = z.object({
126 result: ContentGenerationTaskResultUnionSchema,
127 })
128
129 const APIUserMessageSchema = z.object({
130 content: z.union([z.string(), z.array(z.unknown())]), // string | Array<ContentBlockParam>
131 role: z.enum(['user', 'assistant']),
132 })
133
134 const APIAssistantMessageSchema = z.object({
135 id: z.string().optional(),
136 content: z.array(z.unknown()).optional(), // Array<BetaContentBlock>
137 model: z.string().optional(),
138 role: z.literal('assistant').optional(),
139 stop_reason: z.enum(['end_turn', 'max_tokens', 'stop_sequence', 'tool_use', 'pause_turn', 'refusal']).nullable().optional(),
140 stop_sequence: z.string().nullable().optional(),
141 type: z.literal('message').optional(),
142 usage: z.object({
143 cache_creation: z.object({
144 ephemeral_1h_input_tokens: z.number().optional(),
145 ephemeral_5m_input_tokens: z.number().optional(),
146 }).nullable().optional(),
147 cache_creation_input_tokens: z.number().nullable().optional(),
148 cache_read_input_tokens: z.number().nullable().optional(),
149 input_tokens: z.number().optional(),
150 output_tokens: z.number().optional(),
151 server_tool_use: z.object({
152 web_search_requests: z.number(),
153 }).nullable().optional(),
154 service_tier: z.string().nullable().optional(), // 允许 service_tier 字段
155 }).loose().optional(), // 使用 passthrough 允许额外字段
156 container: z.unknown().nullable().optional(), // BetaContainer
157 context_management: z.unknown().nullable().optional(), // BetaContextManagementResponse
158 }).loose() // 允许额外字段
159
160 const NonNullableUsageSchema = z.object({
161 cache_creation: z.object({
162 ephemeral_1h_input_tokens: z.number(),
163 ephemeral_5m_input_tokens: z.number(),
164 }).optional(),
165 cache_creation_input_tokens: z.number().optional(),
166 cache_read_input_tokens: z.number().optional(),
167 input_tokens: z.number().optional(),
168 output_tokens: z.number().optional(),
169 server_tool_use: z.object({
170 web_search_requests: z.number(),
171 }).optional(),
172 })
173
174 const RawMessageStreamEventSchema = z.discriminatedUnion('type', [
175 z.object({
176 type: z.literal('message_start'),
177 message: z.unknown(),
178 }),
179 z.object({
180 type: z.literal('message_delta'),
181 delta: z.object({
182 stop_reason: z.string().nullable().optional(),
183 stop_sequence: z.string().nullable().optional(),
184 }).optional(),
185 usage: z.object({
186 cache_creation_input_tokens: z.number().nullable().optional(),
187 cache_read_input_tokens: z.number().nullable().optional(),
188 input_tokens: z.number().nullable().optional(),
189 output_tokens: z.number().optional(),
190 server_tool_use: z.object({
191 web_search_requests: z.number(),
192 }).nullable().optional(),
193 }).loose().optional(),
194 }),
195 z.object({
196 type: z.literal('message_stop'),
197 }),
198 z.object({
199 type: z.literal('content_block_start'),
200 index: z.number(),
201 content_block: z.unknown(),
202 }),
203 z.object({
204 type: z.literal('content_block_delta'),
205 index: z.number(),
206 delta: z.unknown(),
207 }),
208 z.object({
209 type: z.literal('content_block_stop'),
210 index: z.number(),
211 }),
212 ])
213
214 const SDKUserMessageSchema = z.object({
215 type: z.literal(AgentMessageType.User),
216 uuid: z.string().optional(),
217 message: APIUserMessageSchema.optional(),
218 content: z.union([z.string(), z.array(z.unknown())]).optional(),
219 parent_tool_use_id: z.string().nullable().optional(),
220 isSynthetic: z.boolean().optional(),
221 tool_use_result: z.unknown().optional(),
222 isReplay: z.literal(true).optional(),
223 })
224
225 const SDKAssistantMessageSchema = z.object({
226 type: z.literal(AgentMessageType.Assistant),
227 uuid: z.string(),
228 message: APIAssistantMessageSchema.optional(),
229 parent_tool_use_id: z.string().nullable().optional(),
230 error: z.enum(['authentication_failed', 'billing_error', 'rate_limit', 'invalid_request', 'server_error', 'unknown']).optional(),
231 })
232
233 const SDKResultMessageSuccessSchema = z.object({
234 type: z.literal(AgentMessageType.Result),
235 subtype: z.literal('success'),
236 uuid: z.string(),
237 duration_ms: z.number().optional(),
238 duration_api_ms: z.number().optional(),
239 is_error: z.boolean().optional(),
240 num_turns: z.number().optional(),
241 message: z.string().optional(),
242 result: ContentGenerationTaskResultUnionSchema.nullable().optional(),
243 total_cost_usd: z.number().optional(),
244 usage: NonNullableUsageSchema.optional(),
245 permission_denials: z.array(z.object({
246 tool_name: z.string(),
247 tool_use_id: z.string(),
248 tool_input: z.record(z.string(), z.unknown()),
249 })).optional(),
250 structured_output: z.unknown().optional(),
251 })
252
253 const SDKResultMessageErrorSchema = z.object({
254 type: z.literal(AgentMessageType.Result),
255 subtype: z.enum(['error_during_execution', 'error_max_turns', 'error_max_budget_usd', 'error_max_structured_output_retries']),
256 uuid: z.string(),
257 duration_ms: z.number().optional(),
258 duration_api_ms: z.number().optional(),
259 is_error: z.boolean().optional(),
260 num_turns: z.number().optional(),
261 total_cost_usd: z.number().optional(),
262 usage: NonNullableUsageSchema.optional(),
263 permission_denials: z.array(z.object({
264 tool_name: z.string(),
265 tool_use_id: z.string(),
266 tool_input: z.record(z.string(), z.unknown()),
267 })).optional(),
268 errors: z.array(z.string()).optional(),
269 })
270
271 const SDKResultMessageSchema = z.discriminatedUnion('subtype', [
272 SDKResultMessageSuccessSchema,
273 SDKResultMessageErrorSchema,
274 ])
275
276 const SDKCompactBoundaryMessageSchema = z.object({
277 type: z.literal(AgentMessageType.System),
278 subtype: z.literal('compact_boundary'),
279 uuid: z.string(),
280 compact_metadata: z.object({
281 trigger: z.enum(['manual', 'auto']),
282 pre_tokens: z.number(),
283 }).optional(),
284 })
285
286 const SDKStatusMessageSchema = z.object({
287 type: z.literal(AgentMessageType.System),
288 subtype: z.literal('status'),
289 uuid: z.string(),
290 status: z.enum(['compacting']).nullable().optional(),
291 })
292
293 const SDKHookResponseMessageSchema = z.object({
294 type: z.literal(AgentMessageType.System),
295 subtype: z.literal('hook_response'),
296 uuid: z.string(),
297 hook_name: z.string().optional(),
298 hook_event: z.string().optional(),
299 stdout: z.string().optional(),
300 stderr: z.string().optional(),
301 exit_code: z.number().optional(),
302 })
303
304 const SDKSystemMessageSchema = z.discriminatedUnion('subtype', [
305 SDKCompactBoundaryMessageSchema,
306 SDKStatusMessageSchema,
307 SDKHookResponseMessageSchema,
308 ])
309
310 const SDKPartialAssistantMessageSchema = z.object({
311 type: z.literal(AgentMessageType.StreamEvent),
312 uuid: z.string(),
313 event: RawMessageStreamEventSchema.optional(),
314 parent_tool_use_id: z.string().nullable().optional(),
315 })
316
317 const SDKToolProgressMessageSchema = z.object({
318 type: z.literal(AgentMessageType.ToolProgress),
319 uuid: z.string(),
320 tool_use_id: z.string().optional(),
321 tool_name: z.string().optional(),
322 parent_tool_use_id: z.string().nullable().optional(),
323 elapsed_time_seconds: z.number().optional(),
324 })
325
326 const SDKAuthStatusMessageSchema = z.object({
327 type: z.literal(AgentMessageType.AuthStatus),
328 uuid: z.string(),
329 isAuthenticating: z.boolean().optional(),
330 output: z.array(z.string()).optional(),
331 error: z.string().optional(),
332 })
333
334 const SDKErrorMessageSchema = z.object({
335 type: z.literal(AgentMessageType.Error),
336 code: z.number(),
337 message: z.string(),
338 data: z.unknown().optional(),
339 timestamp: z.number(),
340 })
341
342 export const AgentMessageVoSchema = z.discriminatedUnion('type', [
343 SDKUserMessageSchema,
344 SDKAssistantMessageSchema,
345 SDKResultMessageSchema,
346 SDKSystemMessageSchema,
347 SDKPartialAssistantMessageSchema,
348 SDKToolProgressMessageSchema,
349 SDKAuthStatusMessageSchema,
350 SDKErrorMessageSchema,
351 ])
352
353 export type AgentMessageVo = z.infer<typeof AgentMessageVoSchema>
354
355 export const AgentMessageVoHelper = {
356 create: (input: unknown): AgentMessageVo => {
357 return AgentMessageVoSchema.parse(input)
358 },
359 }
360
361 export const ContentGenerationTaskVoSchema = z.object({
362 id: z.string(),
363 userId: z.string(),
364 createdAt: z.coerce.date(),
365 updatedAt: z.coerce.date(),
366 title: z.string().optional(),
367 messages: z.array(AgentMessageVoSchema).optional(),
368 status: z.enum(ContentGenerationTaskStatus),
369 rating: z.number().int().min(1).max(5).optional(),
370 ratingComment: z.string().optional(),
371 favoritedAt: z.coerce.date().nullable().optional(),
372 })
373 export class ContentGenerationTaskVo extends createZodDto(ContentGenerationTaskVoSchema) { }
374
375 export const ContentGenerationTaskListItemVoSchema = z.object({
376 id: z.string(),
377 userId: z.string(),
378 title: z.string().optional(),
379 status: z.enum(ContentGenerationTaskStatus),
380 createdAt: z.coerce.date(),
381 updatedAt: z.coerce.date(),
382 rating: z.number().int().min(1).max(5).optional(),
383 ratingComment: z.string().optional(),
384 favoritedAt: z.coerce.date().nullable().optional(),
385 })
386 export class ContentGenerationTaskListItemVo extends createZodDto(ContentGenerationTaskListItemVoSchema) { }
387
388 export class ContentGenerationTaskListVo extends createPaginationVo(ContentGenerationTaskListItemVoSchema, 'ContentGenerationTaskListVo') { }
389
390 export const ContentGenerationTaskInitChunkVoSchema = z.object({
391 type: z.literal(AgentMessageType.Init),
392 taskId: z.string(),
393 messages: z.array(AgentMessageVoSchema).optional(),
394 })
395 export class ContentGenerationTaskInitChunkVo extends createZodDto(ContentGenerationTaskInitChunkVoSchema) { }
396
397 export const ContentGenerationTaskKeepAliveChunkVoSchema = z.object({
398 type: z.literal(AgentMessageType.KeepAlive),
399 })
400 export class ContentGenerationTaskKeepAliveChunkVo extends createZodDto(ContentGenerationTaskKeepAliveChunkVoSchema) { }
401
402 export const ContentGenerationTaskTitleUpdatedChunkVoSchema = z.object({
403 type: z.literal(AgentMessageType.TitleUpdated),
404 taskId: z.string(),
405 title: z.string(),
406 })
407 export class ContentGenerationTaskTitleUpdatedChunkVo extends createZodDto(ContentGenerationTaskTitleUpdatedChunkVoSchema) { }
408
409 export const ContentGenerationTaskErrorChunkVoSchema = z.object({
410 type: z.literal(AgentMessageType.Error),
411 code: z.number(),
412 message: z.string(),
413 data: z.unknown().optional(),
414 timestamp: z.number(),
415 })
416 export class ContentGenerationTaskErrorChunkVo extends createZodDto(ContentGenerationTaskErrorChunkVoSchema) { }
417
418 export const ContentGenerationTaskAgentChunkVoSchema = z.object({
419 type: z.enum([
420 AgentMessageType.Assistant,
421 AgentMessageType.User,
422 AgentMessageType.Result,
423 AgentMessageType.System,
424 AgentMessageType.StreamEvent,
425 AgentMessageType.ToolProgress,
426 AgentMessageType.AuthStatus,
427 ]),
428 message: AgentMessageVoSchema,
429 })
430 export class ContentGenerationTaskAgentChunkVo extends createZodDto(ContentGenerationTaskAgentChunkVoSchema) { }
431
432 export type ContentGenerationTaskChunkVo
433 = | ContentGenerationTaskInitChunkVo
434 | ContentGenerationTaskKeepAliveChunkVo
435 | ContentGenerationTaskTitleUpdatedChunkVo
436 | ContentGenerationTaskAgentChunkVo
437 | ContentGenerationTaskErrorChunkVo
438
439 export const ContentGenerationTaskChunkVoSchema = z.discriminatedUnion('type', [
440 ContentGenerationTaskInitChunkVoSchema,
441 ContentGenerationTaskKeepAliveChunkVoSchema,
442 ContentGenerationTaskTitleUpdatedChunkVoSchema,
443 ContentGenerationTaskAgentChunkVoSchema,
444 ContentGenerationTaskErrorChunkVoSchema,
445 ])
446
447 export const TaskMessagesVoSchema = z.object({
448 messages: z.array(AgentMessageVoSchema),
449 status: z.enum(ContentGenerationTaskStatus),
450 })
451 export class TaskMessagesVo extends createZodDto(TaskMessagesVoSchema, 'TaskMessagesVo') { }
452
453 export const PublicShareVoSchema = z.object({
454 token: z.string(),
455 expiresAt: z.coerce.date(),
456 })
457 export class PublicShareVo extends createZodDto(PublicShareVoSchema, 'PublicShareVo') { }
458
458 lines TYPESCRIPT