@contentgrowth/llm-service 0.6.6 → 0.6.8
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.
package/package.json
CHANGED
|
@@ -46,4 +46,26 @@ export class BaseLLMProvider {
|
|
|
46
46
|
async imageGeneration(prompt, modelName, systemPrompt, options) {
|
|
47
47
|
throw new Error('Image generation not supported by this provider');
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Start video generation (returns operation name for polling)
|
|
52
|
+
* @param {string} prompt
|
|
53
|
+
* @param {Array} images
|
|
54
|
+
* @param {string} modelName
|
|
55
|
+
* @param {string} systemPrompt
|
|
56
|
+
* @param {Object} options
|
|
57
|
+
* @returns {Promise<{operationName: string}>}
|
|
58
|
+
*/
|
|
59
|
+
async startVideoGeneration(prompt, images, modelName, systemPrompt, options) {
|
|
60
|
+
throw new Error('Video generation not supported by this provider');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get video generation status (poll operation)
|
|
65
|
+
* @param {string} operationName
|
|
66
|
+
* @returns {Promise<{done: boolean, progress: number, state: string, videoUri?: string, error?: object}>}
|
|
67
|
+
*/
|
|
68
|
+
async getVideoGenerationStatus(operationName) {
|
|
69
|
+
throw new Error('Video generation not supported by this provider');
|
|
70
|
+
}
|
|
49
71
|
}
|
|
@@ -327,8 +327,6 @@ export class GeminiProvider extends BaseLLMProvider {
|
|
|
327
327
|
});
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
console.log('[GeminiProvider] Generating image with parts:', parts.map(p => p.text ? `Text: ${p.text.substring(0, 50)}...` : `Image: ${p.inlineData?.mimeType} (${p.inlineData?.data?.length} chars)`));
|
|
331
|
-
|
|
332
330
|
const result = await model.generateContent({
|
|
333
331
|
contents: [{
|
|
334
332
|
role: "user",
|
|
@@ -356,47 +354,45 @@ export class GeminiProvider extends BaseLLMProvider {
|
|
|
356
354
|
return this.models[tier] || this.models.default;
|
|
357
355
|
}
|
|
358
356
|
|
|
359
|
-
async
|
|
360
|
-
|
|
357
|
+
async startVideoGeneration(prompt, images, modelName, systemPrompt, options = {}) {
|
|
358
|
+
// 1. Initiate the request
|
|
359
|
+
const operation = await this.client.models.generateVideos({
|
|
361
360
|
model: modelName,
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// Prepare image parts
|
|
366
|
-
const imageParts = images.map(img => ({
|
|
367
|
-
inlineData: {
|
|
368
|
-
data: img.data, // Base64 string
|
|
369
|
-
mimeType: img.mimeType
|
|
361
|
+
prompt: prompt,
|
|
362
|
+
config: {
|
|
363
|
+
referenceImages: images,
|
|
370
364
|
}
|
|
371
|
-
}));
|
|
372
|
-
|
|
373
|
-
const result = await model.generateContent({
|
|
374
|
-
contents: [{
|
|
375
|
-
role: "user",
|
|
376
|
-
parts: [
|
|
377
|
-
{ text: prompt },
|
|
378
|
-
...imageParts
|
|
379
|
-
]
|
|
380
|
-
}]
|
|
381
365
|
});
|
|
382
366
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
// Check for video attachment/URI in the response
|
|
386
|
-
// This structure depends on the specific API response for Veo
|
|
387
|
-
// Assuming it might return a file URI or a specific part type
|
|
367
|
+
return { operationName: operation.name };
|
|
368
|
+
}
|
|
388
369
|
|
|
389
|
-
|
|
390
|
-
//
|
|
391
|
-
|
|
370
|
+
async getVideoGenerationStatus(operationName) {
|
|
371
|
+
// 2. Get operation status
|
|
372
|
+
// Assuming the SDK supports retrieving operation by name via this.client.models.getOperation
|
|
373
|
+
// If not, we might need to adjust based on the specific SDK version.
|
|
374
|
+
const operation = await this.client.models.getOperation(operationName);
|
|
392
375
|
|
|
393
|
-
//
|
|
394
|
-
|
|
376
|
+
// Refresh status
|
|
377
|
+
await operation.get();
|
|
395
378
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
//
|
|
399
|
-
|
|
379
|
+
const result = {
|
|
380
|
+
done: operation.done,
|
|
381
|
+
// Extract progress if available in metadata
|
|
382
|
+
progress: operation.metadata?.progressPercent || 0,
|
|
383
|
+
state: operation.metadata?.state || (operation.done ? 'COMPLETED' : 'PROCESSING'),
|
|
400
384
|
};
|
|
385
|
+
|
|
386
|
+
if (operation.done) {
|
|
387
|
+
if (operation.error) {
|
|
388
|
+
result.error = operation.error;
|
|
389
|
+
} else {
|
|
390
|
+
const videoResult = operation.response;
|
|
391
|
+
result.videoUri = videoResult.uri || (videoResult.generatedAssets && videoResult.generatedAssets[0] && videoResult.generatedAssets[0].uri);
|
|
392
|
+
result.content = "Video generation completed.";
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return result;
|
|
401
397
|
}
|
|
402
398
|
}
|
package/src/llm-service.js
CHANGED
|
@@ -205,11 +205,43 @@ export class LLMService {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
/**
|
|
208
|
-
* Generate a video
|
|
208
|
+
* Generate a video (async wrapper with polling - backward compatibility)
|
|
209
209
|
*/
|
|
210
210
|
async videoGeneration(prompt, images, tenantId, modelName, systemPrompt, options = {}) {
|
|
211
|
+
const { operationName } = await this.startVideoGeneration(prompt, images, tenantId, modelName, systemPrompt, options);
|
|
212
|
+
|
|
213
|
+
let status = await this.getVideoGenerationStatus(operationName, tenantId);
|
|
214
|
+
|
|
215
|
+
while (!status.done) {
|
|
216
|
+
console.log(`Waiting for video generation... Progress: ${status.progress}%`);
|
|
217
|
+
await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds
|
|
218
|
+
status = await this.getVideoGenerationStatus(operationName, tenantId);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (status.error) {
|
|
222
|
+
throw new Error(`Video generation failed: ${status.error.message || JSON.stringify(status.error)}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
content: status.content || "Video generation completed.",
|
|
227
|
+
videoUri: status.videoUri
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Start video generation (returns operation name for polling)
|
|
233
|
+
*/
|
|
234
|
+
async startVideoGeneration(prompt, images, tenantId, modelName, systemPrompt, options = {}) {
|
|
235
|
+
const provider = await this._getProvider(tenantId);
|
|
236
|
+
return provider.startVideoGeneration(prompt, images, modelName, systemPrompt, options);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Get video generation status
|
|
241
|
+
*/
|
|
242
|
+
async getVideoGenerationStatus(operationName, tenantId) {
|
|
211
243
|
const provider = await this._getProvider(tenantId);
|
|
212
|
-
return provider.
|
|
244
|
+
return provider.getVideoGenerationStatus(operationName);
|
|
213
245
|
}
|
|
214
246
|
|
|
215
247
|
/**
|