UNPKG

@xynehq/jaf

Version:

Juspay Agent Framework - A purely functional agent framework with immutable state and composable tools

321 lines (319 loc) 15 kB
/** * JAF ADK Layer - Multi-Agent Example * * Demonstrates multi-agent coordination and delegation */ import { createAgent, createMultiAgent, createFunctionTool, createInMemorySessionProvider, createRunnerConfig, runAgent, createUserMessage, Model, ToolParameterType } from '../index'; // ========== Specialized Agents ========== export const createWeatherSpecialistAgent = () => { const weatherTool = createFunctionTool({ name: 'get_weather', description: 'Get current weather information', execute: (params) => { const { location } = params; // Mock weather data const weatherData = { 'new york': { temp: 15, condition: 'cloudy', humidity: 78 }, 'london': { temp: 8, condition: 'rainy', humidity: 85 }, 'tokyo': { temp: 22, condition: 'sunny', humidity: 60 }, 'sydney': { temp: 25, condition: 'partly cloudy', humidity: 65 } }; const location_key = location.toLowerCase(); const weather = weatherData[location_key] || { temp: 20, condition: 'unknown', humidity: 50 }; return { location, temperature: weather.temp, condition: weather.condition, humidity: weather.humidity, forecast: 'Clear skies expected for the next few days' }; }, parameters: [ { name: 'location', type: ToolParameterType.STRING, description: 'City or location name', required: true } ] }); return { name: 'weather_specialist', model: Model.GEMINI_2_0_FLASH, instruction: `You are a weather specialist. Use the get_weather tool to provide accurate, detailed weather information. Include temperature, conditions, and helpful advice based on the weather.`, tools: [weatherTool] }; }; export const createNewsSpecialistAgent = () => { const newsTool = createFunctionTool({ name: 'get_news', description: 'Get latest news headlines', execute: ({ category, limit }) => { // Mock news data const newsCategories = { tech: [ 'AI breakthrough announced by major tech company', 'New smartphone features revolutionary battery technology', 'Cybersecurity update addresses critical vulnerabilities' ], business: [ 'Stock markets show positive growth this quarter', 'New startup secures major funding round', 'Economic indicators suggest stable growth' ], science: [ 'Scientists discover new exoplanet in habitable zone', 'Medical research shows promising cancer treatment results', 'Climate study reveals important environmental insights' ] }; const selectedCategory = category || 'tech'; const headlines = newsCategories[selectedCategory] || newsCategories.tech; const limitedHeadlines = headlines.slice(0, limit || 3); return { category: selectedCategory, headlines: limitedHeadlines, timestamp: new Date().toISOString() }; }, parameters: [ { name: 'category', type: ToolParameterType.STRING, description: 'News category (tech, business, science)', required: false, enum: ['tech', 'business', 'science'] }, { name: 'limit', type: ToolParameterType.NUMBER, description: 'Number of headlines to return', required: false, default: 3 } ] }); return { name: 'news_specialist', model: Model.GEMINI_2_0_FLASH, instruction: `You are a news specialist. Use the get_news tool to provide current news headlines. Summarize the news clearly and provide context when helpful.`, tools: [newsTool] }; }; export const createCalculatorSpecialistAgent = () => { const advancedCalcTool = createFunctionTool({ name: 'advanced_calculate', description: 'Perform complex mathematical calculations', execute: (params) => { const { expression, type } = params; try { let result; switch (type) { case 'percentage': { // Handle percentage calculations const percentMatch = expression.match(/(\d+)\s*%\s*of\s*(\d+)/i); if (percentMatch) { const [, percent, of] = percentMatch; result = (parseFloat(percent) / 100) * parseFloat(of); } else { // Use safe math evaluator instead of eval // eslint-disable-next-line @typescript-eslint/no-var-requires const { evaluateMathExpression } = require('../../utils/safe-math'); result = evaluateMathExpression(expression); } break; } case 'area': { // Handle area calculations const areaMatch = expression.match(/circle\s*r=(\d+)/i); if (areaMatch) { const radius = parseFloat(areaMatch[1]); result = Math.PI * radius * radius; } else { // Use safe math evaluator instead of eval // eslint-disable-next-line @typescript-eslint/no-var-requires const { evaluateMathExpression } = require('../../utils/safe-math'); result = evaluateMathExpression(expression); } break; } default: { // Use safe math evaluator instead of eval // eslint-disable-next-line @typescript-eslint/no-var-requires const { evaluateMathExpression } = require('../../utils/safe-math'); result = evaluateMathExpression(expression); } } return { expression, result, type: type || 'basic', formatted: typeof result === 'number' ? result.toLocaleString() : result }; } catch (error) { throw new Error(`Invalid expression: ${expression}`); } }, parameters: [ { name: 'expression', type: ToolParameterType.STRING, description: 'Mathematical expression to evaluate', required: true }, { name: 'type', type: ToolParameterType.STRING, description: 'Type of calculation (basic, percentage, area)', required: false, enum: ['basic', 'percentage', 'area'] } ] }); return { name: 'calculator_specialist', model: Model.GEMINI_2_0_FLASH, instruction: `You are a mathematics specialist. Use the advanced_calculate tool for all mathematical operations. Explain your calculations clearly and provide step-by-step solutions when helpful.`, tools: [advancedCalcTool] }; }; // ========== Multi-Agent Coordinator ========== export const createMultiAgentCoordinator = () => { const weatherAgent = createWeatherSpecialistAgent(); const newsAgent = createNewsSpecialistAgent(); const calcAgent = createCalculatorSpecialistAgent(); const coordinator = createMultiAgent('smart_coordinator', Model.GEMINI_2_0_FLASH, `You are an intelligent coordinator that manages multiple specialist agents. Based on the user's request, delegate to the appropriate specialist: - Weather questions → weather_specialist - News/current events → news_specialist - Math/calculations → calculator_specialist If the request involves multiple areas, coordinate between specialists. Always provide a comprehensive response combining their expertise.`, [weatherAgent, newsAgent, calcAgent], 'conditional'); const sessionProvider = createInMemorySessionProvider(); const runnerConfig = createRunnerConfig(coordinator, sessionProvider); return { coordinator, sessionProvider, runnerConfig }; }; // ========== Sequential Multi-Agent Example ========== export const createSequentialAgentPipeline = () => { // Agent 1: Data Collector const dataCollectorAgent = { name: 'data_collector', model: Model.GEMINI_2_0_FLASH, instruction: 'You collect and organize raw data. Extract key information and prepare it for analysis.', tools: [] }; // Agent 2: Data Analyzer const dataAnalyzerAgent = { name: 'data_analyzer', model: Model.GEMINI_2_0_FLASH, instruction: 'You analyze data provided by the data collector. Look for patterns, insights, and trends.', tools: [] }; // Agent 3: Report Generator const reportGeneratorAgent = { name: 'report_generator', model: Model.GEMINI_2_0_FLASH, instruction: 'You create comprehensive reports based on analysis. Present findings clearly and actionably.', tools: [] }; const sequentialCoordinator = createMultiAgent('sequential_pipeline', Model.GEMINI_2_0_FLASH, 'You coordinate a sequential data processing pipeline: collection → analysis → reporting.', [dataCollectorAgent, dataAnalyzerAgent, reportGeneratorAgent], 'sequential'); const sessionProvider = createInMemorySessionProvider(); const runnerConfig = createRunnerConfig(sequentialCoordinator, sessionProvider); return { sequentialCoordinator, sessionProvider, runnerConfig }; }; // ========== Example Usage Functions ========== export async function runMultiAgentExample() { console.log('=== JAF ADK Layer - Multi-Agent Coordinator Example ===\n'); const { runnerConfig } = createMultiAgentCoordinator(); // Test weather delegation console.log('1. Weather Query:'); const weatherMessage = createUserMessage('What\'s the weather like in Tokyo?'); const weatherResponse = await runAgent(runnerConfig, { userId: 'user_123', sessionId: 'session_multi_1' }, weatherMessage); console.log('User:', weatherMessage.parts[0].text); console.log('Coordinator:', weatherResponse.content.parts[0].text); // Test news delegation console.log('\n2. News Query:'); const newsMessage = createUserMessage('What are the latest tech news headlines?'); const newsResponse = await runAgent(runnerConfig, { userId: 'user_123', sessionId: 'session_multi_2' }, newsMessage); console.log('User:', newsMessage.parts[0].text); console.log('Coordinator:', newsResponse.content.parts[0].text); // Test calculation delegation console.log('\n3. Math Query:'); const mathMessage = createUserMessage('What is 25% of 240?'); const mathResponse = await runAgent(runnerConfig, { userId: 'user_123', sessionId: 'session_multi_3' }, mathMessage); console.log('User:', mathMessage.parts[0].text); console.log('Coordinator:', mathResponse.content.parts[0].text); // Test complex query requiring multiple specialists console.log('\n4. Complex Multi-Domain Query:'); const complexMessage = createUserMessage('I need the weather in London, latest business news, and help calculating a 15% tip on a $85 bill'); const complexResponse = await runAgent(runnerConfig, { userId: 'user_123', sessionId: 'session_multi_4' }, complexMessage); console.log('User:', complexMessage.parts[0].text); console.log('Coordinator:', complexResponse.content.parts[0].text); } export async function runSequentialAgentExample() { console.log('\n=== JAF ADK Layer - Sequential Agent Pipeline Example ===\n'); const { runnerConfig } = createSequentialAgentPipeline(); const dataMessage = createUserMessage('Please analyze this sales data: Q1: $100k, Q2: $120k, Q3: $95k, Q4: $140k. Create a comprehensive report.'); const response = await runAgent(runnerConfig, { userId: 'user_123', sessionId: 'session_sequential' }, dataMessage); console.log('User:', dataMessage.parts[0].text); console.log('Sequential Pipeline Result:', response.content.parts[0].text); } export async function runAgentSpecializationExample() { console.log('\n=== JAF ADK Layer - Agent Specialization Example ===\n'); // Test individual specialists const weatherConfig = createRunnerConfig(createAgent(createWeatherSpecialistAgent()), createInMemorySessionProvider()); const newsConfig = createRunnerConfig(createAgent(createNewsSpecialistAgent()), createInMemorySessionProvider()); const calcConfig = createRunnerConfig(createAgent(createCalculatorSpecialistAgent()), createInMemorySessionProvider()); // Test weather specialist console.log('Weather Specialist:'); const weatherResp = await runAgent(weatherConfig, { userId: 'user_123' }, createUserMessage('Weather in Sydney please')); console.log('Response:', weatherResp.content.parts[0].text); // Test news specialist console.log('\nNews Specialist:'); const newsResp = await runAgent(newsConfig, { userId: 'user_123' }, createUserMessage('Show me science news')); console.log('Response:', newsResp.content.parts[0].text); // Test calculator specialist console.log('\nCalculator Specialist:'); const calcResp = await runAgent(calcConfig, { userId: 'user_123' }, createUserMessage('Calculate the area of a circle with radius 5')); console.log('Response:', calcResp.content.parts[0].text); } // ========== Main Example Runner ========== export async function runAllMultiAgentExamples() { try { await runMultiAgentExample(); await runSequentialAgentExample(); await runAgentSpecializationExample(); console.log('\n=== All multi-agent examples completed successfully! ==='); } catch (error) { console.error('Multi-agent example failed:', error); } } // Run examples if this file is executed directly if (require.main === module) { runAllMultiAgentExamples(); } //# sourceMappingURL=multi-agent.js.map