@purpleschool/gptbot 0.14.27 → 0.14.28

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 (67) hide show
  1. package/api/controllers/http/avatar-studio.ts +23 -12
  2. package/api/routes.ts +68 -19
  3. package/build/api/controllers/http/avatar-studio.js +22 -12
  4. package/build/api/routes.js +41 -10
  5. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-frame.command.js +2 -1
  6. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-image.command.js +23 -0
  7. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-scene-voice.command.js +4 -1
  8. package/build/commands/avatar-studio/generation-job/index.js +1 -3
  9. package/build/commands/avatar-studio/media/create-avatar-studio-media-from-file.command.js +6 -9
  10. package/build/commands/avatar-studio/media/find-avatar-studio-media.query.js +7 -5
  11. package/build/commands/avatar-studio/media/update-avatar-studio-media.command.js +1 -4
  12. package/build/commands/avatar-studio/scene/apply-avatar-studio-voice-sample-to-all-scenes.command.js +15 -0
  13. package/build/commands/avatar-studio/scene/index.js +2 -0
  14. package/build/commands/avatar-studio/scene/set-avatar-studio-scene-slot.command.js +21 -0
  15. package/build/commands/avatar-studio/scriptwriter/calculate-avatar-studio-scriptwriter-price.command.js +13 -6
  16. package/build/commands/avatar-studio/scriptwriter/create-avatar-studio-scriptwriter-message.command.js +23 -1
  17. package/build/commands/avatar-studio/shared/avatar-studio-common.schema.js +2 -1
  18. package/build/commands/avatar-studio/shared/get-avatar-studio-config.query.js +28 -18
  19. package/build/commands/avatar-studio/voice/design-avatar-studio-voice.command.js +5 -7
  20. package/build/commands/avatar-studio/voice/index.js +0 -3
  21. package/build/constants/avatar-studio/enums/avatar-studio-job-type.enum.js +0 -3
  22. package/build/constants/avatar-studio/enums/avatar-studio-slot.enum.js +10 -7
  23. package/build/constants/avatar-studio/enums/avatar-studio-unavailable-reason.enum.js +16 -0
  24. package/build/constants/avatar-studio/enums/index.js +1 -5
  25. package/build/models/avatar-studio/avatar-studio.schema.js +60 -68
  26. package/commands/avatar-studio/generation-job/generate-avatar-studio-frame.command.ts +2 -1
  27. package/commands/avatar-studio/generation-job/{generate-avatar-studio-media-image.command.ts → generate-avatar-studio-image.command.ts} +5 -1
  28. package/commands/avatar-studio/generation-job/generate-avatar-studio-scene-voice.command.ts +4 -1
  29. package/commands/avatar-studio/generation-job/index.ts +1 -3
  30. package/commands/avatar-studio/media/create-avatar-studio-media-from-file.command.ts +7 -16
  31. package/commands/avatar-studio/media/find-avatar-studio-media.query.ts +9 -7
  32. package/commands/avatar-studio/media/update-avatar-studio-media.command.ts +1 -4
  33. package/commands/avatar-studio/scene/apply-avatar-studio-voice-sample-to-all-scenes.command.ts +20 -0
  34. package/commands/avatar-studio/scene/index.ts +2 -0
  35. package/commands/avatar-studio/{generation-job/generate-avatar-studio-voice-timings.command.ts → scene/set-avatar-studio-scene-slot.command.ts} +8 -5
  36. package/commands/avatar-studio/scriptwriter/calculate-avatar-studio-scriptwriter-price.command.ts +14 -7
  37. package/commands/avatar-studio/scriptwriter/create-avatar-studio-scriptwriter-message.command.ts +26 -1
  38. package/commands/avatar-studio/shared/avatar-studio-common.schema.ts +2 -1
  39. package/commands/avatar-studio/shared/get-avatar-studio-config.query.ts +31 -19
  40. package/commands/avatar-studio/voice/design-avatar-studio-voice.command.ts +6 -14
  41. package/commands/avatar-studio/voice/index.ts +0 -3
  42. package/constants/avatar-studio/enums/avatar-studio-job-type.enum.ts +0 -3
  43. package/constants/avatar-studio/enums/avatar-studio-slot.enum.ts +10 -7
  44. package/constants/avatar-studio/enums/avatar-studio-unavailable-reason.enum.ts +12 -0
  45. package/constants/avatar-studio/enums/index.ts +1 -5
  46. package/models/avatar-studio/avatar-studio.schema.ts +59 -75
  47. package/package.json +1 -1
  48. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-library-image.command.js +0 -20
  49. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-media-image.command.js +0 -19
  50. package/build/commands/avatar-studio/generation-job/generate-avatar-studio-voice-timings.command.js +0 -18
  51. package/build/commands/avatar-studio/voice/find-avatar-studio-clip-voices.query.js +0 -14
  52. package/build/commands/avatar-studio/voice/find-avatar-studio-voices.query.js +0 -19
  53. package/build/commands/avatar-studio/voice/update-avatar-studio-clip-voice.command.js +0 -19
  54. package/build/constants/avatar-studio/enums/avatar-studio-job-phase.enum.js +0 -12
  55. package/build/constants/avatar-studio/enums/avatar-studio-media-role.enum.js +0 -14
  56. package/build/constants/avatar-studio/enums/avatar-studio-media-source.enum.js +0 -13
  57. package/build/constants/avatar-studio/enums/avatar-studio-scene-kind.enum.js +0 -7
  58. package/build/constants/avatar-studio/enums/avatar-studio-voice-source.enum.js +0 -10
  59. package/commands/avatar-studio/generation-job/generate-avatar-studio-library-image.command.ts +0 -25
  60. package/commands/avatar-studio/voice/find-avatar-studio-clip-voices.query.ts +0 -21
  61. package/commands/avatar-studio/voice/find-avatar-studio-voices.query.ts +0 -24
  62. package/commands/avatar-studio/voice/update-avatar-studio-clip-voice.command.ts +0 -21
  63. package/constants/avatar-studio/enums/avatar-studio-job-phase.enum.ts +0 -8
  64. package/constants/avatar-studio/enums/avatar-studio-media-role.enum.ts +0 -10
  65. package/constants/avatar-studio/enums/avatar-studio-media-source.enum.ts +0 -9
  66. package/constants/avatar-studio/enums/avatar-studio-scene-kind.enum.ts +0 -3
  67. package/constants/avatar-studio/enums/avatar-studio-voice-source.enum.ts +0 -6
@@ -11,12 +11,29 @@ const AvatarStudioGenerationPriceSchema = zod_1.z
11
11
  pricePerSymbol: zod_1.z.number().nonnegative().optional(),
12
12
  })
13
13
  .strict();
14
+ /**
15
+ * Картинки генерирует одна модель, с референсами и без. Наценка за референсы плоская:
16
+ * её берёт сам инструмент за факт вложения, количество картинок значения не имеет.
17
+ */
18
+ const AvatarStudioImagePricingSchema = zod_1.z
19
+ .object({
20
+ base: AvatarStudioGenerationPriceSchema.nullable(),
21
+ referenceSurcharge: zod_1.z.number().nonnegative(),
22
+ })
23
+ .strict();
14
24
  const AvatarStudioConfigSectionBaseSchema = zod_1.z
15
25
  .object({
16
26
  available: zod_1.z.boolean(),
17
- unavailableReason: zod_1.z.string().optional(),
27
+ /** Присутствует только когда available = false. */
28
+ unavailableReason: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_UNAVAILABLE_REASON).optional(),
18
29
  })
19
30
  .strict();
31
+ /**
32
+ * Сценарист доступен не всем: у анрега нет доступа к его модели. Цены здесь нет: она зависит
33
+ * от длины ввода и считается на лету — POST scriptwriter/price. Конфиг отвечает только на
34
+ * вопрос «можно ли пользоваться».
35
+ */
36
+ const AvatarStudioScriptwriterConfigSectionSchema = AvatarStudioConfigSectionBaseSchema;
20
37
  const AvatarStudioTextFieldSchema = zod_1.z
21
38
  .object({
22
39
  kind: zod_1.z.literal('text'),
@@ -36,7 +53,6 @@ const AvatarStudioMediaFieldSchema = zod_1.z
36
53
  kind: zod_1.z.literal('media'),
37
54
  required: zod_1.z.boolean(),
38
55
  mediaKind: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_MEDIA_KIND),
39
- mediaRole: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_MEDIA_ROLE),
40
56
  })
41
57
  .strict();
42
58
  const AvatarStudioMediaArrayFieldSchema = zod_1.z
@@ -44,6 +60,8 @@ const AvatarStudioMediaArrayFieldSchema = zod_1.z
44
60
  kind: zod_1.z.literal('media-array'),
45
61
  required: zod_1.z.boolean(),
46
62
  supported: zod_1.z.boolean(),
63
+ /** Предел задаёт модель (maxAttachedImages), поэтому он приезжает сюда, а не зашит в контракт. */
64
+ maxCount: zod_1.z.number().int().nonnegative(),
47
65
  })
48
66
  .strict();
49
67
  const AvatarStudioFixedFieldSchema = (valueSchema) => zod_1.z
@@ -73,10 +91,11 @@ const AvatarStudioAudioConfigSectionSchema = AvatarStudioConfigSectionBaseSchema
73
91
  text: AvatarStudioTextFieldSchema.extend({
74
92
  required: zod_1.z.boolean(),
75
93
  }),
76
- mediaId: AvatarStudioMediaFieldSchema.extend({
94
+ // Образец голоса — вход генерации наравне с текстом, поэтому живёт
95
+ // в voiceConfig и ставится через PATCH .../scenes/:sceneId.
96
+ voiceSampleMediaId: AvatarStudioMediaFieldSchema.extend({
77
97
  required: zod_1.z.boolean(),
78
98
  mediaKind: zod_1.z.literal(constants_1.AVATAR_STUDIO_MEDIA_KIND.AUDIO),
79
- mediaRole: zod_1.z.literal(constants_1.AVATAR_STUDIO_MEDIA_ROLE.VOICE_SAMPLE),
80
99
  }),
81
100
  })
82
101
  .strict(),
@@ -95,7 +114,7 @@ const AvatarStudioFrameConfigSectionSchema = AvatarStudioConfigSectionBaseSchema
95
114
  style: AvatarStudioSelectFieldSchema(zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_IMAGE_STYLE)).extend({
96
115
  required: zod_1.z.boolean(),
97
116
  }),
98
- referenceMediaIds: AvatarStudioMediaArrayFieldSchema.extend({
117
+ references: AvatarStudioMediaArrayFieldSchema.extend({
99
118
  required: zod_1.z.boolean(),
100
119
  }),
101
120
  aspectRatio: AvatarStudioFixedFieldSchema(zod_1.z.literal('9:16')),
@@ -104,12 +123,7 @@ const AvatarStudioFrameConfigSectionSchema = AvatarStudioConfigSectionBaseSchema
104
123
  defaults: models_1.AvatarStudioSceneImageConfigSchema.extend({
105
124
  aspectRatio: zod_1.z.literal('9:16'),
106
125
  }),
107
- pricing: zod_1.z
108
- .object({
109
- withoutReference: AvatarStudioGenerationPriceSchema.nullable(),
110
- withReference: AvatarStudioGenerationPriceSchema.nullable(),
111
- })
112
- .strict(),
126
+ pricing: AvatarStudioImagePricingSchema,
113
127
  });
114
128
  const AvatarStudioVideoConfigSectionSchema = AvatarStudioConfigSectionBaseSchema.extend({
115
129
  fields: zod_1.z
@@ -152,7 +166,7 @@ const AvatarStudioLibraryImageConfigSectionSchema = AvatarStudioConfigSectionBas
152
166
  fields: zod_1.z
153
167
  .object({
154
168
  prompt: AvatarStudioTextFieldSchema.extend({ required: zod_1.z.boolean() }),
155
- referenceMediaIds: AvatarStudioMediaArrayFieldSchema.extend({
169
+ references: AvatarStudioMediaArrayFieldSchema.extend({
156
170
  required: zod_1.z.boolean(),
157
171
  }),
158
172
  aspectRatio: AvatarStudioSelectFieldSchema(models_1.AvatarStudioAspectRatioSchema).extend({
@@ -166,12 +180,7 @@ const AvatarStudioLibraryImageConfigSectionSchema = AvatarStudioConfigSectionBas
166
180
  aspectRatio: models_1.AvatarStudioAspectRatioSchema,
167
181
  })
168
182
  .strict(),
169
- pricing: zod_1.z
170
- .object({
171
- withoutReference: AvatarStudioGenerationPriceSchema.nullable(),
172
- withReference: AvatarStudioGenerationPriceSchema.nullable(),
173
- })
174
- .strict(),
183
+ pricing: AvatarStudioImagePricingSchema,
175
184
  });
176
185
  var GetAvatarStudioConfigQuery;
177
186
  (function (GetAvatarStudioConfigQuery) {
@@ -182,6 +191,7 @@ var GetAvatarStudioConfigQuery;
182
191
  frame: AvatarStudioFrameConfigSectionSchema,
183
192
  video: AvatarStudioVideoConfigSectionSchema,
184
193
  libraryImage: AvatarStudioLibraryImageConfigSectionSchema,
194
+ scriptwriter: AvatarStudioScriptwriterConfigSectionSchema,
185
195
  })
186
196
  .strict(),
187
197
  });
@@ -3,10 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DesignAvatarStudioVoiceCommand = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const models_1 = require("../../../models");
6
- const avatar_studio_common_schema_1 = require("../shared/avatar-studio-common.schema");
7
6
  var DesignAvatarStudioVoiceCommand;
8
7
  (function (DesignAvatarStudioVoiceCommand) {
9
- DesignAvatarStudioVoiceCommand.ParamsSchema = avatar_studio_common_schema_1.AvatarStudioClipIdParamsSchema;
10
8
  DesignAvatarStudioVoiceCommand.RequestSchema = zod_1.z
11
9
  .object({
12
10
  title: zod_1.z.string().trim().min(1).optional(),
@@ -14,11 +12,11 @@ var DesignAvatarStudioVoiceCommand;
14
12
  language: zod_1.z.string().trim().min(2).optional(),
15
13
  })
16
14
  .strict();
15
+ /**
16
+ * Отдаём job, как и все остальные генерации: созданный голос лежит в job.resultMedia.
17
+ * Отдельного поля media нет — форма ответа одинакова у всех роутов генерации.
18
+ */
17
19
  DesignAvatarStudioVoiceCommand.ResponseSchema = zod_1.z.object({
18
- data: zod_1.z.object({
19
- job: models_1.AvatarStudioGenerationJobSchema,
20
- voice: models_1.AvatarStudioVoiceSchema,
21
- media: models_1.AvatarStudioMediaSchema,
22
- }),
20
+ data: models_1.AvatarStudioGenerationJobSchema,
23
21
  });
24
22
  })(DesignAvatarStudioVoiceCommand || (exports.DesignAvatarStudioVoiceCommand = DesignAvatarStudioVoiceCommand = {}));
@@ -15,6 +15,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./design-avatar-studio-voice.command"), exports);
18
- __exportStar(require("./find-avatar-studio-clip-voices.query"), exports);
19
- __exportStar(require("./find-avatar-studio-voices.query"), exports);
20
- __exportStar(require("./update-avatar-studio-clip-voice.command"), exports);
@@ -6,11 +6,8 @@ var AVATAR_STUDIO_JOB_TYPE;
6
6
  AVATAR_STUDIO_JOB_TYPE["FRAME_IMAGE"] = "frame_image";
7
7
  AVATAR_STUDIO_JOB_TYPE["LIBRARY_IMAGE"] = "library_image";
8
8
  AVATAR_STUDIO_JOB_TYPE["SCENE_VIDEO"] = "scene_video";
9
- AVATAR_STUDIO_JOB_TYPE["SCENE_VOICE"] = "scene_voice";
10
9
  AVATAR_STUDIO_JOB_TYPE["VOICE_TTS"] = "voice_tts";
11
10
  AVATAR_STUDIO_JOB_TYPE["VOICE_STT"] = "voice_stt";
12
- AVATAR_STUDIO_JOB_TYPE["VOICE_TIMINGS"] = "voice_timings";
13
11
  AVATAR_STUDIO_JOB_TYPE["TALKING_AVATAR"] = "talking_avatar";
14
12
  AVATAR_STUDIO_JOB_TYPE["VOICE_DESIGN"] = "voice_design";
15
- AVATAR_STUDIO_JOB_TYPE["SCRIPTWRITER"] = "scriptwriter";
16
13
  })(AVATAR_STUDIO_JOB_TYPE || (exports.AVATAR_STUDIO_JOB_TYPE = AVATAR_STUDIO_JOB_TYPE = {}));
@@ -1,15 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AVATAR_STUDIO_SLOT = void 0;
4
+ /**
5
+ * Слоты-результаты сцены: в каждом ровно одно медиа за раз.
6
+ *
7
+ * Здесь только то, что действительно является слотом сцены:
8
+ * - аватар и b-roll — два способа получить VIDEO, а не два слота (режим в videoConfig.videoMode);
9
+ * - образец голоса — вход сцены (scene.voiceSampleMediaId), а не её результат;
10
+ * - референсы — несколько упорядоченных медиа, у них своя join-таблица;
11
+ * - «медиатека» слотом никогда не была: у таких job'ов targetSlot = null.
12
+ */
4
13
  var AVATAR_STUDIO_SLOT;
5
14
  (function (AVATAR_STUDIO_SLOT) {
15
+ AVATAR_STUDIO_SLOT["VOICE"] = "voice";
6
16
  AVATAR_STUDIO_SLOT["FRAME"] = "frame";
7
17
  AVATAR_STUDIO_SLOT["VIDEO"] = "video";
8
- AVATAR_STUDIO_SLOT["VOICE"] = "voice";
9
- AVATAR_STUDIO_SLOT["AVATAR"] = "avatar";
10
- AVATAR_STUDIO_SLOT["LIBRARY"] = "library";
11
- AVATAR_STUDIO_SLOT["VOICE_TIMINGS"] = "voice_timings";
12
- AVATAR_STUDIO_SLOT["VOICE_SAMPLE"] = "voice_sample";
13
- AVATAR_STUDIO_SLOT["SCRIPTWRITER"] = "scriptwriter";
14
- AVATAR_STUDIO_SLOT["EXPORT"] = "export";
15
18
  })(AVATAR_STUDIO_SLOT || (exports.AVATAR_STUDIO_SLOT = AVATAR_STUDIO_SLOT = {}));
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AVATAR_STUDIO_UNAVAILABLE_REASON = void 0;
4
+ var AVATAR_STUDIO_UNAVAILABLE_REASON;
5
+ (function (AVATAR_STUDIO_UNAVAILABLE_REASON) {
6
+ /**
7
+ * Функция есть, но этому пользователю не положена: анрег либо нет подходящей подписки.
8
+ * Фронт вправе звать зарегистрироваться или улучшить тариф.
9
+ */
10
+ AVATAR_STUDIO_UNAVAILABLE_REASON["NO_ACCESS"] = "no_access";
11
+ /**
12
+ * Модель выключена, не найдена или проверка доступа не удалась. Пользователь ни при чём,
13
+ * звать его никуда не нужно — это наша проблема.
14
+ */
15
+ AVATAR_STUDIO_UNAVAILABLE_REASON["MODEL_UNAVAILABLE"] = "model_unavailable";
16
+ })(AVATAR_STUDIO_UNAVAILABLE_REASON || (exports.AVATAR_STUDIO_UNAVAILABLE_REASON = AVATAR_STUDIO_UNAVAILABLE_REASON = {}));
@@ -16,17 +16,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./avatar-studio-export-status.enum"), exports);
18
18
  __exportStar(require("./avatar-studio-image-style.enum"), exports);
19
- __exportStar(require("./avatar-studio-job-phase.enum"), exports);
20
19
  __exportStar(require("./avatar-studio-job-status.enum"), exports);
21
20
  __exportStar(require("./avatar-studio-job-type.enum"), exports);
22
21
  __exportStar(require("./avatar-studio-media-kind.enum"), exports);
23
- __exportStar(require("./avatar-studio-media-role.enum"), exports);
24
- __exportStar(require("./avatar-studio-media-source.enum"), exports);
25
- __exportStar(require("./avatar-studio-scene-kind.enum"), exports);
26
22
  __exportStar(require("./avatar-studio-scriptwriter-role.enum"), exports);
27
23
  __exportStar(require("./avatar-studio-slot.enum"), exports);
28
24
  __exportStar(require("./avatar-studio-subtitle-font.enum"), exports);
25
+ __exportStar(require("./avatar-studio-unavailable-reason.enum"), exports);
29
26
  __exportStar(require("./avatar-studio-subtitle-mode.enum"), exports);
30
27
  __exportStar(require("./avatar-studio-video-mode.enum"), exports);
31
28
  __exportStar(require("./avatar-studio-video-quality.enum"), exports);
32
- __exportStar(require("./avatar-studio-voice-source.enum"), exports);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AvatarStudioClipSchema = exports.AvatarStudioScriptwriterMessageSchema = exports.AvatarStudioExportJobSchema = exports.AvatarStudioGenerationJobSchema = exports.AvatarStudioGenerationJobBaseSchema = exports.AvatarStudioVoiceSchema = exports.AvatarStudioSceneSchema = exports.AvatarStudioSceneGenerationJobSchema = exports.AvatarStudioSceneVideoConfigSchema = exports.AvatarStudioSceneVideoConfigBaseSchema = exports.AvatarStudioSceneImageConfigSchema = exports.AvatarStudioSceneVoiceConfigSchema = exports.AvatarStudioSceneVoiceConfigBaseSchema = exports.validateAvatarStudioTrim = exports.AvatarStudioTrimConfigFields = exports.AvatarStudioSceneReferenceMediaSchema = exports.AvatarStudioMediaSchema = exports.AvatarStudioWordTimingSchema = exports.AvatarStudioSubtitleSettingsSchema = exports.AvatarStudioAspectRatioSchema = void 0;
3
+ exports.AvatarStudioClipSchema = exports.AvatarStudioScriptwriterMessageSchema = exports.AvatarStudioExportJobSchema = exports.AvatarStudioGenerationJobSchema = exports.AvatarStudioGenerationJobBaseSchema = exports.AvatarStudioSceneSchema = exports.AvatarStudioSceneGenerationJobSchema = exports.AvatarStudioSceneVideoConfigSchema = exports.AvatarStudioSceneVideoConfigBaseSchema = exports.AvatarStudioSceneImageConfigSchema = exports.AvatarStudioSceneVoiceConfigSchema = exports.AvatarStudioSceneVoiceConfigBaseSchema = exports.validateAvatarStudioTrim = exports.AvatarStudioTrimConfigFields = exports.AvatarStudioMediaSchema = exports.AvatarStudioWordTimingSchema = exports.AvatarStudioSubtitleSettingsSchema = exports.AvatarStudioAspectRatioSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const constants_1 = require("../../constants");
6
6
  const file_schema_1 = require("../file.schema");
@@ -24,30 +24,29 @@ exports.AvatarStudioWordTimingSchema = zod_1.z.object({
24
24
  });
25
25
  exports.AvatarStudioMediaSchema = zod_1.z.object({
26
26
  uuid: zod_1.z.string().uuid(),
27
+ // Медиа принадлежит пользователю, а не клипу. Оба поля NULL — общее системное медиа (пресет).
27
28
  userId: zod_1.z.string().uuid().nullable(),
28
- clipId: zod_1.z.string().uuid().nullable(),
29
- sceneId: zod_1.z.string().uuid().nullable(),
29
+ unregisteredUserId: zod_1.z.string().uuid().nullable(),
30
30
  fileId: zod_1.z.string().uuid(),
31
31
  kind: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_MEDIA_KIND),
32
- source: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_MEDIA_SOURCE),
33
- role: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_MEDIA_ROLE),
34
32
  title: zod_1.z.string().nullable(),
35
- prompt: zod_1.z.string().nullable(),
33
+ // Чем медиа сгенерировали, помнит job: media.toolJobId ⇢ job.request.
36
34
  toolJobId: zod_1.z.string().uuid().nullable(),
37
35
  durationSeconds: zod_1.z.number().nullable(),
36
+ /**
37
+ * Расшифровка аудио: «что сказано» — вход zero-shot TTS, когда медиа используют образцом.
38
+ * NULL — расшифровка ещё идёт или не удалась; таким медиа озвучивать нельзя.
39
+ */
38
40
  transcript: zod_1.z.string().nullable(),
41
+ /** «Когда сказано», по словам: из этого рисуются субтитры. Свойство файла, не сцены. */
42
+ wordTimings: zod_1.z.array(exports.AvatarStudioWordTimingSchema).nullable(),
43
+ /** Готовые артефакты субтитров от провайдера STT. */
44
+ subtitles: json_value_schema_1.JsonValueSchema.nullable(),
45
+ deletedAt: zod_1.z.date().nullable(),
39
46
  file: file_schema_1.FileSchema.optional(),
40
47
  createdAt: zod_1.z.date(),
41
48
  updatedAt: zod_1.z.date(),
42
49
  });
43
- exports.AvatarStudioSceneReferenceMediaSchema = zod_1.z.object({
44
- uuid: zod_1.z.string().uuid(),
45
- sceneId: zod_1.z.string().uuid(),
46
- mediaId: zod_1.z.string().uuid(),
47
- position: zod_1.z.number().int().min(0),
48
- media: exports.AvatarStudioMediaSchema.optional(),
49
- createdAt: zod_1.z.date(),
50
- });
51
50
  exports.AvatarStudioTrimConfigFields = {
52
51
  trimStart: zod_1.z.number().nonnegative().nullable().default(null),
53
52
  trimEnd: zod_1.z.number().nonnegative().nullable().default(null),
@@ -62,19 +61,31 @@ const validateAvatarStudioTrim = ({ trimStart, trimEnd }, ctx) => {
62
61
  }
63
62
  };
64
63
  exports.validateAvatarStudioTrim = validateAvatarStudioTrim;
65
- exports.AvatarStudioSceneVoiceConfigBaseSchema = zod_1.z.object(Object.assign({ text: zod_1.z.string().default(''), mediaId: zod_1.z.string().uuid().nullable().default(null) }, exports.AvatarStudioTrimConfigFields));
64
+ /**
65
+ * Образец голоса — вход генерации наравне с текстом, поэтому лежит здесь, а не колонкой
66
+ * сцены: колонки сцены хранят результаты в слотах, конфиги — то, из чего их делают.
67
+ */
68
+ exports.AvatarStudioSceneVoiceConfigBaseSchema = zod_1.z.object(Object.assign({ text: zod_1.z.string().default(''), voiceSampleMediaId: zod_1.z.string().uuid().nullable().default(null) }, exports.AvatarStudioTrimConfigFields));
66
69
  exports.AvatarStudioSceneVoiceConfigSchema = exports.AvatarStudioSceneVoiceConfigBaseSchema.superRefine(exports.validateAvatarStudioTrim);
70
+ /**
71
+ * Референсы — вход генерации кадра, наравне с prompt и style, поэтому лежат здесь,
72
+ * а не отдельной связью сцены: больше они ни для чего не нужны.
73
+ *
74
+ * Верхнюю границу числа референсов задаёт модель (maxAttachedImages), а не контракт:
75
+ * она разная у разных моделей и приезжает в конфиге.
76
+ */
67
77
  exports.AvatarStudioSceneImageConfigSchema = zod_1.z.object({
68
78
  prompt: zod_1.z.string().nullable().default(null),
69
79
  style: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_IMAGE_STYLE).default(constants_1.AVATAR_STUDIO_IMAGE_STYLE.UGC),
80
+ references: zod_1.z.array(zod_1.z.string().uuid()).default([]),
70
81
  });
71
82
  exports.AvatarStudioSceneVideoConfigBaseSchema = zod_1.z.object(Object.assign({ prompt: zod_1.z.string().nullable().default(null), durationSeconds: zod_1.z.number().positive().default(5), videoMode: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_VIDEO_MODE).default(constants_1.AVATAR_STUDIO_VIDEO_MODE.B_ROLL), quality: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_VIDEO_QUALITY).default(constants_1.AVATAR_STUDIO_VIDEO_QUALITY.P720), sound: zod_1.z.boolean().default(false) }, exports.AvatarStudioTrimConfigFields));
72
83
  exports.AvatarStudioSceneVideoConfigSchema = exports.AvatarStudioSceneVideoConfigBaseSchema.superRefine(exports.validateAvatarStudioTrim);
73
84
  exports.AvatarStudioSceneGenerationJobSchema = zod_1.z.object({
74
85
  jobId: zod_1.z.string().uuid(),
75
86
  type: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_TYPE),
76
- phase: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_PHASE).nullable(),
77
- targetSlot: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_SLOT),
87
+ /** NULL — генерация не целится ни в один слот сцены. */
88
+ targetSlot: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_SLOT).nullable(),
78
89
  status: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
79
90
  resultMediaId: zod_1.z.string().uuid().nullable(),
80
91
  error: zod_1.z.string().nullable(),
@@ -88,62 +99,37 @@ exports.AvatarStudioSceneSchema = zod_1.z.object({
88
99
  voiceConfig: exports.AvatarStudioSceneVoiceConfigSchema,
89
100
  imageConfig: exports.AvatarStudioSceneImageConfigSchema,
90
101
  videoConfig: exports.AvatarStudioSceneVideoConfigSchema,
91
- frameMediaId: zod_1.z.string().uuid().nullable(),
92
- sceneVideoMediaId: zod_1.z.string().uuid().nullable(),
102
+ // Что лежит в слотах сцены прямо сейчас.
93
103
  voiceMediaId: zod_1.z.string().uuid().nullable(),
94
- avatarVideoMediaId: zod_1.z.string().uuid().nullable(),
95
- frameStatus: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
96
- videoStatus: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
97
- voiceStatus: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
98
- avatarStatus: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
99
- frameError: zod_1.z.string().nullable(),
100
- videoError: zod_1.z.string().nullable(),
101
- voiceError: zod_1.z.string().nullable(),
102
- avatarError: zod_1.z.string().nullable(),
103
- wordTimings: zod_1.z.array(exports.AvatarStudioWordTimingSchema).nullable(),
104
- transcript: zod_1.z.string().nullable(),
105
- subtitles: json_value_schema_1.JsonValueSchema.nullable(),
106
- frameMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
107
- sceneVideoMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
104
+ frameMediaId: zod_1.z.string().uuid().nullable(),
105
+ videoMediaId: zod_1.z.string().uuid().nullable(),
108
106
  voiceMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
109
- avatarVideoMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
110
- referenceMedia: zod_1.z.array(exports.AvatarStudioSceneReferenceMediaSchema).optional(),
107
+ frameMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
108
+ videoMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
109
+ /**
110
+ * Ход генерации слотов. Статус слота — это статус свежайшего job'а с нужным targetSlot;
111
+ * сцена его не дублирует, чтобы не хранить одно и то же в двух местах.
112
+ */
111
113
  generationJobs: zod_1.z.array(exports.AvatarStudioSceneGenerationJobSchema).optional(),
112
114
  createdAt: zod_1.z.date(),
113
115
  updatedAt: zod_1.z.date(),
114
116
  });
115
- exports.AvatarStudioVoiceSchema = zod_1.z.object({
116
- uuid: zod_1.z.string().uuid(),
117
- userId: zod_1.z.string().uuid().nullable(),
118
- clipId: zod_1.z.string().uuid().nullable(),
119
- title: zod_1.z.string(),
120
- source: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_VOICE_SOURCE),
121
- presetKey: zod_1.z.string().nullable(),
122
- gender: zod_1.z.enum(['male', 'female']).nullable(),
123
- sortOrder: zod_1.z.number().int().nullable(),
124
- sampleMediaId: zod_1.z.string().uuid().nullable(),
125
- sampleText: zod_1.z.string().nullable(),
126
- metadata: json_value_schema_1.JsonObjectSchema.nullable(),
127
- sampleMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
128
- createdAt: zod_1.z.date(),
129
- updatedAt: zod_1.z.date(),
130
- deletedAt: zod_1.z.date().nullable(),
131
- });
132
117
  exports.AvatarStudioGenerationJobBaseSchema = zod_1.z.object({
133
118
  uuid: zod_1.z.string().uuid(),
134
- userId: zod_1.z.string().uuid(),
119
+ // Владелец ровно один: зарегистрированный пользователь либо анрег.
120
+ userId: zod_1.z.string().uuid().nullable(),
121
+ unregisteredUserId: zod_1.z.string().uuid().nullable(),
135
122
  clipId: zod_1.z.string().uuid().nullable(),
136
123
  sceneId: zod_1.z.string().uuid().nullable(),
137
- parentJobId: zod_1.z.string().uuid().nullable(),
138
124
  toolJobId: zod_1.z.string().uuid().nullable(),
139
125
  type: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_TYPE),
140
- phase: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_PHASE).nullable(),
141
- targetSlot: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_SLOT),
126
+ /** NULL — генерация не целится ни в один слот сцены. */
127
+ targetSlot: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_SLOT).nullable(),
142
128
  status: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_JOB_STATUS),
143
129
  request: json_value_schema_1.JsonObjectSchema.nullable(),
144
130
  resultMediaId: zod_1.z.string().uuid().nullable(),
145
- tokenReservationUuid: zod_1.z.string().uuid().nullable(),
146
- price: zod_1.z.number().nullable(),
131
+ // tokenReservationUuid и price фронту не нужны: это внутренняя бухгалтерия резервирований.
132
+ // Колонки в БД остаются — по ним ведётся аудит списаний.
147
133
  error: zod_1.z.string().nullable(),
148
134
  resultMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
149
135
  startedAt: zod_1.z.date().nullable(),
@@ -151,12 +137,12 @@ exports.AvatarStudioGenerationJobBaseSchema = zod_1.z.object({
151
137
  createdAt: zod_1.z.date(),
152
138
  updatedAt: zod_1.z.date(),
153
139
  });
154
- exports.AvatarStudioGenerationJobSchema = exports.AvatarStudioGenerationJobBaseSchema.extend({
155
- children: zod_1.z.array(exports.AvatarStudioGenerationJobBaseSchema).optional(),
156
- });
140
+ exports.AvatarStudioGenerationJobSchema = exports.AvatarStudioGenerationJobBaseSchema;
157
141
  exports.AvatarStudioExportJobSchema = zod_1.z.object({
158
142
  uuid: zod_1.z.string().uuid(),
159
- userId: zod_1.z.string().uuid(),
143
+ // Владелец ровно один: зарегистрированный пользователь либо анрег.
144
+ userId: zod_1.z.string().uuid().nullable(),
145
+ unregisteredUserId: zod_1.z.string().uuid().nullable(),
160
146
  clipId: zod_1.z.string().uuid(),
161
147
  status: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_EXPORT_STATUS),
162
148
  resultMediaId: zod_1.z.string().uuid().nullable(),
@@ -170,7 +156,9 @@ exports.AvatarStudioExportJobSchema = zod_1.z.object({
170
156
  });
171
157
  exports.AvatarStudioScriptwriterMessageSchema = zod_1.z.object({
172
158
  uuid: zod_1.z.string().uuid(),
173
- userId: zod_1.z.string().uuid(),
159
+ // Владелец ровно один: зарегистрированный пользователь либо анрег.
160
+ userId: zod_1.z.string().uuid().nullable(),
161
+ unregisteredUserId: zod_1.z.string().uuid().nullable(),
174
162
  clipId: zod_1.z.string().uuid(),
175
163
  sceneId: zod_1.z.string().uuid().nullable(),
176
164
  role: zod_1.z.nativeEnum(constants_1.AVATAR_STUDIO_SCRIPTWRITER_ROLE),
@@ -180,16 +168,20 @@ exports.AvatarStudioScriptwriterMessageSchema = zod_1.z.object({
180
168
  });
181
169
  exports.AvatarStudioClipSchema = zod_1.z.object({
182
170
  uuid: zod_1.z.string().uuid(),
183
- userId: zod_1.z.string().uuid(),
171
+ // Владелец ровно один: зарегистрированный пользователь либо анрег.
172
+ userId: zod_1.z.string().uuid().nullable(),
173
+ unregisteredUserId: zod_1.z.string().uuid().nullable(),
184
174
  title: zod_1.z.string(),
185
175
  subtitleSettings: exports.AvatarStudioSubtitleSettingsSchema,
186
- selectedVoiceId: zod_1.z.string().uuid().nullable(),
187
176
  exportMediaId: zod_1.z.string().uuid().nullable(),
188
- selectedVoice: exports.AvatarStudioVoiceSchema.nullable().optional(),
177
+ /**
178
+ * Обложка клипа: кадр первой по порядку сцены, у которой он есть. NULL — кадров нет ни у одной.
179
+ * Считается на лету из уже загруженных сцен, отдельного поля в БД нет.
180
+ */
181
+ previewUrl: zod_1.z.string().nullable(),
189
182
  exportMedia: exports.AvatarStudioMediaSchema.nullable().optional(),
190
183
  scenes: zod_1.z.array(exports.AvatarStudioSceneSchema).optional(),
191
- media: zod_1.z.array(exports.AvatarStudioMediaSchema).optional(),
192
- voices: zod_1.z.array(exports.AvatarStudioVoiceSchema).optional(),
184
+ // Медиатеки у клипа нет: она принадлежит пользователю — GET /media?owner=me.
193
185
  generationJobs: zod_1.z.array(exports.AvatarStudioGenerationJobSchema).optional(),
194
186
  exportJobs: zod_1.z.array(exports.AvatarStudioExportJobSchema).optional(),
195
187
  scriptwriterMessages: zod_1.z.array(exports.AvatarStudioScriptwriterMessageSchema).optional(),
@@ -10,11 +10,12 @@ export namespace GenerateAvatarStudioFrameCommand {
10
10
  export const ParamsSchema = AvatarStudioSceneIdParamsSchema;
11
11
  export type Params = z.infer<typeof ParamsSchema>;
12
12
 
13
+ /** Все три поля — параметры imageConfig сцены: они же в неё и сохраняются. */
13
14
  export const RequestSchema = z
14
15
  .object({
15
16
  prompt: z.string().trim().min(1),
16
17
  style: z.nativeEnum(AVATAR_STUDIO_IMAGE_STYLE).default(AVATAR_STUDIO_IMAGE_STYLE.UGC),
17
- referenceMediaIds: AvatarStudioUuidListSchema.optional(),
18
+ references: AvatarStudioUuidListSchema,
18
19
  })
19
20
  .strict();
20
21
  export type Request = z.infer<typeof RequestSchema>;
@@ -2,7 +2,11 @@ import { z } from 'zod';
2
2
  import { AvatarStudioAspectRatioSchema, AvatarStudioGenerationJobSchema } from '../../../models';
3
3
  import { AvatarStudioUuidListSchema } from '../shared/avatar-studio-common.schema';
4
4
 
5
- export namespace GenerateAvatarStudioMediaImageCommand {
5
+ /**
6
+ * Генерация изображения в медиатеку пользователя. Клипа у неё нет: медиатека
7
+ * принадлежит пользователю, и картинка доступна из любого его клипа.
8
+ */
9
+ export namespace GenerateAvatarStudioImageCommand {
6
10
  export const RequestSchema = z
7
11
  .object({
8
12
  prompt: z.string().trim().min(1),
@@ -6,10 +6,13 @@ export namespace GenerateAvatarStudioSceneVoiceCommand {
6
6
  export const ParamsSchema = AvatarStudioSceneIdParamsSchema;
7
7
  export type Params = z.infer<typeof ParamsSchema>;
8
8
 
9
+ /**
10
+ * Образец голоса не передаётся: он берётся из voiceConfig.voiceSampleMediaId сцены.
11
+ * Сменить образец — обычный PATCH сцены, а не отдельная операция.
12
+ */
9
13
  export const RequestSchema = z
10
14
  .object({
11
15
  text: z.string().trim().min(1).optional(),
12
- mediaId: z.string().uuid().optional(),
13
16
  })
14
17
  .strict();
15
18
  export type Request = z.infer<typeof RequestSchema>;
@@ -1,9 +1,7 @@
1
1
  export * from './find-avatar-studio-generation-jobs.query';
2
2
  export * from './generate-avatar-studio-frame.command';
3
- export * from './generate-avatar-studio-library-image.command';
4
- export * from './generate-avatar-studio-media-image.command';
3
+ export * from './generate-avatar-studio-image.command';
5
4
  export * from './generate-avatar-studio-scene-video.command';
6
5
  export * from './generate-avatar-studio-scene-voice.command';
7
6
  export * from './generate-avatar-studio-talking-avatar.command';
8
- export * from './generate-avatar-studio-voice-timings.command';
9
7
  export * from './get-avatar-studio-generation-job.query';
@@ -1,28 +1,19 @@
1
1
  import { z } from 'zod';
2
- import {
3
- AVATAR_STUDIO_MEDIA_KIND,
4
- AVATAR_STUDIO_MEDIA_ROLE,
5
- AVATAR_STUDIO_MEDIA_SOURCE,
6
- } from '../../../constants';
2
+ import { AVATAR_STUDIO_MEDIA_KIND } from '../../../constants';
7
3
  import { AvatarStudioMediaSchema } from '../../../models';
8
- import { AvatarStudioClipIdParamsSchema } from '../shared/avatar-studio-common.schema';
9
4
 
5
+ /**
6
+ * Загруженный файл попадает в медиатеку пользователя и доступен из любого его клипа.
7
+ * Положить его в сцену — отдельная операция: PUT .../scenes/:sceneId/slots/:slot.
8
+ * Чем медиа будет — озвучкой, образцом голоса, референсом — решает поле, которое на него
9
+ * сошлётся, а не признак на самом медиа.
10
+ */
10
11
  export namespace CreateAvatarStudioMediaFromFileCommand {
11
- export const ParamsSchema = AvatarStudioClipIdParamsSchema;
12
- export type Params = z.infer<typeof ParamsSchema>;
13
-
14
12
  export const RequestSchema = z
15
13
  .object({
16
14
  fileId: z.string().uuid(),
17
- sceneId: z.string().uuid().optional(),
18
15
  kind: z.nativeEnum(AVATAR_STUDIO_MEDIA_KIND),
19
- source: z
20
- .nativeEnum(AVATAR_STUDIO_MEDIA_SOURCE)
21
- .default(AVATAR_STUDIO_MEDIA_SOURCE.UPLOAD)
22
- .optional(),
23
- role: z.nativeEnum(AVATAR_STUDIO_MEDIA_ROLE),
24
16
  title: z.string().trim().min(1).max(255).optional(),
25
- prompt: z.string().optional(),
26
17
  })
27
18
  .strict();
28
19
  export type Request = z.infer<typeof RequestSchema>;
@@ -1,20 +1,22 @@
1
1
  import { z } from 'zod';
2
- import { AVATAR_STUDIO_MEDIA_KIND, AVATAR_STUDIO_MEDIA_ROLE } from '../../../constants';
2
+ import { AVATAR_STUDIO_MEDIA_KIND } from '../../../constants';
3
3
  import { AvatarStudioMediaSchema } from '../../../models';
4
4
  import {
5
5
  AvatarStudioPagedResponseSchema,
6
6
  AvatarStudioPaginationQuerySchema,
7
7
  } from '../shared/avatar-studio-common.schema';
8
8
 
9
- export namespace FindAvatarStudioMediaQuery {
10
- export const ParamsSchema = z.object({}).strict();
11
- export type Params = z.infer<typeof ParamsSchema>;
9
+ /**
10
+ * Список медиа всегда однороден по владельцу: либо медиатека пользователя,
11
+ * либо общие системные медиа. Смешанного списка нет, поэтому owner обязателен.
12
+ */
13
+ export const AvatarStudioMediaOwnerSchema = z.enum(['me', 'system']);
14
+ export type AvatarStudioMediaOwner = z.infer<typeof AvatarStudioMediaOwnerSchema>;
12
15
 
16
+ export namespace FindAvatarStudioMediaQuery {
13
17
  export const QuerySchema = AvatarStudioPaginationQuerySchema.extend({
14
- clipId: z.string().uuid().optional(),
15
- sceneId: z.string().uuid().optional(),
18
+ owner: AvatarStudioMediaOwnerSchema,
16
19
  kind: z.nativeEnum(AVATAR_STUDIO_MEDIA_KIND).optional(),
17
- role: z.nativeEnum(AVATAR_STUDIO_MEDIA_ROLE).optional(),
18
20
  });
19
21
  export type Query = z.infer<typeof QuerySchema>;
20
22
 
@@ -1,18 +1,15 @@
1
1
  import { z } from 'zod';
2
- import { AVATAR_STUDIO_MEDIA_ROLE } from '../../../constants';
3
2
  import { AvatarStudioMediaSchema } from '../../../models';
4
3
  import { AvatarStudioMediaIdParamsSchema } from '../shared/avatar-studio-common.schema';
5
4
 
5
+ /** Только метаданные: прикрепление медиа в сцену — операция сцены, а не медиа. */
6
6
  export namespace UpdateAvatarStudioMediaCommand {
7
7
  export const ParamsSchema = AvatarStudioMediaIdParamsSchema;
8
8
  export type Params = z.infer<typeof ParamsSchema>;
9
9
 
10
10
  export const RequestSchema = z
11
11
  .object({
12
- sceneId: z.string().uuid().nullable().optional(),
13
- role: z.nativeEnum(AVATAR_STUDIO_MEDIA_ROLE).optional(),
14
12
  title: z.string().trim().min(1).max(255).nullable().optional(),
15
- prompt: z.string().nullable().optional(),
16
13
  })
17
14
  .strict();
18
15
  export type Request = z.infer<typeof RequestSchema>;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ import { AvatarStudioClipSchema } from '../../../models';
3
+ import {
4
+ AvatarStudioClipIdParamsSchema,
5
+ AvatarStudioMediaIdParamsSchema,
6
+ } from '../shared/avatar-studio-common.schema';
7
+
8
+ export namespace ApplyAvatarStudioVoiceSampleToAllScenesCommand {
9
+ export const ParamsSchema = AvatarStudioClipIdParamsSchema.merge(
10
+ AvatarStudioMediaIdParamsSchema,
11
+ );
12
+ export type Params = z.infer<typeof ParamsSchema>;
13
+
14
+ // Ответ — клип со сценами, а не список сцен: фронт перерисовывает клип целиком
15
+ // и не ходит следом за GET /clips/:clipId.
16
+ export const ResponseSchema = z.object({
17
+ data: AvatarStudioClipSchema,
18
+ });
19
+ export type Response = z.infer<typeof ResponseSchema>;
20
+ }
@@ -1,4 +1,6 @@
1
+ export * from './apply-avatar-studio-voice-sample-to-all-scenes.command';
1
2
  export * from './create-avatar-studio-scene.command';
2
3
  export * from './delete-avatar-studio-scene.command';
3
4
  export * from './reorder-avatar-studio-scenes.command';
5
+ export * from './set-avatar-studio-scene-slot.command';
4
6
  export * from './update-avatar-studio-scene.command';