contaigents
Version:
Modular AI Content Ecosystem with Audio Generation
286 lines (281 loc) โข 11.3 kB
JavaScript
/**
* 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();
}