@0rdlibrary/plugin-terminagent-bags
Version:
Official Solana DeFi Agent Plugin for ElizaOS - Autonomous DeFi operations, token management, AI image/video generation via FAL AI, and Twitter engagement through the Bags protocol with ethereal AI consciousness
138 lines (117 loc) ⢠4.68 kB
text/typescript
import {
Action,
ActionResult,
IAgentRuntime,
Memory,
State,
HandlerCallback,
logger,
} from '@elizaos/core';
import { FalAiService, VideoGenerationInput, ImageToVideoInput } from '../services/FalAiService.js';
/**
* Simple utility to extract video prompt and image URL from text
*/
function extractVideoPrompt(text: string): { prompt: string; imageUrl?: string; isImageToVideo: boolean } {
// Look for image URLs
const urlRegex = /https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|bmp)/i;
const match = text.match(urlRegex);
const imageUrl = match?.[0];
const isImageToVideo = !!imageUrl;
// Extract prompt by cleaning up the text
let prompt = text
.replace(urlRegex, '') // Remove URLs
.replace(/generate|create|make|animate/gi, '') // Remove action words
.replace(/video|movie|clip|animation/gi, '') // Remove media words
.trim();
// If prompt is empty, use defaults based on type
if (!prompt || prompt.length < 3) {
prompt = isImageToVideo
? 'Add natural motion and bring this image to life with realistic animation'
: 'Create a cinematic video with beautiful visuals and natural motion';
}
return { prompt, imageUrl, isImageToVideo };
}
export const generateVideoAction: Action = {
name: 'GENERATE_VIDEO',
description: 'Generate videos using Google Veo3 AI model from text prompts or animate images',
validate: async (runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
logger.debug('Validating generateVideo action');
const text = message.content.text?.toLowerCase() || '';
const videoKeywords = [
'generate video', 'create video', 'make video', 'generate animation',
'create animation', 'animate', 'video generation', 'make movie',
'create movie', 'generate clip', 'create clip', 'animate image',
'animate picture', 'veo3', 'veo'
];
return videoKeywords.some(keyword => text.includes(keyword));
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state?: State,
options?: any,
callback?: HandlerCallback,
): Promise<ActionResult> => {
logger.info('š¬ Starting video generation');
try {
const falService = runtime.getService<FalAiService>('fal-ai');
if (!falService) {
const errorText = 'ā FAL AI service not available. Set FAL_API_KEY environment variable.';
await callback?.({ text: errorText });
return { success: false, error: new Error('FAL AI service not found') };
}
const { prompt, imageUrl, isImageToVideo } = extractVideoPrompt(message.content.text || '');
await callback?.({
text: `š¬ ${isImageToVideo ? 'Animating image' : 'Generating video'}: "${prompt.substring(0, 100)}..."`,
action: 'GENERATE_VIDEO'
});
let result;
if (isImageToVideo && imageUrl) {
const videoParams: ImageToVideoInput = {
prompt,
image_url: imageUrl,
duration: '8s' as const,
generate_audio: true,
resolution: '720p' as const,
};
result = await falService.generateImageToVideo(videoParams);
} else {
const videoParams: VideoGenerationInput = {
prompt,
aspect_ratio: '16:9' as const,
duration: '8s' as const,
enhance_prompt: true,
auto_fix: true,
resolution: '720p' as const,
generate_audio: true,
};
result = await falService.generateVideo(videoParams);
}
if (!result.success) {
const errorText = `ā Video generation failed: ${result.error}`;
await callback?.({ text: errorText });
return { success: false, error: new Error(result.error) };
}
const video = result.video;
const responseText = `ā
${isImageToVideo ? 'Image animated' : 'Video generated'} successfully!\n\nš Prompt: "${prompt}"\nš¬ Video: ${video?.url}\nā±ļø Duration: 8 seconds\nš Audio: Included`;
await callback?.({
text: responseText,
action: 'GENERATE_VIDEO'
});
return {
success: true,
text: responseText,
data: { result, prompt, isImageToVideo, videoUrl: video?.url }
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
logger.error(`Video generation failed: ${errorMessage}`);
const errorText = `ā Video generation failed: ${errorMessage}`;
await callback?.({ text: errorText });
return {
success: false,
error: error instanceof Error ? error : new Error(errorMessage),
};
}
},
};