@use-lattice/litmus 0.121.3

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 (199) hide show
  1. package/LICENSE +19 -0
  2. package/dist/src/accounts-Bt1oJb1Z.cjs +219 -0
  3. package/dist/src/accounts-DjOU8Rm3.js +178 -0
  4. package/dist/src/agentic-utils-D03IiXQc.js +153 -0
  5. package/dist/src/agentic-utils-Dh7xaMQM.cjs +180 -0
  6. package/dist/src/agents-C6BIMlZa.js +231 -0
  7. package/dist/src/agents-DvIpNX1L.cjs +666 -0
  8. package/dist/src/agents-ZP0RP9vV.cjs +231 -0
  9. package/dist/src/agents-maJXdjbR.js +665 -0
  10. package/dist/src/aimlapi-BTbQjG2E.cjs +30 -0
  11. package/dist/src/aimlapi-CwMxqfXP.js +30 -0
  12. package/dist/src/audio-BBUdvsde.cjs +97 -0
  13. package/dist/src/audio-D5DPZ7I-.js +97 -0
  14. package/dist/src/base-BEysXrkq.cjs +222 -0
  15. package/dist/src/base-C451JQfq.js +193 -0
  16. package/dist/src/blobs-BY8MDmpo.js +230 -0
  17. package/dist/src/blobs-BgcNn97m.cjs +256 -0
  18. package/dist/src/cache-BBE_lsTA.cjs +4 -0
  19. package/dist/src/cache-BkrqU5Ba.js +237 -0
  20. package/dist/src/cache-DsCxFlsZ.cjs +297 -0
  21. package/dist/src/chat-CPJWDP6a.cjs +289 -0
  22. package/dist/src/chat-CXX3xzkk.cjs +811 -0
  23. package/dist/src/chat-CcDgZFJ4.js +787 -0
  24. package/dist/src/chat-Dz5ZeGO2.js +289 -0
  25. package/dist/src/chatkit-Dw0mKkML.cjs +1158 -0
  26. package/dist/src/chatkit-swAIVuea.js +1157 -0
  27. package/dist/src/chunk-DEq-mXcV.js +15 -0
  28. package/dist/src/claude-agent-sdk-BXZJtOg6.js +379 -0
  29. package/dist/src/claude-agent-sdk-CkfyjDoG.cjs +383 -0
  30. package/dist/src/cloudflare-ai-BzpJcqUH.js +161 -0
  31. package/dist/src/cloudflare-ai-Cmy_R1y2.cjs +161 -0
  32. package/dist/src/cloudflare-gateway-B9tVQKok.cjs +272 -0
  33. package/dist/src/cloudflare-gateway-DrD3ew3H.js +272 -0
  34. package/dist/src/codex-sdk-Dezj9Nwm.js +1056 -0
  35. package/dist/src/codex-sdk-Dl9D4k5B.cjs +1060 -0
  36. package/dist/src/cometapi-C-9YvCHC.js +54 -0
  37. package/dist/src/cometapi-DHgDKoO2.cjs +54 -0
  38. package/dist/src/completion-B8Ctyxpr.js +120 -0
  39. package/dist/src/completion-Cxrt08sj.cjs +131 -0
  40. package/dist/src/createHash-BwgE13yv.cjs +27 -0
  41. package/dist/src/createHash-DmPQkvBh.js +15 -0
  42. package/dist/src/docker-BiqcTwLv.js +80 -0
  43. package/dist/src/docker-C7tEJnP-.cjs +80 -0
  44. package/dist/src/esm-C62Zofr1.cjs +409 -0
  45. package/dist/src/esm-DMVc93eh.js +379 -0
  46. package/dist/src/evalResult-C3NJPQOo.cjs +301 -0
  47. package/dist/src/evalResult-C7JJAPBb.js +295 -0
  48. package/dist/src/evalResult-DoVTZZWI.cjs +2 -0
  49. package/dist/src/extractor-DnMD3fwt.cjs +391 -0
  50. package/dist/src/extractor-DtlL28vL.js +374 -0
  51. package/dist/src/fetch-BTxakTSg.cjs +1133 -0
  52. package/dist/src/fetch-DQckpUFz.js +928 -0
  53. package/dist/src/fileExtensions-DnqA1y9x.js +85 -0
  54. package/dist/src/fileExtensions-bYh77CN8.cjs +114 -0
  55. package/dist/src/genaiTracer-CyZrmaK0.cjs +268 -0
  56. package/dist/src/genaiTracer-D3fD9dNV.js +256 -0
  57. package/dist/src/graders-BNscxFrU.js +13644 -0
  58. package/dist/src/graders-D2oE9Msq.js +2 -0
  59. package/dist/src/graders-c0Ez_w-9.cjs +2 -0
  60. package/dist/src/graders-d0F2M3e9.cjs +14056 -0
  61. package/dist/src/image-0ZhE0VlR.cjs +280 -0
  62. package/dist/src/image-CWE1pdNv.js +257 -0
  63. package/dist/src/image-D9ZK6hwL.js +163 -0
  64. package/dist/src/image-DKZgZITg.cjs +163 -0
  65. package/dist/src/index.cjs +11366 -0
  66. package/dist/src/index.d.cts +19640 -0
  67. package/dist/src/index.d.ts +19641 -0
  68. package/dist/src/index.js +11306 -0
  69. package/dist/src/invariant-Ddh24eXh.js +25 -0
  70. package/dist/src/invariant-kfQ8Bu82.cjs +30 -0
  71. package/dist/src/knowledgeBase-BgPyGFUd.cjs +122 -0
  72. package/dist/src/knowledgeBase-DyHilYaP.js +122 -0
  73. package/dist/src/litellm-CyMeneHS.js +135 -0
  74. package/dist/src/litellm-DWDF73yF.cjs +135 -0
  75. package/dist/src/logger-C40ZGil9.js +717 -0
  76. package/dist/src/logger-DyfK9PBt.cjs +917 -0
  77. package/dist/src/luma-ray-BAU9X_ep.cjs +315 -0
  78. package/dist/src/luma-ray-nwVseBbv.js +313 -0
  79. package/dist/src/messages-B5ADWTTv.js +245 -0
  80. package/dist/src/messages-BCnZfqrS.cjs +257 -0
  81. package/dist/src/meteor-DLZZ3osF.cjs +134 -0
  82. package/dist/src/meteor-DUiCJRC-.js +134 -0
  83. package/dist/src/modelslab-00cveB8L.cjs +163 -0
  84. package/dist/src/modelslab-D9sCU_L7.js +163 -0
  85. package/dist/src/nova-reel-CTapvqYH.js +276 -0
  86. package/dist/src/nova-reel-DlWuuroF.cjs +278 -0
  87. package/dist/src/nova-sonic-5UPWfeMv.cjs +363 -0
  88. package/dist/src/nova-sonic-BhSwQNym.js +363 -0
  89. package/dist/src/openai-BWrJK9d8.cjs +52 -0
  90. package/dist/src/openai-DumO8WQn.js +47 -0
  91. package/dist/src/openclaw-B8brrjC_.cjs +577 -0
  92. package/dist/src/openclaw-Bkayww9q.js +571 -0
  93. package/dist/src/opencode-sdk-7xjoDNiM.cjs +562 -0
  94. package/dist/src/opencode-sdk-SGwAPxht.js +558 -0
  95. package/dist/src/otlpReceiver-CoAHfAN9.cjs +15 -0
  96. package/dist/src/otlpReceiver-oO3EQwI9.js +14 -0
  97. package/dist/src/providerRegistry-4yjhaEM8.js +45 -0
  98. package/dist/src/providerRegistry-DhV4rJIc.cjs +50 -0
  99. package/dist/src/providers-B5RJVG-7.cjs +33609 -0
  100. package/dist/src/providers-BdmZCLzV.js +33262 -0
  101. package/dist/src/providers-CxtRxn8e.js +2 -0
  102. package/dist/src/providers-DnQLNbx1.cjs +3 -0
  103. package/dist/src/pythonUtils-BD0druiM.cjs +275 -0
  104. package/dist/src/pythonUtils-IBhn5YGR.js +249 -0
  105. package/dist/src/quiverai-BDOwZBsM.cjs +213 -0
  106. package/dist/src/quiverai-D3JTF5lD.js +213 -0
  107. package/dist/src/responses-B2LCDCXZ.js +667 -0
  108. package/dist/src/responses-BvNm4Xv9.cjs +685 -0
  109. package/dist/src/rubyUtils-B0NwnfpY.cjs +245 -0
  110. package/dist/src/rubyUtils-BroxzZ7c.cjs +2 -0
  111. package/dist/src/rubyUtils-hqVw5UvJ.js +222 -0
  112. package/dist/src/sagemaker-Cno2V-Sx.js +689 -0
  113. package/dist/src/sagemaker-fV_KUgs5.cjs +691 -0
  114. package/dist/src/server-BOuAXb06.cjs +238 -0
  115. package/dist/src/server-CtI-EWzm.cjs +2 -0
  116. package/dist/src/server-Cy3DZymt.js +189 -0
  117. package/dist/src/slack-CP8xBePa.js +135 -0
  118. package/dist/src/slack-DSQ1yXVb.cjs +135 -0
  119. package/dist/src/store-BwDDaBjb.cjs +246 -0
  120. package/dist/src/store-DcbLC593.cjs +2 -0
  121. package/dist/src/store-IGpqMIkv.js +240 -0
  122. package/dist/src/tables-3Q2cL7So.cjs +373 -0
  123. package/dist/src/tables-Bi2fjr4W.js +288 -0
  124. package/dist/src/telemetry-Bg2WqF79.js +161 -0
  125. package/dist/src/telemetry-D0x6u5kX.cjs +166 -0
  126. package/dist/src/telemetry-DXNimrI0.cjs +2 -0
  127. package/dist/src/text-B_UCRPp2.js +22 -0
  128. package/dist/src/text-CW1cyrwj.cjs +33 -0
  129. package/dist/src/tokenUsageUtils-NYT-WKS6.js +138 -0
  130. package/dist/src/tokenUsageUtils-bVa1ga6f.cjs +173 -0
  131. package/dist/src/transcription-Cl_W16Pr.js +122 -0
  132. package/dist/src/transcription-yt1EecY8.cjs +124 -0
  133. package/dist/src/transform-BCtGrl_W.cjs +228 -0
  134. package/dist/src/transform-Bv6gG2MJ.cjs +1688 -0
  135. package/dist/src/transform-CY1wbpRy.js +1507 -0
  136. package/dist/src/transform-DU8rUL9P.cjs +2 -0
  137. package/dist/src/transform-yWaShiKr.js +216 -0
  138. package/dist/src/transformersAvailability-BGkzavwb.js +35 -0
  139. package/dist/src/transformersAvailability-DKoRtQLy.cjs +35 -0
  140. package/dist/src/types-5aqHpBwE.cjs +3769 -0
  141. package/dist/src/types-Bn6D9c4U.js +3300 -0
  142. package/dist/src/util-BkKlTkI2.js +293 -0
  143. package/dist/src/util-CTh0bfOm.cjs +1119 -0
  144. package/dist/src/util-D17oBwo7.cjs +328 -0
  145. package/dist/src/util-DsS_-v4p.js +613 -0
  146. package/dist/src/util-DuntT1Ga.js +951 -0
  147. package/dist/src/util-aWjdCYMI.cjs +667 -0
  148. package/dist/src/utils-CisQwpjA.js +94 -0
  149. package/dist/src/utils-yWamDvmz.cjs +123 -0
  150. package/dist/tsconfig.tsbuildinfo +1 -0
  151. package/drizzle/0000_lush_hellion.sql +36 -0
  152. package/drizzle/0001_wide_calypso.sql +3 -0
  153. package/drizzle/0002_tidy_juggernaut.sql +1 -0
  154. package/drizzle/0003_lively_naoko.sql +8 -0
  155. package/drizzle/0004_minor_peter_quill.sql +19 -0
  156. package/drizzle/0005_silky_millenium_guard.sql +2 -0
  157. package/drizzle/0006_harsh_caretaker.sql +42 -0
  158. package/drizzle/0007_cloudy_wong.sql +1 -0
  159. package/drizzle/0008_broad_boomer.sql +2 -0
  160. package/drizzle/0009_strong_marten_broadcloak.sql +19 -0
  161. package/drizzle/0010_needy_bishop.sql +11 -0
  162. package/drizzle/0011_moaning_millenium_guard.sql +1 -0
  163. package/drizzle/0012_late_marten_broadcloak.sql +2 -0
  164. package/drizzle/0013_previous_dormammu.sql +9 -0
  165. package/drizzle/0014_lazy_captain_universe.sql +2 -0
  166. package/drizzle/0015_zippy_wallop.sql +29 -0
  167. package/drizzle/0016_jazzy_zemo.sql +2 -0
  168. package/drizzle/0017_reflective_praxagora.sql +4 -0
  169. package/drizzle/0018_fat_vanisher.sql +22 -0
  170. package/drizzle/0019_new_clint_barton.sql +8 -0
  171. package/drizzle/0020_skinny_maverick.sql +1 -0
  172. package/drizzle/0021_mysterious_madelyne_pryor.sql +13 -0
  173. package/drizzle/0022_sleepy_ultimo.sql +25 -0
  174. package/drizzle/0023_wooden_mandrill.sql +2 -0
  175. package/drizzle/AGENTS.md +68 -0
  176. package/drizzle/CLAUDE.md +1 -0
  177. package/drizzle/meta/0000_snapshot.json +221 -0
  178. package/drizzle/meta/0001_snapshot.json +214 -0
  179. package/drizzle/meta/0002_snapshot.json +221 -0
  180. package/drizzle/meta/0005_snapshot.json +369 -0
  181. package/drizzle/meta/0006_snapshot.json +638 -0
  182. package/drizzle/meta/0007_snapshot.json +640 -0
  183. package/drizzle/meta/0008_snapshot.json +649 -0
  184. package/drizzle/meta/0009_snapshot.json +554 -0
  185. package/drizzle/meta/0010_snapshot.json +619 -0
  186. package/drizzle/meta/0011_snapshot.json +627 -0
  187. package/drizzle/meta/0012_snapshot.json +639 -0
  188. package/drizzle/meta/0013_snapshot.json +717 -0
  189. package/drizzle/meta/0014_snapshot.json +717 -0
  190. package/drizzle/meta/0015_snapshot.json +897 -0
  191. package/drizzle/meta/0016_snapshot.json +1031 -0
  192. package/drizzle/meta/0018_snapshot.json +1210 -0
  193. package/drizzle/meta/0019_snapshot.json +1165 -0
  194. package/drizzle/meta/0020_snapshot.json +1232 -0
  195. package/drizzle/meta/0021_snapshot.json +1311 -0
  196. package/drizzle/meta/0022_snapshot.json +1481 -0
  197. package/drizzle/meta/0023_snapshot.json +1496 -0
  198. package/drizzle/meta/_journal.json +174 -0
  199. package/package.json +240 -0
@@ -0,0 +1,276 @@
1
+ import { r as logger } from "./logger-C40ZGil9.js";
2
+ import { d as sleep } from "./fetch-DQckpUFz.js";
3
+ import { n as storeBlob } from "./blobs-BY8MDmpo.js";
4
+ import { t as ellipsize } from "./text-B_UCRPp2.js";
5
+ import { t as AwsBedrockGenericProvider } from "./base-C451JQfq.js";
6
+ import * as fs$1 from "fs";
7
+ import * as path$1 from "path";
8
+ //#region src/providers/bedrock/nova-reel.ts
9
+ /**
10
+ * Amazon Nova Reel Video Generation Provider
11
+ *
12
+ * Supports text-to-video and image-to-video generation using AWS Bedrock's
13
+ * async invoke API. Videos are generated in 6-second increments up to 2 minutes.
14
+ */
15
+ const MODEL_ID = "amazon.nova-reel-v1:1";
16
+ const DEFAULT_DURATION_SECONDS = 6;
17
+ const DEFAULT_POLL_INTERVAL_MS = 1e4;
18
+ const DEFAULT_MAX_POLL_TIME_MS = 9e5;
19
+ const VIDEO_DIMENSION = "1280x720";
20
+ const VIDEO_FPS = 24;
21
+ var NovaReelVideoProvider = class extends AwsBedrockGenericProvider {
22
+ videoConfig;
23
+ providerId;
24
+ constructor(modelName = MODEL_ID, options = {}) {
25
+ super(modelName, options);
26
+ this.videoConfig = options.config || {};
27
+ this.providerId = options.id;
28
+ }
29
+ id() {
30
+ return this.providerId || `bedrock:video:${this.modelName}`;
31
+ }
32
+ toString() {
33
+ return `[Amazon Nova Reel Video Provider ${this.modelName}]`;
34
+ }
35
+ /**
36
+ * Load image data from file:// path or return as-is if base64
37
+ */
38
+ loadImageData(imagePath) {
39
+ if (imagePath.startsWith("file://")) {
40
+ const filePath = imagePath.slice(7);
41
+ const resolvedPath = path$1.resolve(filePath);
42
+ if (filePath.includes("..") && resolvedPath !== path$1.resolve(path$1.normalize(filePath))) return { error: `Invalid image path (path traversal detected): ${filePath}` };
43
+ if (!fs$1.existsSync(resolvedPath)) return { error: `Image file not found: ${resolvedPath}` };
44
+ return { data: fs$1.readFileSync(resolvedPath).toString("base64") };
45
+ }
46
+ return { data: imagePath };
47
+ }
48
+ /**
49
+ * Detect image format from path or data
50
+ */
51
+ detectImageFormat(imagePath) {
52
+ const lowerPath = imagePath.toLowerCase();
53
+ if (lowerPath.includes(".png") || lowerPath.startsWith("ivborw")) return "png";
54
+ return "jpeg";
55
+ }
56
+ /**
57
+ * Build model input based on task type
58
+ */
59
+ buildModelInput(prompt, config) {
60
+ const taskType = config.taskType || "TEXT_VIDEO";
61
+ const durationSeconds = config.durationSeconds || DEFAULT_DURATION_SECONDS;
62
+ if (taskType === "TEXT_VIDEO" && durationSeconds !== 6) return { error: "TEXT_VIDEO task type only supports durationSeconds: 6" };
63
+ if ((taskType === "MULTI_SHOT_AUTOMATED" || taskType === "MULTI_SHOT_MANUAL") && (durationSeconds < 12 || durationSeconds > 120 || durationSeconds % 6 !== 0)) return { error: `Multi-shot videos require durationSeconds between 12-120 in multiples of 6. Got: ${durationSeconds}` };
64
+ const videoGenerationConfig = {
65
+ durationSeconds,
66
+ fps: VIDEO_FPS,
67
+ dimension: VIDEO_DIMENSION,
68
+ ...config.seed !== void 0 && { seed: config.seed }
69
+ };
70
+ if (taskType === "TEXT_VIDEO") {
71
+ const textToVideoParams = { text: prompt };
72
+ if (config.image) {
73
+ const { data, error } = this.loadImageData(config.image);
74
+ if (error) return { error };
75
+ textToVideoParams.images = [{
76
+ format: this.detectImageFormat(config.image),
77
+ source: { bytes: data }
78
+ }];
79
+ }
80
+ return { input: {
81
+ taskType: "TEXT_VIDEO",
82
+ textToVideoParams,
83
+ videoGenerationConfig
84
+ } };
85
+ }
86
+ if (taskType === "MULTI_SHOT_AUTOMATED") {
87
+ if (prompt.length > 4e3) return { error: `MULTI_SHOT_AUTOMATED prompt exceeds 4000 character limit. Got: ${prompt.length}` };
88
+ return { input: {
89
+ taskType: "MULTI_SHOT_AUTOMATED",
90
+ multiShotAutomatedParams: { text: prompt },
91
+ videoGenerationConfig
92
+ } };
93
+ }
94
+ if (taskType === "MULTI_SHOT_MANUAL") {
95
+ if (!config.shots || config.shots.length === 0) return { error: "MULTI_SHOT_MANUAL requires shots array in config" };
96
+ return { input: {
97
+ taskType: "MULTI_SHOT_MANUAL",
98
+ multiShotManualParams: { shots: config.shots.map((shot) => {
99
+ const shotDef = { text: shot.text };
100
+ if (shot.image) shotDef.image = shot.image;
101
+ return shotDef;
102
+ }) },
103
+ videoGenerationConfig
104
+ } };
105
+ }
106
+ return { error: `Unknown task type: ${taskType}` };
107
+ }
108
+ /**
109
+ * Start async video generation job
110
+ */
111
+ async startVideoGeneration(modelInput, s3OutputUri) {
112
+ try {
113
+ const { BedrockRuntimeClient, StartAsyncInvokeCommand } = await import("@aws-sdk/client-bedrock-runtime");
114
+ const credentials = await this.getCredentials();
115
+ const client = new BedrockRuntimeClient({
116
+ region: this.getRegion(),
117
+ ...credentials ? { credentials } : {}
118
+ });
119
+ const command = new StartAsyncInvokeCommand({
120
+ modelId: this.modelName,
121
+ modelInput,
122
+ outputDataConfig: { s3OutputDataConfig: { s3Uri: s3OutputUri } }
123
+ });
124
+ return { invocationArn: (await client.send(command)).invocationArn };
125
+ } catch (err) {
126
+ const error = err;
127
+ logger.error("[Nova Reel] Failed to start video generation", { error });
128
+ return { error: `Failed to start video generation: ${error.message || String(err)}` };
129
+ }
130
+ }
131
+ /**
132
+ * Poll for job completion
133
+ */
134
+ async pollForCompletion(invocationArn, pollIntervalMs, maxPollTimeMs) {
135
+ const startTime = Date.now();
136
+ try {
137
+ const { BedrockRuntimeClient, GetAsyncInvokeCommand } = await import("@aws-sdk/client-bedrock-runtime");
138
+ const credentials = await this.getCredentials();
139
+ const client = new BedrockRuntimeClient({
140
+ region: this.getRegion(),
141
+ ...credentials ? { credentials } : {}
142
+ });
143
+ while (Date.now() - startTime < maxPollTimeMs) {
144
+ const command = new GetAsyncInvokeCommand({ invocationArn });
145
+ const invocation = await client.send(command);
146
+ logger.debug(`[Nova Reel] Job status: ${invocation.status}`, {
147
+ invocationArn,
148
+ elapsedMs: Date.now() - startTime
149
+ });
150
+ if (invocation.status === "Completed") return { response: {
151
+ invocationArn: invocation.invocationArn || invocationArn,
152
+ status: "Completed",
153
+ submitTime: invocation.submitTime?.toISOString(),
154
+ endTime: invocation.endTime?.toISOString(),
155
+ outputDataConfig: invocation.outputDataConfig
156
+ } };
157
+ if (invocation.status === "Failed") return { error: `Video generation failed: ${invocation.failureMessage}` };
158
+ await sleep(pollIntervalMs);
159
+ }
160
+ return { error: `Video generation timed out after ${maxPollTimeMs / 1e3} seconds` };
161
+ } catch (err) {
162
+ const error = err;
163
+ logger.error("[Nova Reel] Polling error", {
164
+ error,
165
+ invocationArn
166
+ });
167
+ return { error: `Polling error: ${error.message || String(err)}` };
168
+ }
169
+ }
170
+ /**
171
+ * Download video from S3 and store to blob storage
172
+ */
173
+ async downloadAndStoreVideo(s3Uri) {
174
+ try {
175
+ const match = s3Uri.match(/^s3:\/\/([^/]+)\/(.+)$/);
176
+ if (!match) return { error: `Invalid S3 URI: ${s3Uri}` };
177
+ const [, bucket, keyPrefix] = match;
178
+ const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
179
+ const credentials = await this.getCredentials();
180
+ const s3 = new S3Client({
181
+ region: this.getRegion(),
182
+ ...credentials ? { credentials } : {}
183
+ });
184
+ const videoKey = keyPrefix.endsWith("/") ? `${keyPrefix}output.mp4` : `${keyPrefix}/output.mp4`;
185
+ logger.debug("[Nova Reel] Downloading video from S3", {
186
+ bucket,
187
+ key: videoKey
188
+ });
189
+ const response = await s3.send(new GetObjectCommand({
190
+ Bucket: bucket,
191
+ Key: videoKey
192
+ }));
193
+ if (!response.Body) return { error: "Empty response from S3" };
194
+ const { ref } = await storeBlob(Buffer.from(await response.Body.transformToByteArray()), "video/mp4", {
195
+ kind: "video",
196
+ location: "response.video"
197
+ });
198
+ logger.debug(`[Nova Reel] Stored video to blob storage`, {
199
+ uri: ref.uri,
200
+ hash: ref.hash
201
+ });
202
+ return { blobRef: ref };
203
+ } catch (err) {
204
+ const error = err;
205
+ logger.error("[Nova Reel] S3 download error", {
206
+ error,
207
+ s3Uri
208
+ });
209
+ if (error.name === "MODULE_NOT_FOUND" || String(err).includes("Cannot find module")) return { error: "The @aws-sdk/client-s3 package is required for Nova Reel video downloads. Install it with: npm install @aws-sdk/client-s3" };
210
+ return { error: `S3 download error: ${error.message || String(err)}` };
211
+ }
212
+ }
213
+ async callApi(prompt, context) {
214
+ const s3OutputUri = this.videoConfig.s3OutputUri;
215
+ if (!s3OutputUri) return { error: "Nova Reel requires s3OutputUri in provider config. Example: s3://my-bucket/videos" };
216
+ if (!s3OutputUri.startsWith("s3://")) return { error: `Invalid s3OutputUri: ${s3OutputUri}. Must start with s3://` };
217
+ if (!prompt || prompt.trim() === "") return { error: "Prompt is required for video generation" };
218
+ const config = {
219
+ ...this.videoConfig,
220
+ ...context?.prompt?.config
221
+ };
222
+ const startTime = Date.now();
223
+ const { input: modelInput, error: buildError } = this.buildModelInput(prompt, config);
224
+ if (buildError || !modelInput) return { error: buildError || "Failed to build model input" };
225
+ logger.info(`[Nova Reel] Starting video generation job...`, {
226
+ taskType: config.taskType || "TEXT_VIDEO",
227
+ durationSeconds: config.durationSeconds || DEFAULT_DURATION_SECONDS,
228
+ s3OutputUri
229
+ });
230
+ const { invocationArn, error: startError } = await this.startVideoGeneration(modelInput, s3OutputUri);
231
+ if (startError || !invocationArn) return { error: startError || "Failed to start video generation" };
232
+ logger.info(`[Nova Reel] Job started`, { invocationArn });
233
+ const pollIntervalMs = config.pollIntervalMs || DEFAULT_POLL_INTERVAL_MS;
234
+ const maxPollTimeMs = config.maxPollTimeMs || DEFAULT_MAX_POLL_TIME_MS;
235
+ const { response, error: pollError } = await this.pollForCompletion(invocationArn, pollIntervalMs, maxPollTimeMs);
236
+ if (pollError || !response) return { error: pollError || "Polling failed" };
237
+ const outputS3Uri = response.outputDataConfig?.s3OutputDataConfig?.s3Uri;
238
+ if (!outputS3Uri) return { error: "No output location in response" };
239
+ let blobRef;
240
+ const outputUrl = `${outputS3Uri}/output.mp4`;
241
+ if (config.downloadFromS3 !== false) {
242
+ const { blobRef: ref, error: downloadError } = await this.downloadAndStoreVideo(outputS3Uri);
243
+ if (downloadError) logger.warn(`[Nova Reel] Failed to download video: ${downloadError}. Using S3 URL.`);
244
+ else blobRef = ref;
245
+ }
246
+ const latencyMs = Date.now() - startTime;
247
+ const durationSeconds = config.durationSeconds || DEFAULT_DURATION_SECONDS;
248
+ return {
249
+ output: `[Video: ${ellipsize(prompt.replace(/\r?\n|\r/g, " ").replace(/\[/g, "(").replace(/\]/g, ")"), 50)}](${blobRef?.uri || outputUrl})`,
250
+ cached: false,
251
+ latencyMs,
252
+ video: {
253
+ id: invocationArn,
254
+ blobRef,
255
+ url: blobRef ? void 0 : outputUrl,
256
+ format: "mp4",
257
+ size: VIDEO_DIMENSION,
258
+ duration: durationSeconds,
259
+ model: this.modelName,
260
+ resolution: VIDEO_DIMENSION
261
+ },
262
+ metadata: {
263
+ invocationArn,
264
+ model: this.modelName,
265
+ taskType: config.taskType || "TEXT_VIDEO",
266
+ durationSeconds,
267
+ s3OutputUri: outputS3Uri,
268
+ ...blobRef && { blobHash: blobRef.hash }
269
+ }
270
+ };
271
+ }
272
+ };
273
+ //#endregion
274
+ export { NovaReelVideoProvider };
275
+
276
+ //# sourceMappingURL=nova-reel-CTapvqYH.js.map
@@ -0,0 +1,278 @@
1
+ const require_logger = require("./logger-DyfK9PBt.cjs");
2
+ const require_fetch = require("./fetch-BTxakTSg.cjs");
3
+ const require_blobs = require("./blobs-BgcNn97m.cjs");
4
+ const require_text = require("./text-CW1cyrwj.cjs");
5
+ const require_base = require("./base-BEysXrkq.cjs");
6
+ let fs = require("fs");
7
+ fs = require_logger.__toESM(fs);
8
+ let path = require("path");
9
+ path = require_logger.__toESM(path);
10
+ //#region src/providers/bedrock/nova-reel.ts
11
+ /**
12
+ * Amazon Nova Reel Video Generation Provider
13
+ *
14
+ * Supports text-to-video and image-to-video generation using AWS Bedrock's
15
+ * async invoke API. Videos are generated in 6-second increments up to 2 minutes.
16
+ */
17
+ const MODEL_ID = "amazon.nova-reel-v1:1";
18
+ const DEFAULT_DURATION_SECONDS = 6;
19
+ const DEFAULT_POLL_INTERVAL_MS = 1e4;
20
+ const DEFAULT_MAX_POLL_TIME_MS = 9e5;
21
+ const VIDEO_DIMENSION = "1280x720";
22
+ const VIDEO_FPS = 24;
23
+ var NovaReelVideoProvider = class extends require_base.AwsBedrockGenericProvider {
24
+ videoConfig;
25
+ providerId;
26
+ constructor(modelName = MODEL_ID, options = {}) {
27
+ super(modelName, options);
28
+ this.videoConfig = options.config || {};
29
+ this.providerId = options.id;
30
+ }
31
+ id() {
32
+ return this.providerId || `bedrock:video:${this.modelName}`;
33
+ }
34
+ toString() {
35
+ return `[Amazon Nova Reel Video Provider ${this.modelName}]`;
36
+ }
37
+ /**
38
+ * Load image data from file:// path or return as-is if base64
39
+ */
40
+ loadImageData(imagePath) {
41
+ if (imagePath.startsWith("file://")) {
42
+ const filePath = imagePath.slice(7);
43
+ const resolvedPath = path.resolve(filePath);
44
+ if (filePath.includes("..") && resolvedPath !== path.resolve(path.normalize(filePath))) return { error: `Invalid image path (path traversal detected): ${filePath}` };
45
+ if (!fs.existsSync(resolvedPath)) return { error: `Image file not found: ${resolvedPath}` };
46
+ return { data: fs.readFileSync(resolvedPath).toString("base64") };
47
+ }
48
+ return { data: imagePath };
49
+ }
50
+ /**
51
+ * Detect image format from path or data
52
+ */
53
+ detectImageFormat(imagePath) {
54
+ const lowerPath = imagePath.toLowerCase();
55
+ if (lowerPath.includes(".png") || lowerPath.startsWith("ivborw")) return "png";
56
+ return "jpeg";
57
+ }
58
+ /**
59
+ * Build model input based on task type
60
+ */
61
+ buildModelInput(prompt, config) {
62
+ const taskType = config.taskType || "TEXT_VIDEO";
63
+ const durationSeconds = config.durationSeconds || DEFAULT_DURATION_SECONDS;
64
+ if (taskType === "TEXT_VIDEO" && durationSeconds !== 6) return { error: "TEXT_VIDEO task type only supports durationSeconds: 6" };
65
+ if ((taskType === "MULTI_SHOT_AUTOMATED" || taskType === "MULTI_SHOT_MANUAL") && (durationSeconds < 12 || durationSeconds > 120 || durationSeconds % 6 !== 0)) return { error: `Multi-shot videos require durationSeconds between 12-120 in multiples of 6. Got: ${durationSeconds}` };
66
+ const videoGenerationConfig = {
67
+ durationSeconds,
68
+ fps: VIDEO_FPS,
69
+ dimension: VIDEO_DIMENSION,
70
+ ...config.seed !== void 0 && { seed: config.seed }
71
+ };
72
+ if (taskType === "TEXT_VIDEO") {
73
+ const textToVideoParams = { text: prompt };
74
+ if (config.image) {
75
+ const { data, error } = this.loadImageData(config.image);
76
+ if (error) return { error };
77
+ textToVideoParams.images = [{
78
+ format: this.detectImageFormat(config.image),
79
+ source: { bytes: data }
80
+ }];
81
+ }
82
+ return { input: {
83
+ taskType: "TEXT_VIDEO",
84
+ textToVideoParams,
85
+ videoGenerationConfig
86
+ } };
87
+ }
88
+ if (taskType === "MULTI_SHOT_AUTOMATED") {
89
+ if (prompt.length > 4e3) return { error: `MULTI_SHOT_AUTOMATED prompt exceeds 4000 character limit. Got: ${prompt.length}` };
90
+ return { input: {
91
+ taskType: "MULTI_SHOT_AUTOMATED",
92
+ multiShotAutomatedParams: { text: prompt },
93
+ videoGenerationConfig
94
+ } };
95
+ }
96
+ if (taskType === "MULTI_SHOT_MANUAL") {
97
+ if (!config.shots || config.shots.length === 0) return { error: "MULTI_SHOT_MANUAL requires shots array in config" };
98
+ return { input: {
99
+ taskType: "MULTI_SHOT_MANUAL",
100
+ multiShotManualParams: { shots: config.shots.map((shot) => {
101
+ const shotDef = { text: shot.text };
102
+ if (shot.image) shotDef.image = shot.image;
103
+ return shotDef;
104
+ }) },
105
+ videoGenerationConfig
106
+ } };
107
+ }
108
+ return { error: `Unknown task type: ${taskType}` };
109
+ }
110
+ /**
111
+ * Start async video generation job
112
+ */
113
+ async startVideoGeneration(modelInput, s3OutputUri) {
114
+ try {
115
+ const { BedrockRuntimeClient, StartAsyncInvokeCommand } = await import("@aws-sdk/client-bedrock-runtime");
116
+ const credentials = await this.getCredentials();
117
+ const client = new BedrockRuntimeClient({
118
+ region: this.getRegion(),
119
+ ...credentials ? { credentials } : {}
120
+ });
121
+ const command = new StartAsyncInvokeCommand({
122
+ modelId: this.modelName,
123
+ modelInput,
124
+ outputDataConfig: { s3OutputDataConfig: { s3Uri: s3OutputUri } }
125
+ });
126
+ return { invocationArn: (await client.send(command)).invocationArn };
127
+ } catch (err) {
128
+ const error = err;
129
+ require_logger.logger.error("[Nova Reel] Failed to start video generation", { error });
130
+ return { error: `Failed to start video generation: ${error.message || String(err)}` };
131
+ }
132
+ }
133
+ /**
134
+ * Poll for job completion
135
+ */
136
+ async pollForCompletion(invocationArn, pollIntervalMs, maxPollTimeMs) {
137
+ const startTime = Date.now();
138
+ try {
139
+ const { BedrockRuntimeClient, GetAsyncInvokeCommand } = await import("@aws-sdk/client-bedrock-runtime");
140
+ const credentials = await this.getCredentials();
141
+ const client = new BedrockRuntimeClient({
142
+ region: this.getRegion(),
143
+ ...credentials ? { credentials } : {}
144
+ });
145
+ while (Date.now() - startTime < maxPollTimeMs) {
146
+ const command = new GetAsyncInvokeCommand({ invocationArn });
147
+ const invocation = await client.send(command);
148
+ require_logger.logger.debug(`[Nova Reel] Job status: ${invocation.status}`, {
149
+ invocationArn,
150
+ elapsedMs: Date.now() - startTime
151
+ });
152
+ if (invocation.status === "Completed") return { response: {
153
+ invocationArn: invocation.invocationArn || invocationArn,
154
+ status: "Completed",
155
+ submitTime: invocation.submitTime?.toISOString(),
156
+ endTime: invocation.endTime?.toISOString(),
157
+ outputDataConfig: invocation.outputDataConfig
158
+ } };
159
+ if (invocation.status === "Failed") return { error: `Video generation failed: ${invocation.failureMessage}` };
160
+ await require_fetch.sleep(pollIntervalMs);
161
+ }
162
+ return { error: `Video generation timed out after ${maxPollTimeMs / 1e3} seconds` };
163
+ } catch (err) {
164
+ const error = err;
165
+ require_logger.logger.error("[Nova Reel] Polling error", {
166
+ error,
167
+ invocationArn
168
+ });
169
+ return { error: `Polling error: ${error.message || String(err)}` };
170
+ }
171
+ }
172
+ /**
173
+ * Download video from S3 and store to blob storage
174
+ */
175
+ async downloadAndStoreVideo(s3Uri) {
176
+ try {
177
+ const match = s3Uri.match(/^s3:\/\/([^/]+)\/(.+)$/);
178
+ if (!match) return { error: `Invalid S3 URI: ${s3Uri}` };
179
+ const [, bucket, keyPrefix] = match;
180
+ const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
181
+ const credentials = await this.getCredentials();
182
+ const s3 = new S3Client({
183
+ region: this.getRegion(),
184
+ ...credentials ? { credentials } : {}
185
+ });
186
+ const videoKey = keyPrefix.endsWith("/") ? `${keyPrefix}output.mp4` : `${keyPrefix}/output.mp4`;
187
+ require_logger.logger.debug("[Nova Reel] Downloading video from S3", {
188
+ bucket,
189
+ key: videoKey
190
+ });
191
+ const response = await s3.send(new GetObjectCommand({
192
+ Bucket: bucket,
193
+ Key: videoKey
194
+ }));
195
+ if (!response.Body) return { error: "Empty response from S3" };
196
+ const { ref } = await require_blobs.storeBlob(Buffer.from(await response.Body.transformToByteArray()), "video/mp4", {
197
+ kind: "video",
198
+ location: "response.video"
199
+ });
200
+ require_logger.logger.debug(`[Nova Reel] Stored video to blob storage`, {
201
+ uri: ref.uri,
202
+ hash: ref.hash
203
+ });
204
+ return { blobRef: ref };
205
+ } catch (err) {
206
+ const error = err;
207
+ require_logger.logger.error("[Nova Reel] S3 download error", {
208
+ error,
209
+ s3Uri
210
+ });
211
+ if (error.name === "MODULE_NOT_FOUND" || String(err).includes("Cannot find module")) return { error: "The @aws-sdk/client-s3 package is required for Nova Reel video downloads. Install it with: npm install @aws-sdk/client-s3" };
212
+ return { error: `S3 download error: ${error.message || String(err)}` };
213
+ }
214
+ }
215
+ async callApi(prompt, context) {
216
+ const s3OutputUri = this.videoConfig.s3OutputUri;
217
+ if (!s3OutputUri) return { error: "Nova Reel requires s3OutputUri in provider config. Example: s3://my-bucket/videos" };
218
+ if (!s3OutputUri.startsWith("s3://")) return { error: `Invalid s3OutputUri: ${s3OutputUri}. Must start with s3://` };
219
+ if (!prompt || prompt.trim() === "") return { error: "Prompt is required for video generation" };
220
+ const config = {
221
+ ...this.videoConfig,
222
+ ...context?.prompt?.config
223
+ };
224
+ const startTime = Date.now();
225
+ const { input: modelInput, error: buildError } = this.buildModelInput(prompt, config);
226
+ if (buildError || !modelInput) return { error: buildError || "Failed to build model input" };
227
+ require_logger.logger.info(`[Nova Reel] Starting video generation job...`, {
228
+ taskType: config.taskType || "TEXT_VIDEO",
229
+ durationSeconds: config.durationSeconds || DEFAULT_DURATION_SECONDS,
230
+ s3OutputUri
231
+ });
232
+ const { invocationArn, error: startError } = await this.startVideoGeneration(modelInput, s3OutputUri);
233
+ if (startError || !invocationArn) return { error: startError || "Failed to start video generation" };
234
+ require_logger.logger.info(`[Nova Reel] Job started`, { invocationArn });
235
+ const pollIntervalMs = config.pollIntervalMs || DEFAULT_POLL_INTERVAL_MS;
236
+ const maxPollTimeMs = config.maxPollTimeMs || DEFAULT_MAX_POLL_TIME_MS;
237
+ const { response, error: pollError } = await this.pollForCompletion(invocationArn, pollIntervalMs, maxPollTimeMs);
238
+ if (pollError || !response) return { error: pollError || "Polling failed" };
239
+ const outputS3Uri = response.outputDataConfig?.s3OutputDataConfig?.s3Uri;
240
+ if (!outputS3Uri) return { error: "No output location in response" };
241
+ let blobRef;
242
+ const outputUrl = `${outputS3Uri}/output.mp4`;
243
+ if (config.downloadFromS3 !== false) {
244
+ const { blobRef: ref, error: downloadError } = await this.downloadAndStoreVideo(outputS3Uri);
245
+ if (downloadError) require_logger.logger.warn(`[Nova Reel] Failed to download video: ${downloadError}. Using S3 URL.`);
246
+ else blobRef = ref;
247
+ }
248
+ const latencyMs = Date.now() - startTime;
249
+ const durationSeconds = config.durationSeconds || DEFAULT_DURATION_SECONDS;
250
+ return {
251
+ output: `[Video: ${require_text.ellipsize(prompt.replace(/\r?\n|\r/g, " ").replace(/\[/g, "(").replace(/\]/g, ")"), 50)}](${blobRef?.uri || outputUrl})`,
252
+ cached: false,
253
+ latencyMs,
254
+ video: {
255
+ id: invocationArn,
256
+ blobRef,
257
+ url: blobRef ? void 0 : outputUrl,
258
+ format: "mp4",
259
+ size: VIDEO_DIMENSION,
260
+ duration: durationSeconds,
261
+ model: this.modelName,
262
+ resolution: VIDEO_DIMENSION
263
+ },
264
+ metadata: {
265
+ invocationArn,
266
+ model: this.modelName,
267
+ taskType: config.taskType || "TEXT_VIDEO",
268
+ durationSeconds,
269
+ s3OutputUri: outputS3Uri,
270
+ ...blobRef && { blobHash: blobRef.hash }
271
+ }
272
+ };
273
+ }
274
+ };
275
+ //#endregion
276
+ exports.NovaReelVideoProvider = NovaReelVideoProvider;
277
+
278
+ //# sourceMappingURL=nova-reel-DlWuuroF.cjs.map