@purpleschool/gptbot-tools 0.0.77-ai-proxy → 0.0.78-ai-proxy

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.
Files changed (215) hide show
  1. package/ai-vendor/index.ts +1 -0
  2. package/ai-vendor/models/ai-vendor.schema.ts +13 -0
  3. package/ai-vendor/models/index.ts +1 -0
  4. package/build/ai-vendor/index.js +17 -0
  5. package/build/ai-vendor/models/ai-vendor.schema.js +13 -0
  6. package/build/ai-vendor/models/index.js +17 -0
  7. package/build/common/errors/errors.js +163 -0
  8. package/build/common/models/attached-file.schema.js +13 -0
  9. package/build/common/models/index.js +1 -0
  10. package/build/image-editor/commands/image-editor-model/get-image-editor-model-by-uuid.command.js +13 -0
  11. package/build/image-editor/commands/image-editor-model/index.js +17 -0
  12. package/build/image-editor/commands/image-editor.command.js +3 -1
  13. package/build/image-editor/commands/index.js +1 -0
  14. package/build/image-editor/commands/retry-image-editor-job.command.js +4 -0
  15. package/build/image-editor/commands/set-reaction-to-image-editor-job.command.js +12 -2
  16. package/build/image-editor/enums/image-editor-model-type.enum.js +2 -0
  17. package/build/image-editor/enums/image-editor-strategy.enum.js +4 -0
  18. package/build/image-editor/models/image-editor-config.schema.js +1 -0
  19. package/build/image-editor/models/image-editor-job.schema.js +2 -0
  20. package/build/image-editor/models/image-editor-model.schema.js +9 -1
  21. package/build/image-editor/routes/image-editor-model.amqp.routes.js +6 -0
  22. package/build/image-editor/routes/image-editor.http.routes.js +1 -0
  23. package/build/image-editor/routes/index.js +1 -0
  24. package/build/image-generation/commands/execute-image-generation.command.js +20 -0
  25. package/build/image-generation/commands/forward-image-generation-job.command.js +32 -0
  26. package/build/image-generation/commands/index.js +23 -0
  27. package/build/image-generation/commands/save-image-generation-job.command.js +17 -0
  28. package/build/image-generation/commands/set-reaction-to-image-generation-job.command.js +27 -0
  29. package/build/image-generation/commands/soft-delete-image-generation-job-by-uuid.command.js +14 -0
  30. package/build/image-generation/commands/soft-delete-image-generation-jobs-by-criteria.command.js +13 -0
  31. package/build/image-generation/commands/update-image-generation-job-title.command.js +16 -0
  32. package/build/image-generation/enums/image-generation-model-strategy.enum.js +23 -0
  33. package/build/image-generation/enums/image-generation-models.enum.js +8 -0
  34. package/build/image-generation/enums/image-generation-resolution.enum.js +9 -0
  35. package/build/image-generation/enums/index.js +19 -0
  36. package/build/image-generation/index.js +21 -0
  37. package/build/image-generation/models/image-generation-config.schema.js +12 -0
  38. package/build/image-generation/models/image-generation-job.schema.js +35 -0
  39. package/build/image-generation/models/image-generation-model.schema.js +51 -0
  40. package/build/image-generation/models/image-generation-preset.schema.js +13 -0
  41. package/build/image-generation/models/index.js +20 -0
  42. package/build/image-generation/queries/find-image-generation-job-by-id.query.js +19 -0
  43. package/build/image-generation/queries/find-image-generation-jobs.query.js +28 -0
  44. package/build/image-generation/queries/get-image-generation-config.query.js +11 -0
  45. package/build/image-generation/queries/index.js +19 -0
  46. package/build/image-generation/routes/image-generation.amqp.routes.js +14 -0
  47. package/build/image-generation/routes/image-generation.http.routes.js +9 -0
  48. package/build/image-generation/routes/index.js +18 -0
  49. package/build/index.js +6 -0
  50. package/build/music/commands/index.js +1 -0
  51. package/build/music/commands/music-model/get-music-model-by-uuid.command.js +13 -0
  52. package/build/music/commands/music-model/index.js +17 -0
  53. package/build/music/commands/retry-music-job.command.js +2 -0
  54. package/build/music/commands/set-reaction-to-music-job.command.js +12 -2
  55. package/build/music/models/music-job.schema.js +1 -0
  56. package/build/music/models/music-track.schema.js +1 -0
  57. package/build/music/routes/index.js +1 -0
  58. package/build/music/routes/music-model.amqp.routes.js +6 -0
  59. package/build/paraphrase/commands/delete-all-paraphrase-jobs.command.js +13 -0
  60. package/build/paraphrase/commands/delete-paraphrase-job-by-uuid.command.js +14 -0
  61. package/build/paraphrase/commands/index.js +5 -0
  62. package/build/paraphrase/commands/retry-paraphrase-job.command.js +16 -0
  63. package/build/paraphrase/commands/set-reaction-to-paraphrase-job.command.js +27 -0
  64. package/build/paraphrase/commands/update-paraphrase-job-title.command.js +16 -0
  65. package/build/paraphrase/models/paraphrase-job.schema.js +7 -0
  66. package/build/paraphrase/queries/find-paraphrase-jobs.query.js +28 -0
  67. package/build/paraphrase/queries/index.js +1 -0
  68. package/build/paraphrase/routes/paraphrase.amqp.routes.js +6 -0
  69. package/build/presentation/commands/index.js +1 -0
  70. package/build/presentation/commands/set-reaction-to-presentation.command.js +26 -0
  71. package/build/presentation/constants/slide-layout-map.constant.js +1 -0
  72. package/build/presentation/enums/slide-content-type.enum.js +1 -0
  73. package/build/presentation/models/pptx-export-payload.js +19 -1
  74. package/build/presentation/models/presentation.schema.js +3 -0
  75. package/build/presentation/models/slide-content-edit.schema.js +18 -1
  76. package/build/presentation/models/slide-content.schema.js +30 -1
  77. package/build/presentation/routes/presentation.routes.js +1 -0
  78. package/build/stt/commands/set-reaction-to-stt-job.command.js +12 -2
  79. package/build/stt/models/stt-job.schema.js +2 -0
  80. package/build/tools/enums/tool-content-type.enum.js +1 -0
  81. package/build/tools/enums/tool-type.enum.js +1 -0
  82. package/build/tools/models/global-tools-config.schema.js +2 -0
  83. package/build/tools/models/tool.schema.js +3 -0
  84. package/build/tools/models/tools-with-configs.schema.js +5 -0
  85. package/build/tts/commands/set-reaction-to-tts-job.command.js +12 -2
  86. package/build/tts/models/tts-job.schema.js +2 -0
  87. package/build/video/commands/index.js +1 -0
  88. package/build/video/commands/retry-video-job.command.js +4 -0
  89. package/build/video/commands/set-reaction-to-video-job.command.js +12 -2
  90. package/build/video/commands/video-model/get-video-model-by-uuid.command.js +13 -0
  91. package/build/video/commands/video-model/index.js +17 -0
  92. package/build/video/enums/video-pricing-rule-type.enum.js +1 -0
  93. package/build/video/enums/video-strategy.enum.js +1 -0
  94. package/build/video/models/video-job.schema.js +3 -0
  95. package/build/video/models/video-model.schema.js +9 -1
  96. package/build/video/routes/index.js +1 -0
  97. package/build/video/routes/video-model.amqp.routes.js +6 -0
  98. package/build/video/routes/video.http.routes.js +1 -0
  99. package/build/video/utils/calculate-video-generation-price.util.js +5 -1
  100. package/build/video-editor/commands/edit-video.command.js +2 -1
  101. package/build/video-editor/commands/index.js +1 -0
  102. package/build/video-editor/commands/retry-video-editor-job.command.js +5 -0
  103. package/build/video-editor/commands/set-reaction-to-video-editor-job.command.js +12 -2
  104. package/build/video-editor/commands/video-editor-model/get-video-editor-model.command.js +13 -0
  105. package/build/video-editor/commands/video-editor-model/index.js +17 -0
  106. package/build/video-editor/models/video-editor-job.schema.js +3 -0
  107. package/build/video-editor/routes/index.js +1 -0
  108. package/build/video-editor/routes/video-editor-model.amqp.routes.js +6 -0
  109. package/build/writer/commands/set-reaction-writer-document.command.js +11 -1
  110. package/build/writer/models/writer-document.schema.js +1 -0
  111. package/common/errors/errors.ts +163 -0
  112. package/common/models/attached-file.schema.ts +11 -0
  113. package/common/models/index.ts +1 -0
  114. package/image-editor/commands/image-editor-model/get-image-editor-model-by-uuid.command.ts +13 -0
  115. package/image-editor/commands/image-editor-model/index.ts +1 -0
  116. package/image-editor/commands/image-editor.command.ts +3 -1
  117. package/image-editor/commands/index.ts +1 -0
  118. package/image-editor/commands/retry-image-editor-job.command.ts +5 -1
  119. package/image-editor/commands/set-reaction-to-image-editor-job.command.ts +19 -6
  120. package/image-editor/enums/image-editor-model-type.enum.ts +2 -0
  121. package/image-editor/enums/image-editor-strategy.enum.ts +4 -0
  122. package/image-editor/models/image-editor-config.schema.ts +1 -0
  123. package/image-editor/models/image-editor-job.schema.ts +3 -1
  124. package/image-editor/models/image-editor-model.schema.ts +16 -0
  125. package/image-editor/routes/image-editor-model.amqp.routes.ts +3 -0
  126. package/image-editor/routes/image-editor.http.routes.ts +1 -0
  127. package/image-editor/routes/index.ts +1 -0
  128. package/image-generation/commands/execute-image-generation.command.ts +20 -0
  129. package/image-generation/commands/forward-image-generation-job.command.ts +32 -0
  130. package/image-generation/commands/index.ts +7 -0
  131. package/image-generation/commands/save-image-generation-job.command.ts +17 -0
  132. package/image-generation/commands/set-reaction-to-image-generation-job.command.ts +30 -0
  133. package/image-generation/commands/soft-delete-image-generation-job-by-uuid.command.ts +14 -0
  134. package/image-generation/commands/soft-delete-image-generation-jobs-by-criteria.command.ts +13 -0
  135. package/image-generation/commands/update-image-generation-job-title.command.ts +16 -0
  136. package/image-generation/enums/image-generation-model-strategy.enum.ts +24 -0
  137. package/image-generation/enums/image-generation-models.enum.ts +4 -0
  138. package/image-generation/enums/image-generation-resolution.enum.ts +5 -0
  139. package/image-generation/enums/index.ts +3 -0
  140. package/image-generation/index.ts +5 -0
  141. package/image-generation/models/image-generation-config.schema.ts +11 -0
  142. package/image-generation/models/image-generation-job.schema.ts +37 -0
  143. package/image-generation/models/image-generation-model.schema.ts +64 -0
  144. package/image-generation/models/image-generation-preset.schema.ts +13 -0
  145. package/image-generation/models/index.ts +4 -0
  146. package/image-generation/queries/find-image-generation-job-by-id.query.ts +19 -0
  147. package/image-generation/queries/find-image-generation-jobs.query.ts +33 -0
  148. package/image-generation/queries/get-image-generation-config.query.ts +11 -0
  149. package/image-generation/queries/index.ts +3 -0
  150. package/image-generation/routes/image-generation.amqp.routes.ts +11 -0
  151. package/image-generation/routes/image-generation.http.routes.ts +7 -0
  152. package/image-generation/routes/index.ts +2 -0
  153. package/index.ts +6 -0
  154. package/music/commands/index.ts +1 -0
  155. package/music/commands/music-model/get-music-model-by-uuid.command.ts +13 -0
  156. package/music/commands/music-model/index.ts +1 -0
  157. package/music/commands/retry-music-job.command.ts +3 -1
  158. package/music/commands/set-reaction-to-music-job.command.ts +19 -6
  159. package/music/models/music-job.schema.ts +1 -0
  160. package/music/models/music-track.schema.ts +1 -0
  161. package/music/routes/index.ts +1 -0
  162. package/music/routes/music-model.amqp.routes.ts +3 -0
  163. package/package.json +1 -1
  164. package/paraphrase/commands/delete-all-paraphrase-jobs.command.ts +13 -0
  165. package/paraphrase/commands/delete-paraphrase-job-by-uuid.command.ts +14 -0
  166. package/paraphrase/commands/index.ts +5 -0
  167. package/paraphrase/commands/retry-paraphrase-job.command.ts +16 -0
  168. package/paraphrase/commands/set-reaction-to-paraphrase-job.command.ts +30 -0
  169. package/paraphrase/commands/update-paraphrase-job-title.command.ts +16 -0
  170. package/paraphrase/models/paraphrase-job.schema.ts +7 -0
  171. package/paraphrase/queries/find-paraphrase-jobs.query.ts +33 -0
  172. package/paraphrase/queries/index.ts +1 -0
  173. package/paraphrase/routes/paraphrase.amqp.routes.ts +6 -0
  174. package/presentation/commands/index.ts +1 -0
  175. package/presentation/commands/set-reaction-to-presentation.command.ts +29 -0
  176. package/presentation/constants/slide-layout-map.constant.ts +1 -0
  177. package/presentation/enums/slide-content-type.enum.ts +1 -0
  178. package/presentation/models/pptx-export-payload.ts +20 -0
  179. package/presentation/models/presentation.schema.ts +3 -0
  180. package/presentation/models/slide-content-edit.schema.ts +21 -0
  181. package/presentation/models/slide-content.schema.ts +51 -0
  182. package/presentation/routes/presentation.routes.ts +1 -0
  183. package/stt/commands/set-reaction-to-stt-job.command.ts +19 -6
  184. package/stt/models/stt-job.schema.ts +2 -0
  185. package/tools/enums/tool-content-type.enum.ts +1 -0
  186. package/tools/enums/tool-type.enum.ts +1 -0
  187. package/tools/models/global-tools-config.schema.ts +2 -0
  188. package/tools/models/tool.schema.ts +3 -0
  189. package/tools/models/tools-with-configs.schema.ts +7 -0
  190. package/tts/commands/set-reaction-to-tts-job.command.ts +19 -6
  191. package/tts/models/tts-job.schema.ts +2 -0
  192. package/video/commands/index.ts +1 -0
  193. package/video/commands/retry-video-job.command.ts +4 -0
  194. package/video/commands/set-reaction-to-video-job.command.ts +19 -6
  195. package/video/commands/video-model/get-video-model-by-uuid.command.ts +13 -0
  196. package/video/commands/video-model/index.ts +1 -0
  197. package/video/enums/video-pricing-rule-type.enum.ts +1 -0
  198. package/video/enums/video-strategy.enum.ts +1 -0
  199. package/video/models/video-job.schema.ts +3 -0
  200. package/video/models/video-model.schema.ts +9 -1
  201. package/video/routes/index.ts +1 -0
  202. package/video/routes/video-model.amqp.routes.ts +3 -0
  203. package/video/routes/video.http.routes.ts +1 -0
  204. package/video/utils/calculate-video-generation-price.util.ts +7 -1
  205. package/video-editor/commands/edit-video.command.ts +2 -1
  206. package/video-editor/commands/index.ts +1 -0
  207. package/video-editor/commands/retry-video-editor-job.command.ts +5 -0
  208. package/video-editor/commands/set-reaction-to-video-editor-job.command.ts +19 -6
  209. package/video-editor/commands/video-editor-model/get-video-editor-model.command.ts +13 -0
  210. package/video-editor/commands/video-editor-model/index.ts +1 -0
  211. package/video-editor/models/video-editor-job.schema.ts +3 -0
  212. package/video-editor/routes/index.ts +1 -0
  213. package/video-editor/routes/video-editor-model.amqp.routes.ts +3 -0
  214. package/writer/commands/set-reaction-writer-document.command.ts +19 -6
  215. package/writer/models/writer-document.schema.ts +1 -0
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import { ICommandResponseSchema } from '../../common/models/command-response.schema';
3
+ import { ParaphraseJobSchema } from '../models/paraphrase-job.schema';
4
+
5
+ export namespace FindParaphraseJobsQuery {
6
+ export const RequestSchema = z
7
+ .object({
8
+ userId: z.string().uuid().optional(),
9
+ unregisteredUserId: z.string().uuid().optional(),
10
+ title: z.string().optional(),
11
+ limit: z.coerce.number().min(1).optional(),
12
+ offset: z.coerce.number().min(0).default(0).optional(),
13
+ })
14
+ .refine(
15
+ (data) => {
16
+ return Boolean(data.userId) !== Boolean(data.unregisteredUserId);
17
+ },
18
+ {
19
+ message: 'At least userId or unregisteredUserId must be present',
20
+ path: ['userId', 'unregisteredUserId'],
21
+ },
22
+ );
23
+ export type Request = z.infer<typeof RequestSchema>;
24
+
25
+ export const ResponseSchema = ICommandResponseSchema(
26
+ z.object({
27
+ data: z.array(ParaphraseJobSchema),
28
+ page: z.number(),
29
+ totalPages: z.number(),
30
+ }),
31
+ );
32
+ export type Response = z.infer<typeof ResponseSchema>;
33
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './find-paraphrase-job-by-uuid.query';
2
2
  export * from './get-paraphrase-tool-config.query';
3
+ export * from './find-paraphrase-jobs.query';
@@ -2,4 +2,10 @@ export const PARAPHRASE_AMQP_ROUTES = {
2
2
  EXECUTE: 'tools.paraphrase.execute.rpc',
3
3
  CONFIG: 'tools.paraphrase.config.rpc',
4
4
  GET_JOB: 'tools.paraphrase.jobs.get.rpc',
5
+ LIST_JOBS: 'tools.paraphrase.jobs.list.rpc',
6
+ SET_REACTION: 'tools.paraphrase.jobs.set-reaction.rpc',
7
+ UPDATE_TITLE: 'tools.paraphrase.jobs.update-title.rpc',
8
+ SOFT_DELETE: 'tools.paraphrase.jobs.soft-delete.rpc',
9
+ SOFT_DELETE_ALL: 'tools.paraphrase.jobs.soft-delete-all.rpc',
10
+ RETRY: 'tools.paraphrase.jobs.retry.rpc',
5
11
  } as const;
@@ -16,3 +16,4 @@ export * from './update-slide-image-slot.command';
16
16
  export * from './update-slide.command';
17
17
  export * from './presentation-paraphrase.command';
18
18
  export * from './presentation-generate-report.command';
19
+ export * from './set-reaction-to-presentation.command';
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { ICommandResponseSchema, USER_REACTION } from '../../common';
3
+ import { PresentationSchema } from '../models';
4
+
5
+ export namespace SetReactionToPresentationCommand {
6
+ export const RequestSchema = z
7
+ .object({
8
+ userId: z.string().uuid().nullable().optional(),
9
+ unregisteredUserId: z.string().uuid().nullable().optional(),
10
+ uuid: z.string().uuid(),
11
+ reaction: z.nativeEnum(USER_REACTION).nullable(),
12
+ dislikeReason: z.string().nullable().default(null),
13
+ })
14
+ .refine(
15
+ (data) => {
16
+ if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
17
+ return false;
18
+ }
19
+ return true;
20
+ },
21
+ {
22
+ message: 'Dislike reason is not allowed when reaction is not disliked',
23
+ },
24
+ );
25
+ export type Request = z.infer<typeof RequestSchema>;
26
+
27
+ export const ResponseSchema = ICommandResponseSchema(PresentationSchema);
28
+ export type Response = z.infer<typeof ResponseSchema>;
29
+ }
@@ -11,4 +11,5 @@ export const SLIDE_LAYOUT_MAP = new Map<SLIDE_CONTENT_TYPE, SLIDE_LAYOUT[]>([
11
11
  [SLIDE_CONTENT_TYPE.THANK_YOU, [SLIDE_LAYOUT.TYPE_1]],
12
12
  [SLIDE_CONTENT_TYPE.TABLE, [SLIDE_LAYOUT.TYPE_1]],
13
13
  [SLIDE_CONTENT_TYPE.CHART, [SLIDE_LAYOUT.TYPE_1]],
14
+ [SLIDE_CONTENT_TYPE.TIMELINE, [SLIDE_LAYOUT.TYPE_1]],
14
15
  ]);
@@ -8,4 +8,5 @@ export enum SLIDE_CONTENT_TYPE {
8
8
  THANK_YOU = 'THANK_YOU',
9
9
  TABLE = 'TABLE',
10
10
  CHART = 'CHART',
11
+ TIMELINE = 'TIMELINE',
11
12
  }
@@ -5,6 +5,7 @@ export enum PPTX_SHAPE_TYPE {
5
5
  PICTURE_BOX = 'picture_box',
6
6
  CUSTOM_SHAPE = 'custom_shape',
7
7
  TABLE = 'table',
8
+ CHEVRON = 'chevron',
8
9
  }
9
10
 
10
11
  export enum PPTX_H_ALIGN {
@@ -47,6 +48,13 @@ export enum PPTX_CUSTOM_SHAPE_TYPE {
47
48
  ROUND_RECT = 'roundRect',
48
49
  }
49
50
 
51
+ export enum PPTX_CHEVRON_DIRECTION {
52
+ RIGHT = 'right',
53
+ LEFT = 'left',
54
+ UP = 'up',
55
+ DOWN = 'down',
56
+ }
57
+
50
58
  export const PPTXShadowSchema = z.object({
51
59
  type: z.nativeEnum(PPTX_SHADOW_TYPE),
52
60
  opacity: z.number().min(0).max(100).optional().describe('percents, range 0-100'),
@@ -182,6 +190,17 @@ export const PPTXTableShapeSchema = z.object({
182
190
  });
183
191
  export type PPTXTableShape = z.infer<typeof PPTXTableShapeSchema>;
184
192
 
193
+ // Chevron
194
+ export const PPTXChevronShapeSchema = z.object({
195
+ type: z.literal(PPTX_SHAPE_TYPE.CHEVRON),
196
+ direction: z.nativeEnum(PPTX_CHEVRON_DIRECTION).default(PPTX_CHEVRON_DIRECTION.RIGHT),
197
+ position: PPTXPositionSchema,
198
+ fill: PPTXFillSchema.optional(),
199
+ align: z.nativeEnum(PPTX_H_ALIGN).optional().default(PPTX_H_ALIGN.CENTER),
200
+ valign: z.nativeEnum(PPTX_V_ALIGN).optional().default(PPTX_V_ALIGN.MIDDLE),
201
+ });
202
+ export type PPTXChevronShape = z.infer<typeof PPTXChevronShapeSchema>;
203
+
185
204
  // Overview
186
205
 
187
206
  export const PPTXShapeSchema = z.discriminatedUnion('type', [
@@ -189,6 +208,7 @@ export const PPTXShapeSchema = z.discriminatedUnion('type', [
189
208
  PPTXPictureBoxSchema,
190
209
  PPTXCustomShapeSchema,
191
210
  PPTXTableShapeSchema,
211
+ PPTXChevronShapeSchema,
192
212
  ]);
193
213
  export type PPTXShape = z.infer<typeof PPTXShapeSchema>;
194
214
 
@@ -2,6 +2,7 @@ import { z } from 'zod';
2
2
  import { PRESENTATION_STAGE } from '../enums';
3
3
  import { SlideOutlineSchema } from './slide-outline.schema';
4
4
  import { SlideSchema } from './slide.schema';
5
+ import { USER_REACTION } from '../../common';
5
6
 
6
7
  export const PresentationSchema = z.object({
7
8
  uuid: z.string().uuid(),
@@ -12,6 +13,8 @@ export const PresentationSchema = z.object({
12
13
  languageId: z.string(),
13
14
  templateId: z.string(),
14
15
  downloadUrl: z.string().nullable(),
16
+ reaction: z.nativeEnum(USER_REACTION).nullable(),
17
+ dislikeReason: z.string().nullable(),
15
18
  userId: z.string().uuid().nullable().optional(),
16
19
  unregisteredUserId: z.string().uuid().nullable().optional(),
17
20
  slideCount: z.number(),
@@ -13,6 +13,7 @@ import {
13
13
  IBarChartSlideDataStructure,
14
14
  IChartSlideDataStructure,
15
15
  ImageSlotSchema,
16
+ ITimelineSlideDataStructure,
16
17
  } from './slide-content.schema';
17
18
 
18
19
  export const CoverSlideDataUserEditSchema = z.object({
@@ -146,6 +147,25 @@ export const ChartSlideDataUserEditSchema = z.object({
146
147
  version: z.literal(1),
147
148
  }) satisfies z.ZodType<IChartSlideDataStructure>;
148
149
 
150
+ export const TimelineSlideDataUserEditSchema = z.object({
151
+ contentType: z.literal(SLIDE_CONTENT_TYPE.TIMELINE),
152
+ title: z.string().min(1).max(500),
153
+ description: z.string().min(1).max(1000),
154
+ timeline: z.object({
155
+ events: z
156
+ .array(
157
+ z.object({
158
+ date: z.string().min(1).max(100),
159
+ title: z.string().min(1).max(200),
160
+ description: z.string().min(1).max(500),
161
+ }),
162
+ )
163
+ .min(2)
164
+ .max(10),
165
+ }),
166
+ version: z.literal(1),
167
+ }) satisfies z.ZodType<ITimelineSlideDataStructure>;
168
+
149
169
  export const SlideContentUserEditSchema = z.discriminatedUnion('contentType', [
150
170
  CoverSlideDataUserEditSchema,
151
171
  StructuredListSlideDataUserEditSchema,
@@ -156,5 +176,6 @@ export const SlideContentUserEditSchema = z.discriminatedUnion('contentType', [
156
176
  ThankYouSlideDataUserEditSchema,
157
177
  TableSlideDataUserEditSchema,
158
178
  ChartSlideDataUserEditSchema,
179
+ TimelineSlideDataUserEditSchema,
159
180
  ]);
160
181
  export type SlideContentUserEdit = z.infer<typeof SlideContentUserEditSchema>;
@@ -108,6 +108,20 @@ export interface IChartSlideDataStructure {
108
108
  version: 1;
109
109
  }
110
110
 
111
+ export interface ITimelineSlideDataStructure {
112
+ contentType: SLIDE_CONTENT_TYPE.TIMELINE;
113
+ title: string;
114
+ description: string;
115
+ timeline: {
116
+ events: Array<{
117
+ date: string;
118
+ title: string;
119
+ description: string;
120
+ }>;
121
+ };
122
+ version: 1;
123
+ }
124
+
111
125
  export const CoverSlideDataSchema = z.object({
112
126
  contentType: z.literal(SLIDE_CONTENT_TYPE.COVER),
113
127
  title: z.string().describe('Slide title in about 6 words').min(10).max(150),
@@ -313,6 +327,42 @@ export const ChartSlideDataSchema = z.object({
313
327
  }) satisfies z.ZodType<IChartSlideDataStructure>;
314
328
  export type ChartSlideData = z.infer<typeof ChartSlideDataSchema>;
315
329
 
330
+ export const TimelineSlideDataSchema = z.object({
331
+ contentType: z.literal(SLIDE_CONTENT_TYPE.TIMELINE),
332
+ title: z.string().describe('Slide title in about 6 words').min(10).max(150),
333
+ description: z.string().describe('Brief context for the timeline').min(10).max(200),
334
+ timeline: z.object({
335
+ events: z
336
+ .array(
337
+ z.object({
338
+ date: z
339
+ .string()
340
+ .describe(
341
+ 'Date or time period label. MUST be general/approximate if exact date unknown (e.g., "Early 2020s", "Mid-1990s", "Recent years")',
342
+ )
343
+ .min(2)
344
+ .max(50),
345
+ title: z
346
+ .string()
347
+ .describe(
348
+ 'Event title. Prefer 2 words, max 3 words. Keep it short and punchy.',
349
+ )
350
+ .min(5)
351
+ .max(60),
352
+ description: z
353
+ .string()
354
+ .describe('Brief description of the event or milestone')
355
+ .min(20)
356
+ .max(150),
357
+ }),
358
+ )
359
+ .length(4)
360
+ .describe('Timeline must contain exactly 4 chronological events'),
361
+ }),
362
+ version: z.literal(1),
363
+ }) satisfies z.ZodType<ITimelineSlideDataStructure>;
364
+ export type TimelineSlideData = z.infer<typeof TimelineSlideDataSchema>;
365
+
316
366
  export const SlideContentSchema = z.discriminatedUnion('contentType', [
317
367
  CoverSlideDataSchema,
318
368
  StructuredListSlideDataSchema,
@@ -323,5 +373,6 @@ export const SlideContentSchema = z.discriminatedUnion('contentType', [
323
373
  ThankYouSlideDataSchema,
324
374
  TableSlideDataSchema,
325
375
  ChartSlideDataSchema,
376
+ TimelineSlideDataSchema,
326
377
  ]);
327
378
  export type SlideContent = z.infer<typeof SlideContentSchema>;
@@ -18,6 +18,7 @@ export const PRESENTATION_AMQP_ROUTES = {
18
18
  UPDATE_SLIDE: 'tools.presentation.update-slide.rpc',
19
19
  PARAPHRASE: 'tools.presentation.actions.paraphrase.rpc',
20
20
  GENERATE_REPORT: 'tools.presentation.actions.generate-report.rpc',
21
+ SET_REACTION: 'tools.presentation.set-reaction.rpc',
21
22
  } as const;
22
23
 
23
24
  export const PRESENTATION_SLIDE_OUTLINE_AMQP_ROUTES = {
@@ -4,12 +4,25 @@ import { USER_REACTION } from '../../common';
4
4
  import { STTJobSchema } from '../models';
5
5
 
6
6
  export namespace SetReactionToSTTJobCommand {
7
- export const RequestSchema = z.object({
8
- userId: z.string().uuid().nullable().optional(),
9
- unregisteredUserId: z.string().uuid().nullable().optional(),
10
- uuid: z.string(),
11
- reaction: z.nativeEnum(USER_REACTION).nullable(),
12
- });
7
+ export const RequestSchema = z
8
+ .object({
9
+ userId: z.string().uuid().nullable().optional(),
10
+ unregisteredUserId: z.string().uuid().nullable().optional(),
11
+ uuid: z.string().uuid(),
12
+ reaction: z.nativeEnum(USER_REACTION).nullable(),
13
+ dislikeReason: z.string().nullable().default(null),
14
+ })
15
+ .refine(
16
+ (data) => {
17
+ if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
18
+ return false;
19
+ }
20
+ return true;
21
+ },
22
+ {
23
+ message: 'Dislike reason is not allowed when reaction is not disliked',
24
+ },
25
+ );
13
26
  export type Request = z.infer<typeof RequestSchema>;
14
27
 
15
28
  export const ResponseSchema = ICommandResponseSchema(STTJobSchema);
@@ -12,7 +12,9 @@ export const STTJobSchema = z.object({
12
12
  fileUrl: z.string(),
13
13
  aiResponse: STTResponseSchema.nullable(),
14
14
  reaction: z.nativeEnum(USER_REACTION).nullable(),
15
+ dislikeReason: z.string().nullable(),
15
16
  status: z.nativeEnum(JOB_STATUS),
17
+ duration: z.number(),
16
18
  error: z.string().nullable(),
17
19
  userId: z.string().nullable(),
18
20
  unregisteredUserId: z.string().nullable(),
@@ -1,5 +1,6 @@
1
1
  export enum TOOL_CONTENT_TYPE {
2
2
  IMAGE_EDITOR = 'IMAGE_EDITOR',
3
+ IMAGE_GENERATION = 'IMAGE_GENERATION',
3
4
  TEXT_TO_SPEECH = 'TEXT_TO_SPEECH',
4
5
  SPEECH_TO_TEXT = 'SPEECH_TO_TEXT',
5
6
  REPHRASE = 'REPHRASE',
@@ -11,4 +11,5 @@ export enum TOOL_TYPE {
11
11
  VIDEO_EDITOR = 'VIDEO_EDITOR',
12
12
  MUSIC = 'MUSIC',
13
13
  MUSIC_ACTION = 'MUSIC_ACTION',
14
+ IMAGE_GENERATION = 'IMAGE_GENERATION',
14
15
  }
@@ -4,6 +4,7 @@ import { VideoConfigSchema } from '../../video';
4
4
  import { MusicConfigSchema } from '../../music';
5
5
  import { WriterConfigSchema } from '../../writer';
6
6
  import { ImageEditorConfigSchema } from '../../image-editor';
7
+ import { ImageGenerationConfigSchema } from '../../image-generation';
7
8
  import { ParaphraseToolConfigSchema } from '../../paraphrase';
8
9
  import { PresentationConfigSchema } from '../../presentation';
9
10
  import { VideoEditorConfigSchema } from '../../video-editor';
@@ -15,6 +16,7 @@ export const GlobalToolsConfigSchema = z.object({
15
16
  [TOOL_CONTENT_TYPE.MUSIC]: MusicConfigSchema,
16
17
  [TOOL_CONTENT_TYPE.WRITER]: WriterConfigSchema,
17
18
  [TOOL_CONTENT_TYPE.IMAGE_EDITOR]: ImageEditorConfigSchema,
19
+ [TOOL_CONTENT_TYPE.IMAGE_GENERATION]: ImageGenerationConfigSchema,
18
20
  [TOOL_CONTENT_TYPE.REPHRASE]: ParaphraseToolConfigSchema,
19
21
  [TOOL_CONTENT_TYPE.PRESENTATION]: PresentationConfigSchema,
20
22
  [TOOL_CONTENT_TYPE.VIDEO_EDITOR]: VideoEditorConfigSchema,
@@ -6,6 +6,9 @@ export const ToolSchema = z.object({
6
6
  title: z.string(),
7
7
  description: z.string(),
8
8
  icon: z.string(),
9
+ alias: z.string(),
10
+ bgColor: z.string(),
11
+ iconColor: z.string(),
9
12
  order: z.number(),
10
13
  contentType: z.nativeEnum(TOOL_CONTENT_TYPE),
11
14
  createdAt: z.date(),
@@ -4,6 +4,7 @@ import { VideoConfigSchema } from '../../video';
4
4
  import { MusicConfigSchema } from '../../music';
5
5
  import { WriterConfigSchema } from '../../writer';
6
6
  import { ImageEditorConfigSchema } from '../../image-editor';
7
+ import { ImageGenerationConfigSchema } from '../../image-generation';
7
8
  import { ParaphraseToolConfigSchema } from '../../paraphrase';
8
9
  import { PresentationConfigSchema } from '../../presentation';
9
10
  import { VideoEditorConfigSchema } from '../../video-editor';
@@ -37,6 +38,12 @@ export const ToolWithConfigSchema = z.discriminatedUnion('contentType', [
37
38
  config: ImageEditorConfigSchema,
38
39
  }),
39
40
  ),
41
+ ToolSchema.merge(
42
+ z.object({
43
+ contentType: z.literal(TOOL_CONTENT_TYPE.IMAGE_GENERATION),
44
+ config: ImageGenerationConfigSchema,
45
+ }),
46
+ ),
40
47
  ToolSchema.merge(
41
48
  z.object({
42
49
  contentType: z.literal(TOOL_CONTENT_TYPE.REPHRASE),
@@ -4,12 +4,25 @@ import { TTSJobSchema } from '../models/tts-job.schema';
4
4
  import { USER_REACTION } from '../../common';
5
5
 
6
6
  export namespace SetReactionToTTSJobCommand {
7
- export const RequestSchema = z.object({
8
- userId: z.string().uuid().nullable().optional(),
9
- unregisteredUserId: z.string().uuid().nullable().optional(),
10
- uuid: z.string(),
11
- reaction: z.nativeEnum(USER_REACTION).nullable(),
12
- });
7
+ export const RequestSchema = z
8
+ .object({
9
+ userId: z.string().uuid().nullable().optional(),
10
+ unregisteredUserId: z.string().uuid().nullable().optional(),
11
+ uuid: z.string().uuid(),
12
+ reaction: z.nativeEnum(USER_REACTION).nullable(),
13
+ dislikeReason: z.string().nullable().default(null),
14
+ })
15
+ .refine(
16
+ (data) => {
17
+ if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
18
+ return false;
19
+ }
20
+ return true;
21
+ },
22
+ {
23
+ message: 'Dislike reason is not allowed when reaction is not disliked',
24
+ },
25
+ );
13
26
  export type Request = z.infer<typeof RequestSchema>;
14
27
 
15
28
  export const ResponseSchema = ICommandResponseSchema(TTSJobSchema);
@@ -15,12 +15,14 @@ export const TTSJobSchema = z.object({
15
15
  userInput: z.string(),
16
16
  aiResponse: z.string().nullable(),
17
17
  reaction: z.nativeEnum(USER_REACTION).nullable(),
18
+ dislikeReason: z.string().nullable(),
18
19
  title: z.string(),
19
20
  status: z.nativeEnum(JOB_STATUS),
20
21
  error: z.string().nullable(),
21
22
  modelId: z.string(),
22
23
  voiceId: z.string(),
23
24
  price: z.number(),
25
+ duration: z.number(),
24
26
  userId: z.string().nullable(),
25
27
  unregisteredUserId: z.string().nullable(),
26
28
  isDeleted: z.boolean(),
@@ -4,3 +4,4 @@ export * from './retry-video-job.command';
4
4
  export * from './set-reaction-to-video-job.command';
5
5
  export * from './video.command';
6
6
  export * from './update-video-job-title.command';
7
+ export * from './video-model';
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { ICommandResponseSchema } from '../../common/models/command-response.schema';
3
3
  import { VideoJobSchema } from '../models/video-job.schema';
4
+ import { VideoGenerationRequestParamsSchema } from '../models';
4
5
 
5
6
  export namespace RetryVideoJobCommand {
6
7
  export const RequestSchema = z.object({
@@ -8,6 +9,9 @@ export namespace RetryVideoJobCommand {
8
9
  userBalance: z.number(),
9
10
  userId: z.string().uuid().nullable().optional(),
10
11
  unregisteredUserId: z.string().uuid().nullable().optional(),
12
+ prompt: z.string().optional(),
13
+ modelId: z.string().uuid().optional(),
14
+ params: VideoGenerationRequestParamsSchema.optional(),
11
15
  });
12
16
  export type Request = z.infer<typeof RequestSchema>;
13
17
 
@@ -4,12 +4,25 @@ import { VideoJobSchema } from '../models/video-job.schema';
4
4
  import { USER_REACTION } from '../../common';
5
5
 
6
6
  export namespace SetReactionToVideoJobCommand {
7
- export const RequestSchema = z.object({
8
- userId: z.string().uuid().nullable().optional(),
9
- unregisteredUserId: z.string().uuid().nullable().optional(),
10
- uuid: z.string(),
11
- reaction: z.nativeEnum(USER_REACTION).nullable(),
12
- });
7
+ export const RequestSchema = z
8
+ .object({
9
+ userId: z.string().uuid().nullable().optional(),
10
+ unregisteredUserId: z.string().uuid().nullable().optional(),
11
+ uuid: z.string().uuid(),
12
+ reaction: z.nativeEnum(USER_REACTION).nullable(),
13
+ dislikeReason: z.string().nullable().default(null),
14
+ })
15
+ .refine(
16
+ (data) => {
17
+ if (data.reaction !== USER_REACTION.DISLIKED && data.dislikeReason) {
18
+ return false;
19
+ }
20
+ return true;
21
+ },
22
+ {
23
+ message: 'Dislike reason is not allowed when reaction is not disliked',
24
+ },
25
+ );
13
26
  export type Request = z.infer<typeof RequestSchema>;
14
27
 
15
28
  export const ResponseSchema = ICommandResponseSchema(VideoJobSchema);
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ import { VideoModelSchema } from '../../models';
3
+ import { ICommandResponseSchema } from '../../../common';
4
+
5
+ export namespace GetVideoModelByUuidCommand {
6
+ export const RequestSchema = z.object({
7
+ uuid: z.string().uuid(),
8
+ });
9
+ export type Request = z.infer<typeof RequestSchema>;
10
+
11
+ export const ResponseSchema = ICommandResponseSchema(VideoModelSchema);
12
+ export type Response = z.infer<typeof ResponseSchema>;
13
+ }
@@ -0,0 +1 @@
1
+ export * from './get-video-model-by-uuid.command';
@@ -1,3 +1,4 @@
1
1
  export enum VIDEO_PRICING_RULE_TYPE {
2
2
  FLAT = 'flat',
3
+ PER_SECOND = 'per_second',
3
4
  }
@@ -5,4 +5,5 @@ export enum VIDEO_GENERATION_STRATEGY {
5
5
  RUNWAY_CALLBACK = 'RUNWAY_CALLBACK',
6
6
  SORA_2_VIDEO_GENERATION_POLLING = 'SORA_2_VIDEO_GENERATION_POLLING',
7
7
  SORA_2_VIDEO_GENERATION_CALLBACK = 'SORA_2_VIDEO_GENERATION_CALLBACK',
8
+ SEEDANCE_VIDEO_GENERATION_CALLBACK = 'SEEDANCE_VIDEO_GENERATION_CALLBACK',
8
9
  }
@@ -4,8 +4,10 @@ import { USER_REACTION } from '../../common';
4
4
 
5
5
  export const VideoJobParamsSchema = z.object({
6
6
  imageUrls: z.string().array().optional(),
7
+ imageIds: z.array(z.string()).optional(),
7
8
  duration: z.number().optional(),
8
9
  aspectRatio: z.string().optional(),
10
+ resolution: z.string().optional(),
9
11
  });
10
12
 
11
13
  export type VideoJobParams = z.infer<typeof VideoJobParamsSchema>;
@@ -14,6 +16,7 @@ export const VideoJobSchema = z.object({
14
16
  uuid: z.string(),
15
17
  prompt: z.string(),
16
18
  reaction: z.nativeEnum(USER_REACTION).nullable(),
19
+ dislikeReason: z.string().nullable(),
17
20
  externalId: z.string().nullable(),
18
21
  title: z.string(),
19
22
  status: z.nativeEnum(JOB_STATUS),
@@ -20,20 +20,28 @@ export const VideoModelParamsSchema = z.object({
20
20
  })
21
21
  .optional(),
22
22
  quality: z.string().optional(),
23
+ resolution: z
24
+ .object({
25
+ options: z.array(z.string()),
26
+ })
27
+ .optional(),
23
28
  });
24
29
 
25
30
  export type VideoModelParams = z.infer<typeof VideoModelParamsSchema>;
26
31
 
27
32
  export const VideoGenerationRequestParamsSchema = z.object({
28
33
  imageUrls: z.string().array().optional(),
34
+ imageIds: z.array(z.string()).optional(),
29
35
  duration: z.number(),
30
36
  aspectRatio: z.string().optional(),
31
37
  quality: z.string().optional(),
38
+ resolution: z.string().optional(),
32
39
  });
33
40
  export type VideoGenerationRequestParams = z.infer<typeof VideoGenerationRequestParamsSchema>;
34
41
 
35
42
  export const VideoModelPricingRuleConditionSchema = z.object({
36
- aspectRatio: z.string(),
43
+ aspectRatio: z.string().optional(),
44
+ resolution: z.string().optional(),
37
45
  });
38
46
  export type VideoModelPricingRuleCondition = z.infer<typeof VideoModelPricingRuleConditionSchema>;
39
47
 
@@ -1,2 +1,3 @@
1
1
  export * from './video.amqp.routes';
2
2
  export * from './video.http.routes';
3
+ export * from './video-model.amqp.routes';
@@ -0,0 +1,3 @@
1
+ export const VIDEO_MODEL_AMQP_ROUTES = {
2
+ GET_MODEL_BY_UUID: 'tools.video.model.get-by-uuid.rpc',
3
+ } as const;
@@ -4,4 +4,5 @@ export const VIDEO_GENERATION_ROUTES = {
4
4
  KIE_VEO_CALLBACK: 'kie/veo/callback',
5
5
  KIE_RUNWAY_CALLBACK: 'kie/runway/callback',
6
6
  KIE_SORA_2_CALLBACK: 'kie/sora-2/callback',
7
+ KIE_SEEDANCE_CALLBACK: 'kie/seedance/callback',
7
8
  };
@@ -36,7 +36,13 @@ export function calculateVideoGenerationPrice({
36
36
  params: VideoGenerationRequestParams;
37
37
  rules: VideoModelPricingRules;
38
38
  }) {
39
- const base = pricePerSecond * params.duration;
39
+ const perSecondRule = rules
40
+ .filter((r) => r.type === VIDEO_PRICING_RULE_TYPE.PER_SECOND)
41
+ .find((r) => matchesCondition(r.condition, params));
42
+
43
+ const effectivePricePerSecond = perSecondRule ? perSecondRule.value : pricePerSecond;
44
+
45
+ const base = effectivePricePerSecond * params.duration;
40
46
 
41
47
  const flatMarkup = rules.reduce((sum, r) => {
42
48
  if (r.type !== VIDEO_PRICING_RULE_TYPE.FLAT) {
@@ -7,10 +7,11 @@ export namespace EditVideoCommand {
7
7
  userId: z.string().uuid().nullable().optional(),
8
8
  unregisteredUserId: z.string().uuid().nullable().optional(),
9
9
  prompt: z.string(),
10
+ inputVideoId: z.string().uuid(),
10
11
  inputVideoUrl: z.string(),
11
12
  duration: z.number(),
12
13
  userBalance: z.number(),
13
- modelId: z.string(),
14
+ modelId: z.string().uuid(),
14
15
  });
15
16
  export type Request = z.infer<typeof RequestSchema>;
16
17
 
@@ -4,3 +4,4 @@ export * from './retry-video-editor-job.command';
4
4
  export * from './set-reaction-to-video-editor-job.command';
5
5
  export * from './update-video-editor-job-title.command';
6
6
  export * from './edit-video.command';
7
+ export * from './video-editor-model';
@@ -8,6 +8,11 @@ export namespace RetryVideoEditorJobCommand {
8
8
  userBalance: z.number(),
9
9
  userId: z.string().uuid().nullable().optional(),
10
10
  unregisteredUserId: z.string().uuid().nullable().optional(),
11
+ prompt: z.string().optional(),
12
+ inputVideoId: z.string().uuid().optional(),
13
+ inputVideoUrl: z.string().optional(),
14
+ duration: z.number().optional(),
15
+ modelId: z.string().uuid().optional(),
11
16
  });
12
17
  export type Request = z.infer<typeof RequestSchema>;
13
18