vidspotai-shared 1.0.82-dev.0 → 1.0.83

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 (468) hide show
  1. package/lib/globals/aiModels/enums.d.ts +11 -1
  2. package/lib/globals/aiModels/enums.d.ts.map +1 -1
  3. package/lib/globals/aiModels/enums.js +24 -1
  4. package/lib/globals/aiModels/index.d.ts.map +1 -1
  5. package/lib/globals/aiModels/index.js +2 -0
  6. package/lib/globals/aiModels/providers/anthropic.d.ts +12 -0
  7. package/lib/globals/aiModels/providers/anthropic.d.ts.map +1 -0
  8. package/lib/globals/aiModels/providers/anthropic.js +88 -0
  9. package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
  10. package/lib/globals/aiModels/providers/google.js +115 -10
  11. package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
  12. package/lib/globals/aiModels/providers/openai.js +63 -4
  13. package/lib/globals/aiModels/tierHelpers.d.ts +12 -0
  14. package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
  15. package/lib/globals/aiModels/tierHelpers.js +83 -0
  16. package/lib/globals/aiModels/types.d.ts +19 -0
  17. package/lib/globals/aiModels/types.d.ts.map +1 -1
  18. package/lib/globals/types.d.ts +120 -1
  19. package/lib/globals/types.d.ts.map +1 -1
  20. package/lib/globals/types.js +135 -1
  21. package/lib/models/agent.model.d.ts +41 -1
  22. package/lib/models/agent.model.d.ts.map +1 -1
  23. package/lib/models/index.d.ts +1 -0
  24. package/lib/models/index.d.ts.map +1 -1
  25. package/lib/models/index.js +1 -0
  26. package/lib/models/social.model.d.ts +180 -0
  27. package/lib/models/social.model.d.ts.map +1 -0
  28. package/lib/models/social.model.js +2 -0
  29. package/lib/models/user.model.d.ts +10 -0
  30. package/lib/models/user.model.d.ts.map +1 -1
  31. package/lib/models/video.model.d.ts +6 -0
  32. package/lib/models/video.model.d.ts.map +1 -1
  33. package/lib/schemas/brief.schema.d.ts +46 -0
  34. package/lib/schemas/brief.schema.d.ts.map +1 -1
  35. package/lib/schemas/brief.schema.js +72 -1
  36. package/lib/schemas/index.d.ts +1 -0
  37. package/lib/schemas/index.d.ts.map +1 -1
  38. package/lib/schemas/index.js +1 -0
  39. package/lib/schemas/project.schema.d.ts +70 -3
  40. package/lib/schemas/project.schema.d.ts.map +1 -1
  41. package/lib/schemas/project.schema.js +12 -0
  42. package/lib/schemas/social.schema.d.ts +91 -0
  43. package/lib/schemas/social.schema.d.ts.map +1 -0
  44. package/lib/schemas/social.schema.js +114 -0
  45. package/lib/schemas/videoPlan.schema.d.ts +117 -3
  46. package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
  47. package/lib/schemas/videoPlan.schema.js +141 -1
  48. package/lib/services/agent/chatAgent.d.ts +25 -1
  49. package/lib/services/agent/chatAgent.d.ts.map +1 -1
  50. package/lib/services/agent/chatAgent.js +145 -9
  51. package/lib/services/agent/costPreflight.d.ts +11 -1
  52. package/lib/services/agent/costPreflight.d.ts.map +1 -1
  53. package/lib/services/agent/costPreflight.js +18 -1
  54. package/lib/services/agent/covers/coverPlanner.d.ts +41 -0
  55. package/lib/services/agent/covers/coverPlanner.d.ts.map +1 -0
  56. package/lib/services/agent/covers/coverPlanner.js +278 -0
  57. package/lib/services/agent/covers/covers.schema.d.ts +158 -0
  58. package/lib/services/agent/covers/covers.schema.d.ts.map +1 -0
  59. package/lib/services/agent/covers/covers.schema.js +166 -0
  60. package/lib/services/agent/covers/index.d.ts +3 -0
  61. package/lib/services/agent/covers/index.d.ts.map +1 -0
  62. package/lib/services/agent/covers/index.js +18 -0
  63. package/lib/services/agent/critic.d.ts +10 -0
  64. package/lib/services/agent/critic.d.ts.map +1 -1
  65. package/lib/services/agent/critic.js +37 -1
  66. package/lib/services/agent/editClassifier.d.ts +4 -4
  67. package/lib/services/agent/editClassifier.js +2 -2
  68. package/lib/services/agent/editExisting/editAssembler.d.ts +78 -0
  69. package/lib/services/agent/editExisting/editAssembler.d.ts.map +1 -0
  70. package/lib/services/agent/editExisting/editAssembler.js +172 -0
  71. package/lib/services/agent/editExisting/editExisting.schema.d.ts +119 -0
  72. package/lib/services/agent/editExisting/editExisting.schema.d.ts.map +1 -0
  73. package/lib/services/agent/editExisting/editExisting.schema.js +157 -0
  74. package/lib/services/agent/editExisting/highlightPicker.d.ts +48 -0
  75. package/lib/services/agent/editExisting/highlightPicker.d.ts.map +1 -0
  76. package/lib/services/agent/editExisting/highlightPicker.js +199 -0
  77. package/lib/services/agent/editExisting/index.d.ts +4 -0
  78. package/lib/services/agent/editExisting/index.d.ts.map +1 -0
  79. package/lib/services/agent/editExisting/index.js +19 -0
  80. package/lib/services/agent/eval/recorder.d.ts +13 -1
  81. package/lib/services/agent/eval/recorder.d.ts.map +1 -1
  82. package/lib/services/agent/eval/recorder.js +59 -0
  83. package/lib/services/agent/eval/seedBriefs.d.ts +4 -3
  84. package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -1
  85. package/lib/services/agent/eval/seedBriefs.js +283 -3
  86. package/lib/services/agent/eval/types.d.ts +10 -0
  87. package/lib/services/agent/eval/types.d.ts.map +1 -1
  88. package/lib/services/agent/executor/core.d.ts +70 -0
  89. package/lib/services/agent/executor/core.d.ts.map +1 -0
  90. package/lib/services/agent/executor/core.js +250 -0
  91. package/lib/services/agent/executor/duration.d.ts +20 -0
  92. package/lib/services/agent/executor/duration.d.ts.map +1 -0
  93. package/lib/services/agent/executor/duration.js +46 -0
  94. package/lib/services/agent/executor/index.d.ts +15 -0
  95. package/lib/services/agent/executor/index.d.ts.map +1 -0
  96. package/lib/services/agent/executor/index.js +32 -0
  97. package/lib/services/agent/executor/types.d.ts +183 -0
  98. package/lib/services/agent/executor/types.d.ts.map +1 -0
  99. package/lib/services/agent/executor/types.js +29 -0
  100. package/lib/services/agent/executor/visual.d.ts +32 -0
  101. package/lib/services/agent/executor/visual.d.ts.map +1 -0
  102. package/lib/services/agent/executor/visual.js +400 -0
  103. package/lib/services/agent/executor/voice.d.ts +17 -0
  104. package/lib/services/agent/executor/voice.d.ts.map +1 -0
  105. package/lib/services/agent/executor/voice.js +119 -0
  106. package/lib/services/agent/extendChain.d.ts +101 -0
  107. package/lib/services/agent/extendChain.d.ts.map +1 -0
  108. package/lib/services/agent/extendChain.js +177 -0
  109. package/lib/services/agent/index.d.ts +11 -1
  110. package/lib/services/agent/index.d.ts.map +1 -1
  111. package/lib/services/agent/index.js +11 -1
  112. package/lib/services/agent/llmCaller.d.ts +7 -8
  113. package/lib/services/agent/llmCaller.d.ts.map +1 -1
  114. package/lib/services/agent/llmCallerAnthropic.d.ts +44 -31
  115. package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -1
  116. package/lib/services/agent/llmCallerAnthropic.js +135 -60
  117. package/lib/services/agent/llmCallerFactory.d.ts +34 -0
  118. package/lib/services/agent/llmCallerFactory.d.ts.map +1 -0
  119. package/lib/services/agent/llmCallerFactory.js +31 -0
  120. package/lib/services/agent/llmCallerGemini.d.ts +62 -0
  121. package/lib/services/agent/llmCallerGemini.d.ts.map +1 -0
  122. package/lib/services/agent/llmCallerGemini.js +235 -0
  123. package/lib/services/agent/llmCallerOpenai.d.ts +56 -0
  124. package/lib/services/agent/llmCallerOpenai.d.ts.map +1 -0
  125. package/lib/services/agent/llmCallerOpenai.js +230 -0
  126. package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -1
  127. package/lib/services/agent/llmCallerRegistry.js +7 -7
  128. package/lib/services/agent/llmCallerRouting.d.ts +63 -0
  129. package/lib/services/agent/llmCallerRouting.d.ts.map +1 -0
  130. package/lib/services/agent/llmCallerRouting.js +124 -0
  131. package/lib/services/agent/llmModelRegistry.d.ts +59 -0
  132. package/lib/services/agent/llmModelRegistry.d.ts.map +1 -0
  133. package/lib/services/agent/llmModelRegistry.js +168 -0
  134. package/lib/services/agent/llmRetry.d.ts +57 -0
  135. package/lib/services/agent/llmRetry.d.ts.map +1 -0
  136. package/lib/services/agent/llmRetry.js +102 -0
  137. package/lib/services/agent/modelRouter.d.ts +3 -3
  138. package/lib/services/agent/modelRouter.d.ts.map +1 -1
  139. package/lib/services/agent/modelRouter.js +27 -13
  140. package/lib/services/agent/planMutations.d.ts +54 -1
  141. package/lib/services/agent/planMutations.d.ts.map +1 -1
  142. package/lib/services/agent/planMutations.js +78 -0
  143. package/lib/services/agent/planner/Planner.d.ts +0 -17
  144. package/lib/services/agent/planner/Planner.d.ts.map +1 -1
  145. package/lib/services/agent/planner/Planner.js +67 -303
  146. package/lib/services/agent/planner/overlayRegen.d.ts +38 -0
  147. package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -0
  148. package/lib/services/agent/planner/overlayRegen.js +145 -0
  149. package/lib/services/agent/planner/plannerMessages.d.ts +34 -0
  150. package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -0
  151. package/lib/services/agent/planner/plannerMessages.js +185 -0
  152. package/lib/services/agent/planner/promptSections.d.ts +12 -0
  153. package/lib/services/agent/planner/promptSections.d.ts.map +1 -1
  154. package/lib/services/agent/planner/promptSections.js +57 -0
  155. package/lib/services/agent/planner/scriptFirstPlanner.d.ts +35 -0
  156. package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -0
  157. package/lib/services/agent/planner/scriptFirstPlanner.js +140 -0
  158. package/lib/services/agent/planner/structuralRules.d.ts +10 -0
  159. package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
  160. package/lib/services/agent/planner/structuralRules.js +92 -9
  161. package/lib/services/agent/planner/validators.d.ts +18 -0
  162. package/lib/services/agent/planner/validators.d.ts.map +1 -1
  163. package/lib/services/agent/planner/validators.js +97 -0
  164. package/lib/services/agent/planner.d.ts +2 -1
  165. package/lib/services/agent/planner.d.ts.map +1 -1
  166. package/lib/services/agent/planner.js +5 -1
  167. package/lib/services/agent/priorProject.d.ts +26 -0
  168. package/lib/services/agent/priorProject.d.ts.map +1 -0
  169. package/lib/services/agent/priorProject.js +51 -0
  170. package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
  171. package/lib/services/agent/providerFallback/chains.js +27 -15
  172. package/lib/services/agent/repurpose/index.d.ts +3 -0
  173. package/lib/services/agent/repurpose/index.d.ts.map +1 -0
  174. package/lib/services/agent/repurpose/index.js +18 -0
  175. package/lib/services/agent/repurpose/repurpose.schema.d.ts +132 -0
  176. package/lib/services/agent/repurpose/repurpose.schema.d.ts.map +1 -0
  177. package/lib/services/agent/repurpose/repurpose.schema.js +144 -0
  178. package/lib/services/agent/repurpose/shortsPicker.d.ts +25 -0
  179. package/lib/services/agent/repurpose/shortsPicker.d.ts.map +1 -0
  180. package/lib/services/agent/repurpose/shortsPicker.js +218 -0
  181. package/lib/services/agent/runHelpers.d.ts +21 -2
  182. package/lib/services/agent/runHelpers.d.ts.map +1 -1
  183. package/lib/services/agent/runHelpers.js +71 -2
  184. package/lib/services/agent/tools/animateImage.tool.d.ts +1 -0
  185. package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
  186. package/lib/services/agent/tools/animateImage.tool.js +12 -0
  187. package/lib/services/agent/tools/chapterOutline.tool.d.ts +42 -0
  188. package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -0
  189. package/lib/services/agent/tools/chapterOutline.tool.js +115 -0
  190. package/lib/services/agent/tools/composeScene.tool.d.ts +65 -2
  191. package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
  192. package/lib/services/agent/tools/estimateCost.tool.d.ts +28 -1
  193. package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
  194. package/lib/services/agent/tools/estimateCost.tool.js +55 -7
  195. package/lib/services/agent/tools/extendVideo.tool.d.ts +26 -0
  196. package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -0
  197. package/lib/services/agent/tools/extendVideo.tool.js +149 -0
  198. package/lib/services/agent/tools/generateScript.tool.d.ts +184 -0
  199. package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -0
  200. package/lib/services/agent/tools/generateScript.tool.js +123 -0
  201. package/lib/services/agent/tools/generateVideo.tool.d.ts +1 -0
  202. package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
  203. package/lib/services/agent/tools/generateVideo.tool.js +20 -1
  204. package/lib/services/agent/tools/index.d.ts +4 -0
  205. package/lib/services/agent/tools/index.d.ts.map +1 -1
  206. package/lib/services/agent/tools/index.js +4 -0
  207. package/lib/services/agent/tools/matchBrollToScript.tool.d.ts +50 -0
  208. package/lib/services/agent/tools/matchBrollToScript.tool.d.ts.map +1 -0
  209. package/lib/services/agent/tools/matchBrollToScript.tool.js +139 -0
  210. package/lib/services/agent/tools/planVideo.tool.d.ts +57 -1
  211. package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
  212. package/lib/services/agent/tools/planVideo.tool.js +3 -3
  213. package/lib/services/agent/tools/render.tool.d.ts +22 -1
  214. package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
  215. package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
  216. package/lib/services/aiGen/aiGenFactory.service.js +18 -3
  217. package/lib/services/aiGen/helpers.d.ts +8 -0
  218. package/lib/services/aiGen/helpers.d.ts.map +1 -1
  219. package/lib/services/aiGen/helpers.js +12 -0
  220. package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts +26 -0
  221. package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts.map +1 -0
  222. package/lib/services/aiGen/providers/anthropic/anthropic.service.js +95 -0
  223. package/lib/services/aiGen/providers/google/google.service.d.ts +25 -1
  224. package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
  225. package/lib/services/aiGen/providers/google/google.service.js +136 -237
  226. package/lib/services/aiGen/providers/google/googleApiKeys.d.ts +71 -0
  227. package/lib/services/aiGen/providers/google/googleApiKeys.d.ts.map +1 -0
  228. package/lib/services/aiGen/providers/google/googleApiKeys.js +137 -0
  229. package/lib/services/aiGen/providers/google/googleErrors.d.ts +13 -0
  230. package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -0
  231. package/lib/services/aiGen/providers/google/googleErrors.js +102 -0
  232. package/lib/services/aiGen/providers/google/googleFetch.d.ts +8 -0
  233. package/lib/services/aiGen/providers/google/googleFetch.d.ts.map +1 -0
  234. package/lib/services/aiGen/providers/google/googleFetch.js +96 -0
  235. package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +52 -0
  236. package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -0
  237. package/lib/services/aiGen/providers/google/googleKeyPool.js +129 -0
  238. package/lib/services/aiGen/providers/google/googleMusic.d.ts +15 -0
  239. package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -0
  240. package/lib/services/aiGen/providers/google/googleMusic.js +77 -0
  241. package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -3
  242. package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
  243. package/lib/services/aiGen/providers/kling/kling.service.js +23 -367
  244. package/lib/services/aiGen/providers/kling/klingCredits.d.ts +9 -0
  245. package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -0
  246. package/lib/services/aiGen/providers/kling/klingCredits.js +63 -0
  247. package/lib/services/aiGen/providers/kling/klingRequests.d.ts +32 -0
  248. package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -0
  249. package/lib/services/aiGen/providers/kling/klingRequests.js +194 -0
  250. package/lib/services/aiGen/providers/kling/klingStatus.d.ts +16 -0
  251. package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -0
  252. package/lib/services/aiGen/providers/kling/klingStatus.js +173 -0
  253. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
  254. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +7 -1
  255. package/lib/services/bullmq.service.d.ts +61 -0
  256. package/lib/services/bullmq.service.d.ts.map +1 -1
  257. package/lib/services/bullmq.service.js +124 -2
  258. package/lib/services/crypto/index.d.ts +2 -0
  259. package/lib/services/crypto/index.d.ts.map +1 -0
  260. package/lib/services/crypto/index.js +17 -0
  261. package/lib/services/crypto/tokenVault.d.ts +47 -0
  262. package/lib/services/crypto/tokenVault.d.ts.map +1 -0
  263. package/lib/services/crypto/tokenVault.js +179 -0
  264. package/lib/services/editor/captionStyleHint.d.ts +3 -0
  265. package/lib/services/editor/captionStyleHint.d.ts.map +1 -0
  266. package/lib/services/editor/captionStyleHint.js +112 -0
  267. package/lib/services/editor/planToProject.d.ts +7 -66
  268. package/lib/services/editor/planToProject.d.ts.map +1 -1
  269. package/lib/services/editor/planToProject.helpers.d.ts +40 -0
  270. package/lib/services/editor/planToProject.helpers.d.ts.map +1 -0
  271. package/lib/services/editor/planToProject.helpers.js +177 -0
  272. package/lib/services/editor/planToProject.js +197 -180
  273. package/lib/services/editor/planToProject.types.d.ts +94 -0
  274. package/lib/services/editor/planToProject.types.d.ts.map +1 -0
  275. package/lib/services/editor/planToProject.types.js +2 -0
  276. package/lib/services/firestore.service.d.ts +5 -0
  277. package/lib/services/firestore.service.d.ts.map +1 -1
  278. package/lib/services/firestore.service.js +13 -0
  279. package/lib/services/index.d.ts +13 -0
  280. package/lib/services/index.d.ts.map +1 -1
  281. package/lib/services/index.js +13 -0
  282. package/lib/services/promptEnhancer/index.d.ts +18 -0
  283. package/lib/services/promptEnhancer/index.d.ts.map +1 -0
  284. package/lib/services/promptEnhancer/index.js +33 -0
  285. package/lib/services/promptEnhancer/models.d.ts +54 -0
  286. package/lib/services/promptEnhancer/models.d.ts.map +1 -0
  287. package/lib/services/promptEnhancer/models.js +37 -0
  288. package/lib/services/promptEnhancer/profiles/agent.profile.d.ts +14 -0
  289. package/lib/services/promptEnhancer/profiles/agent.profile.d.ts.map +1 -0
  290. package/lib/services/promptEnhancer/profiles/agent.profile.js +40 -0
  291. package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts +13 -0
  292. package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts.map +1 -0
  293. package/lib/services/promptEnhancer/profiles/avatar.profile.js +40 -0
  294. package/lib/services/promptEnhancer/profiles/base.d.ts +28 -0
  295. package/lib/services/promptEnhancer/profiles/base.d.ts.map +1 -0
  296. package/lib/services/promptEnhancer/profiles/base.js +35 -0
  297. package/lib/services/promptEnhancer/profiles/image.profile.d.ts +11 -0
  298. package/lib/services/promptEnhancer/profiles/image.profile.d.ts.map +1 -0
  299. package/lib/services/promptEnhancer/profiles/image.profile.js +42 -0
  300. package/lib/services/promptEnhancer/profiles/index.d.ts +12 -0
  301. package/lib/services/promptEnhancer/profiles/index.d.ts.map +1 -0
  302. package/lib/services/promptEnhancer/profiles/index.js +33 -0
  303. package/lib/services/promptEnhancer/profiles/video.profile.d.ts +15 -0
  304. package/lib/services/promptEnhancer/profiles/video.profile.d.ts.map +1 -0
  305. package/lib/services/promptEnhancer/profiles/video.profile.js +81 -0
  306. package/lib/services/promptEnhancer/promptEnhancer.service.d.ts +45 -0
  307. package/lib/services/promptEnhancer/promptEnhancer.service.d.ts.map +1 -0
  308. package/lib/services/promptEnhancer/promptEnhancer.service.js +157 -0
  309. package/lib/services/promptEnhancer/schema.d.ts +19 -0
  310. package/lib/services/promptEnhancer/schema.d.ts.map +1 -0
  311. package/lib/services/promptEnhancer/schema.js +43 -0
  312. package/lib/services/promptEnhancer/types.d.ts +112 -0
  313. package/lib/services/promptEnhancer/types.d.ts.map +1 -0
  314. package/lib/services/promptEnhancer/types.js +2 -0
  315. package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +60 -5
  316. package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -1
  317. package/lib/services/rateLimiter/distributedRateLimiter.service.js +184 -16
  318. package/lib/services/socialAI/captionGen.d.ts +81 -0
  319. package/lib/services/socialAI/captionGen.d.ts.map +1 -0
  320. package/lib/services/socialAI/captionGen.js +206 -0
  321. package/lib/services/socialAI/hookScore.d.ts +85 -0
  322. package/lib/services/socialAI/hookScore.d.ts.map +1 -0
  323. package/lib/services/socialAI/hookScore.js +170 -0
  324. package/lib/services/socialAI/index.d.ts +3 -0
  325. package/lib/services/socialAI/index.d.ts.map +1 -0
  326. package/lib/services/socialAI/index.js +18 -0
  327. package/lib/services/socialAccounts/index.d.ts +2 -0
  328. package/lib/services/socialAccounts/index.d.ts.map +1 -0
  329. package/lib/services/socialAccounts/index.js +17 -0
  330. package/lib/services/socialAccounts/socialAccountService.d.ts +25 -0
  331. package/lib/services/socialAccounts/socialAccountService.d.ts.map +1 -0
  332. package/lib/services/socialAccounts/socialAccountService.js +105 -0
  333. package/lib/services/socialEngage/factory.d.ts +7 -0
  334. package/lib/services/socialEngage/factory.d.ts.map +1 -0
  335. package/lib/services/socialEngage/factory.js +25 -0
  336. package/lib/services/socialEngage/index.d.ts +6 -0
  337. package/lib/services/socialEngage/index.d.ts.map +1 -0
  338. package/lib/services/socialEngage/index.js +21 -0
  339. package/lib/services/socialEngage/meta.engage.d.ts +17 -0
  340. package/lib/services/socialEngage/meta.engage.d.ts.map +1 -0
  341. package/lib/services/socialEngage/meta.engage.js +128 -0
  342. package/lib/services/socialEngage/metaWebhook.d.ts +50 -0
  343. package/lib/services/socialEngage/metaWebhook.d.ts.map +1 -0
  344. package/lib/services/socialEngage/metaWebhook.js +93 -0
  345. package/lib/services/socialEngage/types.d.ts +72 -0
  346. package/lib/services/socialEngage/types.d.ts.map +1 -0
  347. package/lib/services/socialEngage/types.js +10 -0
  348. package/lib/services/socialEngage/youtube.engage.d.ts +9 -0
  349. package/lib/services/socialEngage/youtube.engage.d.ts.map +1 -0
  350. package/lib/services/socialEngage/youtube.engage.js +87 -0
  351. package/lib/services/socialFormat/aspectGeometry.d.ts +74 -0
  352. package/lib/services/socialFormat/aspectGeometry.d.ts.map +1 -0
  353. package/lib/services/socialFormat/aspectGeometry.js +135 -0
  354. package/lib/services/socialFormat/index.d.ts +2 -0
  355. package/lib/services/socialFormat/index.d.ts.map +1 -0
  356. package/lib/services/socialFormat/index.js +19 -0
  357. package/lib/services/socialInsights/index.d.ts +3 -0
  358. package/lib/services/socialInsights/index.d.ts.map +1 -0
  359. package/lib/services/socialInsights/index.js +18 -0
  360. package/lib/services/socialInsights/recommendations.d.ts +131 -0
  361. package/lib/services/socialInsights/recommendations.d.ts.map +1 -0
  362. package/lib/services/socialInsights/recommendations.js +277 -0
  363. package/lib/services/socialInsights/timeBuckets.d.ts +35 -0
  364. package/lib/services/socialInsights/timeBuckets.d.ts.map +1 -0
  365. package/lib/services/socialInsights/timeBuckets.js +78 -0
  366. package/lib/services/socialMetrics/factory.d.ts +5 -0
  367. package/lib/services/socialMetrics/factory.d.ts.map +1 -0
  368. package/lib/services/socialMetrics/factory.js +24 -0
  369. package/lib/services/socialMetrics/index.d.ts +6 -0
  370. package/lib/services/socialMetrics/index.d.ts.map +1 -0
  371. package/lib/services/socialMetrics/index.js +21 -0
  372. package/lib/services/socialMetrics/meta.metrics.d.ts +22 -0
  373. package/lib/services/socialMetrics/meta.metrics.d.ts.map +1 -0
  374. package/lib/services/socialMetrics/meta.metrics.js +137 -0
  375. package/lib/services/socialMetrics/tiktok.metrics.d.ts +8 -0
  376. package/lib/services/socialMetrics/tiktok.metrics.d.ts.map +1 -0
  377. package/lib/services/socialMetrics/tiktok.metrics.js +43 -0
  378. package/lib/services/socialMetrics/types.d.ts +54 -0
  379. package/lib/services/socialMetrics/types.d.ts.map +1 -0
  380. package/lib/services/socialMetrics/types.js +2 -0
  381. package/lib/services/socialMetrics/youtube.metrics.d.ts +8 -0
  382. package/lib/services/socialMetrics/youtube.metrics.d.ts.map +1 -0
  383. package/lib/services/socialMetrics/youtube.metrics.js +43 -0
  384. package/lib/services/socialOAuth/factory.d.ts +7 -0
  385. package/lib/services/socialOAuth/factory.d.ts.map +1 -0
  386. package/lib/services/socialOAuth/factory.js +42 -0
  387. package/lib/services/socialOAuth/index.d.ts +11 -0
  388. package/lib/services/socialOAuth/index.d.ts.map +1 -0
  389. package/lib/services/socialOAuth/index.js +26 -0
  390. package/lib/services/socialOAuth/linkedin.oauth.d.ts +14 -0
  391. package/lib/services/socialOAuth/linkedin.oauth.d.ts.map +1 -0
  392. package/lib/services/socialOAuth/linkedin.oauth.js +127 -0
  393. package/lib/services/socialOAuth/meta.oauth.d.ts +31 -0
  394. package/lib/services/socialOAuth/meta.oauth.d.ts.map +1 -0
  395. package/lib/services/socialOAuth/meta.oauth.js +214 -0
  396. package/lib/services/socialOAuth/oauthState.d.ts +14 -0
  397. package/lib/services/socialOAuth/oauthState.d.ts.map +1 -0
  398. package/lib/services/socialOAuth/oauthState.js +66 -0
  399. package/lib/services/socialOAuth/pinterest.oauth.d.ts +15 -0
  400. package/lib/services/socialOAuth/pinterest.oauth.d.ts.map +1 -0
  401. package/lib/services/socialOAuth/pinterest.oauth.js +126 -0
  402. package/lib/services/socialOAuth/threads.oauth.d.ts +14 -0
  403. package/lib/services/socialOAuth/threads.oauth.d.ts.map +1 -0
  404. package/lib/services/socialOAuth/threads.oauth.js +129 -0
  405. package/lib/services/socialOAuth/tiktok.oauth.d.ts +15 -0
  406. package/lib/services/socialOAuth/tiktok.oauth.d.ts.map +1 -0
  407. package/lib/services/socialOAuth/tiktok.oauth.js +151 -0
  408. package/lib/services/socialOAuth/types.d.ts +67 -0
  409. package/lib/services/socialOAuth/types.d.ts.map +1 -0
  410. package/lib/services/socialOAuth/types.js +2 -0
  411. package/lib/services/socialOAuth/x.oauth.d.ts +17 -0
  412. package/lib/services/socialOAuth/x.oauth.d.ts.map +1 -0
  413. package/lib/services/socialOAuth/x.oauth.js +134 -0
  414. package/lib/services/socialOAuth/youtube.oauth.d.ts +15 -0
  415. package/lib/services/socialOAuth/youtube.oauth.d.ts.map +1 -0
  416. package/lib/services/socialOAuth/youtube.oauth.js +156 -0
  417. package/lib/services/socialPublish/factory.d.ts +5 -0
  418. package/lib/services/socialPublish/factory.d.ts.map +1 -0
  419. package/lib/services/socialPublish/factory.js +32 -0
  420. package/lib/services/socialPublish/index.d.ts +10 -0
  421. package/lib/services/socialPublish/index.d.ts.map +1 -0
  422. package/lib/services/socialPublish/index.js +25 -0
  423. package/lib/services/socialPublish/linkedin.publish.d.ts +9 -0
  424. package/lib/services/socialPublish/linkedin.publish.d.ts.map +1 -0
  425. package/lib/services/socialPublish/linkedin.publish.js +143 -0
  426. package/lib/services/socialPublish/meta.publish.d.ts +28 -0
  427. package/lib/services/socialPublish/meta.publish.d.ts.map +1 -0
  428. package/lib/services/socialPublish/meta.publish.js +149 -0
  429. package/lib/services/socialPublish/pinterest.publish.d.ts +13 -0
  430. package/lib/services/socialPublish/pinterest.publish.d.ts.map +1 -0
  431. package/lib/services/socialPublish/pinterest.publish.js +130 -0
  432. package/lib/services/socialPublish/threads.publish.d.ts +12 -0
  433. package/lib/services/socialPublish/threads.publish.d.ts.map +1 -0
  434. package/lib/services/socialPublish/threads.publish.js +96 -0
  435. package/lib/services/socialPublish/tiktok.publish.d.ts +13 -0
  436. package/lib/services/socialPublish/tiktok.publish.d.ts.map +1 -0
  437. package/lib/services/socialPublish/tiktok.publish.js +118 -0
  438. package/lib/services/socialPublish/types.d.ts +47 -0
  439. package/lib/services/socialPublish/types.d.ts.map +1 -0
  440. package/lib/services/socialPublish/types.js +2 -0
  441. package/lib/services/socialPublish/x.publish.d.ts +12 -0
  442. package/lib/services/socialPublish/x.publish.d.ts.map +1 -0
  443. package/lib/services/socialPublish/x.publish.js +147 -0
  444. package/lib/services/socialPublish/youtube.publish.d.ts +9 -0
  445. package/lib/services/socialPublish/youtube.publish.d.ts.map +1 -0
  446. package/lib/services/socialPublish/youtube.publish.js +107 -0
  447. package/lib/services/stock/index.d.ts +2 -0
  448. package/lib/services/stock/index.d.ts.map +1 -0
  449. package/lib/services/stock/index.js +17 -0
  450. package/lib/services/stock/realPersonSafety.d.ts +99 -0
  451. package/lib/services/stock/realPersonSafety.d.ts.map +1 -0
  452. package/lib/services/stock/realPersonSafety.js +248 -0
  453. package/lib/services/translation/index.d.ts +2 -0
  454. package/lib/services/translation/index.d.ts.map +1 -0
  455. package/lib/services/translation/index.js +9 -0
  456. package/lib/services/translation/translation.service.d.ts +50 -0
  457. package/lib/services/translation/translation.service.d.ts.map +1 -0
  458. package/lib/services/translation/translation.service.js +211 -0
  459. package/lib/utils/helpers.d.ts +2 -4
  460. package/lib/utils/helpers.d.ts.map +1 -1
  461. package/lib/utils/helpers.js +9 -63
  462. package/lib/utils/index.d.ts +1 -0
  463. package/lib/utils/index.d.ts.map +1 -1
  464. package/lib/utils/index.js +1 -0
  465. package/lib/utils/renderTier.d.ts +26 -0
  466. package/lib/utils/renderTier.d.ts.map +1 -0
  467. package/lib/utils/renderTier.js +34 -0
  468. package/package.json +1 -1
@@ -5,6 +5,7 @@ exports.isVideoModelCapable = isVideoModelCapable;
5
5
  exports.buildVideoChain = buildVideoChain;
6
6
  exports.snapDurationForModel = snapDurationForModel;
7
7
  const aiModels_1 = require("../../../globals/aiModels");
8
+ const helpers_1 = require("../../aiGen/helpers");
8
9
  /**
9
10
  * Provider-chain configuration per modality (F3.3).
10
11
  * Ordered primary → fallback. The wrapper walks the chain on recoverable
@@ -133,20 +134,30 @@ function normalizeAspect(a) {
133
134
  function gcd(a, b) {
134
135
  return b === 0 ? a : gcd(b, a % b);
135
136
  }
136
- // AG-16: small allow-lists for capabilities not yet on the schema. Conservative
137
- // extend as we wire native audio / lastFrame as proper schema fields.
138
- const END_FRAME_MODELS = new Set([
139
- aiModels_1.EVideoGenModels.GOOGLE_VEO_3_1,
140
- aiModels_1.EVideoGenModels.GOOGLE_VEO_3_1_FAST,
141
- aiModels_1.EVideoGenModels.GOOGLE_VEO_3_1_LITE,
142
- aiModels_1.EVideoGenModels.KLING_V2_6,
143
- aiModels_1.EVideoGenModels.KLING_V2_5_TURBO,
144
- aiModels_1.EVideoGenModels.KLING_V3_0,
145
- aiModels_1.EVideoGenModels.RUNWAY_GEN4_TURBO,
146
- aiModels_1.EVideoGenModels.RUNWAY_GEN4_5,
147
- aiModels_1.EVideoGenModels.BYTEDANCE_SEEDANCE_2_0,
148
- aiModels_1.EVideoGenModels.PIXVERSE_V5_6,
149
- ]);
137
+ // AG-1: last-frame (FLF) support is now read from the SAME source of truth the
138
+ // prod API-time guard uses a model declares `lastFrameImageUrl` in its config
139
+ // `fields` (see aiGen/helpers.modelSupportsLastFrame). The old hardcoded
140
+ // END_FRAME_MODELS set had drifted (it listed veo-3.1-lite, pixverse-v5.6 and
141
+ // seedance-2.0, none of which actually declare the field), so the agent gate
142
+ // would pass a request the provider/validator then rejected — wasting a chain
143
+ // slot. Reading the config removes that drift and self-maintains.
144
+ //
145
+ // REMOVED FOR v2 (AG-1) — kept for reference: the stale hardcoded allow-list.
146
+ // const END_FRAME_MODELS = new Set<string>([
147
+ // EVideoGenModels.GOOGLE_VEO_3_1,
148
+ // EVideoGenModels.GOOGLE_VEO_3_1_FAST,
149
+ // EVideoGenModels.GOOGLE_VEO_3_1_LITE,
150
+ // EVideoGenModels.KLING_V2_6,
151
+ // EVideoGenModels.KLING_V2_5_TURBO,
152
+ // EVideoGenModels.KLING_V3_0,
153
+ // EVideoGenModels.RUNWAY_GEN4_TURBO,
154
+ // EVideoGenModels.RUNWAY_GEN4_5,
155
+ // EVideoGenModels.BYTEDANCE_SEEDANCE_2_0,
156
+ // EVideoGenModels.PIXVERSE_V5_6,
157
+ // ]);
158
+ // AG-16: small allow-list for native-audio support — not yet on the schema as a
159
+ // queryable field, so kept hardcoded (conservative). Extend when audio becomes
160
+ // a proper config field like lastFrameImageUrl did.
150
161
  const AUDIO_MODELS = new Set([
151
162
  aiModels_1.EVideoGenModels.GOOGLE_VEO_3,
152
163
  aiModels_1.EVideoGenModels.GOOGLE_VEO_3_1,
@@ -156,7 +167,8 @@ const AUDIO_MODELS = new Set([
156
167
  aiModels_1.EVideoGenModels.KLING_AVATAR,
157
168
  ]);
158
169
  function supportsEndFrame(m) {
159
- return END_FRAME_MODELS.has(m);
170
+ // Single source of truth: model config declares `lastFrameImageUrl` in fields.
171
+ return (0, helpers_1.modelSupportsLastFrame)(m);
160
172
  }
161
173
  function supportsAudio(m) {
162
174
  return AUDIO_MODELS.has(m);
@@ -0,0 +1,3 @@
1
+ export * from "./repurpose.schema";
2
+ export * from "./shortsPicker";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./repurpose.schema"), exports);
18
+ __exportStar(require("./shortsPicker"), exports);
@@ -0,0 +1,132 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * X8 Social Suite · Phase 6 · E3 — "auto-repurpose" schemas.
4
+ *
5
+ * One long source video → an LLM picks the strongest STANDALONE moments → each
6
+ * becomes an independent, platform-native vertical short (its own title + hook
7
+ * + score). This is opus.pro's core loop; we can do it AND host the source
8
+ * generation, so the long-form and its shorts share one brain + one bill.
9
+ *
10
+ * Deliberately a sibling of L-5 (edit-existing), not a fork of it. L-5 picks N
11
+ * segments and CONCATENATES them into ONE tighter recut; E3 picks N
12
+ * INDEPENDENT spans and emits N separate shorts. They share the ffmpeg
13
+ * primitives (cut/probe/upload) and the ASR transcript shape, but the
14
+ * selection brain and the output shape are different — so E3 gets its own pure
15
+ * picker (shortsPicker.ts) and its own worker, leaving the proven L-5 path
16
+ * untouched.
17
+ *
18
+ * As with the rest of the agent surface, the PURE logic (span selection,
19
+ * clamping, scoring, credit math) lives in `shared` so it is unit-/eval-able;
20
+ * the IO-heavy stages (download → ASR → ffmpeg cut → B2 reframe → upload) run
21
+ * in the node-express worker where ffmpeg already is.
22
+ */
23
+ export declare const RepurposeRequestSchema: z.ZodObject<{
24
+ sourceVideoUrl: z.ZodString;
25
+ sourceDurationSec: z.ZodNumber;
26
+ maxShorts: z.ZodOptional<z.ZodNumber>;
27
+ targetShortSec: z.ZodOptional<z.ZodNumber>;
28
+ aspect: z.ZodOptional<z.ZodEnum<{
29
+ "9:16": "9:16";
30
+ "1:1": "1:1";
31
+ "4:5": "4:5";
32
+ "16:9": "16:9";
33
+ }>>;
34
+ language: z.ZodOptional<z.ZodString>;
35
+ instructions: z.ZodOptional<z.ZodString>;
36
+ tone: z.ZodOptional<z.ZodString>;
37
+ title: z.ZodOptional<z.ZodString>;
38
+ }, z.core.$strict>;
39
+ export type RepurposeRequest = z.infer<typeof RepurposeRequestSchema>;
40
+ /** Bounds for a single short, enforced after the LLM picks (see clampShorts). */
41
+ export declare const MIN_SHORT_MS = 3000;
42
+ export declare const MAX_SHORT_MS = 180000;
43
+ export declare const SHORT_TITLE_MAX = 100;
44
+ export declare const SHORT_HOOK_MAX = 280;
45
+ export declare const SHORT_REASON_MAX = 500;
46
+ export declare const SHORT_LABEL_MAX = 120;
47
+ /**
48
+ * One standalone short: a single contiguous span of the source plus the copy
49
+ * needed to post it. (v1 is one span per short — a jump-cut micro-montage per
50
+ * short is a deferred enhancement; the shape stays span-based so it's easy to
51
+ * extend later.) Per-platform caption variants are NOT produced here — the E1
52
+ * caption generator can enrich each short downstream from `title`/`hook`.
53
+ */
54
+ export declare const ShortCandidateSchema: z.ZodObject<{
55
+ startMs: z.ZodNumber;
56
+ endMs: z.ZodNumber;
57
+ title: z.ZodString;
58
+ hook: z.ZodString;
59
+ reason: z.ZodString;
60
+ score: z.ZodNumber;
61
+ label: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>;
63
+ export type ShortCandidate = z.infer<typeof ShortCandidateSchema>;
64
+ export declare const ShortPlanSchema: z.ZodObject<{
65
+ shorts: z.ZodArray<z.ZodObject<{
66
+ startMs: z.ZodNumber;
67
+ endMs: z.ZodNumber;
68
+ title: z.ZodString;
69
+ hook: z.ZodString;
70
+ reason: z.ZodString;
71
+ score: z.ZodNumber;
72
+ label: z.ZodOptional<z.ZodString>;
73
+ }, z.core.$strict>>;
74
+ summary: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strict>;
76
+ export type ShortPlan = z.infer<typeof ShortPlanSchema>;
77
+ /**
78
+ * Tiny job envelope — same design rule as EditJobPayload: the full request
79
+ * lives on `agentProjects/{projectId}.repurposeRequest`, the worker reads it at
80
+ * job start. Keeps the Redis stream light.
81
+ */
82
+ export declare const RepurposeJobPayloadSchema: z.ZodObject<{
83
+ runId: z.ZodString;
84
+ projectId: z.ZodString;
85
+ userId: z.ZodString;
86
+ enqueuedAt: z.ZodNumber;
87
+ }, z.core.$strict>;
88
+ export type RepurposeJobPayload = z.infer<typeof RepurposeJobPayloadSchema>;
89
+ /**
90
+ * A finished short on `agentProjects/{projectId}.shorts[]`. Carries the copy
91
+ * the composer needs (title/hook) plus the reframed MP4 and its source span so
92
+ * the user can trace / re-edit it.
93
+ */
94
+ export interface ProducedShort {
95
+ index: number;
96
+ title: string;
97
+ hook: string;
98
+ reason: string;
99
+ score: number;
100
+ /** Source span this short was cut from, ms. */
101
+ sourceStartMs: number;
102
+ sourceEndMs: number;
103
+ /** Output aspect (the requested target, e.g. "9:16"). */
104
+ aspect: string;
105
+ /** Long-lived signed URL of the reframed short MP4. */
106
+ mp4Url: string;
107
+ durationMs: number;
108
+ width: number;
109
+ height: number;
110
+ }
111
+ /**
112
+ * Flat USD overheads beyond the per-second ASR cost:
113
+ * - the shorts-picker LLM call (one structured call over the transcript), and
114
+ * - our ffmpeg compute per short (cut + B2 reframe + upload — our own metal,
115
+ * priced so the op isn't free).
116
+ */
117
+ export declare const REPURPOSE_PICKER_LLM_USD = 0.05;
118
+ export declare const REPURPOSE_COMPUTE_PER_SHORT_USD = 0.03;
119
+ /** Default shorts assumed for the upfront estimate when maxShorts is omitted. */
120
+ export declare const DEFAULT_MAX_SHORTS = 5;
121
+ /**
122
+ * Pure upfront credit estimate for a repurpose job. The controller deducts this
123
+ * before enqueue; the worker reconciles against the REAL ASR duration and the
124
+ * actual number of shorts produced, refunding any overcharge. 1 credit = $0.10.
125
+ * Shorts picking needs no diarization (no speaker-aware Q→A constraint), so no
126
+ * diarization surcharge — unlike L-5's podcast/interview goals.
127
+ */
128
+ export declare function estimateRepurposeCredits(args: {
129
+ sourceDurationSec: number;
130
+ maxShorts?: number;
131
+ }): number;
132
+ //# sourceMappingURL=repurpose.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repurpose.schema.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/repurpose.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;kBA4BxB,CAAC;AACZ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE,iFAAiF;AACjF,eAAO,MAAM,YAAY,OAAQ,CAAC;AAClC,eAAO,MAAM,YAAY,SAAU,CAAC;AACpC,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;kBAqB7B,CAAC;AACL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,eAAe;;;;;;;;;;;kBAMjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAIxD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;;;;kBAO3B,CAAC;AACZ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAI5E;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAGpD,iFAAiF;AACjF,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAQT"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MAX_SHORTS = exports.REPURPOSE_COMPUTE_PER_SHORT_USD = exports.REPURPOSE_PICKER_LLM_USD = exports.RepurposeJobPayloadSchema = exports.ShortPlanSchema = exports.ShortCandidateSchema = exports.SHORT_LABEL_MAX = exports.SHORT_REASON_MAX = exports.SHORT_HOOK_MAX = exports.SHORT_TITLE_MAX = exports.MAX_SHORT_MS = exports.MIN_SHORT_MS = exports.RepurposeRequestSchema = void 0;
4
+ exports.estimateRepurposeCredits = estimateRepurposeCredits;
5
+ const zod_1 = require("zod");
6
+ const project_schema_1 = require("../../../schemas/project.schema");
7
+ const helpers_1 = require("../../../utils/helpers");
8
+ /**
9
+ * X8 Social Suite · Phase 6 · E3 — "auto-repurpose" schemas.
10
+ *
11
+ * One long source video → an LLM picks the strongest STANDALONE moments → each
12
+ * becomes an independent, platform-native vertical short (its own title + hook
13
+ * + score). This is opus.pro's core loop; we can do it AND host the source
14
+ * generation, so the long-form and its shorts share one brain + one bill.
15
+ *
16
+ * Deliberately a sibling of L-5 (edit-existing), not a fork of it. L-5 picks N
17
+ * segments and CONCATENATES them into ONE tighter recut; E3 picks N
18
+ * INDEPENDENT spans and emits N separate shorts. They share the ffmpeg
19
+ * primitives (cut/probe/upload) and the ASR transcript shape, but the
20
+ * selection brain and the output shape are different — so E3 gets its own pure
21
+ * picker (shortsPicker.ts) and its own worker, leaving the proven L-5 path
22
+ * untouched.
23
+ *
24
+ * As with the rest of the agent surface, the PURE logic (span selection,
25
+ * clamping, scoring, credit math) lives in `shared` so it is unit-/eval-able;
26
+ * the IO-heavy stages (download → ASR → ffmpeg cut → B2 reframe → upload) run
27
+ * in the node-express worker where ffmpeg already is.
28
+ */
29
+ // ─── request (the controller body) ───────────────────────────────────────────
30
+ exports.RepurposeRequestSchema = zod_1.z
31
+ .object({
32
+ /** Publicly-fetchable URL of the long source video (Firebase Storage / signed). */
33
+ sourceVideoUrl: zod_1.z.string().url(),
34
+ /**
35
+ * Source duration in seconds — the uploader knows it, and we need it for the
36
+ * UPFRONT credit estimate (ASR is billed per second). The worker reconciles
37
+ * against the real ASR `audioDuration` after transcription.
38
+ */
39
+ sourceDurationSec: zod_1.z.number().positive(),
40
+ /** Hard cap on how many shorts to produce. Picker default is 5 if omitted. */
41
+ maxShorts: zod_1.z.number().int().positive().max(20).optional(),
42
+ /**
43
+ * Target length of EACH short in seconds. The picker treats this as a soft
44
+ * aim (it won't pad weak material to hit it). Omitted → ~30s default.
45
+ */
46
+ targetShortSec: zod_1.z.number().positive().max(180).optional(),
47
+ /** Output aspect for the shorts. Default 9:16 (Reels/Shorts/TikTok). */
48
+ aspect: project_schema_1.AspectSchema.optional(),
49
+ /** ASR language hint (e.g. "en", "es"). Omitted → AssemblyAI autodetect. */
50
+ language: zod_1.z.string().min(2).max(10).optional(),
51
+ /** Free-form steering for the picker ("focus on the product demo", etc.). */
52
+ instructions: zod_1.z.string().max(2000).optional(),
53
+ /** Tone hint for the generated hooks ("energetic", "professional"). */
54
+ tone: zod_1.z.string().max(200).optional(),
55
+ /** Display title prefix for the produced shorts / project. */
56
+ title: zod_1.z.string().max(200).optional(),
57
+ })
58
+ .strict();
59
+ // ─── short candidates (LLM output) ───────────────────────────────────────────
60
+ /** Bounds for a single short, enforced after the LLM picks (see clampShorts). */
61
+ exports.MIN_SHORT_MS = 3000;
62
+ exports.MAX_SHORT_MS = 180000;
63
+ exports.SHORT_TITLE_MAX = 100;
64
+ exports.SHORT_HOOK_MAX = 280;
65
+ exports.SHORT_REASON_MAX = 500;
66
+ exports.SHORT_LABEL_MAX = 120;
67
+ /**
68
+ * One standalone short: a single contiguous span of the source plus the copy
69
+ * needed to post it. (v1 is one span per short — a jump-cut micro-montage per
70
+ * short is a deferred enhancement; the shape stays span-based so it's easy to
71
+ * extend later.) Per-platform caption variants are NOT produced here — the E1
72
+ * caption generator can enrich each short downstream from `title`/`hook`.
73
+ */
74
+ exports.ShortCandidateSchema = zod_1.z
75
+ .object({
76
+ /** Inclusive start in the SOURCE timeline, ms. */
77
+ startMs: zod_1.z.number().nonnegative(),
78
+ /** Exclusive end in the SOURCE timeline, ms. Must be > startMs (refined below). */
79
+ endMs: zod_1.z.number().positive(),
80
+ /** Short, scroll-stopping title (used by YouTube Shorts). */
81
+ title: zod_1.z.string().max(exports.SHORT_TITLE_MAX),
82
+ /** First-line caption hook — the opening line that earns the watch. */
83
+ hook: zod_1.z.string().max(exports.SHORT_HOOK_MAX),
84
+ /** Why this moment stands alone as a short — surfaced in the UI + eval. */
85
+ reason: zod_1.z.string().max(exports.SHORT_REASON_MAX),
86
+ /** Predicted engagement 0–100 (used to rank when more are picked than the cap). */
87
+ score: zod_1.z.number().min(0).max(100),
88
+ /** Optional short human label (e.g. "The pricing reveal"). */
89
+ label: zod_1.z.string().max(exports.SHORT_LABEL_MAX).optional(),
90
+ })
91
+ .strict()
92
+ .refine((s) => s.endMs > s.startMs, {
93
+ message: "endMs must be greater than startMs",
94
+ path: ["endMs"],
95
+ });
96
+ exports.ShortPlanSchema = zod_1.z
97
+ .object({
98
+ shorts: zod_1.z.array(exports.ShortCandidateSchema).min(1),
99
+ /** One-line description of the repurpose run (optional; shown in UI). */
100
+ summary: zod_1.z.string().max(500).optional(),
101
+ })
102
+ .strict();
103
+ // ─── BullMQ envelope ─────────────────────────────────────────────────────────
104
+ /**
105
+ * Tiny job envelope — same design rule as EditJobPayload: the full request
106
+ * lives on `agentProjects/{projectId}.repurposeRequest`, the worker reads it at
107
+ * job start. Keeps the Redis stream light.
108
+ */
109
+ exports.RepurposeJobPayloadSchema = zod_1.z
110
+ .object({
111
+ runId: zod_1.z.string().min(1),
112
+ projectId: zod_1.z.string().min(1),
113
+ userId: zod_1.z.string().min(1),
114
+ enqueuedAt: zod_1.z.number().int().nonnegative(),
115
+ })
116
+ .strict();
117
+ // ─── cost ────────────────────────────────────────────────────────────────────
118
+ /**
119
+ * Flat USD overheads beyond the per-second ASR cost:
120
+ * - the shorts-picker LLM call (one structured call over the transcript), and
121
+ * - our ffmpeg compute per short (cut + B2 reframe + upload — our own metal,
122
+ * priced so the op isn't free).
123
+ */
124
+ exports.REPURPOSE_PICKER_LLM_USD = 0.05;
125
+ exports.REPURPOSE_COMPUTE_PER_SHORT_USD = 0.03;
126
+ /** AssemblyAI Universal-2 base rate, $/hr (mirrors AssemblyAIService / L-5). */
127
+ const ASR_USD_PER_HOUR = 0.15;
128
+ /** Default shorts assumed for the upfront estimate when maxShorts is omitted. */
129
+ exports.DEFAULT_MAX_SHORTS = 5;
130
+ /**
131
+ * Pure upfront credit estimate for a repurpose job. The controller deducts this
132
+ * before enqueue; the worker reconciles against the REAL ASR duration and the
133
+ * actual number of shorts produced, refunding any overcharge. 1 credit = $0.10.
134
+ * Shorts picking needs no diarization (no speaker-aware Q→A constraint), so no
135
+ * diarization surcharge — unlike L-5's podcast/interview goals.
136
+ */
137
+ function estimateRepurposeCredits(args) {
138
+ const shorts = args.maxShorts ?? exports.DEFAULT_MAX_SHORTS;
139
+ const asrUsd = (ASR_USD_PER_HOUR / 3600) * Math.max(0, args.sourceDurationSec);
140
+ const totalUsd = asrUsd +
141
+ exports.REPURPOSE_PICKER_LLM_USD +
142
+ exports.REPURPOSE_COMPUTE_PER_SHORT_USD * Math.max(1, shorts);
143
+ return (0, helpers_1.getCreditsFromCost)(totalUsd);
144
+ }
@@ -0,0 +1,25 @@
1
+ import { LlmCaller } from "../llmCaller";
2
+ import { TranscriptForPicking } from "../editExisting/highlightPicker";
3
+ import { RepurposeRequest, ShortCandidate } from "./repurpose.schema";
4
+ /**
5
+ * Clamp shorts into [0, sourceDurationMs], cap each to MAX_SHORT_MS, drop
6
+ * slivers below MIN_SHORT_MS, sort chronologically, and remove overlaps (a
7
+ * later span starting before the previous one ended is pushed forward; if that
8
+ * collapses it below the minimum, it's dropped). Also clamps the copy fields
9
+ * and score. Pure + idempotent — safe on already-clean input.
10
+ */
11
+ export declare function clampShorts(shorts: ShortCandidate[], sourceDurationMs: number): ShortCandidate[];
12
+ /**
13
+ * Pick standalone shorts from a transcript. Retries up to `maxRetries` times,
14
+ * feeding the model its previous problems. Throws only if every attempt yields
15
+ * zero usable shorts.
16
+ */
17
+ export declare function pickShortsCore(llm: LlmCaller, args: {
18
+ request: RepurposeRequest;
19
+ transcript: TranscriptForPicking;
20
+ maxRetries?: number;
21
+ }): Promise<{
22
+ shorts: ShortCandidate[];
23
+ summary?: string;
24
+ }>;
25
+ //# sourceMappingURL=shortsPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shortsPicker.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/repurpose/shortsPicker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAEL,oBAAoB,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAIL,gBAAgB,EAChB,cAAc,EAKf,MAAM,oBAAoB,CAAC;AAwG5B;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,cAAc,EAAE,EACxB,gBAAgB,EAAE,MAAM,GACvB,cAAc,EAAE,CA4BlB;AAmDD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE;IACJ,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,oBAAoB,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DzD"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clampShorts = clampShorts;
4
+ exports.pickShortsCore = pickShortsCore;
5
+ const zod_1 = require("zod");
6
+ const logger_1 = require("../../../utils/logger");
7
+ const modelRouter_1 = require("../modelRouter");
8
+ const highlightPicker_1 = require("../editExisting/highlightPicker");
9
+ const repurpose_schema_1 = require("./repurpose.schema");
10
+ /**
11
+ * X8 Social Suite · Phase 6 · E3 — shorts picker. The reasoning core of the
12
+ * auto-repurpose pipeline: given an ASR transcript of a LONG video, an LLM
13
+ * selects the strongest STANDALONE spans, each of which becomes an independent
14
+ * vertical short with its own title, hook, and predicted-engagement score.
15
+ *
16
+ * Pure (injected LlmCaller), so the worker, scripts, and a no-spend eval can
17
+ * all drive it. Reuses L-5's transcript shape + `buildTranscriptLines` (same
18
+ * AssemblyAI output), but the selection bias is the opposite: L-5 keeps a
19
+ * continuous "best of" recut; here every pick must work ALONE as a clip.
20
+ */
21
+ const DEFAULT_TARGET_SHORT_SEC = 30;
22
+ /**
23
+ * The raw LLM output. Looser than ShortCandidateSchema (no refine / max) on
24
+ * purpose — we bounds-check + clamp afterwards so a slightly-off model answer
25
+ * is repaired rather than rejected.
26
+ */
27
+ const LlmShortsSchema = zod_1.z.object({
28
+ shorts: zod_1.z
29
+ .array(zod_1.z.object({
30
+ startMs: zod_1.z.number(),
31
+ endMs: zod_1.z.number(),
32
+ title: zod_1.z.string(),
33
+ hook: zod_1.z.string(),
34
+ reason: zod_1.z.string(),
35
+ score: zod_1.z.number(),
36
+ label: zod_1.z.string().optional(),
37
+ }))
38
+ .min(1),
39
+ summary: zod_1.z.string().optional(),
40
+ });
41
+ function fmtTs(ms) {
42
+ const totalSec = Math.floor(ms / 1000);
43
+ const m = Math.floor(totalSec / 60);
44
+ const s = totalSec % 60;
45
+ return `${m}:${String(s).padStart(2, "0")}`;
46
+ }
47
+ function buildMessages(request, transcript, feedback) {
48
+ const targetSec = request.targetShortSec ?? DEFAULT_TARGET_SHORT_SEC;
49
+ const maxShorts = request.maxShorts ?? repurpose_schema_1.DEFAULT_MAX_SHORTS;
50
+ const system = [
51
+ "You are a short-form video strategist (think the editor behind a viral",
52
+ "Reels/TikTok/Shorts channel). You are given a timestamped transcript of a",
53
+ "LONG source video and must choose the spans that would each become the",
54
+ "BEST STANDALONE vertical short. Output only spans that exist in the",
55
+ "transcript, using millisecond start/end times taken from the bracketed",
56
+ "timestamps.",
57
+ "",
58
+ "Each short MUST work on its own with no other context:",
59
+ "- It opens on a strong hook and resolves a complete thought (never cut",
60
+ " mid-sentence).",
61
+ "- It is self-contained: a viewer who never saw the rest still gets value.",
62
+ `- Aim for roughly ${Math.round(targetSec)}s each (a tight ${repurpose_schema_1.MIN_SHORT_MS / 1000}–${repurpose_schema_1.MAX_SHORT_MS / 1000}s is the hard range); shorter & punchier beats padded.`,
63
+ "- Spans must NOT overlap each other and must lie within the video bounds.",
64
+ `- Every span must lie within [0, ${transcript.audioDurationMs}] ms.`,
65
+ "",
66
+ "For each short also write:",
67
+ "- `title`: a scroll-stopping title (≤ ~10 words) for YouTube Shorts.",
68
+ "- `hook`: the first-line caption that earns the watch (curiosity / payoff /",
69
+ " bold claim) — one or two sentences.",
70
+ "- `reason`: why this moment stands alone as a short.",
71
+ "- `score`: 0–100 predicted engagement; reserve 80+ for genuinely strong picks.",
72
+ "Pick QUALITY over quantity — only spans that are actually share-worthy.",
73
+ ].join("\n");
74
+ const langLine = request.language
75
+ ? `Write the title and hook in this language (BCP-47 "${request.language}").`
76
+ : "Write the title and hook in the same language the transcript is spoken in.";
77
+ const toneLine = request.tone
78
+ ? `Tone for the title/hook: ${request.tone}.`
79
+ : "";
80
+ const user = [
81
+ `GOAL: repurpose this long video into up to ${maxShorts} standalone vertical shorts.`,
82
+ langLine,
83
+ toneLine,
84
+ request.instructions ? `ADDITIONAL INSTRUCTIONS: ${request.instructions}` : "",
85
+ feedback ? `\nYOUR PREVIOUS ANSWER HAD PROBLEMS — FIX THESE:\n${feedback}` : "",
86
+ "",
87
+ `TRANSCRIPT (total ${fmtTs(transcript.audioDurationMs)}):`,
88
+ (0, highlightPicker_1.buildTranscriptLines)(transcript),
89
+ ]
90
+ .filter(Boolean)
91
+ .join("\n");
92
+ return [
93
+ { role: "system", content: system },
94
+ { role: "user", content: user },
95
+ ];
96
+ }
97
+ /**
98
+ * Clamp shorts into [0, sourceDurationMs], cap each to MAX_SHORT_MS, drop
99
+ * slivers below MIN_SHORT_MS, sort chronologically, and remove overlaps (a
100
+ * later span starting before the previous one ended is pushed forward; if that
101
+ * collapses it below the minimum, it's dropped). Also clamps the copy fields
102
+ * and score. Pure + idempotent — safe on already-clean input.
103
+ */
104
+ function clampShorts(shorts, sourceDurationMs) {
105
+ const bounded = shorts
106
+ .map((s) => {
107
+ const startMs = Math.max(0, Math.min(s.startMs, sourceDurationMs));
108
+ let endMs = Math.max(0, Math.min(s.endMs, sourceDurationMs));
109
+ if (endMs - startMs > repurpose_schema_1.MAX_SHORT_MS)
110
+ endMs = startMs + repurpose_schema_1.MAX_SHORT_MS;
111
+ return {
112
+ startMs,
113
+ endMs,
114
+ title: (s.title ?? "").slice(0, repurpose_schema_1.SHORT_TITLE_MAX),
115
+ hook: (s.hook ?? "").slice(0, repurpose_schema_1.SHORT_HOOK_MAX),
116
+ reason: (s.reason ?? "").slice(0, repurpose_schema_1.SHORT_REASON_MAX),
117
+ score: Math.max(0, Math.min(100, Number.isFinite(s.score) ? s.score : 0)),
118
+ ...(s.label ? { label: s.label.slice(0, repurpose_schema_1.SHORT_LABEL_MAX) } : {}),
119
+ };
120
+ })
121
+ .filter((s) => s.endMs - s.startMs >= repurpose_schema_1.MIN_SHORT_MS)
122
+ .sort((a, b) => a.startMs - b.startMs);
123
+ const out = [];
124
+ let prevEnd = 0;
125
+ for (const s of bounded) {
126
+ const start = Math.max(s.startMs, prevEnd);
127
+ if (s.endMs - start < repurpose_schema_1.MIN_SHORT_MS)
128
+ continue; // collapsed by overlap removal
129
+ out.push({ ...s, startMs: start });
130
+ prevEnd = s.endMs;
131
+ }
132
+ return out;
133
+ }
134
+ /**
135
+ * Validate + repair a raw LLM selection against the transcript bounds and the
136
+ * request constraints. Returns cleaned shorts (top-`maxShorts` by score, then
137
+ * re-sorted chronologically) and human-readable problems used as retry feedback.
138
+ */
139
+ function validateSelection(raw, request, audioDurationMs) {
140
+ const problems = [];
141
+ const maxShorts = request.maxShorts ?? repurpose_schema_1.DEFAULT_MAX_SHORTS;
142
+ const mapped = raw.shorts.map((s) => ({
143
+ startMs: s.startMs,
144
+ endMs: s.endMs,
145
+ title: s.title ?? "",
146
+ hook: s.hook ?? "",
147
+ reason: s.reason ?? "",
148
+ score: s.score ?? 0,
149
+ ...(s.label ? { label: s.label } : {}),
150
+ }));
151
+ const outOfBounds = mapped.filter((s) => s.startMs < 0 || s.endMs > audioDurationMs + 250 || s.endMs <= s.startMs);
152
+ if (outOfBounds.length > 0) {
153
+ problems.push(`${outOfBounds.length} short(s) were out of bounds or had endMs ≤ startMs (video is ${audioDurationMs}ms). Keep every span inside [0, ${audioDurationMs}] with endMs > startMs.`);
154
+ }
155
+ let cleaned = clampShorts(mapped, audioDurationMs);
156
+ if (cleaned.length === 0) {
157
+ return { shorts: [], problems };
158
+ }
159
+ if (cleaned.length > maxShorts) {
160
+ // Keep the strongest by score, then restore chronological order.
161
+ cleaned = [...cleaned]
162
+ .sort((a, b) => b.score - a.score)
163
+ .slice(0, maxShorts)
164
+ .sort((a, b) => a.startMs - b.startMs);
165
+ }
166
+ return { shorts: cleaned, problems };
167
+ }
168
+ /**
169
+ * Pick standalone shorts from a transcript. Retries up to `maxRetries` times,
170
+ * feeding the model its previous problems. Throws only if every attempt yields
171
+ * zero usable shorts.
172
+ */
173
+ async function pickShortsCore(llm, args) {
174
+ const router = new modelRouter_1.ModelRouter();
175
+ const maxRetries = args.maxRetries ?? 2;
176
+ const { request, transcript } = args;
177
+ let feedback;
178
+ let lastProblems = [];
179
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
180
+ const res = await llm.structured({
181
+ model: router.pickFor("planner"),
182
+ fallbackModel: router.fallbackFor("planner"),
183
+ schema: LlmShortsSchema,
184
+ schemaName: "ShortPlan",
185
+ messages: buildMessages(request, transcript, feedback),
186
+ temperature: 0.4,
187
+ maxTokens: 8000,
188
+ });
189
+ const { shorts, problems } = validateSelection(res.data, request, transcript.audioDurationMs);
190
+ lastProblems = problems;
191
+ if (shorts.length > 0 && problems.length === 0) {
192
+ logger_1.logger.info("repurpose.picker: selection accepted", {
193
+ attempt,
194
+ shorts: shorts.length,
195
+ audioDurationMs: transcript.audioDurationMs,
196
+ });
197
+ return { shorts, ...(res.data.summary ? { summary: res.data.summary } : {}) };
198
+ }
199
+ // Usable-but-imperfect on the final attempt: accept rather than throw — a
200
+ // few good shorts beat failing the whole job.
201
+ if (shorts.length > 0 && attempt === maxRetries) {
202
+ logger_1.logger.warn("repurpose.picker: accepting imperfect selection on last attempt", {
203
+ shorts: shorts.length,
204
+ problems,
205
+ });
206
+ return { shorts, ...(res.data.summary ? { summary: res.data.summary } : {}) };
207
+ }
208
+ feedback =
209
+ problems.join("\n") ||
210
+ "Your previous answer returned no usable shorts. Select at least one strong, self-contained span with valid timestamps.";
211
+ logger_1.logger.warn("repurpose.picker: retrying", {
212
+ attempt,
213
+ problems,
214
+ durationMs: transcript.audioDurationMs,
215
+ });
216
+ }
217
+ throw new Error(`repurpose.picker: no usable shorts after ${maxRetries + 1} attempts (${lastProblems.join("; ")})`);
218
+ }