@robota-sdk/team
Version:
Multi-agent teamwork functionality for Robota SDK - dynamic agent coordination and task delegation
148 lines (115 loc) • 24.7 kB
JavaScript
import {ExecutionAnalyticsPlugin,Robota,createZodFunctionTool}from'@robota-sdk/agents';import {v4}from'uuid';import {z as z$1}from'zod';var w=z$1.object({jobDescription:z$1.string().describe("Clear, specific description of the job to be completed. Should provide enough detail for the specialist agent to understand the scope and deliverables expected."),context:z$1.string().optional().describe("Additional context, constraints, or requirements for the job. Helps the specialist agent understand the broader context and any specific limitations or guidelines to follow."),requiredTools:z$1.array(z$1.string()).optional().describe("List of tools the specialist agent might need for this task. If specified, the system will attempt to configure the agent with access to these tools."),priority:z$1.enum(["low","medium","high","urgent"]).default("medium").describe("Priority level for the task, affecting resource allocation and urgency. Higher priority tasks may receive more resources or faster processing."),agentTemplate:z$1.string().optional().describe("Name of the agent template to use for this task. If not specified, a dynamic agent will be created based on the job description."),allowFurtherDelegation:z$1.boolean().default(false).describe("Whether the assigned agent can delegate parts of the task to other specialists if needed. Set true ONLY for very complex tasks requiring multiple specialized areas of expertise, false for focused execution.")});function f(n){let e=n.map(t=>`${t.id}: ${t.description}`).join(", ");return w.extend({agentTemplate:z$1.string().optional().describe(`Name of the agent template to use for this task. Available templates: ${e}. If not specified, a dynamic agent will be created based on the job description.`)})}function v(n,e){let t=f(n);return createZodFunctionTool("assignTask",$(n),t,async s=>{let o=t.parse(s),l=await e(P(o));return I(l)})}function P(n){let e={jobDescription:n.jobDescription};return n.context!==void 0&&(e.context=n.context),n.requiredTools!==void 0&&(e.requiredTools=n.requiredTools),n.priority!==void 0&&(e.priority=n.priority),n.agentTemplate!==void 0&&(e.agentTemplate=n.agentTemplate),n.allowFurtherDelegation!==void 0&&(e.allowFurtherDelegation=n.allowFurtherDelegation),e}function $(n){let e="Assign a specialized task to a temporary expert agent. Use this when the task requires specific expertise, complex analysis, or when breaking down work into specialized components would be beneficial. The expert agent will be created, complete the task, and be automatically cleaned up.",t="Set allowFurtherDelegation=true ONLY for extremely complex tasks requiring multiple different areas of expertise, otherwise keep false for direct execution.",i=n.length>0?`Choose appropriate agentTemplate based on the nature of the work. Available templates: ${n.map(s=>s.id).join(", ")}.`:"A dynamic agent will be created based on the job description.";return `${e} ${t} ${i}`}function I(n){let e=`Task completed successfully by ${n.agentId}.
Result:
${n.result}`,t=`
Execution time: ${n.metadata.executionTime}ms`,i=[];n.metadata.tokensUsed&&i.push(`Tokens used: ${n.metadata.tokensUsed}`),n.metadata.agentExecutions&&i.push(`Agent executions: ${n.metadata.agentExecutions}`),n.metadata.agentSuccessRate!==void 0&&i.push(`Success rate: ${(n.metadata.agentSuccessRate*100).toFixed(1)}%`);let s=i.length>0?`
${i.join(", ")}`:"";return `${e}${t}${s}`}function b(n,e){let i=f(e).parse(n);return P(i)}function D(n,e){return {tool:v(n,e),validateParams:o=>b(o,n),safeValidateParams:o=>{let r=f(n).safeParse(o);return {success:r.success,data:r.success?r.data:void 0,error:r.success?void 0:r.error.message}},availableTemplates:[...n]}}var y=class{teamAgent;options;logger;availableTemplates;delegationHistory=[];activeAgentsCount=0;totalAgentsCreated=0;tasksCompleted=0;totalExecutionTime=0;constructor(e){this.options=e,this.logger=e.logger,this.availableTemplates=this.getBuiltinTemplates();let t=new ExecutionAnalyticsPlugin({maxEntries:1e3,trackErrors:true,performanceThreshold:5e3,enableWarnings:true}),i=this.createAssignTaskTool(),s=this.options.leaderTemplate||"task_coordinator",o=this.getTemplate(s);if(!o)throw new Error(`Leader template '${s}' not found. Available templates: ${this.availableTemplates.map(g=>g.id).join(", ")}`);let l=this.options.baseRobotaOptions.aiProviders.map(g=>g.name);if(!l.includes(o.config.provider))throw new Error(`Leader template requires provider '${o.config.provider}' but it's not available. Available providers: ${l.join(", ")}`);let r={name:"team-leader",aiProviders:this.options.baseRobotaOptions.aiProviders,defaultModel:{provider:o.config.provider,model:o.config.model,temperature:o.config.temperature,systemMessage:o.config.systemMessage,...o.config.maxTokens&&{maxTokens:o.config.maxTokens}},plugins:[...this.options.baseRobotaOptions.plugins||[],t],tools:[...this.options.baseRobotaOptions.tools||[],i]};this.teamAgent=new Robota(r),this.logger?.info(`Team created with leader template: ${s} (${o.config.provider}/${o.config.model})`);}async execute(e){let t=Date.now();try{this.logger?.info("\u{1F680} Starting team execution");let i=await this.teamAgent.run(e),s=Date.now()-t;return this.tasksCompleted++,this.totalExecutionTime+=s,this.logger?.info(`\u2705 Team execution completed in ${s}ms`),i}catch(i){let s=Date.now()-t;this.totalExecutionTime+=s;let o=i instanceof Error?i.message:String(i);throw this.logger?.error(`\u274C Team execution failed after ${s}ms: ${o}`),i}}async assignTask(e){let t=null,i=false,s=`agent-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,o=Date.now();try{if(this.options.maxMembers&&this.totalAgentsCreated>=this.options.maxMembers){let c=`Maximum number of team members (${this.options.maxMembers}) reached. Total created: ${this.totalAgentsCreated}, Currently active: ${this.activeAgentsCount}`;return this.logger?.warn(c),{result:`Task assignment failed: ${c}`,agentId:s,metadata:{executionTime:0,errors:[c]}}}this.activeAgentsCount++,this.totalAgentsCreated++,i=!0,this.logger?.info(`\u{1F4CA} Agent slot reserved - Active: ${this.activeAgentsCount}, Total: ${this.totalAgentsCreated}, Max: ${this.options.maxMembers||"unlimited"}`);let l=new ExecutionAnalyticsPlugin({maxEntries:100,trackErrors:!0,performanceThreshold:1e4,enableWarnings:!0}),r=e.allowFurtherDelegation===!0,g=r?[this.createAssignTaskTool()]:[];if(e.agentTemplate){let c=this.getTemplate(e.agentTemplate);if(!c)throw new Error(`Template '${e.agentTemplate}' not found. Available templates: ${this.availableTemplates.map(k=>k.id).join(", ")}`);let A=this.options.baseRobotaOptions.aiProviders.map(k=>k.name);if(!A.includes(c.config.provider))throw new Error(`Template requires provider '${c.config.provider}' but it's not available. Available providers: ${A.join(", ")}`);let T=c.config.systemMessage;r?T+=`
DELEGATION GUIDANCE: You can use assignTask to delegate parts of this work to other specialists if the task would benefit from specialized expertise outside your primary domain. Focus on your expertise but delegate when it would significantly improve quality.`:T+=`
DIRECT EXECUTION: Handle this task directly using your specialized knowledge and skills. Do not delegate - focus on completing the work within your expertise.`,t=new Robota({name:`temp-agent-${s}`,aiProviders:this.options.baseRobotaOptions.aiProviders,defaultModel:{provider:c.config.provider,model:c.config.model,temperature:c.config.temperature,systemMessage:T,...c.config.maxTokens&&{maxTokens:c.config.maxTokens}},plugins:[l],tools:[...g,...this.options.baseRobotaOptions.tools||[]]});}else {let c=`You are a specialist agent created to handle this specific task: ${e.jobDescription}. ${e.context||""}`;r?c+=`
DELEGATION GUIDANCE: You can use assignTask to delegate parts of this work to other specialists if the task would benefit from specialized expertise outside your capabilities.`:c+=`
DIRECT EXECUTION: Handle this task directly using your knowledge and skills. Do not delegate - focus on completing the work yourself.`,t=new Robota({name:`temp-agent-${s}`,aiProviders:this.options.baseRobotaOptions.aiProviders,defaultModel:{provider:this.options.baseRobotaOptions.aiProviders[0]?.name||"openai",model:"gpt-4o-mini",systemMessage:c},plugins:[l],tools:[...g,...this.options.baseRobotaOptions.tools||[]]});}this.logger?.info(`\u{1F4CA} Agent created - Active: ${this.activeAgentsCount}, Total: ${this.totalAgentsCreated}`);let u=this.buildTaskPrompt(e),h=await t.run(u),a=t.getPlugin("ExecutionAnalyticsPlugin")?.getAggregatedStats(),p=Date.now()-o;this.logger?.info(`\u2705 Task completed by agent ${s} (${p}ms)`);let S={id:v4(),originalTask:e.jobDescription,delegatedTask:u,...e.agentTemplate&&{agentTemplate:e.agentTemplate},agentId:s,priority:e.priority||"medium",startTime:new Date(o),endTime:new Date(Date.now()),duration:p,result:h,success:!0,tokensUsed:this.estimateTokenUsage(u,h),executionStats:{agentExecutions:a&&"totalExecutions"in a?Number(a.totalExecutions):0,agentAverageDuration:a&&"averageDuration"in a?Number(a.averageDuration):0,agentSuccessRate:a&&"successRate"in a?Number(a.successRate):0}};return this.delegationHistory.push(S),{result:h,agentId:s,metadata:{executionTime:p,tokensUsed:this.estimateTokenUsage(u,h),agentExecutions:a&&"totalExecutions"in a?Number(a.totalExecutions):0,agentAverageDuration:a&&"averageDuration"in a?Number(a.averageDuration):0,agentSuccessRate:a&&"successRate"in a?Number(a.successRate):0,errors:[]}}}catch(l){let r=l instanceof Error?l.message:String(l),g=Date.now()-o;i&&this.activeAgentsCount>0&&(this.activeAgentsCount--,i=false,this.logger?.info(`\u{1F4CA} Agent failed, slot released - Active: ${this.activeAgentsCount}`)),this.logger?.error(`\u274C Task failed for agent ${s} (${g}ms): ${r}`);let u={id:v4(),originalTask:e.jobDescription,delegatedTask:e.jobDescription,...e.agentTemplate&&{agentTemplate:e.agentTemplate},agentId:s,priority:e.priority||"medium",startTime:new Date(o),endTime:new Date(Date.now()),duration:g,result:`Task failed: ${r}`,success:false,tokensUsed:this.estimateTokenUsage(e.jobDescription,`Task failed: ${r}`),executionStats:{agentExecutions:0,agentAverageDuration:0,agentSuccessRate:0}};return this.delegationHistory.push(u),{result:`Task failed: ${r}`,agentId:s,metadata:{executionTime:g,errors:[r]}}}finally{i&&t&&this.activeAgentsCount>0&&(this.activeAgentsCount--,this.logger?.info(`\u{1F4CA} Agent completed successfully - Active agents now: ${this.activeAgentsCount}`)),t=null;}}getAnalytics(){let e=this.teamAgent.getPlugin("ExecutionAnalyticsPlugin");if(e&&"getStats"in e&&typeof e.getStats=="function")return e.getStats()}getExecutionStats(e){let t=this.teamAgent.getPlugin("ExecutionAnalyticsPlugin");return t&&typeof t.getExecutionStats=="function"?t.getExecutionStats(e):[]}getStatus(){let e=this.teamAgent.getPlugin("ExecutionAnalyticsPlugin");if(e&&"getStatus"in e&&typeof e.getStatus=="function")return e.getStatus()}clearAnalytics(){let e=this.teamAgent.getPlugin("ExecutionAnalyticsPlugin");e&&"clearData"in e&&typeof e.clearData=="function"&&e.clearData();}getAnalyticsData(){let e=this.teamAgent.getPlugin("ExecutionAnalyticsPlugin");if(e&&"getData"in e&&typeof e.getData=="function")return e.getData()}getPluginStatuses(){return this.teamAgent.getPlugins().map(t=>"getStatus"in t&&typeof t.getStatus=="function"?t.getStatus():{name:t.name,version:t.version,enabled:t.isEnabled(),initialized:true})}getDelegationHistory(){return [...this.delegationHistory]}getTeamExecutionAnalysis(){let e=this.getAnalytics(),t=e&&"totalExecutions"in e?Number(e.totalExecutions):0,i=this.delegationHistory.length,s=Math.max(0,t-i),o=new Map;this.delegationHistory.forEach(d=>{let a=d.agentTemplate||"dynamic",p=o.get(a)||{count:0,totalDuration:0,successes:0};p.count++,p.totalDuration+=d.duration||0,d.success&&p.successes++,o.set(a,p);});let l=Array.from(o.entries()).map(([d,a])=>({template:d,count:a.count,averageDuration:a.count>0?a.totalDuration/a.count:0,successRate:a.count>0?a.successes/a.count:0})),r=this.delegationHistory.map(d=>d.duration||0),g=r.length>0?r.reduce((d,a)=>d+a,0)/r.length:0,u=e&&"averageDuration"in e?Number(e.averageDuration):0,h=r.reduce((d,a)=>d+a,0);return {totalTasks:t,directlyHandledTasks:s,delegatedTasks:i,delegationRate:t>0?i/t:0,delegationBreakdown:l,taskComplexityAnalysis:{simple:s,complex:i},performanceMetrics:{averageDirectHandlingTime:u,averageDelegationTime:g,totalExecutionTime:h}}}clearDelegationHistory(){this.delegationHistory=[],this.logger?.debug("Delegation history cleared");}getStats(){return {tasksCompleted:this.tasksCompleted,totalAgentsCreated:this.totalAgentsCreated,totalExecutionTime:this.totalExecutionTime}}getTeamStats(){return {activeAgentsCount:this.activeAgentsCount,totalAgentsCreated:this.totalAgentsCreated,maxMembers:this.options.maxMembers||"unlimited",delegationHistoryLength:this.delegationHistory.length,successfulTasks:this.delegationHistory.filter(e=>e.success).length,failedTasks:this.delegationHistory.filter(e=>!e.success).length,tasksCompleted:this.tasksCompleted,totalExecutionTime:this.totalExecutionTime}}resetTeamStats(){this.activeAgentsCount=0,this.totalAgentsCreated=0,this.tasksCompleted=0,this.totalExecutionTime=0,this.delegationHistory=[];}getTemplates(){return [...this.availableTemplates]}getTemplate(e){return this.availableTemplates.find(t=>t.id===e)}buildTaskPrompt(e){let t=`Task: ${e.jobDescription}
`;return e.context&&(t+=`Context: ${e.context}
`),e.requiredTools&&e.requiredTools.length>0&&(t+=`Available tools: ${e.requiredTools.join(", ")}
`),t+=`Priority: ${e.priority||"medium"}
Please complete this task thoroughly and provide a comprehensive response.`,t}estimateTokenUsage(e,t){return Math.ceil((e.length+t.length)/4)}createAssignTaskTool(){let e=this.availableTemplates.map(i=>({id:i.id,description:i.description}));return D(e,async i=>await this.assignTask(i)).tool}getBuiltinTemplates(){let e=this.options.baseRobotaOptions.defaultModel.model||"gpt-4o-mini",t=this.options.baseRobotaOptions.defaultModel.provider||"openai";return [{id:"general",name:"General Purpose Agent",description:"Basic general-purpose agent with no specific specialization. Use only when no other specialized template fits the task requirements or when task scope is too broad and unclear for specialist agents. This is the fallback option when specialized expertise is not needed.",category:"general",tags:["general","default","versatile","specialist"],config:{model:e,provider:t,systemMessage:`You are a helpful and capable AI assistant with broad knowledge and skills. You can adapt to various tasks and requirements while maintaining high quality and accuracy. Your strengths include:
\u2022 General problem-solving and analysis
\u2022 Clear communication and explanation
\u2022 Flexible task adaptation
\u2022 Balanced approach to different types of work
\u2022 Reliable execution of varied requests
When handling tasks:
1. Analyze the request to understand requirements
2. Apply appropriate methods and knowledge
3. Provide clear, useful, and accurate responses
4. Ask for clarification when needed
5. Adapt your approach to the specific context
6. Ensure completeness and quality in your work
Provide helpful, accurate, and well-structured responses that meet the user's needs effectively.`,temperature:.5}},{id:"summarizer",name:"Content Summarizer",description:"Analysis specialist expert in document summarization, data extraction, and distilling complex information. Use for: summarizing documents, extracting key insights, creating executive summaries, condensing reports, highlighting main points, creating meeting notes, and comprehensive content analysis.",category:"analysis",tags:["analysis","summarization","extraction","specialist"],config:{model:e,provider:t,systemMessage:`You are an expert summarization specialist with advanced capabilities in analyzing and distilling complex information. Your expertise includes:
\u2022 Extracting key points and main ideas from lengthy documents
\u2022 Creating concise summaries while preserving essential information
\u2022 Identifying critical insights and actionable items
\u2022 Structuring information in clear, digestible formats
\u2022 Adapting summary length and style to audience needs
When summarizing, focus on:
1. Main themes and central arguments
2. Supporting evidence and key data points
3. Conclusions and recommendations
4. Action items and next steps
5. Critical dependencies and risks
DELEGATION GUIDELINES:
- Handle summarization and analysis tasks directly within your expertise
- Consider delegating if the task requires specialized domain research, creative ideation, or ethical review beyond summarization
- Only delegate when it would significantly improve quality or when the task clearly falls outside summarization expertise
- For pure summarization requests, always handle directly
Provide summaries that are accurate, comprehensive, and immediately useful for decision-making.`,temperature:.3}},{id:"ethical_reviewer",name:"Ethical Reviewer",description:"Ethics and compliance specialist expert in comprehensive review processes. Use for: ethical evaluation, compliance checking, bias detection, privacy assessment, content moderation, legal review, risk analysis, safety evaluation, and responsible AI practices.",category:"analysis",tags:["ethics","review","compliance","specialist"],config:{model:e,provider:t,systemMessage:`You are an ethical review specialist focused on responsible AI practices and content compliance. Your expertise covers:
\u2022 AI ethics and responsible technology development
\u2022 Privacy protection and data governance
\u2022 Bias detection and fairness assessment
\u2022 Legal compliance and regulatory requirements
\u2022 Content moderation and safety guidelines
\u2022 Transparency and accountability standards
When reviewing content or proposals, evaluate:
1. Potential ethical implications and risks
2. Privacy and data protection concerns
3. Bias, fairness, and inclusivity issues
4. Legal and regulatory compliance
5. Transparency and explainability requirements
6. Potential unintended consequences
Provide balanced assessments with specific recommendations for addressing identified concerns while supporting innovation and progress.`,temperature:.2}},{id:"creative_ideator",name:"Creative Ideator",description:"Creativity and innovation specialist expert in brainstorming and imaginative problem solving. Use for: brainstorming sessions, innovative product concepts, creative problem solving, design thinking, artistic projects, marketing campaigns, breakthrough ideas, imaginative solutions, and out-of-the-box thinking.",category:"creative",tags:["creativity","brainstorming","innovation","specialist"],config:{model:e,provider:t,systemMessage:`You are a creative ideation expert specializing in innovative thinking and breakthrough idea generation. Your strengths include:
\u2022 Divergent thinking and brainstorming techniques
\u2022 Cross-industry innovation and pattern recognition
\u2022 Creative problem-solving methodologies
\u2022 Design thinking and user-centered innovation
\u2022 Future-oriented scenario planning
\u2022 Connecting disparate concepts and ideas
When generating ideas, apply:
1. Multiple perspective-taking and reframing
2. "What if" scenarios and possibility thinking
3. Combination and recombination of existing concepts
4. Challenge assumptions and conventional wisdom
5. Explore edge cases and unconventional approaches
6. Consider both incremental and radical innovations
Deliver creative solutions that are imaginative yet practical, pushing boundaries while remaining grounded in feasibility.`,temperature:.8}},{id:"fast_executor",name:"Fast Executor",description:"Speed and accuracy specialist expert in rapid task execution. Use for: quick tasks, urgent requests, simple implementations, straightforward analysis, routine operations, time-sensitive work, efficient problem solving, rapid prototyping, and immediate action items requiring fast, accurate execution.",category:"execution",tags:["execution","speed","accuracy","specialist"],config:{model:e,provider:t,systemMessage:`You are a fast and accurate task executor focused on efficiency and precision. Your core competencies include:
\u2022 Rapid task analysis and prioritization
\u2022 Efficient workflow optimization
\u2022 Quick decision-making with available information
\u2022 Streamlined communication and reporting
\u2022 Resource optimization and time management
\u2022 Quality control under time constraints
When executing tasks, prioritize:
1. Speed without compromising accuracy
2. Clear, concise deliverables
3. Essential information over comprehensive detail
4. Actionable outputs and next steps
5. Efficient use of available resources
6. Quick validation and error checking
Deliver results that meet requirements efficiently, focusing on what matters most for immediate progress and decision-making.`,temperature:.1,maxTokens:1e3}},{id:"domain_researcher",name:"Domain Researcher",description:"Research and analysis specialist with deep domain-expertise. Use for: market research, competitive analysis, technical investigation, academic research, industry analysis, trend studies, data analysis, expert insights, comprehensive reports, and evidence-based conclusions requiring specialized research skills.",category:"research",tags:["research","analysis","domain-expertise","specialist"],config:{model:e,provider:t,systemMessage:`You are a domain research specialist with expertise in conducting thorough investigations across various fields. Your research capabilities include:
\u2022 Systematic literature review and analysis
\u2022 Primary and secondary source evaluation
\u2022 Cross-disciplinary knowledge synthesis
\u2022 Trend analysis and pattern recognition
\u2022 Expert opinion and perspective gathering
\u2022 Evidence-based conclusion development
When conducting research, focus on:
1. Comprehensive coverage of relevant sources
2. Critical evaluation of information quality
3. Identification of knowledge gaps and limitations
4. Synthesis of findings into coherent insights
5. Recognition of competing perspectives and debates
6. Practical implications and applications
Provide research that is thorough, well-sourced, and analytically rigorous, delivering insights that advance understanding and inform decision-making.`,temperature:.4}},{id:"task_coordinator",name:"Task Coordinator",description:"Management and coordination specialist expert in task-management workflows. Use for: managing team workload, assigning tasks, monitoring progress, coordinating resources, ensuring timely completion of tasks, and complex project coordination requiring management expertise.",category:"management",tags:["management","coordination","task-management"],config:{model:e,provider:t,systemMessage:`You are a Team Coordinator that manages collaborative work through intelligent task delegation.
CORE PRINCIPLES:
- Respond in the same language as the user's input
- For simple, single-component tasks, handle them directly yourself
- For complex or multi-faceted tasks, delegate to specialized team members
- Each delegated task must be self-contained and understandable without context
- Always synthesize and integrate results from team members into your final response
AVAILABLE ROLES:
- Coordinators: Can break down complex tasks and manage workflows
- Specialists: Focus on specific domains and can handle targeted tasks efficiently
DELEGATION BEST PRACTICES:
- Create clear, standalone instructions for each specialist
- Avoid overlapping tasks between different team members
- Select appropriate specialist templates based on task requirements
- Ensure each delegated task is complete and actionable
- Handle final synthesis and coordination yourself
Your goal is to coordinate effectively while leveraging specialist expertise for optimal results.`,temperature:.6}}]}};function M(n){if(!n.aiProviders||n.aiProviders.length===0)throw new Error("At least one AI provider must be provided in aiProviders");let e=n.aiProviders[0],t=z(e.name)||"gpt-4o-mini",i={baseRobotaOptions:{name:"team-base",aiProviders:n.aiProviders,defaultModel:{provider:e.name,model:t,maxTokens:n.maxTokenLimit||5e4}},maxMembers:n.maxMembers||5,debug:n.debug||false,...n.customTemplates&&{customTemplates:n.customTemplates},...n.leaderTemplate&&{leaderTemplate:n.leaderTemplate},...n.logger&&{logger:n.logger}};return new y(i)}function z(n){switch(n.toLowerCase()){case "openai":return "gpt-4o-mini";case "anthropic":return "claude-3-5-sonnet-20241022";case "google":return "gemini-pro";default:return "not_specified"}}export{y as TeamContainer,M as createTeam};