@sogni-ai/sogni-intelligence-client 3.0.0-alpha.0

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 (659) hide show
  1. package/.env.example +33 -0
  2. package/LICENSE +22 -0
  3. package/README.md +823 -0
  4. package/contracts/index.d.ts +1 -0
  5. package/contracts/index.js +2 -0
  6. package/dist/client/SogniClientWrapper.d.ts +86 -0
  7. package/dist/client/SogniClientWrapper.d.ts.map +1 -0
  8. package/dist/client/SogniClientWrapper.js +914 -0
  9. package/dist/client/SogniClientWrapper.js.map +1 -0
  10. package/dist/contracts/backboneDurableWorkflow.d.ts +82 -0
  11. package/dist/contracts/backboneDurableWorkflow.d.ts.map +1 -0
  12. package/dist/contracts/backboneDurableWorkflow.js +96 -0
  13. package/dist/contracts/backboneDurableWorkflow.js.map +1 -0
  14. package/dist/contracts/backboneToolCatalog.d.ts +7 -0
  15. package/dist/contracts/backboneToolCatalog.d.ts.map +1 -0
  16. package/dist/contracts/backboneToolCatalog.js +62 -0
  17. package/dist/contracts/backboneToolCatalog.js.map +1 -0
  18. package/dist/contracts/composeWorkflowTypes.d.ts +6 -0
  19. package/dist/contracts/composeWorkflowTypes.d.ts.map +1 -0
  20. package/dist/contracts/composeWorkflowTypes.js +3 -0
  21. package/dist/contracts/composeWorkflowTypes.js.map +1 -0
  22. package/dist/contracts/data/costEstimation.d.ts +5 -0
  23. package/dist/contracts/data/costEstimation.d.ts.map +1 -0
  24. package/dist/contracts/data/costEstimation.js +22 -0
  25. package/dist/contracts/data/costEstimation.js.map +1 -0
  26. package/dist/contracts/data/gatingPolicies.d.ts +6 -0
  27. package/dist/contracts/data/gatingPolicies.d.ts.map +1 -0
  28. package/dist/contracts/data/gatingPolicies.js +218 -0
  29. package/dist/contracts/data/gatingPolicies.js.map +1 -0
  30. package/dist/contracts/data/gatingPoliciesToolSurface.d.ts +7 -0
  31. package/dist/contracts/data/gatingPoliciesToolSurface.d.ts.map +1 -0
  32. package/dist/contracts/data/gatingPoliciesToolSurface.js +61 -0
  33. package/dist/contracts/data/gatingPoliciesToolSurface.js.map +1 -0
  34. package/dist/contracts/data/index.d.ts +14 -0
  35. package/dist/contracts/data/index.d.ts.map +1 -0
  36. package/dist/contracts/data/index.js +57 -0
  37. package/dist/contracts/data/index.js.map +1 -0
  38. package/dist/contracts/data/promptContracts.d.ts +5 -0
  39. package/dist/contracts/data/promptContracts.d.ts.map +1 -0
  40. package/dist/contracts/data/promptContracts.js +1173 -0
  41. package/dist/contracts/data/promptContracts.js.map +1 -0
  42. package/dist/contracts/data/repairRecipes.d.ts +5 -0
  43. package/dist/contracts/data/repairRecipes.d.ts.map +1 -0
  44. package/dist/contracts/data/repairRecipes.js +197 -0
  45. package/dist/contracts/data/repairRecipes.js.map +1 -0
  46. package/dist/contracts/data/toolCatalog.d.ts +31 -0
  47. package/dist/contracts/data/toolCatalog.d.ts.map +1 -0
  48. package/dist/contracts/data/toolCatalog.js +129 -0
  49. package/dist/contracts/data/toolCatalog.js.map +1 -0
  50. package/dist/contracts/data/toolCostMetadata.d.ts +16 -0
  51. package/dist/contracts/data/toolCostMetadata.d.ts.map +1 -0
  52. package/dist/contracts/data/toolCostMetadata.js +284 -0
  53. package/dist/contracts/data/toolCostMetadata.js.map +1 -0
  54. package/dist/contracts/data/toolPermissions.d.ts +27 -0
  55. package/dist/contracts/data/toolPermissions.d.ts.map +1 -0
  56. package/dist/contracts/data/toolPermissions.js +78 -0
  57. package/dist/contracts/data/toolPermissions.js.map +1 -0
  58. package/dist/contracts/evaluators.d.ts +94 -0
  59. package/dist/contracts/evaluators.d.ts.map +1 -0
  60. package/dist/contracts/evaluators.js +468 -0
  61. package/dist/contracts/evaluators.js.map +1 -0
  62. package/dist/contracts/hostedComposition.d.ts +85 -0
  63. package/dist/contracts/hostedComposition.d.ts.map +1 -0
  64. package/dist/contracts/hostedComposition.js +139 -0
  65. package/dist/contracts/hostedComposition.js.map +1 -0
  66. package/dist/contracts/hostedToolValidation.d.ts +47 -0
  67. package/dist/contracts/hostedToolValidation.d.ts.map +1 -0
  68. package/dist/contracts/hostedToolValidation.js +301 -0
  69. package/dist/contracts/hostedToolValidation.js.map +1 -0
  70. package/dist/contracts/idLoraPrompt.d.ts +13 -0
  71. package/dist/contracts/idLoraPrompt.d.ts.map +1 -0
  72. package/dist/contracts/idLoraPrompt.js +78 -0
  73. package/dist/contracts/idLoraPrompt.js.map +1 -0
  74. package/dist/contracts/imagePrompt.d.ts +16 -0
  75. package/dist/contracts/imagePrompt.d.ts.map +1 -0
  76. package/dist/contracts/imagePrompt.js +148 -0
  77. package/dist/contracts/imagePrompt.js.map +1 -0
  78. package/dist/contracts/index.d.ts +48 -0
  79. package/dist/contracts/index.d.ts.map +1 -0
  80. package/dist/contracts/index.js +156 -0
  81. package/dist/contracts/index.js.map +1 -0
  82. package/dist/contracts/index.mjs +102 -0
  83. package/dist/contracts/musicComposition.d.ts +17 -0
  84. package/dist/contracts/musicComposition.d.ts.map +1 -0
  85. package/dist/contracts/musicComposition.js +188 -0
  86. package/dist/contracts/musicComposition.js.map +1 -0
  87. package/dist/contracts/promptContract.d.ts +11 -0
  88. package/dist/contracts/promptContract.d.ts.map +1 -0
  89. package/dist/contracts/promptContract.js +37 -0
  90. package/dist/contracts/promptContract.js.map +1 -0
  91. package/dist/contracts/promptOverrideMarker.d.ts +2 -0
  92. package/dist/contracts/promptOverrideMarker.d.ts.map +1 -0
  93. package/dist/contracts/promptOverrideMarker.js +5 -0
  94. package/dist/contracts/promptOverrideMarker.js.map +1 -0
  95. package/dist/contracts/randomThemes.d.ts +5 -0
  96. package/dist/contracts/randomThemes.d.ts.map +1 -0
  97. package/dist/contracts/randomThemes.js +159 -0
  98. package/dist/contracts/randomThemes.js.map +1 -0
  99. package/dist/contracts/registry.d.ts +29 -0
  100. package/dist/contracts/registry.d.ts.map +1 -0
  101. package/dist/contracts/registry.js +104 -0
  102. package/dist/contracts/registry.js.map +1 -0
  103. package/dist/contracts/repairRecipe.d.ts +14 -0
  104. package/dist/contracts/repairRecipe.d.ts.map +1 -0
  105. package/dist/contracts/repairRecipe.js +38 -0
  106. package/dist/contracts/repairRecipe.js.map +1 -0
  107. package/dist/contracts/storyboard.d.ts +112 -0
  108. package/dist/contracts/storyboard.d.ts.map +1 -0
  109. package/dist/contracts/storyboard.js +7 -0
  110. package/dist/contracts/storyboard.js.map +1 -0
  111. package/dist/contracts/telemetry.d.ts +57 -0
  112. package/dist/contracts/telemetry.d.ts.map +1 -0
  113. package/dist/contracts/telemetry.js +37 -0
  114. package/dist/contracts/telemetry.js.map +1 -0
  115. package/dist/contracts/toolGatingPolicy.d.ts +19 -0
  116. package/dist/contracts/toolGatingPolicy.d.ts.map +1 -0
  117. package/dist/contracts/toolGatingPolicy.js +63 -0
  118. package/dist/contracts/toolGatingPolicy.js.map +1 -0
  119. package/dist/contracts/toolPromptMarkers.d.ts +9 -0
  120. package/dist/contracts/toolPromptMarkers.d.ts.map +1 -0
  121. package/dist/contracts/toolPromptMarkers.js +13 -0
  122. package/dist/contracts/toolPromptMarkers.js.map +1 -0
  123. package/dist/contracts/toolSurface.d.ts +46 -0
  124. package/dist/contracts/toolSurface.d.ts.map +1 -0
  125. package/dist/contracts/toolSurface.js +119 -0
  126. package/dist/contracts/toolSurface.js.map +1 -0
  127. package/dist/contracts/turnPolicy.d.ts +22 -0
  128. package/dist/contracts/turnPolicy.d.ts.map +1 -0
  129. package/dist/contracts/turnPolicy.js +16 -0
  130. package/dist/contracts/turnPolicy.js.map +1 -0
  131. package/dist/contracts/videoComposition.d.ts +35 -0
  132. package/dist/contracts/videoComposition.d.ts.map +1 -0
  133. package/dist/contracts/videoComposition.js +224 -0
  134. package/dist/contracts/videoComposition.js.map +1 -0
  135. package/dist/index.d.ts +8 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +46 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/media/aspectRatio.d.ts +15 -0
  140. package/dist/media/aspectRatio.d.ts.map +1 -0
  141. package/dist/media/aspectRatio.js +72 -0
  142. package/dist/media/aspectRatio.js.map +1 -0
  143. package/dist/media/audioReference.d.ts +57 -0
  144. package/dist/media/audioReference.d.ts.map +1 -0
  145. package/dist/media/audioReference.js +194 -0
  146. package/dist/media/audioReference.js.map +1 -0
  147. package/dist/media/cameraAngle.d.ts +170 -0
  148. package/dist/media/cameraAngle.d.ts.map +1 -0
  149. package/dist/media/cameraAngle.js +48 -0
  150. package/dist/media/cameraAngle.js.map +1 -0
  151. package/dist/media/characterSheet.d.ts +9 -0
  152. package/dist/media/characterSheet.d.ts.map +1 -0
  153. package/dist/media/characterSheet.js +54 -0
  154. package/dist/media/characterSheet.js.map +1 -0
  155. package/dist/media/danceMontage.d.ts +18 -0
  156. package/dist/media/danceMontage.d.ts.map +1 -0
  157. package/dist/media/danceMontage.js +34 -0
  158. package/dist/media/danceMontage.js.map +1 -0
  159. package/dist/media/enhancementProfiles.d.ts +158 -0
  160. package/dist/media/enhancementProfiles.d.ts.map +1 -0
  161. package/dist/media/enhancementProfiles.js +224 -0
  162. package/dist/media/enhancementProfiles.js.map +1 -0
  163. package/dist/media/generationJob.d.ts +81 -0
  164. package/dist/media/generationJob.d.ts.map +1 -0
  165. package/dist/media/generationJob.js +91 -0
  166. package/dist/media/generationJob.js.map +1 -0
  167. package/dist/media/gptImage.d.ts +21 -0
  168. package/dist/media/gptImage.d.ts.map +1 -0
  169. package/dist/media/gptImage.js +162 -0
  170. package/dist/media/gptImage.js.map +1 -0
  171. package/dist/media/imageDimensions.d.ts +24 -0
  172. package/dist/media/imageDimensions.d.ts.map +1 -0
  173. package/dist/media/imageDimensions.js +64 -0
  174. package/dist/media/imageDimensions.js.map +1 -0
  175. package/dist/media/index.d.ts +16 -0
  176. package/dist/media/index.d.ts.map +1 -0
  177. package/dist/media/index.js +32 -0
  178. package/dist/media/index.js.map +1 -0
  179. package/dist/media/index.mjs +116 -0
  180. package/dist/media/musicSettings.d.ts +86 -0
  181. package/dist/media/musicSettings.d.ts.map +1 -0
  182. package/dist/media/musicSettings.js +234 -0
  183. package/dist/media/musicSettings.js.map +1 -0
  184. package/dist/media/vendorModelPremium.d.ts +21 -0
  185. package/dist/media/vendorModelPremium.d.ts.map +1 -0
  186. package/dist/media/vendorModelPremium.js +89 -0
  187. package/dist/media/vendorModelPremium.js.map +1 -0
  188. package/dist/media/videoAppSettings.d.ts +41 -0
  189. package/dist/media/videoAppSettings.d.ts.map +1 -0
  190. package/dist/media/videoAppSettings.js +128 -0
  191. package/dist/media/videoAppSettings.js.map +1 -0
  192. package/dist/media/videoContentLimit.d.ts +15 -0
  193. package/dist/media/videoContentLimit.d.ts.map +1 -0
  194. package/dist/media/videoContentLimit.js +169 -0
  195. package/dist/media/videoContentLimit.js.map +1 -0
  196. package/dist/media/videoReference.d.ts +35 -0
  197. package/dist/media/videoReference.d.ts.map +1 -0
  198. package/dist/media/videoReference.js +77 -0
  199. package/dist/media/videoReference.js.map +1 -0
  200. package/dist/media/videoSettings.d.ts +50 -0
  201. package/dist/media/videoSettings.d.ts.map +1 -0
  202. package/dist/media/videoSettings.js +200 -0
  203. package/dist/media/videoSettings.js.map +1 -0
  204. package/dist/public-skill-runtime/index.d.ts +1220 -0
  205. package/dist/public-skill-runtime/index.d.ts.map +1 -0
  206. package/dist/public-skill-runtime/index.js +6396 -0
  207. package/dist/public-skill-runtime/index.js.map +1 -0
  208. package/dist/public-skill-runtime/index.mjs +141 -0
  209. package/dist/replay/index.d.ts +4 -0
  210. package/dist/replay/index.d.ts.map +1 -0
  211. package/dist/replay/index.js +12 -0
  212. package/dist/replay/index.js.map +1 -0
  213. package/dist/replay/index.mjs +12 -0
  214. package/dist/replay/redact.d.ts +7 -0
  215. package/dist/replay/redact.d.ts.map +1 -0
  216. package/dist/replay/redact.js +108 -0
  217. package/dist/replay/redact.js.map +1 -0
  218. package/dist/replay/types.d.ts +61 -0
  219. package/dist/replay/types.d.ts.map +1 -0
  220. package/dist/replay/types.js +24 -0
  221. package/dist/replay/types.js.map +1 -0
  222. package/dist/runtime/chatTypes.d.ts +47 -0
  223. package/dist/runtime/chatTypes.d.ts.map +1 -0
  224. package/dist/runtime/chatTypes.js +3 -0
  225. package/dist/runtime/chatTypes.js.map +1 -0
  226. package/dist/runtime/durableWorkflowClient.d.ts +80 -0
  227. package/dist/runtime/durableWorkflowClient.d.ts.map +1 -0
  228. package/dist/runtime/durableWorkflowClient.js +312 -0
  229. package/dist/runtime/durableWorkflowClient.js.map +1 -0
  230. package/dist/runtime/index.d.ts +3 -0
  231. package/dist/runtime/index.d.ts.map +1 -0
  232. package/dist/runtime/index.js +18 -0
  233. package/dist/runtime/index.js.map +1 -0
  234. package/dist/runtime/index.mjs +21 -0
  235. package/dist/skills/asset_reference_management/index.d.ts +6 -0
  236. package/dist/skills/asset_reference_management/index.d.ts.map +1 -0
  237. package/dist/skills/asset_reference_management/index.js +18 -0
  238. package/dist/skills/asset_reference_management/index.js.map +1 -0
  239. package/dist/skills/asset_reference_management/index.mjs +18 -0
  240. package/dist/skills/asset_reference_management/manifest.d.ts +42 -0
  241. package/dist/skills/asset_reference_management/manifest.d.ts.map +1 -0
  242. package/dist/skills/asset_reference_management/manifest.js +237 -0
  243. package/dist/skills/asset_reference_management/manifest.js.map +1 -0
  244. package/dist/skills/asset_reference_management/modelRefRegistry.d.ts +24 -0
  245. package/dist/skills/asset_reference_management/modelRefRegistry.d.ts.map +1 -0
  246. package/dist/skills/asset_reference_management/modelRefRegistry.js +136 -0
  247. package/dist/skills/asset_reference_management/modelRefRegistry.js.map +1 -0
  248. package/dist/skills/asset_reference_management/types.d.ts +31 -0
  249. package/dist/skills/asset_reference_management/types.d.ts.map +1 -0
  250. package/dist/skills/asset_reference_management/types.js +3 -0
  251. package/dist/skills/asset_reference_management/types.js.map +1 -0
  252. package/dist/tools/definitions/add-subtitles/definition.d.ts +4 -0
  253. package/dist/tools/definitions/add-subtitles/definition.d.ts.map +1 -0
  254. package/dist/tools/definitions/add-subtitles/definition.js +83 -0
  255. package/dist/tools/definitions/add-subtitles/definition.js.map +1 -0
  256. package/dist/tools/definitions/animate-photo/definition.d.ts +3 -0
  257. package/dist/tools/definitions/animate-photo/definition.d.ts.map +1 -0
  258. package/dist/tools/definitions/animate-photo/definition.js +124 -0
  259. package/dist/tools/definitions/animate-photo/definition.js.map +1 -0
  260. package/dist/tools/definitions/apply-style/definition.d.ts +3 -0
  261. package/dist/tools/definitions/apply-style/definition.d.ts.map +1 -0
  262. package/dist/tools/definitions/apply-style/definition.js +50 -0
  263. package/dist/tools/definitions/apply-style/definition.js.map +1 -0
  264. package/dist/tools/definitions/change-angle/definition.d.ts +3 -0
  265. package/dist/tools/definitions/change-angle/definition.d.ts.map +1 -0
  266. package/dist/tools/definitions/change-angle/definition.js +49 -0
  267. package/dist/tools/definitions/change-angle/definition.js.map +1 -0
  268. package/dist/tools/definitions/dance-montage/dances.d.ts +11 -0
  269. package/dist/tools/definitions/dance-montage/dances.d.ts.map +1 -0
  270. package/dist/tools/definitions/dance-montage/dances.js +90 -0
  271. package/dist/tools/definitions/dance-montage/dances.js.map +1 -0
  272. package/dist/tools/definitions/dance-montage/definition.d.ts +3 -0
  273. package/dist/tools/definitions/dance-montage/definition.d.ts.map +1 -0
  274. package/dist/tools/definitions/dance-montage/definition.js +45 -0
  275. package/dist/tools/definitions/dance-montage/definition.js.map +1 -0
  276. package/dist/tools/definitions/edit-image/definition.d.ts +3 -0
  277. package/dist/tools/definitions/edit-image/definition.d.ts.map +1 -0
  278. package/dist/tools/definitions/edit-image/definition.js +128 -0
  279. package/dist/tools/definitions/edit-image/definition.js.map +1 -0
  280. package/dist/tools/definitions/extend-video/definition.d.ts +3 -0
  281. package/dist/tools/definitions/extend-video/definition.d.ts.map +1 -0
  282. package/dist/tools/definitions/extend-video/definition.js +51 -0
  283. package/dist/tools/definitions/extend-video/definition.js.map +1 -0
  284. package/dist/tools/definitions/generate-image/definition.d.ts +3 -0
  285. package/dist/tools/definitions/generate-image/definition.d.ts.map +1 -0
  286. package/dist/tools/definitions/generate-image/definition.js +107 -0
  287. package/dist/tools/definitions/generate-image/definition.js.map +1 -0
  288. package/dist/tools/definitions/generate-music/definition.d.ts +3 -0
  289. package/dist/tools/definitions/generate-music/definition.d.ts.map +1 -0
  290. package/dist/tools/definitions/generate-music/definition.js +75 -0
  291. package/dist/tools/definitions/generate-music/definition.js.map +1 -0
  292. package/dist/tools/definitions/generate-video/definition.d.ts +3 -0
  293. package/dist/tools/definitions/generate-video/definition.d.ts.map +1 -0
  294. package/dist/tools/definitions/generate-video/definition.js +120 -0
  295. package/dist/tools/definitions/generate-video/definition.js.map +1 -0
  296. package/dist/tools/definitions/index.d.ts +25 -0
  297. package/dist/tools/definitions/index.d.ts.map +1 -0
  298. package/dist/tools/definitions/index.js +66 -0
  299. package/dist/tools/definitions/index.js.map +1 -0
  300. package/dist/tools/definitions/orbit-video/definition.d.ts +3 -0
  301. package/dist/tools/definitions/orbit-video/definition.d.ts.map +1 -0
  302. package/dist/tools/definitions/orbit-video/definition.js +103 -0
  303. package/dist/tools/definitions/orbit-video/definition.js.map +1 -0
  304. package/dist/tools/definitions/overlay-video/definition.d.ts +4 -0
  305. package/dist/tools/definitions/overlay-video/definition.d.ts.map +1 -0
  306. package/dist/tools/definitions/overlay-video/definition.js +142 -0
  307. package/dist/tools/definitions/overlay-video/definition.js.map +1 -0
  308. package/dist/tools/definitions/refine-result/definition.d.ts +3 -0
  309. package/dist/tools/definitions/refine-result/definition.d.ts.map +1 -0
  310. package/dist/tools/definitions/refine-result/definition.js +56 -0
  311. package/dist/tools/definitions/refine-result/definition.js.map +1 -0
  312. package/dist/tools/definitions/replace-video-segment/definition.d.ts +3 -0
  313. package/dist/tools/definitions/replace-video-segment/definition.d.ts.map +1 -0
  314. package/dist/tools/definitions/replace-video-segment/definition.js +65 -0
  315. package/dist/tools/definitions/replace-video-segment/definition.js.map +1 -0
  316. package/dist/tools/definitions/restore-photo/definition.d.ts +3 -0
  317. package/dist/tools/definitions/restore-photo/definition.d.ts.map +1 -0
  318. package/dist/tools/definitions/restore-photo/definition.js +58 -0
  319. package/dist/tools/definitions/restore-photo/definition.js.map +1 -0
  320. package/dist/tools/definitions/sound-to-video/definition.d.ts +3 -0
  321. package/dist/tools/definitions/sound-to-video/definition.d.ts.map +1 -0
  322. package/dist/tools/definitions/sound-to-video/definition.js +91 -0
  323. package/dist/tools/definitions/sound-to-video/definition.js.map +1 -0
  324. package/dist/tools/definitions/stitch-video/definition.d.ts +4 -0
  325. package/dist/tools/definitions/stitch-video/definition.d.ts.map +1 -0
  326. package/dist/tools/definitions/stitch-video/definition.js +89 -0
  327. package/dist/tools/definitions/stitch-video/definition.js.map +1 -0
  328. package/dist/tools/definitions/types.d.ts +15 -0
  329. package/dist/tools/definitions/types.d.ts.map +1 -0
  330. package/dist/tools/definitions/types.js +3 -0
  331. package/dist/tools/definitions/types.js.map +1 -0
  332. package/dist/tools/definitions/video-to-video/definition.d.ts +3 -0
  333. package/dist/tools/definitions/video-to-video/definition.d.ts.map +1 -0
  334. package/dist/tools/definitions/video-to-video/definition.js +101 -0
  335. package/dist/tools/definitions/video-to-video/definition.js.map +1 -0
  336. package/dist/tools/index.d.ts +19 -0
  337. package/dist/tools/index.d.ts.map +1 -0
  338. package/dist/tools/index.js +70 -0
  339. package/dist/tools/index.js.map +1 -0
  340. package/dist/tools/index.mjs +86 -0
  341. package/dist/tools/normalizeArgs.d.ts +2 -0
  342. package/dist/tools/normalizeArgs.d.ts.map +1 -0
  343. package/dist/tools/normalizeArgs.js +40 -0
  344. package/dist/tools/normalizeArgs.js.map +1 -0
  345. package/dist/tools/result.d.ts +47 -0
  346. package/dist/tools/result.d.ts.map +1 -0
  347. package/dist/tools/result.js +38 -0
  348. package/dist/tools/result.js.map +1 -0
  349. package/dist/tools/shared/downloadFilename.d.ts +18 -0
  350. package/dist/tools/shared/downloadFilename.d.ts.map +1 -0
  351. package/dist/tools/shared/downloadFilename.js +157 -0
  352. package/dist/tools/shared/downloadFilename.js.map +1 -0
  353. package/dist/tools/shared/errorClassification.d.ts +15 -0
  354. package/dist/tools/shared/errorClassification.d.ts.map +1 -0
  355. package/dist/tools/shared/errorClassification.js +78 -0
  356. package/dist/tools/shared/errorClassification.js.map +1 -0
  357. package/dist/tools/shared/imageEncoding.d.ts +2 -0
  358. package/dist/tools/shared/imageEncoding.d.ts.map +1 -0
  359. package/dist/tools/shared/imageEncoding.js +11 -0
  360. package/dist/tools/shared/imageEncoding.js.map +1 -0
  361. package/dist/tools/shared/llmHelpers.d.ts +14 -0
  362. package/dist/tools/shared/llmHelpers.d.ts.map +1 -0
  363. package/dist/tools/shared/llmHelpers.js +145 -0
  364. package/dist/tools/shared/llmHelpers.js.map +1 -0
  365. package/dist/tools/shared/modelRegistry.d.ts +10 -0
  366. package/dist/tools/shared/modelRegistry.d.ts.map +1 -0
  367. package/dist/tools/shared/modelRegistry.js +98 -0
  368. package/dist/tools/shared/modelRegistry.js.map +1 -0
  369. package/dist/tools/shared/policyChecks.d.ts +25 -0
  370. package/dist/tools/shared/policyChecks.d.ts.map +1 -0
  371. package/dist/tools/shared/policyChecks.js +79 -0
  372. package/dist/tools/shared/policyChecks.js.map +1 -0
  373. package/dist/tools/shared/promptRefinementCache.d.ts +10 -0
  374. package/dist/tools/shared/promptRefinementCache.d.ts.map +1 -0
  375. package/dist/tools/shared/promptRefinementCache.js +81 -0
  376. package/dist/tools/shared/promptRefinementCache.js.map +1 -0
  377. package/dist/tools/shared/promptSanitizer.d.ts +2 -0
  378. package/dist/tools/shared/promptSanitizer.d.ts.map +1 -0
  379. package/dist/tools/shared/promptSanitizer.js +73 -0
  380. package/dist/tools/shared/promptSanitizer.js.map +1 -0
  381. package/dist/tools/shared/seedancePolicyErrors.d.ts +33 -0
  382. package/dist/tools/shared/seedancePolicyErrors.d.ts.map +1 -0
  383. package/dist/tools/shared/seedancePolicyErrors.js +239 -0
  384. package/dist/tools/shared/seedancePolicyErrors.js.map +1 -0
  385. package/dist/tools/shared/slotFailureSummary.d.ts +7 -0
  386. package/dist/tools/shared/slotFailureSummary.d.ts.map +1 -0
  387. package/dist/tools/shared/slotFailureSummary.js +63 -0
  388. package/dist/tools/shared/slotFailureSummary.js.map +1 -0
  389. package/dist/tools/shared/visionDescriptionCache.d.ts +5 -0
  390. package/dist/tools/shared/visionDescriptionCache.d.ts.map +1 -0
  391. package/dist/tools/shared/visionDescriptionCache.js +35 -0
  392. package/dist/tools/shared/visionDescriptionCache.js.map +1 -0
  393. package/dist/types/index.d.ts +224 -0
  394. package/dist/types/index.d.ts.map +1 -0
  395. package/dist/types/index.js +34 -0
  396. package/dist/types/index.js.map +1 -0
  397. package/dist/utils/errors.d.ts +38 -0
  398. package/dist/utils/errors.d.ts.map +1 -0
  399. package/dist/utils/errors.js +99 -0
  400. package/dist/utils/errors.js.map +1 -0
  401. package/dist/utils/helpers.d.ts +36 -0
  402. package/dist/utils/helpers.d.ts.map +1 -0
  403. package/dist/utils/helpers.js +445 -0
  404. package/dist/utils/helpers.js.map +1 -0
  405. package/dist/workflows/bindings.d.ts +23 -0
  406. package/dist/workflows/bindings.d.ts.map +1 -0
  407. package/dist/workflows/bindings.js +190 -0
  408. package/dist/workflows/bindings.js.map +1 -0
  409. package/dist/workflows/executor-ports.d.ts +11 -0
  410. package/dist/workflows/executor-ports.d.ts.map +1 -0
  411. package/dist/workflows/executor-ports.js +3 -0
  412. package/dist/workflows/executor-ports.js.map +1 -0
  413. package/dist/workflows/executor.d.ts +17 -0
  414. package/dist/workflows/executor.d.ts.map +1 -0
  415. package/dist/workflows/executor.js +526 -0
  416. package/dist/workflows/executor.js.map +1 -0
  417. package/dist/workflows/index.d.ts +8 -0
  418. package/dist/workflows/index.d.ts.map +1 -0
  419. package/dist/workflows/index.js +25 -0
  420. package/dist/workflows/index.js.map +1 -0
  421. package/dist/workflows/index.mjs +22 -0
  422. package/dist/workflows/summarize.d.ts +7 -0
  423. package/dist/workflows/summarize.d.ts.map +1 -0
  424. package/dist/workflows/summarize.js +54 -0
  425. package/dist/workflows/summarize.js.map +1 -0
  426. package/dist/workflows/types.d.ts +302 -0
  427. package/dist/workflows/types.d.ts.map +1 -0
  428. package/dist/workflows/types.js +3 -0
  429. package/dist/workflows/types.js.map +1 -0
  430. package/dist/workflows/validation.d.ts +10 -0
  431. package/dist/workflows/validation.d.ts.map +1 -0
  432. package/dist/workflows/validation.js +340 -0
  433. package/dist/workflows/validation.js.map +1 -0
  434. package/dist-esm/client/SogniClientWrapper.js +877 -0
  435. package/dist-esm/client/SogniClientWrapper.js.map +1 -0
  436. package/dist-esm/contracts/backboneDurableWorkflow.js +90 -0
  437. package/dist-esm/contracts/backboneDurableWorkflow.js.map +1 -0
  438. package/dist-esm/contracts/backboneToolCatalog.js +59 -0
  439. package/dist-esm/contracts/backboneToolCatalog.js.map +1 -0
  440. package/dist-esm/contracts/composeWorkflowTypes.js +2 -0
  441. package/dist-esm/contracts/composeWorkflowTypes.js.map +1 -0
  442. package/dist-esm/contracts/data/costEstimation.js +18 -0
  443. package/dist-esm/contracts/data/costEstimation.js.map +1 -0
  444. package/dist-esm/contracts/data/gatingPolicies.js +214 -0
  445. package/dist-esm/contracts/data/gatingPolicies.js.map +1 -0
  446. package/dist-esm/contracts/data/gatingPoliciesToolSurface.js +57 -0
  447. package/dist-esm/contracts/data/gatingPoliciesToolSurface.js.map +1 -0
  448. package/dist-esm/contracts/data/index.js +23 -0
  449. package/dist-esm/contracts/data/index.js.map +1 -0
  450. package/dist-esm/contracts/data/promptContracts.js +1169 -0
  451. package/dist-esm/contracts/data/promptContracts.js.map +1 -0
  452. package/dist-esm/contracts/data/repairRecipes.js +193 -0
  453. package/dist-esm/contracts/data/repairRecipes.js.map +1 -0
  454. package/dist-esm/contracts/data/toolCatalog.js +122 -0
  455. package/dist-esm/contracts/data/toolCatalog.js.map +1 -0
  456. package/dist-esm/contracts/data/toolCostMetadata.js +277 -0
  457. package/dist-esm/contracts/data/toolCostMetadata.js.map +1 -0
  458. package/dist-esm/contracts/data/toolPermissions.js +70 -0
  459. package/dist-esm/contracts/data/toolPermissions.js.map +1 -0
  460. package/dist-esm/contracts/evaluators.js +463 -0
  461. package/dist-esm/contracts/evaluators.js.map +1 -0
  462. package/dist-esm/contracts/hostedComposition.js +128 -0
  463. package/dist-esm/contracts/hostedComposition.js.map +1 -0
  464. package/dist-esm/contracts/hostedToolValidation.js +296 -0
  465. package/dist-esm/contracts/hostedToolValidation.js.map +1 -0
  466. package/dist-esm/contracts/idLoraPrompt.js +72 -0
  467. package/dist-esm/contracts/idLoraPrompt.js.map +1 -0
  468. package/dist-esm/contracts/imagePrompt.js +143 -0
  469. package/dist-esm/contracts/imagePrompt.js.map +1 -0
  470. package/dist-esm/contracts/index.js +27 -0
  471. package/dist-esm/contracts/index.js.map +1 -0
  472. package/dist-esm/contracts/musicComposition.js +182 -0
  473. package/dist-esm/contracts/musicComposition.js.map +1 -0
  474. package/dist-esm/contracts/promptContract.js +34 -0
  475. package/dist-esm/contracts/promptContract.js.map +1 -0
  476. package/dist-esm/contracts/promptOverrideMarker.js +2 -0
  477. package/dist-esm/contracts/promptOverrideMarker.js.map +1 -0
  478. package/dist-esm/contracts/randomThemes.js +154 -0
  479. package/dist-esm/contracts/randomThemes.js.map +1 -0
  480. package/dist-esm/contracts/registry.js +100 -0
  481. package/dist-esm/contracts/registry.js.map +1 -0
  482. package/dist-esm/contracts/repairRecipe.js +35 -0
  483. package/dist-esm/contracts/repairRecipe.js.map +1 -0
  484. package/dist-esm/contracts/storyboard.js +4 -0
  485. package/dist-esm/contracts/storyboard.js.map +1 -0
  486. package/dist-esm/contracts/telemetry.js +33 -0
  487. package/dist-esm/contracts/telemetry.js.map +1 -0
  488. package/dist-esm/contracts/toolGatingPolicy.js +60 -0
  489. package/dist-esm/contracts/toolGatingPolicy.js.map +1 -0
  490. package/dist-esm/contracts/toolPromptMarkers.js +10 -0
  491. package/dist-esm/contracts/toolPromptMarkers.js.map +1 -0
  492. package/dist-esm/contracts/toolSurface.js +110 -0
  493. package/dist-esm/contracts/toolSurface.js.map +1 -0
  494. package/dist-esm/contracts/turnPolicy.js +13 -0
  495. package/dist-esm/contracts/turnPolicy.js.map +1 -0
  496. package/dist-esm/contracts/videoComposition.js +216 -0
  497. package/dist-esm/contracts/videoComposition.js.map +1 -0
  498. package/dist-esm/index.js +7 -0
  499. package/dist-esm/index.js.map +1 -0
  500. package/dist-esm/media/aspectRatio.js +65 -0
  501. package/dist-esm/media/aspectRatio.js.map +1 -0
  502. package/dist-esm/media/audioReference.js +186 -0
  503. package/dist-esm/media/audioReference.js.map +1 -0
  504. package/dist-esm/media/cameraAngle.js +41 -0
  505. package/dist-esm/media/cameraAngle.js.map +1 -0
  506. package/dist-esm/media/characterSheet.js +48 -0
  507. package/dist-esm/media/characterSheet.js.map +1 -0
  508. package/dist-esm/media/danceMontage.js +29 -0
  509. package/dist-esm/media/danceMontage.js.map +1 -0
  510. package/dist-esm/media/enhancementProfiles.js +219 -0
  511. package/dist-esm/media/enhancementProfiles.js.map +1 -0
  512. package/dist-esm/media/generationJob.js +87 -0
  513. package/dist-esm/media/generationJob.js.map +1 -0
  514. package/dist-esm/media/gptImage.js +150 -0
  515. package/dist-esm/media/gptImage.js.map +1 -0
  516. package/dist-esm/media/imageDimensions.js +59 -0
  517. package/dist-esm/media/imageDimensions.js.map +1 -0
  518. package/dist-esm/media/index.js +16 -0
  519. package/dist-esm/media/index.js.map +1 -0
  520. package/dist-esm/media/musicSettings.js +230 -0
  521. package/dist-esm/media/musicSettings.js.map +1 -0
  522. package/dist-esm/media/vendorModelPremium.js +81 -0
  523. package/dist-esm/media/vendorModelPremium.js.map +1 -0
  524. package/dist-esm/media/videoAppSettings.js +125 -0
  525. package/dist-esm/media/videoAppSettings.js.map +1 -0
  526. package/dist-esm/media/videoContentLimit.js +162 -0
  527. package/dist-esm/media/videoContentLimit.js.map +1 -0
  528. package/dist-esm/media/videoReference.js +72 -0
  529. package/dist-esm/media/videoReference.js.map +1 -0
  530. package/dist-esm/media/videoSettings.js +191 -0
  531. package/dist-esm/media/videoSettings.js.map +1 -0
  532. package/dist-esm/package.json +3 -0
  533. package/dist-esm/public-skill-runtime/index.js +6294 -0
  534. package/dist-esm/public-skill-runtime/index.js.map +1 -0
  535. package/dist-esm/replay/index.js +3 -0
  536. package/dist-esm/replay/index.js.map +1 -0
  537. package/dist-esm/replay/redact.js +102 -0
  538. package/dist-esm/replay/redact.js.map +1 -0
  539. package/dist-esm/replay/types.js +20 -0
  540. package/dist-esm/replay/types.js.map +1 -0
  541. package/dist-esm/runtime/chatTypes.js +2 -0
  542. package/dist-esm/runtime/chatTypes.js.map +1 -0
  543. package/dist-esm/runtime/durableWorkflowClient.js +295 -0
  544. package/dist-esm/runtime/durableWorkflowClient.js.map +1 -0
  545. package/dist-esm/runtime/index.js +2 -0
  546. package/dist-esm/runtime/index.js.map +1 -0
  547. package/dist-esm/skills/asset_reference_management/index.js +3 -0
  548. package/dist-esm/skills/asset_reference_management/index.js.map +1 -0
  549. package/dist-esm/skills/asset_reference_management/manifest.js +228 -0
  550. package/dist-esm/skills/asset_reference_management/manifest.js.map +1 -0
  551. package/dist-esm/skills/asset_reference_management/modelRefRegistry.js +129 -0
  552. package/dist-esm/skills/asset_reference_management/modelRefRegistry.js.map +1 -0
  553. package/dist-esm/skills/asset_reference_management/types.js +2 -0
  554. package/dist-esm/skills/asset_reference_management/types.js.map +1 -0
  555. package/dist-esm/tools/definitions/add-subtitles/definition.js +80 -0
  556. package/dist-esm/tools/definitions/add-subtitles/definition.js.map +1 -0
  557. package/dist-esm/tools/definitions/animate-photo/definition.js +121 -0
  558. package/dist-esm/tools/definitions/animate-photo/definition.js.map +1 -0
  559. package/dist-esm/tools/definitions/apply-style/definition.js +47 -0
  560. package/dist-esm/tools/definitions/apply-style/definition.js.map +1 -0
  561. package/dist-esm/tools/definitions/change-angle/definition.js +46 -0
  562. package/dist-esm/tools/definitions/change-angle/definition.js.map +1 -0
  563. package/dist-esm/tools/definitions/dance-montage/dances.js +86 -0
  564. package/dist-esm/tools/definitions/dance-montage/dances.js.map +1 -0
  565. package/dist-esm/tools/definitions/dance-montage/definition.js +42 -0
  566. package/dist-esm/tools/definitions/dance-montage/definition.js.map +1 -0
  567. package/dist-esm/tools/definitions/edit-image/definition.js +125 -0
  568. package/dist-esm/tools/definitions/edit-image/definition.js.map +1 -0
  569. package/dist-esm/tools/definitions/extend-video/definition.js +48 -0
  570. package/dist-esm/tools/definitions/extend-video/definition.js.map +1 -0
  571. package/dist-esm/tools/definitions/generate-image/definition.js +104 -0
  572. package/dist-esm/tools/definitions/generate-image/definition.js.map +1 -0
  573. package/dist-esm/tools/definitions/generate-music/definition.js +72 -0
  574. package/dist-esm/tools/definitions/generate-music/definition.js.map +1 -0
  575. package/dist-esm/tools/definitions/generate-video/definition.js +117 -0
  576. package/dist-esm/tools/definitions/generate-video/definition.js.map +1 -0
  577. package/dist-esm/tools/definitions/index.js +41 -0
  578. package/dist-esm/tools/definitions/index.js.map +1 -0
  579. package/dist-esm/tools/definitions/orbit-video/definition.js +100 -0
  580. package/dist-esm/tools/definitions/orbit-video/definition.js.map +1 -0
  581. package/dist-esm/tools/definitions/overlay-video/definition.js +139 -0
  582. package/dist-esm/tools/definitions/overlay-video/definition.js.map +1 -0
  583. package/dist-esm/tools/definitions/refine-result/definition.js +53 -0
  584. package/dist-esm/tools/definitions/refine-result/definition.js.map +1 -0
  585. package/dist-esm/tools/definitions/replace-video-segment/definition.js +62 -0
  586. package/dist-esm/tools/definitions/replace-video-segment/definition.js.map +1 -0
  587. package/dist-esm/tools/definitions/restore-photo/definition.js +55 -0
  588. package/dist-esm/tools/definitions/restore-photo/definition.js.map +1 -0
  589. package/dist-esm/tools/definitions/sound-to-video/definition.js +88 -0
  590. package/dist-esm/tools/definitions/sound-to-video/definition.js.map +1 -0
  591. package/dist-esm/tools/definitions/stitch-video/definition.js +86 -0
  592. package/dist-esm/tools/definitions/stitch-video/definition.js.map +1 -0
  593. package/dist-esm/tools/definitions/types.js +2 -0
  594. package/dist-esm/tools/definitions/types.js.map +1 -0
  595. package/dist-esm/tools/definitions/video-to-video/definition.js +98 -0
  596. package/dist-esm/tools/definitions/video-to-video/definition.js.map +1 -0
  597. package/dist-esm/tools/index.js +15 -0
  598. package/dist-esm/tools/index.js.map +1 -0
  599. package/dist-esm/tools/normalizeArgs.js +37 -0
  600. package/dist-esm/tools/normalizeArgs.js.map +1 -0
  601. package/dist-esm/tools/result.js +31 -0
  602. package/dist-esm/tools/result.js.map +1 -0
  603. package/dist-esm/tools/shared/downloadFilename.js +147 -0
  604. package/dist-esm/tools/shared/downloadFilename.js.map +1 -0
  605. package/dist-esm/tools/shared/errorClassification.js +74 -0
  606. package/dist-esm/tools/shared/errorClassification.js.map +1 -0
  607. package/dist-esm/tools/shared/imageEncoding.js +8 -0
  608. package/dist-esm/tools/shared/imageEncoding.js.map +1 -0
  609. package/dist-esm/tools/shared/llmHelpers.js +137 -0
  610. package/dist-esm/tools/shared/llmHelpers.js.map +1 -0
  611. package/dist-esm/tools/shared/modelRegistry.js +91 -0
  612. package/dist-esm/tools/shared/modelRegistry.js.map +1 -0
  613. package/dist-esm/tools/shared/policyChecks.js +73 -0
  614. package/dist-esm/tools/shared/policyChecks.js.map +1 -0
  615. package/dist-esm/tools/shared/promptRefinementCache.js +70 -0
  616. package/dist-esm/tools/shared/promptRefinementCache.js.map +1 -0
  617. package/dist-esm/tools/shared/promptSanitizer.js +70 -0
  618. package/dist-esm/tools/shared/promptSanitizer.js.map +1 -0
  619. package/dist-esm/tools/shared/seedancePolicyErrors.js +232 -0
  620. package/dist-esm/tools/shared/seedancePolicyErrors.js.map +1 -0
  621. package/dist-esm/tools/shared/slotFailureSummary.js +60 -0
  622. package/dist-esm/tools/shared/slotFailureSummary.js.map +1 -0
  623. package/dist-esm/tools/shared/visionDescriptionCache.js +29 -0
  624. package/dist-esm/tools/shared/visionDescriptionCache.js.map +1 -0
  625. package/dist-esm/types/index.js +31 -0
  626. package/dist-esm/types/index.js.map +1 -0
  627. package/dist-esm/utils/errors.js +86 -0
  628. package/dist-esm/utils/errors.js.map +1 -0
  629. package/dist-esm/utils/helpers.js +419 -0
  630. package/dist-esm/utils/helpers.js.map +1 -0
  631. package/dist-esm/workflows/bindings.js +182 -0
  632. package/dist-esm/workflows/bindings.js.map +1 -0
  633. package/dist-esm/workflows/executor-ports.js +2 -0
  634. package/dist-esm/workflows/executor-ports.js.map +1 -0
  635. package/dist-esm/workflows/executor.js +522 -0
  636. package/dist-esm/workflows/executor.js.map +1 -0
  637. package/dist-esm/workflows/index.js +7 -0
  638. package/dist-esm/workflows/index.js.map +1 -0
  639. package/dist-esm/workflows/summarize.js +51 -0
  640. package/dist-esm/workflows/summarize.js.map +1 -0
  641. package/dist-esm/workflows/types.js +2 -0
  642. package/dist-esm/workflows/types.js.map +1 -0
  643. package/dist-esm/workflows/validation.js +330 -0
  644. package/dist-esm/workflows/validation.js.map +1 -0
  645. package/media/index.d.ts +1 -0
  646. package/media/index.js +2 -0
  647. package/package.json +134 -0
  648. package/public-skill-runtime/index.d.ts +1 -0
  649. package/public-skill-runtime/index.js +2 -0
  650. package/replay/index.d.ts +1 -0
  651. package/replay/index.js +2 -0
  652. package/runtime/index.d.ts +1 -0
  653. package/runtime/index.js +2 -0
  654. package/skills/asset_reference_management/index.d.ts +1 -0
  655. package/skills/asset_reference_management/index.js +2 -0
  656. package/tools/index.d.ts +1 -0
  657. package/tools/index.js +2 -0
  658. package/workflows/index.d.ts +1 -0
  659. package/workflows/index.js +2 -0
@@ -0,0 +1,1173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PHASE_5_PROMPT_CONTRACTS = void 0;
4
+ exports.populateContractsPromptContracts = populateContractsPromptContracts;
5
+ const ORBIT_VIDEO_CONTRACT = {
6
+ contractId: 'orbit_video_v1',
7
+ version: '1.0.0',
8
+ toolName: 'orbit_video',
9
+ baseDescription: [
10
+ 'orbit_video is a self-contained pipeline that handles angle generation, video transitions,',
11
+ 'and stitching internally. If the user uploaded an image, call orbit_video directly — it uses',
12
+ 'the upload as the front view. If no image exists yet, generate ONE front-view image first,',
13
+ 'then call orbit_video. Never pre-generate multiple angles or variations for orbit_video.',
14
+ '',
15
+ 'ORBIT DIALOGUE: When the user wants spoken dialogue in an orbit video, ALWAYS use the',
16
+ 'dialogue parameter (NOT prompt). Dialogue goes in ONLY the specified segment — put',
17
+ 'motion/foley in prompt. If the user says "only in the first segment" or "just at the start",',
18
+ 'set dialogueSegment=0 (default). Never put dialogue text in the prompt parameter — it will',
19
+ 'be duplicated across all segments.',
20
+ '',
21
+ 'ORBIT ANGLES: Do NOT send the angles parameter for standard 360° orbits — omit it entirely.',
22
+ 'The default (right side view, back view, left side view at 90° increments) is correct for all',
23
+ 'normal orbit requests. Only send angles when the user explicitly asks for specific azimuth',
24
+ 'positions (e.g. "show me from the front-right and back-left only") or a partial orbit.',
25
+ '',
26
+ 'ORBIT DIALOGUE UPDATE: For dialogue in multiple/every orbit segment, before every 90-degree',
27
+ 'turn, or with per-turn sequence numbers, use the dialogues array instead of the single dialogue',
28
+ 'parameter. Default 360-degree orbit has 4 transitions, so provide 4 short lines in order; leave',
29
+ 'prompt for subject, action, ambient audio, and foley only. Preserve the real names from the',
30
+ 'request/prior result; never invent placeholder speaker tags. For a couple/persona request',
31
+ 'phrased as "us", "we", or "my wife and I", each per-turn line should make the named people',
32
+ 'speak together. When the user picks a generated image by 1-based number ("number 3",',
33
+ '"use #3"), pass sourceImageIndex as that number minus one (number 3 -> sourceImageIndex=2)',
34
+ 'instead of omitting it.',
35
+ ].join('\n'),
36
+ parameterDocs: {
37
+ dialogue: 'Spoken dialogue for the first/default orbit segment. Do NOT put dialogue in prompt — it repeats across all segments.',
38
+ dialogues: 'Per-segment dialogue lines array. Use for multi-segment dialogue (4 lines for full 360° orbit).',
39
+ dialogueSegment: 'Which orbit segment gets the dialogue (0-based). Default 0 = first segment.',
40
+ angles: 'Omit for standard 360° orbits. Only set for explicit azimuth positions or partial orbits.',
41
+ sourceImageIndex: 'Use uploaded image if present. If user picks by 1-based number, subtract 1.',
42
+ },
43
+ };
44
+ const ANIMATE_PHOTO_CONTRACT = {
45
+ contractId: 'animate_photo_v1',
46
+ version: '1.0.0',
47
+ toolName: 'animate_photo',
48
+ baseDescription: [
49
+ 'animate_photo produces video from one or more source images using LTX 2.3.',
50
+ '',
51
+ 'VIDEO PROMPT QUOTING: In video prompts, ONLY use double quotes for spoken dialogue.',
52
+ 'Speaker tags are allowed outside the quotes for screenplay-style dialogue, e.g.',
53
+ 'CHARACTER: "We made it." Never put on-screen text, overlay text, titles, captions, signs,',
54
+ 'watermarks, or any visual text in quotes — describe them without quotes (e.g. bold white text',
55
+ 'reading CONGRATULATIONS overlays the lower third). Quotes signal speech to the model;',
56
+ 'quoting non-speech text confuses audio generation.',
57
+ '',
58
+ 'DIALOGUE DURATION: Spoken dialogue in video prompts must fit the clip duration. Estimate',
59
+ 'at 2.5 words per second for natural cinematic delivery, plus ~1 second per acting beat',
60
+ '(pauses, gestures, glances between lines). If the user did NOT explicitly request a specific',
61
+ 'duration (using default 5s), extend the duration to fit the dialogue (max 20s). If the user',
62
+ 'explicitly requested a specific duration, condense the dialogue to fit while preserving meaning.',
63
+ 'Always check: total dialogue words ÷ 2.5 + beat count ≤ clip duration.',
64
+ '',
65
+ 'LATEST GENERATED IMAGE FOLLOW-UP: When the newest user turn asks to animate, make a video,',
66
+ 'or make a clip from a generated image/result (for example "the apple", "this one",',
67
+ '"the latest image"), use animate_photo with that latest generated image. Do not inherit an',
68
+ 'older Seedance model, resolution, or duration from an unrelated prior turn unless the newest',
69
+ 'user turn explicitly says Seedance or confirms an immediately suggested Seedance video stage.',
70
+ 'LTX supports exact 2-20s durations, so honor requests like 3s exactly.',
71
+ '',
72
+ 'WORD BUDGET PER CLIP: The handler REJECTS clips whose spoken dialogue exceeds the budget',
73
+ '— there is NO auto-trim, so plan dialogue lengths up-front. Hard maximum is 3.75 spoken',
74
+ 'words per second. Ceilings: 5s = 18 words, 6s = 22 words, 8s = 30 words, 10s = 37 words,',
75
+ '15s = 56 words, 20s = 75 words. Aim below these ceilings. If a scene\'s dialogue won\'t fit,',
76
+ 'tighten the lines, raise the per-clip duration, or split into two segments — do NOT submit',
77
+ 'and hope it works. Spoken words inside double quotes count toward the budget; speaker tags',
78
+ 'and visual/action prose are free.',
79
+ '',
80
+ 'BATCH VIDEO PER-CLIP DURATION: For a multi-segment animate_photo batch',
81
+ '(sourceImageIndices + prompts) when the user states a TOTAL video length but NO per-clip',
82
+ 'length, target 15 seconds per clip when dialogue is involved, and pass that duration',
83
+ 'explicitly. Example: 60s total → 4 segments × 15s, NOT 6×10s or 12×5s. There is NO 3-clip',
84
+ 'batch cap: sourceImageIndices supports up to 16 clips, so never split one planned batch into',
85
+ '"first 3" and "remaining clips" calls. Do NOT split a planned 15s dialogue scene into multiple',
86
+ 'shorter clips just because a retry complains about word budget; keep duration=15 and tighten',
87
+ 'the line. Use 5s clips only for single short motion beats or one very short spoken phrase.',
88
+ 'If the user explicitly specifies a per-clip duration, honor that instead.',
89
+ '',
90
+ 'N-VERSIONS-OF-A-VIDEO PATTERN: NEVER call animate_photo N times sequentially — ALWAYS',
91
+ 'use sourceImageIndices in ONE call so all N projects run in parallel. Two flavors:',
92
+ '(A) SHARED CONTENT — one edit_image/generate_image call with numberOfVariations=N + {|}',
93
+ 'Dynamic Prompts to make N distinct source images, then ONE animate_photo call with',
94
+ 'sourceImageIndices=[start..start+N-1] and a single shared prompt.',
95
+ '(B) PER-CLIP CONTENT — when each clip has DIFFERENT dialogue, jokes, narration, or motion,',
96
+ 'pass BOTH sourceImageIndices AND prompts (array of N strings, one per clip) in the SAME',
97
+ 'single animate_photo call. The top-level prompt is still required — pass a brief batch summary.',
98
+ '',
99
+ 'CRITICAL: sourceImageIndices values MUST be read from the latest edit_image/generate_image',
100
+ 'tool result\'s startIndex field — if startIndex=3 and 4 images were generated, pass',
101
+ 'sourceImageIndices=[3,4,5,6], NOT [0,1,2,3]. Negative indices refer to uploaded images:',
102
+ '-1 first upload, -2 second upload, -3 third upload. Use repeated -1 entries only when',
103
+ 'intentionally reusing the primary uploaded image. When prompts is supplied, prompts.length',
104
+ 'MUST equal sourceImageIndices.length.',
105
+ '',
106
+ 'SEEDANCE UPLOADED STORYBOARD DEFAULT: If the user uploaded a storyboard, shot sheet,',
107
+ 'or visual trailer board and asks to make a trailer/video/movie/clip from it, do NOT use',
108
+ 'animate_photo on the board image and do NOT split it into four LTX clips. Use generate_video',
109
+ 'with Seedance referenceImageIndices for one continuous clip unless the user explicitly asks',
110
+ 'for separate LTX clips or first-frame/last-frame animation.',
111
+ '',
112
+ 'SCREENPLAY / STORYBOARD ANIMATE RULE: For full storyboard projects, use one',
113
+ 'animate_photo batch with sourceImageIndices + prompts so each clip keeps its own exact',
114
+ 'scene text, stable cast anchors, and screenplay-style speaker-tagged dialogue, and all video',
115
+ 'clips render in parallel. Every speaking clip\'s video prompt must include that clip\'s actual',
116
+ 'quoted dialogue, not placeholders such as "while speaking", "dialogue begins", "explaining",',
117
+ 'or "final line lands". If each generated scene keyframe should be both the first and last frame',
118
+ 'of its own stitched segment, call animate_photo with sourceImageIndices=[start..end],',
119
+ 'frameRole="both", prompts=[...], and OMIT endImageIndex/endImageIndices so the handler',
120
+ 'uses each source as its own end frame.',
121
+ '',
122
+ 'UPLOADED REFERENCE LOOPED SKITS: When the user supplies one uploaded reference image and',
123
+ 'asks for several scripted/storyboard/dialogue segments to reuse that same image as BOTH the',
124
+ 'first frame and last frame of each segment before stitching, do it in ONE animate_photo call:',
125
+ 'sourceImageIndices=[-1,-1,...], frameRole="both", endImageIndex=-1 (or matching',
126
+ 'endImageIndices=[-1,-1,...]), duration equal to the requested per-segment duration, and',
127
+ 'prompts=[one full scene prompt per segment]. Each prompt must preserve the exact screenplay',
128
+ 'speaker tags and quoted dialogue from that scene, e.g. HOST: "..." GUEST: "...". Do not',
129
+ 'drop speaker tags, convert them to generic narration, omit the last-frame contract, analyze',
130
+ 'the image first, generate new keyframes first, or split the batch into serial calls. After',
131
+ 'the single animate_photo batch completes, call stitch_video with the returned video indices.',
132
+ '',
133
+ 'For adjacent transition chains: N images create N-1 clips — call animate_photo with',
134
+ 'frameRole="both", sourceImageIndices=[start..end-1], endImageIndices=[start+1..end],',
135
+ 'prompts=[one transition prompt per adjacent pair], then stitch_video. If 5 uploaded images',
136
+ 'are the keyframe sequence, use sourceImageIndices=[-1,-2,-3,-4],',
137
+ 'endImageIndices=[-2,-3,-4,-5], frameRole="both", prompts length 4, then stitch_video.',
138
+ 'Do NOT set endImageIndex=-1 in generated-keyframe patterns — that means every clip ends',
139
+ 'on the primary uploaded image.',
140
+ '',
141
+ 'UPLOADED FIRST-FRAME/LAST-FRAME TRANSITION CHAINS: If the user uploads multiple images',
142
+ 'and asks for a video that transitions from image to image, changes country/version every',
143
+ 'N seconds, or says to use first-frame/last-frame for each pair, call animate_photo directly.',
144
+ 'Do not call edit_image, generate_image, analyze_image, or map_assets_for_model first — the',
145
+ 'uploaded images are already the keyframes. For N uploaded images, create N-1 adjacent clips',
146
+ 'unless the user explicitly asks for a loop back to the first image. Use per-clip duration',
147
+ 'from "every N seconds" when present; otherwise divide the requested total by the number of',
148
+ 'adjacent clips. After animate_photo returns the batch videos, always call stitch_video with',
149
+ 'those video indices before finalizing.',
150
+ ].join('\n'),
151
+ parameterDocs: {
152
+ sourceImageIndices: 'Batch source image indices. Read startIndex from prior generate_image/edit_image result. Negative = uploaded images (-1 = first upload).',
153
+ prompts: 'Per-clip prompt array. Length MUST equal sourceImageIndices.length when both are set.',
154
+ duration: 'Per-clip duration in seconds. Target 15s when dialogue is involved and total length is given without per-clip spec.',
155
+ frameRole: 'Set to "both" for first+last frame transitions using sourceImageIndices + endImageIndices.',
156
+ endImageIndices: 'End frames for adjacent-chain transitions. N images → N-1 clips.',
157
+ },
158
+ };
159
+ const GENERATE_VIDEO_CONTRACT = {
160
+ contractId: 'generate_video_v1',
161
+ version: '1.1.0',
162
+ toolName: 'generate_video',
163
+ baseDescription: [
164
+ 'generate_video produces text-to-video clips and Seedance multimodal reference videos.',
165
+ 'Use for text-only video generation with no source image input. For Seedance, also use this',
166
+ 'tool when uploaded/generated images, videos, or audio are loose references. Use animate_photo',
167
+ 'only when a non-Seedance source image must become the first frame of an LTX/WAN animation.',
168
+ '',
169
+ 'SEEDANCE UPLOADED STORYBOARD DEFAULT: When the user uploads a storyboard, shot sheet,',
170
+ 'mood board, or trailer concept image and asks to make a movie trailer/video/clip from it,',
171
+ 'default to one Seedance generate_video call with referenceImageIndices=[-1]. Do not first',
172
+ 'extract panels with edit_image, do not generate replacement keyframes, and do not make four',
173
+ 'separate LTX animate_photo clips unless the user explicitly asks for separate clips or LTX.',
174
+ 'Use seedance2 when premium Spark access is available; if premium access is unavailable,',
175
+ 'explain the limitation or use the best non-Seedance fallback the user accepts.',
176
+ '',
177
+ 'STORYTELLING / COMMERCIAL / TRAILER PROMPTS: For creative video requests, turn the brief',
178
+ 'into timed, causally connected visual beats before writing the final prompt. Default social',
179
+ 'video is 15s 9:16 with a strong first 1-2s, visible escalation, payoff, and brand/CTA/final',
180
+ 'image. Commercials should show audience desire/problem, transformation, proof/benefit, and',
181
+ 'CTA. Trailers should follow hook → world → disruption → escalation → reveal → title/CTA.',
182
+ 'Every beat must be generatable: subject, setting, action, camera, lighting, audio, and text',
183
+ 'role where relevant. Avoid vague "cinematic" filler, feature dumps, and beautiful images with',
184
+ 'no visible change.',
185
+ '',
186
+ 'VIDEO PROMPT QUOTING: ONLY use double quotes for spoken dialogue in video prompts. Never',
187
+ 'quote on-screen text, titles, captions, or visual text elements — describe them without',
188
+ 'quotes. Quotes signal speech to the model and confuse audio generation.',
189
+ '',
190
+ 'STORYBOARD TEXT: Structural headings, section numbers, slide titles, panel titles, and',
191
+ 'captions in storyboard references may become short audio-only narration/VO or',
192
+ 'key-message beats, but they are not subtitles, title cards, lower thirds, or visible',
193
+ 'overlays unless the user explicitly asks for visible text, on-screen text, a title',
194
+ 'card, subtitle, lower third, signage, or CTA. Keep narration as separate brief phrases',
195
+ 'with pauses; do not concatenate storyboard labels into run-on voiceover.',
196
+ '',
197
+ 'DIALOGUE DURATION: Spoken dialogue must fit the clip. Estimate 2.5 words per second',
198
+ 'natural delivery plus ~1s per acting beat. Hard maximum 3.75 words/second.',
199
+ 'Check: dialogue words ÷ 2.5 + beats ≤ duration. Do not submit oversized dialogue.',
200
+ '',
201
+ 'LATEST USER DURATION WINS: In follow-up turns, use the newest duration the user states,',
202
+ 'even if a previous assistant message mentioned a longer script/runtime. For example, if',
203
+ 'history says "the full script is 66 seconds" but the user now says "do a 30 second version",',
204
+ 'generate the 30 second version. Do not ask a clarification question just because history',
205
+ 'contains another duration; treat the latest user request as the override.',
206
+ '',
207
+ 'SEEDANCE SHORT-DURATION LIMIT: Seedance supports 4-15s clips. If the user explicitly asks',
208
+ 'for Seedance below 4s, do not silently round up. Ask whether they prefer a 4s Seedance clip',
209
+ 'or an exact-duration LTX clip. If the user did not explicitly ask for Seedance, choose the',
210
+ 'model/tool that can satisfy the requested duration exactly.',
211
+ ].join('\n'),
212
+ parameterDocs: {
213
+ prompt: 'Video prompt. Use double quotes ONLY for spoken dialogue. Describe visual text without quotes.',
214
+ duration: 'Clip duration in seconds. Plan dialogue word count against the 3.75 words/second ceiling.',
215
+ },
216
+ };
217
+ const EDIT_IMAGE_CONTRACT = {
218
+ contractId: 'edit_image_v1',
219
+ version: '1.0.0',
220
+ toolName: 'edit_image',
221
+ baseDescription: [
222
+ 'edit_image applies instruction-based edits to uploaded or generated images. Use when',
223
+ 'uploaded or reference images must guide identity or likeness.',
224
+ '',
225
+ 'Image-to-Image prompt order: [IDENTITY LOCK] → [REQUESTED EDIT] → [REFERENCE ROLE',
226
+ 'MAPPING] → [POSE/COMPOSITION] → [STYLE] → [LIGHTING/REALISM] → [PRESERVE ALL',
227
+ 'UNMENTIONED DETAILS]. GOLDEN RULE: When editing a person, always state which image owns',
228
+ 'identity — never leave identity ambiguous. Describe only the DELTA — what changes. Don\'t',
229
+ 'rewrite the entire image; the base image already contains most of the truth. Default to minimal',
230
+ 'change. For multi-image edits, assign ONE primary role per reference image (identity, pose,',
231
+ 'outfit, style, environment). Never let a style/pose/clothing reference silently override the face.',
232
+ 'Use positive constraints — "preserve exact facial likeness, face structure, eye shape, nose',
233
+ 'shape, mouth shape, jawline, skin tone, hairline, apparent age, and overall recognizability"',
234
+ '— not vague negatives like "don\'t mess up the face".',
235
+ '',
236
+ 'UPLOADED IMAGE VARIANT SETS: When the user supplies a photo/portrait/reference image and',
237
+ 'asks for N distinct generated images deriving from that source while changing paired',
238
+ 'per-output details, call edit_image exactly once with sourceImageIndex=-1,',
239
+ 'numberOfVariations=N, and ONE Dynamic Prompt branch with N complete options. Each option',
240
+ 'must be a full concrete image prompt for one output, including the uploaded subject/reference',
241
+ 'anchor, requested pose or placement preservation, the specific changed appearance/style/role,',
242
+ 'clothing or surface details when relevant, setting/background, and any requested label text or',
243
+ 'visual symbol. If one option is a remade original/preserved source and the rest are themed',
244
+ 'variants, the original option must explicitly say to preserve the original clothing/wardrobe/outfit',
245
+ 'and background/setting, plus any requested added label, flag, logo, symbol, or prop.',
246
+ 'Do not call generate_image, analyze_image, or multiple serial edit_image calls first.',
247
+ '',
248
+ 'SELECTION-GATED IMAGE STAGES: If the user asks for N image options and says they will pick',
249
+ 'one before a later dance/video/animation, call edit_image exactly once with numberOfVariations=N',
250
+ 'and one Dynamic Prompt branch. After images are created, stop and ask the user to choose;',
251
+ 'do not call dance_montage, animate_photo, or generate_video until they select.',
252
+ '',
253
+ 'MULTI-PERSONA (COMBINED): When multiple personas must appear in the SAME scene, make',
254
+ 'ONE edit_image call with ALL persona faces in one prompt and DO NOT pass personaName.',
255
+ 'Per-persona splits (one call each with personaName set) are RARE — only when the user',
256
+ 'explicitly asks for solo images of each person individually.',
257
+ '',
258
+ 'STORYBOARD IMAGE BATCH RULE: When rendering scene keyframes from a screenplay/storyboard,',
259
+ 'numberOfVariations is only the count; the prompt MUST be one Dynamic Prompt branch with one',
260
+ 'full keyframe prompt per scene:',
261
+ '{scene 1 full keyframe prompt|scene 2 full keyframe prompt|...|scene N full keyframe prompt}.',
262
+ 'NEVER set numberOfVariations=N with only the first scene prompt — that creates N versions of',
263
+ 'scene 1. For full project requests, one edit_image batch for all scene keyframes, then one',
264
+ 'animate_photo batch for all video clips in parallel.',
265
+ 'Exception: if the storyboard/shot sheet is already uploaded and the user asks to make a',
266
+ 'trailer/video/movie/clip from that uploaded board, do not extract panels or redraw keyframes.',
267
+ 'Use generate_video with Seedance references for one continuous clip unless the user explicitly',
268
+ 'asks for separate image keyframes or a storyboard sheet output.',
269
+ '',
270
+ 'DIRECT UPLOADED GPT IMAGE 2 STORYBOARD SHEETS: If the user uploaded reference images and',
271
+ 'asks for one finished GPT Image 2 storyboard/keyframe sheet now, call edit_image directly',
272
+ 'with sourceImageIndex=-1, model="gpt-image-2", numberOfVariations=1, and the requested',
273
+ 'canvas/aspect settings. If the user did not explicitly specify a storyboard page/canvas/sheet',
274
+ 'shape, default the GPT Image 2 storyboard sheet pixel dimensions to a balanced grid that hosts',
275
+ 'the target cell aspect ratio natively (e.g., 12 cells with 9:16 portrait video target -> ~3:4',
276
+ 'portrait sheet around 1728x2304; 12 cells with 16:9 landscape video target -> ~4:3 landscape',
277
+ 'sheet around 2304x1728; 6 cells with 9:16 target -> ~27:32 portrait sheet around 1840x2176). Do',
278
+ 'NOT default the sheet to 2560x1440 landscape when cells are portrait — a landscape sheet with',
279
+ 'a portrait-cell grid physically forces cells to ~4:3 landscape and the model will not render',
280
+ '9:16 portrait rectangles inside it. Keep individual scene-cell/frame areas at the target video',
281
+ 'aspect ratio. Do not call map_assets_for_model, analyze_image, generate_image, or a separate',
282
+ 'planning tool first. The uploaded files are already available as references; describe their',
283
+ 'roles plainly in the edit_image prompt and generate the sheet in that call.',
284
+ '',
285
+ 'DO NOT USE edit_image FOR UPLOADED REFERENCE LOOPED VIDEO SEGMENTS: If the user says the',
286
+ 'same uploaded image/reference should be reused as the first frame and last frame of each',
287
+ 'scripted segment/scene/clip before stitching, they are explicitly asking to animate the',
288
+ 'uploaded image, not to generate new storyboard keyframes. Do not call edit_image for that',
289
+ 'request. Call animate_photo once with repeated uploaded source indices and per-scene prompts.',
290
+ ].join('\n'),
291
+ parameterDocs: {
292
+ sourceImageIndex: 'Index of uploaded/generated image. Use -1 for the first uploaded image.',
293
+ numberOfVariations: 'Number of output variants. When > 1, use a Dynamic Prompt branch with one complete prompt per output.',
294
+ prompt: 'Edit instruction. Start with identity lock (who owns the face), then describe only the delta.',
295
+ },
296
+ };
297
+ const GENERATE_IMAGE_CONTRACT = {
298
+ contractId: 'generate_image_v1',
299
+ version: '1.1.0',
300
+ toolName: 'generate_image',
301
+ baseDescription: [
302
+ 'generate_image creates images from text descriptions. Use for text-only image generation;',
303
+ 'use edit_image when uploaded or reference images must guide identity/likeness.',
304
+ 'Exception: Z-image and Z-image Turbo image-to-image/enhancement requests use generate_image',
305
+ 'with model="z-turbo" or model="z-image", sourceImageIndex=-1, and starting_image_strength;',
306
+ 'do not route explicit Z-image Turbo uploaded-image enhancement to edit_image because',
307
+ 'edit_image does not expose Z-image models.',
308
+ '',
309
+ 'FLUX.2 PROMPT ORDER: [SUBJECT] → [ATTRIBUTES] → [ACTION/POSE] → [CAMERA/FRAMING]',
310
+ '→ [ENVIRONMENT] → [LIGHTING] → [STYLE/MEDIUM] → [MATERIALS/TEXTURES] →',
311
+ '[SECONDARY DETAILS]. Always start with the main subject, never mood or atmosphere.',
312
+ 'Use concrete nouns and observable adjectives — "soft overcast daylight" not "nice lighting".',
313
+ 'Good defaults when user is underspecified: medium shot for portraits, wide shot for',
314
+ 'environments, eye-level angle, soft natural light for realism.',
315
+ '',
316
+ 'DYNAMIC PROMPTS: When numberOfVariations > 1, use Dynamic Prompt syntax to make each',
317
+ 'variation meaningfully different — not just seed-different. Syntax: {a|b|c} cycles',
318
+ 'sequentially, {@a|b|c} picks randomly, {~a|b} paired cycling across groups. Rules: (1) Vary',
319
+ 'ONLY what the user left unspecified — lock in everything they specified. (2) Match option',
320
+ 'count to numberOfVariations so every result is unique. (3) Briefly tell the user what you\'re',
321
+ 'varying — never show raw {|} syntax. (4) Skip when: user wants consistency, prompt is fully',
322
+ 'specified, user typed their own {|} syntax, or iterating on a specific result. (5) NEVER put',
323
+ 'the count or the word "versions"/"variations" inside the prompt — the prompt always describes',
324
+ 'a single image. The multiplicity comes ONLY from numberOfVariations + the {|} syntax.',
325
+ 'LINKED VARIANTS: when multiple attributes must stay paired per result, use ONE top-level',
326
+ 'Dynamic Prompt branch with one complete self-contained prompt per output. Do NOT split',
327
+ 'linked fields into separate Dynamic Prompt groups.',
328
+ '',
329
+ 'SELECTION-GATED IMAGE STAGES: If the user asks for N image options and says they will pick',
330
+ 'one before a later dance/video/animation, call generate_image once with numberOfVariations=N.',
331
+ 'After images are created, stop and ask the user to choose; do not call dance_montage,',
332
+ 'animate_photo, or generate_video until they select.',
333
+ '',
334
+ 'IMAGE→VIDEO DIMENSION RULE: When generating an image that will feed into a video tool',
335
+ '(animate_photo, sound_to_video, etc.), the image MUST be generated at the SAME aspect',
336
+ 'ratio and dimensions as the target video. Default video aspect ratio is 16:9 landscape —',
337
+ 'pass aspectRatio="16:9" (or the user\'s specified/reference ratio) so the source image',
338
+ 'matches the video output. Never generate a square image for a widescreen video. Exception:',
339
+ 'a composite GPT Image 2 storyboard/keyframe sheet for a later Seedance video is a board,',
340
+ 'not a single source frame; unless the user explicitly specifies a storyboard page/canvas/sheet',
341
+ 'shape, default the sheet image dimensions to a balanced grid that hosts the target',
342
+ 'scene-cell/frame aspect natively (portrait video target -> portrait or square sheet whose',
343
+ 'columns x rows grid produces ~9:16 cells; landscape video target -> landscape sheet whose',
344
+ 'rows x columns grid produces ~16:9 cells). Each scene-cell/frame area preserves the target',
345
+ 'video aspect ratio.',
346
+ '',
347
+ 'STORYBOARD IMAGE BATCH RULE: When rendering scene keyframes from a screenplay/storyboard,',
348
+ 'numberOfVariations is only the count; the prompt MUST be one Dynamic Prompt branch with one',
349
+ 'full keyframe prompt per scene:',
350
+ '{scene 1 full keyframe prompt|scene 2 full keyframe prompt|...|scene N full keyframe prompt}.',
351
+ 'NEVER set numberOfVariations=N with only the first scene prompt — that creates N versions of',
352
+ 'scene 1. For full project requests, one generate_image batch for all scene keyframes, then',
353
+ 'one animate_photo batch for all video clips in parallel.',
354
+ '',
355
+ 'STORYTELLING / BRAND / SOCIAL IMAGE PROMPTS: If generating a storyboard, ad concept,',
356
+ 'trailer sheet, meme, creator post, or provocative social concept, make the first frame or',
357
+ 'panel immediately legible. Preserve the user\'s requested tone and audience. Use concrete',
358
+ 'composition, persona, product/brand role, caption placement, readable required text, and a',
359
+ 'clear visual transformation or punchline. For provocative adult social content, keep subjects',
360
+ 'clearly adult and consensual, PG-13/non-explicit, and avoid minor-coded styling or school-coded',
361
+ 'settings while still optimizing visual magnet, persona, caption bait, and replay/comment value.',
362
+ '',
363
+ 'GPT IMAGE 2 STORYBOARD SHEET → SEEDANCE AUTO-PROCEED: If the user asks to run the whole',
364
+ 'GPT Image 2 storyboard/keyframe sheet plus Seedance workflow without approval, the FIRST',
365
+ 'generate_image call must create ONE composite storyboard/keyframe sheet, not loose concept',
366
+ 'art and not separate keyframes. Use model="gpt-image-2", numberOfVariations=1, and a',
367
+ 'compiled storyboard prompt that literally includes: "Create exactly N sequential video',
368
+ 'storyboard frames as one composite storyboard image", "Target final video aspect ratio: X",',
369
+ 'a `SCENES:` section, and exactly N concrete scene entries named `SCENE_01`, `SCENE_02`,',
370
+ 'etc. Each scene entry must include `Visual/Action:`, `Camera/Motion:`, `Dialogue/VO:`',
371
+ '(use `[no dialogue]` when silent), `Audio/SFX:`, and any reference/visible-text notes',
372
+ 'needed for that scene. Do not send only a source brief, storyboard concept, or generic',
373
+ 'layout instructions as the prompt; malformed compiled storyboard prompts are blocked by',
374
+ 'quality audit instead of being repaired at runtime. Unless the user explicitly specifies another',
375
+ 'storyboard page/canvas/sheet shape, default the GPT Image 2 storyboard sheet pixel dimensions',
376
+ 'to a balanced grid that hosts the target cell aspect natively: for a 9:16 portrait video,',
377
+ 'pick a portrait-leaning sheet whose columns x rows grid produces ~9:16 cells (e.g., 12 cells',
378
+ '-> ~3:4 sheet around 1728x2304, 6 cells -> ~27:32 around 1840x2176, 9 cells -> ~9:16 around',
379
+ '1504x2672); for a 16:9 landscape video, pick a landscape sheet whose rows x columns grid',
380
+ 'produces ~16:9 cells (e.g., 12 cells -> ~4:3 sheet around 2304x1728). Do not force landscape',
381
+ '2560x1440 when cells are portrait — a landscape sheet with a portrait-cell grid cannot host',
382
+ '9:16 cells without crushing them. Preserve the requested final video aspect ratio for every',
383
+ 'frame area. After',
384
+ 'that image completes, call generate_video once using the generated storyboard board as',
385
+ '@Image1/referenceImageIndices=[0], with skipPromptProcessing=false only when the user',
386
+ 'explicitly wants the storyboard text rewritten; otherwise preserve the compiled shot guide',
387
+ 'and use skipPromptProcessing=true, expandPrompt=false.',
388
+ '',
389
+ 'DO NOT USE generate_image FOR UPLOADED REFERENCE LOOPED VIDEO SEGMENTS: If the user says',
390
+ 'the same uploaded image/reference should be reused as the first frame and last frame of each',
391
+ 'scripted segment/scene/clip before stitching, they are explicitly asking to animate the',
392
+ 'uploaded image, not to generate new storyboard keyframes. Do not call generate_image for',
393
+ 'that request. Call animate_photo once with repeated uploaded source indices and per-scene',
394
+ 'prompts.',
395
+ '',
396
+ 'REUSING RESULTS: When the user asks to redo, retry, or revise (e.g., "try a new version",',
397
+ '"redo the video with X"), reuse the existing source images — do NOT regenerate them unless',
398
+ 'the user explicitly asks for new images or describes changes to the images themselves.',
399
+ 'Reference the existing result indices from the prior generation. If unsure whether the user',
400
+ 'wants new images, ask — don\'t regenerate by default.',
401
+ ].join('\n'),
402
+ parameterDocs: {
403
+ prompt: 'Text description. Follow FLUX.2 prompt order: subject first. Use Dynamic Prompt syntax when numberOfVariations > 1.',
404
+ numberOfVariations: 'Number of distinct outputs. Use Dynamic Prompt {|} syntax to vary one attribute per image. Never put the count in the prompt itself.',
405
+ aspectRatio: 'For ordinary images feeding a video tool, set to match the target video aspect ratio. For composite GPT Image 2 storyboard sheets, default the sheet pixel dimensions to a balanced grid that hosts the target cell aspect natively (portrait video target -> portrait/square sheet, landscape video target -> landscape sheet) unless the user explicitly specifies a storyboard page/canvas/sheet shape; keep the target video ratio inside each frame area.',
406
+ },
407
+ };
408
+ const EXTEND_VIDEO_CONTRACT = {
409
+ contractId: 'extend_video_v1',
410
+ version: '1.0.0',
411
+ toolName: 'extend_video',
412
+ baseDescription: [
413
+ 'Use extend_video when a video already exists in the session — whether previously rendered OR',
414
+ 'uploaded — and the user asks to make it longer, add a segment, or append a bumper, outro,',
415
+ 'intro, tag, or sting to the end (or start). Do NOT call generate_video, animate_photo, or build',
416
+ 'a new bumper from scratch via edit_image+animate_photo+stitch_video — those render fresh',
417
+ 'clips and either waste the previous render or ignore the uploaded base.',
418
+ '',
419
+ 'For uploaded base videos, set videoIndex to a negative number (-1 for first uploaded video).',
420
+ 'Set duration to the ADDITIONAL seconds (not the new total).',
421
+ '',
422
+ 'Trigger phrases: "make it longer", "extend the video", "add another N seconds", "continue the',
423
+ 'scene", "add a bumper/outro/intro/tag/sting to the end (or start)".',
424
+ '',
425
+ 'Both extend_video and replace_video_segment auto-detect the base video\'s model (Seedance',
426
+ 'source → Seedance continuation; LTX source → LTX continuation; Wan source → Wan continuation), so OMIT videoModel unless',
427
+ 'the user explicitly demands a different model. This applies regardless of whether the prior',
428
+ 'render came from generate_video, animate_photo, sound_to_video, or video_to_video.',
429
+ ].join('\n'),
430
+ parameterDocs: {
431
+ videoIndex: 'Index of the existing video. Use -1 for first uploaded video, non-negative for generated videos.',
432
+ duration: 'ADDITIONAL seconds to add — not the new total length.',
433
+ videoModel: 'Omit to auto-detect from source video. Only set if user explicitly requests a different model.',
434
+ },
435
+ };
436
+ const REPLACE_VIDEO_SEGMENT_CONTRACT = {
437
+ contractId: 'replace_video_segment_v1',
438
+ version: '1.0.0',
439
+ toolName: 'replace_video_segment',
440
+ baseDescription: [
441
+ 'Use replace_video_segment when the user wants to regenerate a specific time range of an',
442
+ 'existing video: "regenerate from Xs to Ys", "redo the last N seconds", "swap out the middle",',
443
+ '"fix the [start/middle/end] of the video", or "replace the [bumper/intro/outro/end card/',
444
+ 'tag/sting] at the [start/end] of the video". Use explicit startSeconds and endSeconds; use',
445
+ '-1 sentinels when exact base duration is unknown — the handler probes and resolves.',
446
+ '',
447
+ 'When the replacement is already another uploaded or generated video clip, still use',
448
+ 'replace_video_segment but pass replacementVideoIndex. Example: "splice video 2 into video 1',
449
+ 'at 5s" means videoIndex=-1, replacementVideoIndex=-2, startSeconds=5, endSeconds=5.',
450
+ 'Use endSeconds=startSeconds for insertion; use a wider endSeconds only when the user says to',
451
+ 'replace/remove that base-video range. Do not use stitch_video for "into the middle"/"insert"',
452
+ 'requests, because stitch_video only concatenates full clips end-to-end.',
453
+ '',
454
+ 'For time-sliced interleaving from existing videos — "alternate 1s from each video", "weave',
455
+ 'one-second clips from video 1 and video 2", "cut back and forth every N seconds" — do NOT',
456
+ 'use stitch_video and do NOT omit replacementVideoIndex. Start with the first requested video',
457
+ 'as the base, then call replace_video_segment once for each window that should come from the',
458
+ 'other video. Set replacementVideoIndex to that other existing video and set',
459
+ 'replacementStartSeconds/replacementEndSeconds to the next source slice from that',
460
+ 'replacement video. For ordinary',
461
+ 'alternation, preserve the base duration: set endSeconds=startSeconds+sliceDuration, not',
462
+ 'endSeconds=startSeconds insertion, unless the user explicitly asks to lengthen the output by',
463
+ 'inserting extra slices. Skip no-op windows that already come from the base video; only splice',
464
+ 'windows that should come from a different source. Example for two 10s uploads alternating every 1s starting with video',
465
+ '1: replace base windows 1..2, 3..4,',
466
+ '5..6, 7..8, and 9..10 with slices 0..1, 1..2, 2..3, 3..4, and 4..5 from video 2. After',
467
+ 'each successful splice, target the newest composite video index for the next splice.',
468
+ 'The -1 time sentinel applies only to base startSeconds/endSeconds when the base duration is',
469
+ 'unknown. Never use -1 for replacementStartSeconds or replacementEndSeconds; source windows',
470
+ 'must use concrete non-negative seconds. For uploaded/generated videos with duration metadata,',
471
+ 'use that known duration directly; do not call analyze_video just to learn the clip length for',
472
+ 'routine alternating slices. Do not add a final tail splice with an unknown source end — stop at',
473
+ 'the known clip duration or skip a no-op tail window.',
474
+ '',
475
+ 'Do NOT call generate_video or animate_photo to re-render an existing video just to change',
476
+ 'part of it (the bumper, the intro, the end card, a single scene, the last few seconds, etc.).',
477
+ 'Use replace_video_segment — it preserves the unchanged portion, keeps the original audio',
478
+ 'outside the replaced window, and costs far less.',
479
+ '',
480
+ 'Auto-detects the base video\'s model, so OMIT videoModel unless the user explicitly demands',
481
+ 'a different model. Short requested windows are supported by rendering with model-specific',
482
+ 'handles and trimming the rendered clip before splicing, so still pass the user\'s exact',
483
+ 'startSeconds/endSeconds.',
484
+ ].join('\n'),
485
+ parameterDocs: {
486
+ startSeconds: 'Start of segment to replace in seconds. Use -1 sentinel if exact base duration is unknown.',
487
+ endSeconds: 'End of segment to replace in seconds. Use the same value as startSeconds for insertion with replacementVideoIndex.',
488
+ replacementVideoIndex: 'Existing uploaded/generated replacement clip. Use negative uploaded-video indices, e.g. -2 for the second uploaded video.',
489
+ replacementStartSeconds: 'Optional start time inside replacementVideoIndex. Use with replacementEndSeconds for time-sliced interleaving. Must be concrete and >= 0; never use -1 here.',
490
+ replacementEndSeconds: 'Optional end time inside replacementVideoIndex. Must be concrete, >= 0, and greater than replacementStartSeconds; never use -1 here.',
491
+ videoModel: 'Omit to auto-detect from source. Only set if user explicitly requests a different model.',
492
+ },
493
+ };
494
+ const OVERLAY_VIDEO_CONTRACT = {
495
+ contractId: 'overlay_video_v1',
496
+ version: '1.0.0',
497
+ toolName: 'overlay_video',
498
+ baseDescription: [
499
+ 'Use overlay_video when the user wants to overlay/place/show a logo, text, caption, or',
500
+ 'watermark ON TOP OF existing video frames.',
501
+ '',
502
+ 'For uploaded base videos, set sourceVideoIndex=-1; for generated videos, use their',
503
+ 'non-negative video index. If the overlay should last only part of the video, set the overlay',
504
+ 'item\'s startSeconds/endSeconds (e.g. a 2s middle overlay on a 20s video: ~9s to ~11s).',
505
+ 'Negative startSeconds/endSeconds are relative to the end of the base video, so startSeconds=-2',
506
+ 'with omitted endSeconds means the last 2 seconds.',
507
+ '',
508
+ 'When the user asks to replace a video time window with an uploaded still image, screenshot,',
509
+ 'photo, frame, logo, or graphic, use an image overlay for that window with widthPct=100 and',
510
+ 'fit="cover"; do not regenerate the video segment.',
511
+ '',
512
+ 'Do NOT use overlay_video for intro/outro/bumper/end-card/start-card requests — those add or',
513
+ 'regenerate video time and should use extend_video or replace_video_segment. After a successful',
514
+ 'overlay_video call, finalize the turn; do not call overlay_video again just to tweak default',
515
+ 'size or placement unless the user asks.',
516
+ ].join('\n'),
517
+ parameterDocs: {
518
+ sourceVideoIndex: 'Use -1 for first uploaded video, non-negative index for generated videos.',
519
+ overlays: 'Use startSeconds/endSeconds for time windows. For still/screenshot replacement windows, use kind="image", widthPct=100, fit="cover".',
520
+ },
521
+ };
522
+ const STITCH_VIDEO_CONTRACT = {
523
+ contractId: 'stitch_video_v1',
524
+ version: '1.0.0',
525
+ toolName: 'stitch_video',
526
+ baseDescription: [
527
+ 'stitch_video joins multiple video clips into one. Reference generated videos by their',
528
+ '0-based video indices (from videoStartIndex in prior tool results). Reference uploaded',
529
+ 'videos with negative indices in current UI order: -1 = first uploaded video, -2 = second, etc.',
530
+ 'When the user asks to stitch these/all uploaded videos and does not name a different order,',
531
+ 'use the current UI order exactly: [-1,-2,...].',
532
+ 'If the user explicitly names a different playback order, preserve that requested order exactly;',
533
+ 'do not rewrite it back to UI order.',
534
+ '',
535
+ 'NEVER tell the user to "upload" a video that was already generated in this conversation —',
536
+ 'stitch_video can reference them directly by index.',
537
+ '',
538
+ 'When stitching results from a batch video tool, use ONLY the video indices actually returned',
539
+ 'by that tool. Do not infer the stitch list from the number of source images, keyframes, or',
540
+ 'storyboard panels. Example: if 5 uploaded keyframes create 4 adjacent animate_photo',
541
+ 'transition clips and the tool result returns videos at indices 0,1,2,3, call stitch_video',
542
+ 'with videoIndices=[0,1,2,3] — never include index 4 unless a fifth video was returned.',
543
+ '',
544
+ 'Do not use stitch_video for alternating/interleaved time slices such as "alternate',
545
+ '1s from each video"; stitch_video joins whole clips end-to-end, while interleaving existing',
546
+ 'video slices belongs to repeated replace_video_segment calls with replacementVideoIndex and',
547
+ 'replacementStartSeconds/replacementEndSeconds.',
548
+ '',
549
+ 'Note: video_to_video requires an actual uploaded video file and cannot use generated video',
550
+ 'indices. Do not claim exact final runtime, dimensions, or aspect ratio after a tool finishes',
551
+ 'unless that value was explicitly requested by the user or explicitly returned by the tool.',
552
+ ].join('\n'),
553
+ parameterDocs: {
554
+ videoIndices: 'Ordered source video indices. Use non-negative generated-video indices from prior tool results; use negative uploaded-video indices in current UI order (-1 first uploaded video, -2 second, etc.).',
555
+ },
556
+ };
557
+ const SOUND_TO_VIDEO_CONTRACT = {
558
+ contractId: 'sound_to_video_v1',
559
+ version: '1.0.0',
560
+ toolName: 'sound_to_video',
561
+ baseDescription: [
562
+ 'sound_to_video creates audio-synced video from an audio source. Works with uploaded audio',
563
+ 'files (mp3, m4a, wav) OR previously generated music from generate_music (auto-detected).',
564
+ '',
565
+ 'When the user asks to "turn that song/music into a video" after generate_music, use',
566
+ 'sound_to_video — it will automatically find the generated audio.',
567
+ '',
568
+ 'For music visualization (syncing video to a specific song or audio track), use the',
569
+ 'generate_music → sound_to_video pipeline. Do NOT use animate_photo or generate_video for',
570
+ 'audio-driven visualization.',
571
+ '',
572
+ 'animate_photo and generate_video produce audio natively via LTX 2.3 — never pre-generate',
573
+ 'audio for those tools. sound_to_video is only for when the audio IS the primary creative',
574
+ 'input driving the video output.',
575
+ ].join('\n'),
576
+ parameterDocs: {
577
+ audioSource: 'Uploaded audio file or reference to a prior generate_music result. Auto-detected when omitted after generate_music.',
578
+ },
579
+ };
580
+ const DANCE_MONTAGE_CONTRACT = {
581
+ contractId: 'dance_montage_v1',
582
+ version: '1.0.0',
583
+ toolName: 'dance_montage',
584
+ baseDescription: [
585
+ 'dance_montage creates dance videos from an uploaded photo. Dance video requests from an',
586
+ 'uploaded photo go directly to dance_montage; do not call edit_image/generate_image first',
587
+ 'unless the user explicitly asks for a new look, outfit, generated character/image, variations,',
588
+ 'or persona identity prep.',
589
+ '',
590
+ 'Dance preset/vibe words like "Barbie", "Metric", "Black Sheep", "Rasputin", or "TikTok" are',
591
+ 'not image-prep requests by themselves.',
592
+ '',
593
+ 'SELECTION-GATED DANCE FLOW: If the user asks for N image options and says they will pick',
594
+ 'one before the dance video, generate the image options first (generate_image or edit_image',
595
+ 'with numberOfVariations=N), then stop and wait for the user to choose before calling',
596
+ 'dance_montage.',
597
+ ].join('\n'),
598
+ parameterDocs: {
599
+ sourceImageIndex: 'Use the uploaded photo directly (-1). Only use a generated image index if the user explicitly requested a new image first.',
600
+ },
601
+ };
602
+ const GENERATE_MUSIC_CONTRACT = {
603
+ contractId: 'generate_music_v1',
604
+ version: '1.1.0',
605
+ toolName: 'generate_music',
606
+ baseDescription: [
607
+ 'generate_music creates music tracks with optional lyrics, BPM, key, and style control.',
608
+ '',
609
+ 'MUSIC CREATIVE BRIEF: Identify purpose before composing: full song, short social hook,',
610
+ 'jingle, trailer score, background underscore, sonic logo, music video cue, or lyric video.',
611
+ 'Define genre, mood, tempo/BPM, energy curve, instrumentation, vocal style, lyrical point of',
612
+ 'view, hook phrase, section structure, and production notes. Lyrics should be original,',
613
+ 'singable, sectioned, rhythmically clear, and have a memorable hook. Brand music should make',
614
+ 'the brand easier to remember without stuffing the name into every line.',
615
+ '',
616
+ 'For music visualization (syncing the generated track to video), chain generate_music →',
617
+ 'sound_to_video. Do NOT use animate_photo or generate_video for audio-driven visualization.',
618
+ '',
619
+ 'After generate_music, if the user asks to "turn that song into a video" or similar, call',
620
+ 'sound_to_video next — it auto-detects the latest generated music track.',
621
+ ].join('\n'),
622
+ parameterDocs: {},
623
+ };
624
+ const RESOLVE_PERSONAS_CONTRACT = {
625
+ contractId: 'resolve_personas_v1',
626
+ version: '1.0.0',
627
+ toolName: 'resolve_personas',
628
+ baseDescription: [
629
+ 'resolve_personas is the required first step when the user explicitly names a saved Persona',
630
+ 'or says to use a Persona Image, Persona reference photo, Persona Voice, registered voice,',
631
+ 'or voice clone. Do not answer in prose, ask a follow-up, or finalize before calling this',
632
+ 'tool when a listed Persona name is present.',
633
+ '',
634
+ 'DIRECT PERSONA IMAGE / VOICE VIDEO: If the user says to use the Persona image/reference',
635
+ 'directly/originally, call resolve_personas first, then call animate_photo using the injected',
636
+ 'persona photo as an uploaded image index. For one named Persona, use sourceImageIndex=-1',
637
+ 'or sourceImageIndices=[-1,...] for a multi-clip batch. If Persona Voice was explicitly',
638
+ 'requested, set voicePersonaName to the exact resolved Persona name and use an LTX model.',
639
+ 'Do not call generate_video for Persona image/voice videos. Do not generate a new image first',
640
+ 'when the user explicitly requested the existing Persona image directly.',
641
+ '',
642
+ 'MULTI-CLIP PERSONA BATCHES: If the user asks for several separate clips from the same',
643
+ 'Persona Image, make one animate_photo call after resolve_personas with repeated persona',
644
+ 'source indices, one prompt per clip, and the requested per-clip duration. If the user asks',
645
+ 'to stitch the clips, call stitch_video with the returned video indices after animate_photo.',
646
+ ].join('\n'),
647
+ parameterDocs: {
648
+ names: 'Persona names to load. Use the exact listed Persona name; call this before any Persona image/voice video or image generation.',
649
+ },
650
+ };
651
+ const MAP_ASSETS_FOR_MODEL_CONTRACT = {
652
+ contractId: 'map_assets_for_model_v1',
653
+ version: '1.0.0',
654
+ toolName: 'map_assets_for_model',
655
+ baseDescription: [
656
+ 'map_assets_for_model is an inspection helper for previously generated asset-manifest entries',
657
+ 'when you need exact model_ref tokens for a later prompt.',
658
+ '',
659
+ 'Do NOT call this for ordinary uploaded image references. If the user uploaded images and',
660
+ 'asks GPT Image 2 to use all uploaded assets as visual references, call edit_image directly',
661
+ 'with sourceImageIndex=-1 and describe the uploaded assets/roles in the prompt. Uploaded',
662
+ 'reference images are already available to edit_image/generate_image; mapping them first',
663
+ 'wastes a tool round and may violate direct-generation requests.',
664
+ '',
665
+ 'Use this helper only when a previous tool result produced assets in the manifest and the',
666
+ 'next prompt must name those prior generated assets with provider-specific tokens.',
667
+ ].join('\n'),
668
+ parameterDocs: {
669
+ model_id: 'Target model for prior generated manifest refs. Do not use for plain uploaded references.',
670
+ },
671
+ };
672
+ const RESTORE_PHOTO_CONTRACT = {
673
+ contractId: 'restore_photo_v1',
674
+ version: '1.0.0',
675
+ toolName: 'restore_photo',
676
+ baseDescription: [
677
+ 'restore_photo edits or restores the ORIGINAL uploaded photograph. Use this for the first',
678
+ 'restoration/edit on an upload, or when the user explicitly asks to start over from the',
679
+ 'original/source photo. Use refine_result for follow-up edits to an existing generated result.',
680
+ '',
681
+ 'For photos with people, front-load identity preservation before the restoration or edit.',
682
+ 'Use positive constraints such as preserve exact facial likeness, face structure, apparent',
683
+ 'age, pose, and composition. End with preservation of unmentioned details.',
684
+ '',
685
+ 'Use Dynamic Prompt syntax only when the user explicitly asks to compare multiple restoration',
686
+ 'approaches. Default restoration batches should keep the same prompt and vary only by seed.',
687
+ ].join('\n'),
688
+ parameterDocs: {
689
+ prompt: 'Natural-language edit/restoration prompt. Start with identity preservation for people, then requested restoration/edit, then preserve unmentioned details.',
690
+ numberOfVariations: 'Use 1 unless the user explicitly asks for multiple outputs or comparison options.',
691
+ scale: 'Set only when the user asks to upscale, enlarge, or increase resolution.',
692
+ quality: 'Omit unless the user explicitly asks for fast or high quality.',
693
+ },
694
+ };
695
+ const APPLY_STYLE_CONTRACT = {
696
+ contractId: 'apply_style_v1',
697
+ version: '1.0.0',
698
+ toolName: 'apply_style',
699
+ baseDescription: [
700
+ 'apply_style transfers an artistic style, era, franchise, medium, or photographic look onto',
701
+ 'an uploaded or generated image. It automatically uses the latest result unless the user',
702
+ 'specifies a result number or asks for the original upload.',
703
+ '',
704
+ 'Transfer visual style only. Do not let a style reference override identity, pose, or',
705
+ 'composition unless the user asked for those changes. For people, state identity preservation',
706
+ 'before the style instructions and finish by preserving pose and composition.',
707
+ '',
708
+ 'Use refine_result instead when the user wants a targeted non-style edit to an existing',
709
+ 'result. Use restore_photo only when they explicitly want to restart from the original upload.',
710
+ ].join('\n'),
711
+ parameterDocs: {
712
+ prompt: 'Style-transfer prompt. Name the style/era/artist/franchise and preserve identity, pose, and composition for people.',
713
+ sourceImageIndex: 'Omit for the latest result. Use -1 only when the user explicitly says original/source upload.',
714
+ scale: 'Set only when the user asks to upscale, enlarge, or increase resolution.',
715
+ },
716
+ };
717
+ const REFINE_RESULT_CONTRACT = {
718
+ contractId: 'refine_result_v1',
719
+ version: '1.0.0',
720
+ toolName: 'refine_result',
721
+ baseDescription: [
722
+ 'refine_result is the default follow-up image-edit tool after generated results exist. Use it',
723
+ 'for targeted changes to a prior result: color, brightness, sharpening, background changes,',
724
+ 'object edits, further restoration, or small creative adjustments.',
725
+ '',
726
+ 'Describe only the delta. The source image already contains the subject, composition, and',
727
+ 'most details. Do not rewrite the whole image unless the user asks for a broad transformation.',
728
+ 'For people, front-load exact identity preservation and end with preserving all unmentioned',
729
+ 'details.',
730
+ '',
731
+ 'Use restore_photo instead only when the user explicitly asks to start over from the original',
732
+ 'upload. Use sourceImageIndex only when the user names a specific result.',
733
+ ].join('\n'),
734
+ parameterDocs: {
735
+ prompt: 'Targeted delta instruction. Preserve identity first for people, then specify the change, then preserve everything else.',
736
+ sourceImageIndex: 'Omit for the latest relevant result unless the user names a specific image number.',
737
+ numberOfVariations: 'Use 1 unless the user asks to compare multiple refinement options.',
738
+ },
739
+ };
740
+ const CHANGE_ANGLE_CONTRACT = {
741
+ contractId: 'change_angle_v1',
742
+ version: '1.0.0',
743
+ toolName: 'change_angle',
744
+ baseDescription: [
745
+ 'change_angle creates a new still image from a different camera perspective. Use when the',
746
+ 'user asks for a left/right/back/three-quarter/front view, elevated/low-angle view, close-up,',
747
+ 'medium shot, or wide shot of an existing image subject.',
748
+ '',
749
+ 'The description must be exactly one azimuth, one elevation, and one distance phrase in the',
750
+ 'tool schema format. Default unspecified elevation to eye-level shot and distance to medium',
751
+ 'shot. Use the latest result unless the user specifies another source or says original.',
752
+ '',
753
+ 'Use orbit_video for a full video orbit. Do not pre-generate angles for orbit_video; that tool',
754
+ 'owns its own angle pipeline.',
755
+ ].join('\n'),
756
+ parameterDocs: {
757
+ description: 'Exact format: "[azimuth] [elevation] [distance]". Pick one value from each schema category.',
758
+ sourceImageIndex: 'Omit for latest result. Use -1 only when the user explicitly says original/source upload.',
759
+ loraStrength: 'Omit unless the user explicitly asks to control the strength of the angle change.',
760
+ },
761
+ };
762
+ const VIDEO_TO_VIDEO_CONTRACT = {
763
+ contractId: 'video_to_video_v1',
764
+ version: '1.0.0',
765
+ toolName: 'video_to_video',
766
+ baseDescription: [
767
+ 'video_to_video transforms an uploaded video. Use for uploaded-video restyling, enhancement,',
768
+ 'upscaling/remastering, motion transfer from video to image, subject replacement, edge/pose/',
769
+ 'depth-guided restyle, or explicit Seedance V2V transforms.',
770
+ '',
771
+ 'This tool requires an uploaded video source. Do not use it for generated video indices. For',
772
+ 'generated or uploaded partial edits use replace_video_segment; for appended time use',
773
+ 'extend_video; for logos/text overlays use overlay_video; for stitching use stitch_video.',
774
+ '',
775
+ 'Choose controlMode by intent. Use detailer for quality-only enhancement without restyling.',
776
+ 'Use seedance-v2v only when the user asks to transform/enhance/remaster an uploaded video',
777
+ 'with Seedance. For detailer, describe the original scene plus quality terms, not new content.',
778
+ ].join('\n'),
779
+ parameterDocs: {
780
+ prompt: 'Describe the target appearance in present tense. For detailer, describe the original content plus quality qualifiers only.',
781
+ videoSourceIndex: 'Uploaded video index. Omit when there is one uploaded video; use 0 for first uploaded video or -1 if using negative upload notation.',
782
+ controlMode: 'Pick from intent: detailer for enhance, seedance-v2v for explicit Seedance V2V, canny/depth/pose for control-net restyles, animate-move/replace for WAN Animate.',
783
+ sourceImageIndex: 'Required for animate-move and animate-replace. Ignored by canny, depth, and detailer.',
784
+ duration: 'Set only when the user requests a different output length; otherwise let the tool match/cap the source duration.',
785
+ },
786
+ };
787
+ const ADD_SUBTITLES_CONTRACT = {
788
+ contractId: 'add_subtitles_v1',
789
+ version: '1.0.0',
790
+ toolName: 'add_subtitles',
791
+ baseDescription: [
792
+ 'add_subtitles burns caller-supplied subtitles, captions, lyrics, or on-screen dialogue into',
793
+ 'an existing video. Use this when the user provides cue text/timing, pastes SRT/VTT, or asks',
794
+ 'to add known caption lines to a generated or uploaded video.',
795
+ '',
796
+ 'Do not use auto_transcribe. Speech-to-text is not enabled; when the user has not supplied',
797
+ 'subtitle text or timing, ask for the cue text/timing instead of calling this tool.',
798
+ '',
799
+ 'Exception: if the user explicitly authorizes invented caption copy with language like',
800
+ '"make them up", "write captions", "invent subtitles", or "add funny captions", create a few',
801
+ 'short generic cue lines yourself and call add_subtitles. Do not ask for exact wording when',
802
+ 'the user has asked you to author the captions.',
803
+ '',
804
+ 'Split subtitles into multiple short cues. Do not burn one paragraph across the whole clip.',
805
+ 'Use overlay_video instead for static title cards, labels, logos, watermarks, or non-timed text.',
806
+ ].join('\n'),
807
+ parameterDocs: {
808
+ sourceVideoIndex: 'Non-negative generated video index or negative uploaded video index. Omit/default to the latest relevant video.',
809
+ cues: 'Multiple short cues with startSeconds, endSeconds, and text. Prefer 1.5-4 seconds per cue.',
810
+ srt: 'Full SRT/VTT string. Provide either srt or cues, not both.',
811
+ auto_transcribe: 'Do not set. Ask the user for subtitle text/timing until STT is available.',
812
+ },
813
+ };
814
+ const ANALYZE_IMAGE_CONTRACT = {
815
+ contractId: 'analyze_image_v1',
816
+ version: '1.0.0',
817
+ toolName: 'analyze_image',
818
+ baseDescription: [
819
+ 'analyze_image answers questions about image content, OCR, objects, style, documents, or',
820
+ 'comparisons. It does not generate or modify media.',
821
+ '',
822
+ 'Use only when the user asks to inspect, describe, read, compare, or reason about an image.',
823
+ 'Do not insert it as a quality-control step inside generation workflows unless the user',
824
+ 'explicitly asks for analysis before continuing.',
825
+ '',
826
+ 'For uploaded images, negative indices refer to the upload order. For compare mode, provide',
827
+ 'both sourceImageIndex and compareImageIndex.',
828
+ ].join('\n'),
829
+ parameterDocs: {
830
+ query: 'Specific question/request about the image. Preserve the user question directly.',
831
+ analysisType: 'Pick describe, ocr, objects, document, compare, or general based on the user request.',
832
+ sourceImageIndex: 'Omit to auto-select latest result or original upload. Use -1 for first uploaded image.',
833
+ compareImageIndex: 'Second image for compare mode. Use negative uploaded-image indices when comparing uploads.',
834
+ },
835
+ };
836
+ const ANALYZE_VIDEO_CONTRACT = {
837
+ contractId: 'analyze_video_v1',
838
+ version: '1.0.0',
839
+ toolName: 'analyze_video',
840
+ baseDescription: [
841
+ 'analyze_video uses sampled frames to answer questions about an uploaded or generated video:',
842
+ 'summary, timeline, visual scene description, action breakdown, or visible text.',
843
+ '',
844
+ 'Use only when the user asks to inspect or understand a video. Do not call it as automatic',
845
+ 'verification after generation, and do not use it before stitch_video when the requested',
846
+ 'generation pipeline should continue.',
847
+ '',
848
+ 'This is visual sampled-frame analysis only. It does not transcribe audio and does not inspect',
849
+ 'every frame.',
850
+ ].join('\n'),
851
+ parameterDocs: {
852
+ query: 'Specific question/request about the video. State whether summary, timeline, OCR, scene, or action detail is needed.',
853
+ analysisType: 'Pick summary, timeline, scene, action, ocr, or general based on the user request.',
854
+ sourceVideoIndex: 'Generated video index or negative uploaded-video index. Omit to auto-select latest generated video or first upload.',
855
+ },
856
+ };
857
+ const EXTRACT_METADATA_CONTRACT = {
858
+ contractId: 'extract_metadata_v1',
859
+ version: '1.0.0',
860
+ toolName: 'extract_metadata',
861
+ baseDescription: [
862
+ 'extract_metadata reads prompt/model/settings metadata from an uploaded media file. Use when',
863
+ 'the user asks what prompt, model, seed, dimensions, or generation settings are embedded in',
864
+ 'an uploaded file, or when they ask to recreate/remix an uploaded file from its metadata.',
865
+ '',
866
+ 'This indexes uploaded files only, not prior generated results already known to chat. Do not',
867
+ 'call it for ordinary visual analysis; use analyze_image or analyze_video for content.',
868
+ ].join('\n'),
869
+ parameterDocs: {
870
+ file_index: '0-based uploaded-file index. Omit for the first uploaded file.',
871
+ },
872
+ };
873
+ const MANAGE_MEMORY_CONTRACT = {
874
+ contractId: 'manage_memory_v1',
875
+ version: '1.0.0',
876
+ toolName: 'manage_memory',
877
+ baseDescription: [
878
+ 'manage_memory reads, writes, or deletes persistent user preferences and facts. Use write',
879
+ 'only when the user states a durable preference/fact or explicitly asks you to remember',
880
+ 'something. Use read when persistent preferences are relevant before generation.',
881
+ '',
882
+ 'Do not save transient one-off creative instructions as memory. Delete/clear actions require',
883
+ 'explicit user intent; never infer memory deletion from vague dissatisfaction.',
884
+ ].join('\n'),
885
+ parameterDocs: {
886
+ action: 'read, write, or delete. Use write only for durable preferences/facts; delete only on explicit request.',
887
+ key: 'Stable concise memory key. Required for write/delete.',
888
+ value: 'Concise durable value. Required for write.',
889
+ category: 'preference for style/defaults, fact for user facts, context for project context.',
890
+ },
891
+ };
892
+ const SET_CONTENT_FILTER_CONTRACT = {
893
+ contractId: 'set_content_filter_v1',
894
+ version: '1.0.0',
895
+ toolName: 'set_content_filter',
896
+ baseDescription: [
897
+ 'set_content_filter enables or disables the Safe Content Filter. Call only when the user',
898
+ 'explicitly asks to change this setting. Do not toggle it as part of ordinary generation.',
899
+ '',
900
+ 'If disabling requires host-side confirmation, let the handler surface that permission flow;',
901
+ 'do not claim the setting changed unless the tool result says it did.',
902
+ ].join('\n'),
903
+ parameterDocs: {
904
+ enabled: 'true to enable the filter, false to disable it. Only set from explicit user intent.',
905
+ },
906
+ };
907
+ const CREATE_ASSET_MANIFEST_CONTRACT = {
908
+ contractId: 'create_asset_manifest_v1',
909
+ version: '1.0.0',
910
+ toolName: 'create_asset_manifest',
911
+ baseDescription: [
912
+ 'create_asset_manifest resets and seeds the session asset manifest with stable asset_id',
913
+ 'records. Use at the start of workflows with multiple named uploaded/generated assets that',
914
+ 'will need durable references across later prompts.',
915
+ '',
916
+ 'Do not call this just to use ordinary uploaded images in edit_image/generate_image; those',
917
+ 'tools can already reference uploads. Resetting discards prior manifest entries.',
918
+ ].join('\n'),
919
+ parameterDocs: {
920
+ assets: 'Ordered assets to register. Each needs user_label and type; include must_preserve/avoid only when they matter later.',
921
+ },
922
+ };
923
+ const INSPECT_ASSET_CONTRACT = {
924
+ contractId: 'inspect_asset_v1',
925
+ version: '1.0.0',
926
+ toolName: 'inspect_asset',
927
+ baseDescription: [
928
+ 'inspect_asset returns one manifest asset or the whole manifest. Use when the current',
929
+ 'manifest state is unclear before referring to a generated asset by asset_id/user_label.',
930
+ '',
931
+ 'Do not call it for ordinary uploaded references that the generation tools can use directly,',
932
+ 'and do not use it as a substitute for analyze_image/analyze_video content inspection.',
933
+ ].join('\n'),
934
+ parameterDocs: {
935
+ asset_id: 'Stable internal asset id. Prefer this when known.',
936
+ user_label: 'Human label to look up case-insensitively when asset_id is not known.',
937
+ },
938
+ };
939
+ const LABEL_ASSET_CONTRACT = {
940
+ contractId: 'label_asset_v1',
941
+ version: '1.0.0',
942
+ toolName: 'label_asset',
943
+ baseDescription: [
944
+ 'label_asset updates the label, description, URL, must_preserve, or avoid fields for an',
945
+ 'existing manifest asset. Use when the user renames an asset, assigns a role, or when a',
946
+ 'previous tool result adds durable reference constraints.',
947
+ '',
948
+ 'Do not invent labels or preservation constraints that the user did not provide or that are',
949
+ 'not present in a tool result.',
950
+ ].join('\n'),
951
+ parameterDocs: {
952
+ asset_id: 'Existing asset_id to update.',
953
+ user_label: 'New human-readable label when the user renames the asset.',
954
+ description: 'Replacement description. Keep it factual and concise.',
955
+ must_preserve: 'Replacement preservation list. Use only explicit or tool-result-backed constraints.',
956
+ avoid: 'Replacement avoid list. Use only explicit or tool-result-backed constraints.',
957
+ },
958
+ };
959
+ const VALIDATE_ASSET_REFERENCES_CONTRACT = {
960
+ contractId: 'validate_asset_references_v1',
961
+ version: '1.0.0',
962
+ toolName: 'validate_asset_references',
963
+ baseDescription: [
964
+ 'validate_asset_references checks a prompt for provider-specific manifest reference tokens',
965
+ 'and reports which resolve or dangle. Call right before dispatching a prompt that names',
966
+ 'manifest assets with model_ref tokens.',
967
+ '',
968
+ 'Do not use this for plain uploaded references. If validation finds dangling refs, repair the',
969
+ 'prompt or register/map the asset before running an expensive generation tool.',
970
+ ].join('\n'),
971
+ parameterDocs: {
972
+ model_id: 'Target provider/model id whose reference token format should be scanned.',
973
+ prompt: 'Prompt text about to be sent to the model.',
974
+ },
975
+ };
976
+ const ASK_CLARIFYING_QUESTION_CONTRACT = {
977
+ contractId: 'ask_clarifying_question_v1',
978
+ version: '1.1.0',
979
+ toolName: 'ask_clarifying_question',
980
+ baseDescription: [
981
+ 'ask_clarifying_question pauses the workflow and asks the user for missing required input.',
982
+ 'Use only when no reasonable safe default exists, when required media/content is missing, or',
983
+ 'when confirmation is required for a destructive or credit-sensitive action.',
984
+ '',
985
+ 'For creative briefs, do not over-question. Ask at most 3 concise high-leverage questions only',
986
+ 'when the answer would materially change audience, product promise, format/duration/platform,',
987
+ 'tone, required assets, dialogue/no-dialogue, safety/legal/factual claims, or credit-sensitive',
988
+ 'execution. Otherwise make reasonable assumptions and continue.',
989
+ '',
990
+ 'This ends the turn. Do not call another tool after it. Ask short concrete question(s) and',
991
+ 'avoid preamble.',
992
+ ].join('\n'),
993
+ parameterDocs: {
994
+ question: 'One short concrete question surfaced verbatim to the user.',
995
+ reason: 'Short telemetry tag such as missing_source_asset, ambiguous_subject, or destructive_confirm.',
996
+ },
997
+ };
998
+ const FINALIZE_RESPONSE_CONTRACT = {
999
+ contractId: 'finalize_response_v1',
1000
+ version: '1.1.0',
1001
+ toolName: 'finalize_response',
1002
+ baseDescription: [
1003
+ 'finalize_response marks the turn complete and stops the tool loop. Use after the requested',
1004
+ 'workflow succeeds, partially succeeds, fails with a surfaced error, or needs no tool action.',
1005
+ '',
1006
+ 'When the user asked for a script, storyboard, ad concept, trailer, creator video, meme/parody,',
1007
+ 'or music prompt and no media tool is required, deliver the final creative in a clean Markdown',
1008
+ 'contract: title, concept/objective, audience if relevant, timed beats or script, audio/text',
1009
+ 'notes, generation prompt(s), CTA, and brief assumptions. For revisions, apply the feedback',
1010
+ 'directly while preserving approved elements and rejected constraints.',
1011
+ '',
1012
+ 'Do not call any other tool after finalize_response. Keep the summary short and grounded in',
1013
+ 'actual tool results; do not claim exact metadata that no tool returned.',
1014
+ ].join('\n'),
1015
+ parameterDocs: {
1016
+ summary: 'Short user-visible closeout. Mention produced media or the concrete blocker; avoid duplicating prior tool output.',
1017
+ outcome: 'success, partial, asked_user, failed, or no_action based on the actual turn outcome.',
1018
+ },
1019
+ };
1020
+ const COMPOSE_WORKFLOW_CONTRACT = {
1021
+ contractId: 'compose_workflow_v1',
1022
+ version: '1.0.0',
1023
+ toolName: 'compose_workflow',
1024
+ baseDescription: [
1025
+ 'compose_workflow turns a creative brief into a runnable ONE-SHOT durable creative workflow',
1026
+ 'plan (the same shape that POST /v1/creative-agent/workflows accepts). Pick this when the',
1027
+ 'user wants to RUN a multi-step pipeline ONCE — they will review the plan, submit it, get',
1028
+ 'the output, and be done. Trigger phrases: "give me a runnable workflow plan", "compose a',
1029
+ 'one-shot plan", "compile a plan I can submit", "I want to run this once", "I do NOT need',
1030
+ 'to save it as a template", "just review the steps and run it", "5-shot teaser, 9:16, 15s"',
1031
+ 'style concrete one-off briefs.',
1032
+ '',
1033
+ 'Hard line vs compose_workflow_template: if the user wants to SAVE / REUSE / NAME a',
1034
+ 'workflow recipe to re-run later on different inputs, use compose_workflow_template',
1035
+ 'instead. compose_workflow returns a one-time plan with no template wrapper; the user',
1036
+ 'CANNOT re-run this output with different inputs without a fresh planner call.',
1037
+ '',
1038
+ 'Do not use compose_workflow for ordinary creative writing artifacts — use compose_script for',
1039
+ 'scripts, storyboards, ad concepts, or trailers. Do not use it for prompt expansion — use',
1040
+ 'enhance_prompt. Do not use it to actually run a workflow — the response is just the plan;',
1041
+ 'the caller is responsible for submitting it to POST /v1/creative-agent/workflows with their',
1042
+ 'own Idempotency-Key.',
1043
+ '',
1044
+ 'The returned plan is not idempotent on its own. Pair the eventual workflow submission with',
1045
+ 'a caller-owned Idempotency-Key. Phase 1 only supports return_format="json".',
1046
+ ].join('\n'),
1047
+ parameterDocs: {
1048
+ brief: 'Required free-form natural-language description of what the workflow should produce.',
1049
+ scene_count: 'Suggested number of distinct shots/scenes (1-12). The planner may emit more steps than scenes (for example, a keyframe + clip pair per scene).',
1050
+ duration_seconds: 'Target total duration in seconds for video-bearing plans (1-120).',
1051
+ aspect_ratio: 'Output aspect ratio. One of 1:1, 4:3, 3:4, 16:9, 9:16, 21:9.',
1052
+ style: 'Optional stylistic guidance such as "cinematic, neon, low-key" or "whiteboard illustration".',
1053
+ destination_models: 'Optional preferred image/video/music model selectors (e.g. flux2, ltx23). Each subkey is optional.',
1054
+ max_estimated_capacity_units: 'Optional coarse capacity budget. If set, the planner tries to keep total estimated cost at or below this value; the API returns fits_budget=false if it cannot.',
1055
+ include_audio: 'When true, include a generate_music step in the plan. Defaults to false.',
1056
+ return_format: 'Reserved for future use; only "json" is supported in Phase 1. Omit if unsure.',
1057
+ },
1058
+ };
1059
+ const COMPOSE_WORKFLOW_TEMPLATE_CONTRACT = {
1060
+ contractId: 'compose_workflow_template_v1',
1061
+ version: '1.0.0',
1062
+ toolName: 'compose_workflow_template',
1063
+ baseDescription: [
1064
+ 'compose_workflow_template turns a creative brief into a savable, parameterized workflow',
1065
+ 'template plus a concrete example plan for the inputs the planner picked. This is the',
1066
+ 'tool to use whenever the user wants to CREATE / SAVE / DESIGN / BUILD a reusable',
1067
+ 'workflow recipe — not just run one once. Trigger phrases: "create a workflow that…",',
1068
+ '"save this as a workflow", "make me a reusable workflow…", "build a workflow that…",',
1069
+ '"design a workflow…", "I want a recipe for…", "I want to be able to re-run this on…",',
1070
+ '"save as workflow", "turn this into a workflow", "workflow that takes X as input".',
1071
+ '',
1072
+ 'The returned `template_draft` carries typed `inputs[]` (image/audio/video/text/number/',
1073
+ 'select/boolean), parameterized `stages[]` that reference inputs via `$inputs.NAME`',
1074
+ 'placeholders, and an optional `graph` layout the visual builder consumes. A sibling',
1075
+ '`plan` field carries a Phase-1-compatible `steps[]` rendering for the example inputs so',
1076
+ 'the UI can preview the workflow without round-tripping the compiler.',
1077
+ '',
1078
+ 'Hard line vs direct generation tools: if the user asked to MAKE / SAVE / DESIGN a',
1079
+ 'workflow, never call generate_video, generate_image, edit_image, animate_photo, or any',
1080
+ 'other rendering tool directly — that consumes credits to produce one-shot media when',
1081
+ 'the user wanted a reusable recipe. Pick compose_workflow_template instead. After',
1082
+ 'compose_workflow_template returns the template_draft, you MUST immediately call',
1083
+ 'finalize_response next. DO NOT call any other tool after compose_workflow_template —',
1084
+ 'no render tools "to show a preview", no demonstration runs, nothing. The user reviews',
1085
+ 'the draft in the builder UI, not in chat. Calling generate_image / generate_video /',
1086
+ 'edit_image after compose_workflow_template is a fixture-failing mistake.',
1087
+ '',
1088
+ 'Hard line vs compose_workflow: if the user said "I do not need to save it as a',
1089
+ 'template", "give me a runnable plan to submit", "one-shot", "just run this once", or',
1090
+ 'similar single-use phrasing — pick compose_workflow, NOT compose_workflow_template.',
1091
+ 'compose_workflow_template is exclusively for SAVING reusable recipes.',
1092
+ '',
1093
+ 'Do not use compose_workflow_template for one-shot turn-by-turn plans — use compose_workflow',
1094
+ 'instead. The returned template is a draft; the caller is responsible for saving it via',
1095
+ 'POST /v1/creative-agent/workflows/templates and minting a stable template id.',
1096
+ '',
1097
+ 'Editing an existing template: pass the full template JSON as `existing_template` together',
1098
+ 'with the modification brief and the planner returns a refined `template_draft` that keeps',
1099
+ 'the id stable, bumps the version, preserves stages the brief did not touch, and applies',
1100
+ 'the requested changes. This is the canonical path for "add a music step", "switch the',
1101
+ 'storyboard model to GPT Image 2", or "make this 9:16 instead of 16:9" style edits.',
1102
+ '',
1103
+ 'Editing a workflow you cannot see: if the user asks to edit a saved workflow by name or',
1104
+ 'id (e.g. "edit the bobblehead workflow", "modify wf_bobblehead_tiktok") and the',
1105
+ 'conversation does not contain the existing template JSON, do NOT call manage_memory and',
1106
+ 'do NOT ask the user to paste the template — just call compose_workflow_template with the',
1107
+ 'modification brief and a sensible name (you may reuse the workflow id the user mentioned).',
1108
+ 'Omit existing_template in that case. The planner composes a fresh template_draft that',
1109
+ 'represents the modification; preserving stage ids only happens when existing_template is',
1110
+ 'present, and that is acceptable — the alternative is a wasted turn.',
1111
+ '',
1112
+ 'Phase 2 supports return_format="json" only. Visibility defaults to "private"; the "team"',
1113
+ 'visibility slot is reserved for a later milestone.',
1114
+ ].join('\n'),
1115
+ parameterDocs: {
1116
+ brief: 'Required free-form natural-language description of what the workflow should produce. When editing an existing template, phrase the brief as the modification request (e.g. "Add a music step at the end and make the duration 12s").',
1117
+ name: 'Required human-readable template name. Shown in the workflow library and run launcher.',
1118
+ description: 'Optional template description; the planner derives one from the brief if omitted.',
1119
+ category: 'Optional category (portrait, video-social, makeover, cinematic, music, analysis, custom, other). Defaults to "custom".',
1120
+ visibility: 'Persistence visibility: "private" (default) or "public". "team" is reserved for a later milestone.',
1121
+ inputs: 'Optional typed input declarations. When omitted, the planner LLM proposes inputs based on the brief. Each entry needs name + type; required, description, default, options, multiple, and internal are optional refinements.',
1122
+ scene_count: 'Suggested number of distinct shots/scenes (1-12).',
1123
+ duration_seconds: 'Target total duration in seconds for video-bearing plans (1-120).',
1124
+ aspect_ratio: 'Output aspect ratio. One of 1:1, 4:3, 3:4, 16:9, 9:16, 21:9.',
1125
+ style: 'Optional stylistic guidance such as "cinematic, neon, low-key" or "whiteboard illustration".',
1126
+ destination_models: 'Optional preferred image/video/music model selectors (e.g. flux2, ltx23). Each subkey is optional.',
1127
+ max_estimated_capacity_units: 'Optional coarse capacity budget. The planner returns fits_budget=false if it cannot fit under the cap.',
1128
+ include_audio: 'When true, include a generate_music step in the example plan. Defaults to false.',
1129
+ return_format: 'Reserved for future use; only "json" is supported in Phase 2. Omit if unsure.',
1130
+ existing_template: 'Optional full WorkflowTemplate JSON. When supplied, the planner edits this template per the brief instead of designing from scratch — preserves stage ids and unchanged stages, bumps version, and applies the requested modifications. Use this for the chat "edit this workflow" flow and the builder "regenerate from prompt" button.',
1131
+ },
1132
+ };
1133
+ exports.PHASE_5_PROMPT_CONTRACTS = [
1134
+ RESTORE_PHOTO_CONTRACT,
1135
+ APPLY_STYLE_CONTRACT,
1136
+ REFINE_RESULT_CONTRACT,
1137
+ ORBIT_VIDEO_CONTRACT,
1138
+ ANIMATE_PHOTO_CONTRACT,
1139
+ CHANGE_ANGLE_CONTRACT,
1140
+ GENERATE_VIDEO_CONTRACT,
1141
+ EDIT_IMAGE_CONTRACT,
1142
+ GENERATE_IMAGE_CONTRACT,
1143
+ VIDEO_TO_VIDEO_CONTRACT,
1144
+ EXTEND_VIDEO_CONTRACT,
1145
+ REPLACE_VIDEO_SEGMENT_CONTRACT,
1146
+ OVERLAY_VIDEO_CONTRACT,
1147
+ ADD_SUBTITLES_CONTRACT,
1148
+ STITCH_VIDEO_CONTRACT,
1149
+ SOUND_TO_VIDEO_CONTRACT,
1150
+ DANCE_MONTAGE_CONTRACT,
1151
+ GENERATE_MUSIC_CONTRACT,
1152
+ ANALYZE_IMAGE_CONTRACT,
1153
+ ANALYZE_VIDEO_CONTRACT,
1154
+ SET_CONTENT_FILTER_CONTRACT,
1155
+ EXTRACT_METADATA_CONTRACT,
1156
+ RESOLVE_PERSONAS_CONTRACT,
1157
+ MANAGE_MEMORY_CONTRACT,
1158
+ CREATE_ASSET_MANIFEST_CONTRACT,
1159
+ INSPECT_ASSET_CONTRACT,
1160
+ LABEL_ASSET_CONTRACT,
1161
+ MAP_ASSETS_FOR_MODEL_CONTRACT,
1162
+ VALIDATE_ASSET_REFERENCES_CONTRACT,
1163
+ ASK_CLARIFYING_QUESTION_CONTRACT,
1164
+ FINALIZE_RESPONSE_CONTRACT,
1165
+ COMPOSE_WORKFLOW_CONTRACT,
1166
+ COMPOSE_WORKFLOW_TEMPLATE_CONTRACT,
1167
+ ];
1168
+ function populateContractsPromptContracts(registry) {
1169
+ for (const contract of exports.PHASE_5_PROMPT_CONTRACTS) {
1170
+ registry.registerPromptContract(contract);
1171
+ }
1172
+ }
1173
+ //# sourceMappingURL=promptContracts.js.map