UNPKG

contaigents

Version:

Modular AI Content Ecosystem with Audio Generation

286 lines (281 loc) โ€ข 11.3 kB
#!/usr/bin/env node /** * Audio Generation Tool Demo * * This script demonstrates the AudioGenerationTool in various scenarios: * 1. Basic audio generation * 2. Multi-tool workflow (read file โ†’ generate audio) * 3. Error handling scenarios * 4. XML tool call parsing and response formatting */ import { ToolManager } from '../services/tools/ToolManager.js'; import fs from 'fs/promises'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Demo configuration const DEMO_BASE_DIR = path.join(__dirname, 'demo_audio_output'); const API_KEY = process.env.GEMINI_API_KEY; class AudioGenerationDemo { constructor() { this.toolManager = new ToolManager(DEMO_BASE_DIR); } async setup() { console.log('๐ŸŽฌ Setting up Audio Generation Tool Demo'); console.log('='.repeat(50)); // Create demo directory await fs.mkdir(DEMO_BASE_DIR, { recursive: true }); // Create a sample text file for reading const sampleText = `# Welcome to Contaigents Contaigents is an open-source platform for creating and managing content using locally running AI agents. This is a demonstration of the audio generation tool that can convert text content into speech using various AI providers like Gemini. The tool supports multiple voices and can handle long text content by automatically chunking it appropriately.`; await fs.writeFile(path.join(DEMO_BASE_DIR, 'sample.md'), sampleText); console.log(`๐Ÿ“ Demo directory created: ${DEMO_BASE_DIR}`); console.log(`๐Ÿ“ Sample file created: sample.md`); console.log(''); } async demonstrateBasicAudioGeneration() { console.log('๐ŸŽ™๏ธ Demo 1: Basic Audio Generation'); console.log('-'.repeat(30)); const toolCall = { tool_name: 'audio_generation', parameters: { text: 'Hello! This is a demonstration of the audio generation tool. It can convert text to speech using AI providers.', output_path: 'demo/basic_greeting.wav', voice: 'zephyr', provider: 'gemini' }, id: 'demo_1' }; console.log('๐Ÿ“‹ Tool Call:'); console.log(this.formatToolCallXML(toolCall)); console.log(''); const result = await this.toolManager.executeTool(toolCall); const response = { id: toolCall.id, tool_call: toolCall, result }; console.log('๐Ÿ“ค Tool Response:'); console.log(this.formatToolResponseXML(response)); console.log(''); } async demonstrateMultiToolWorkflow() { console.log('๐Ÿ”„ Demo 2: Multi-Tool Workflow (Read File โ†’ Generate Audio)'); console.log('-'.repeat(50)); // Step 1: Read the sample file const readToolCall = { tool_name: 'read_file', parameters: { file_path: 'sample.md' }, id: 'demo_2a' }; console.log('๐Ÿ“– Step 1: Reading file'); console.log('Tool Call:'); console.log(this.formatToolCallXML(readToolCall)); console.log(''); const readResult = await this.toolManager.executeTool(readToolCall); const readResponse = { id: readToolCall.id, tool_call: readToolCall, result: readResult }; console.log('Tool Response:'); console.log(this.formatToolResponseXML(readResponse)); console.log(''); if (readResult.success) { // Step 2: Generate audio from the file content const audioToolCall = { tool_name: 'audio_generation', parameters: { text: readResult.data.content, output_path: 'demo/sample_narration.wav', voice: 'despina', provider: 'gemini' }, id: 'demo_2b' }; console.log('๐ŸŽ™๏ธ Step 2: Generating audio from file content'); console.log('Tool Call:'); console.log(this.formatToolCallXML(audioToolCall)); console.log(''); const audioResult = await this.toolManager.executeTool(audioToolCall); const audioResponse = { id: audioToolCall.id, tool_call: audioToolCall, result: audioResult }; console.log('Tool Response:'); console.log(this.formatToolResponseXML(audioResponse)); console.log(''); } } async demonstrateErrorHandling() { console.log('โŒ Demo 3: Error Handling Scenarios'); console.log('-'.repeat(35)); // Error 1: Missing required parameter console.log('Error Scenario 1: Missing required parameter'); const errorCall1 = { tool_name: 'audio_generation', parameters: { output_path: 'error_test.wav' // Missing 'text' parameter }, id: 'error_1' }; const errorResult1 = await this.toolManager.executeTool(errorCall1); console.log('Result:', errorResult1.error); console.log(''); // Error 2: Path traversal attempt console.log('Error Scenario 2: Path traversal attempt'); const errorCall2 = { tool_name: 'audio_generation', parameters: { text: 'Hello world', output_path: '../../../etc/passwd' }, id: 'error_2' }; const errorResult2 = await this.toolManager.executeTool(errorCall2); console.log('Result:', errorResult2.error); console.log(''); // Error 3: No API key (if not set) if (!API_KEY) { console.log('Error Scenario 3: Missing API key'); const errorCall3 = { tool_name: 'audio_generation', parameters: { text: 'Hello world', output_path: 'test.wav' }, id: 'error_3' }; const errorResult3 = await this.toolManager.executeTool(errorCall3); console.log('Result:', errorResult3.error); console.log(''); } } async demonstrateAgentConversation() { console.log('๐Ÿ’ฌ Demo 4: Agent Conversation Simulation'); console.log('-'.repeat(40)); console.log('User: "Can you create an audio version of the sample.md file for accessibility?"'); console.log(''); console.log('Agent: "I\'ll read the sample.md file and generate an audio version for you."'); console.log(''); // Simulate agent making tool calls const conversationToolCalls = `<tool_call name="read_file" id="1"> <file_path>sample.md</file_path> </tool_call> <tool_call name="audio_generation" id="2"> <text>[Content will be inserted after reading file]</text> <output_path>accessibility/sample_audio.wav</output_path> <voice>Zephyr</voice> </tool_call>`; console.log('Agent Tool Calls:'); console.log(conversationToolCalls); console.log(''); // Execute the actual workflow const readCall = { tool_name: 'read_file', parameters: { file_path: 'sample.md' }, id: '1' }; const readResult = await this.toolManager.executeTool(readCall); if (readResult.success) { const audioCall = { tool_name: 'audio_generation', parameters: { text: readResult.data.content, output_path: 'accessibility/sample_audio.wav', voice: 'zephyr' }, id: '2' }; const audioResult = await this.toolManager.executeTool(audioCall); if (audioResult.success) { console.log('Agent Final Response:'); console.log(`"I've successfully created an audio version of your sample.md file! The narration has been saved to \`${audioResult.data.output_file_path}\` (${audioResult.data.file_size} bytes, approximately ${audioResult.data.duration_estimate}). You can now use this for accessibility purposes."`); } else { console.log('Agent Error Response:'); console.log(`"I encountered an error while generating the audio: ${audioResult.error}"`); } } console.log(''); } formatToolCallXML(toolCall) { let xml = `<tool_call name="${toolCall.tool_name}" id="${toolCall.id}">`; for (const [key, value] of Object.entries(toolCall.parameters)) { if (typeof value === 'string' && (value.includes('\n') || value.includes('<') || value.includes('>'))) { xml += `\n <${key}><![CDATA[${value}]]></${key}>`; } else { xml += `\n <${key}>${value}</${key}>`; } } xml += '\n</tool_call>'; return xml; } formatToolResponseXML(response) { let xml = `<tool_response id="${response.id}">`; xml += `\n <tool_call name="${response.tool_call.tool_name}">`; for (const [key, value] of Object.entries(response.tool_call.parameters)) { xml += `\n <${key}>${value}</${key}>`; } xml += '\n </tool_call>'; xml += '\n <result>'; if (response.result.success) { xml += '\n <success>true</success>'; if (response.result.message) { xml += `\n <message>${response.result.message}</message>`; } if (response.result.data) { xml += '\n <data>'; for (const [key, value] of Object.entries(response.result.data)) { xml += `\n <${key}>${value}</${key}>`; } xml += '\n </data>'; } } else { xml += '\n <success>false</success>'; xml += `\n <error>${response.result.error}</error>`; } xml += '\n </result>'; xml += '\n</tool_response>'; return xml; } async cleanup() { console.log('๐Ÿงน Demo completed! Check the output files in:'); console.log(` ${DEMO_BASE_DIR}`); console.log(''); console.log('Generated files may include:'); console.log(' - demo/basic_greeting.wav'); console.log(' - demo/sample_narration.wav'); console.log(' - accessibility/sample_audio.wav'); console.log(''); } } // Run the demo async function runDemo() { const demo = new AudioGenerationDemo(); try { await demo.setup(); await demo.demonstrateBasicAudioGeneration(); await demo.demonstrateMultiToolWorkflow(); await demo.demonstrateErrorHandling(); await demo.demonstrateAgentConversation(); await demo.cleanup(); } catch (error) { console.error('โŒ Demo failed:', error); process.exit(1); } } // Run if called directly if (import.meta.url === `file://${process.argv[1]}`) { runDemo(); }