npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@wundr.io/autogen-orchestrator

v1.0.6

Published

AutoGen-style conversational multi-agent orchestration for the Wundr platform

Readme

@wundr.io/autogen-orchestrator

AutoGen-style conversational multi-agent orchestration for the Wundr platform. This package implements sophisticated patterns for coordinating multiple AI agents in group chat settings with configurable speaker selection, termination conditions, and nested chat support.

Table of Contents

Installation

npm install @wundr.io/autogen-orchestrator
# or
yarn add @wundr.io/autogen-orchestrator
# or
pnpm add @wundr.io/autogen-orchestrator

Quick Start

import {
  GroupChatManager,
  GroupChatBuilder,
  createParticipant,
  TerminationPresets,
} from '@wundr.io/autogen-orchestrator';

// Create participants
const analyst = createParticipant(
  'Analyst',
  'You are a data analyst specializing in market research.',
  ['analysis', 'research', 'data']
);

const developer = createParticipant(
  'Developer',
  'You are a senior software developer.',
  ['coding', 'architecture', 'debugging']
);

const reviewer = createParticipant(
  'Reviewer',
  'You are a code reviewer ensuring quality standards.',
  ['review', 'testing', 'quality']
);

// Build and configure the group chat
const chat = new GroupChatBuilder()
  .withName('Project Discussion')
  .withDescription('Multi-agent collaboration for project planning')
  .withParticipant(analyst)
  .withParticipant(developer)
  .withParticipant(reviewer)
  .withSpeakerSelection('round_robin')
  .withMaxRounds(10)
  .withTerminationCondition(TerminationPresets.taskCompletion())
  .build();

// Set up response generator (integrate with your LLM provider)
chat.setResponseGenerator(async (participant, messages, context) => {
  // Your LLM integration here
  return `Response from ${participant.name}`;
});

// Start the conversation
const result = await chat.start({
  initialMessage: 'Let us discuss the project requirements.',
  initialSender: 'user',
});

console.log('Chat completed:', result.summary);

Core Concepts

Participants

Participants represent agents in the conversation. Each participant has:

  • name: Unique identifier in the chat
  • type: 'human' | 'assistant' | 'agent' | 'tool'
  • systemPrompt: Instructions defining behavior
  • capabilities: Skills/expertise areas
  • status: Current state ('active' | 'idle' | 'busy' | 'offline' | 'error')
import { ChatParticipant, createParticipant } from '@wundr.io/autogen-orchestrator';

// Simple creation
const agent = createParticipant(
  'ResearchAgent',
  'You conduct thorough research and provide citations.',
  ['research', 'citations', 'fact-checking']
);

// Full configuration
const advancedAgent: ChatParticipant = {
  id: 'agent-001',
  name: 'AdvancedAgent',
  type: 'agent',
  systemPrompt: 'You are an expert in financial analysis.',
  status: 'active',
  capabilities: ['finance', 'analysis', 'forecasting'],
  modelConfig: {
    model: 'claude-3-opus',
    temperature: 0.7,
    maxTokens: 4096,
  },
  maxConsecutiveReplies: 3,
  description: 'Financial analysis specialist',
};

Messages

Messages track the conversation flow:

import { Message, MessageRole, ContentType } from '@wundr.io/autogen-orchestrator';

// Message structure
interface Message {
  id: string;
  role: MessageRole;        // 'system' | 'user' | 'assistant' | 'function'
  content: string;
  name: string;             // Sender name
  timestamp: Date;
  contentType?: ContentType; // 'text' | 'code' | 'image' | 'function_call' | 'function_result'
  functionCall?: FunctionCall;
  metadata?: MessageMetadata;
  status?: MessageStatus;
}

Context

The ChatContext provides state throughout the conversation:

interface ChatContext {
  chatId: string;
  currentRound: number;
  messageCount: number;
  activeParticipants: string[];
  currentSpeaker?: string;
  previousSpeaker?: string;
  startTime: Date;
  state: Record<string, unknown>;  // Custom state storage
  parentContext?: ChatContext;      // For nested chats
}

Agent Conversation Patterns

Round-Robin Conversations

Each participant speaks in order:

const chat = new GroupChatBuilder()
  .withName('Round Robin Discussion')
  .withParticipant(agent1)
  .withParticipant(agent2)
  .withParticipant(agent3)
  .withSpeakerSelection('round_robin')
  .withMaxRounds(5)
  .build();

Priority-Based Conversations

Agents speak based on configured priority:

const chat = new GroupChatManager({
  name: 'Priority Discussion',
  participants: [leader, specialist, assistant],
  speakerSelectionMethod: 'priority',
  speakerSelectionConfig: {
    priorityOrder: ['Leader', 'Specialist', 'Assistant'],
    transitionRules: [
      { from: 'Leader', to: ['Specialist'], weight: 0.8 },
      { from: 'Specialist', to: ['Leader', 'Assistant'], weight: 0.5 },
    ],
    allowedTransitions: {
      'Leader': ['Specialist', 'Assistant'],
      'Specialist': ['Leader'],
      'Assistant': ['Leader', 'Specialist'],
    },
  },
});

LLM-Selected Speakers

Let an LLM decide who speaks next based on context:

const chat = new GroupChatBuilder()
  .withName('Dynamic Discussion')
  .withParticipant(analyst)
  .withParticipant(developer)
  .withParticipant(designer)
  .withSpeakerSelection('llm_selected')
  .build();

// The LLM selector analyzes:
// - Recent message content
// - Participant capabilities
// - Conversation flow
// - Mentions of participant names

Auto-Adaptive Selection

Automatically chooses the best selection strategy:

const chat = new GroupChatBuilder()
  .withSpeakerSelection('auto')
  .build();

// Strategy selection logic:
// - Uses 'priority' if transition rules are configured
// - Uses 'llm' for complex conversations (>3 participants, >5 messages)
// - Uses 'llm' if participants have diverse capabilities
// - Defaults to 'round_robin' for simple cases

Group Chat Management

Creating a Group Chat

Using the builder pattern:

import { GroupChatBuilder, TerminationPresets } from '@wundr.io/autogen-orchestrator';

const chat = new GroupChatBuilder()
  .withName('Code Review Session')
  .withDescription('Multi-agent code review and improvement')
  .withParticipant(codeWriter)
  .withParticipant(reviewer)
  .withParticipant(tester)
  .withSpeakerSelection('priority')
  .withMaxRounds(15)
  .withMaxMessages(50)
  .withTerminationCondition({ type: 'keyword', value: ['APPROVED', 'MERGED'] })
  .withTimeout(300000) // 5 minutes
  .withAdmin('moderator')
  .withNestedChats()
  .build();

Using direct configuration:

import { GroupChatManager, GroupChatConfig } from '@wundr.io/autogen-orchestrator';

const config: GroupChatConfig = {
  name: 'Analysis Team',
  participants: [analyst, researcher, writer],
  speakerSelectionMethod: 'round_robin',
  maxRounds: 10,
  maxMessages: 100,
  terminationConditions: [
    { type: 'keyword', value: 'COMPLETE' },
    { type: 'max_rounds', value: 10 },
  ],
  enableHistory: true,
  maxHistoryLength: 500,
  timeoutMs: 600000,
};

const chat = new GroupChatManager(config);

Managing Participants Dynamically

// Add participant during chat
const newAgent = chat.addParticipant({
  name: 'ExpertConsultant',
  type: 'agent',
  systemPrompt: 'You provide expert consultation on complex issues.',
  capabilities: ['consulting', 'strategy'],
});

// Remove participant
chat.removeParticipant('ExpertConsultant');

// Update participant status
chat.updateParticipantStatus('Analyst', 'busy');

// Get all participants
const participants = chat.getParticipants();

Chat Lifecycle

// Start the chat
const result = await chat.start({
  initialMessage: 'Begin the analysis.',
  initialSender: 'user',
  initialState: { projectId: 'proj-123' },
});

// Pause and resume
chat.pause();
// ... some time later
chat.resume();

// Stop the chat
const finalResult = await chat.stop('User requested termination');

// Get current status
const status = chat.getStatus(); // 'initializing' | 'active' | 'paused' | 'completed' | 'terminated' | 'error'

Event Handling

import { GroupChatEvents } from '@wundr.io/autogen-orchestrator';

// Listen to chat events
chat.on('chat:started', ({ chatId, config }) => {
  console.log(`Chat ${chatId} started with ${config.participants.length} participants`);
});

chat.on('message:received', ({ chatId, message }) => {
  console.log(`[${message.name}]: ${message.content}`);
});

chat.on('speaker:selected', ({ chatId, speaker, reason }) => {
  console.log(`Next speaker: ${speaker} (${reason})`);
});

chat.on('round:started', ({ chatId, round }) => {
  console.log(`Starting round ${round}`);
});

chat.on('termination:triggered', ({ chatId, reason }) => {
  console.log(`Chat terminated: ${reason}`);
});

chat.on('chat:ended', ({ chatId, result }) => {
  console.log(`Chat ended. Total messages: ${result.totalMessages}`);
});

chat.on('chat:error', ({ chatId, error }) => {
  console.error(`Error in chat: ${error.message}`);
});

Speaker Selection

Available Strategies

import {
  createSpeakerSelector,
  SpeakerSelectionManager,
  RoundRobinSelector,
  RandomSelector,
  LLMSelector,
  PrioritySelector,
  ManualSelector,
  AutoSelector,
} from '@wundr.io/autogen-orchestrator';

// Factory function
const selector = createSpeakerSelector('llm_selected');

// Using the manager
const manager = new SpeakerSelectionManager('round_robin');

// Select next speaker
const result = await manager.selectSpeaker(
  participants,
  messages,
  context,
  selectionConfig
);

console.log(result);
// {
//   speaker: 'AnalystAgent',
//   reason: 'Round-robin selection: position 2 of 3',
//   confidence: 1.0,
//   alternatives: ['DeveloperAgent', 'ReviewerAgent']
// }

// Change strategy at runtime
manager.setMethod('priority');

Custom Speaker Selection

import { SpeakerSelectionStrategy, SpeakerSelectionResult } from '@wundr.io/autogen-orchestrator';

class CapabilityMatchSelector implements SpeakerSelectionStrategy {
  async selectSpeaker(
    participants: ChatParticipant[],
    messages: Message[],
    context: ChatContext,
    config?: SpeakerSelectionConfig
  ): Promise<SpeakerSelectionResult> {
    const lastMessage = messages[messages.length - 1];

    // Find participant whose capabilities best match the message content
    let bestMatch = participants[0];
    let bestScore = 0;

    for (const participant of participants) {
      const score = participant.capabilities.filter(cap =>
        lastMessage?.content.toLowerCase().includes(cap.toLowerCase())
      ).length;

      if (score > bestScore) {
        bestScore = score;
        bestMatch = participant;
      }
    }

    return {
      speaker: bestMatch.name,
      reason: `Capability match score: ${bestScore}`,
      confidence: bestScore > 0 ? 0.9 : 0.5,
      alternatives: participants.filter(p => p.name !== bestMatch.name).map(p => p.name),
    };
  }
}

Transition Rules

const config: SpeakerSelectionConfig = {
  priorityOrder: ['Manager', 'Developer', 'Tester'],
  transitionRules: [
    {
      from: 'Manager',
      to: ['Developer', 'Tester'],
      condition: 'after assignment',
      weight: 0.9,
    },
    {
      from: 'Developer',
      to: ['Tester'],
      weight: 0.7,
    },
    {
      from: 'Tester',
      to: ['Developer', 'Manager'],
      weight: 0.5,
    },
  ],
  allowedTransitions: {
    'Manager': ['Developer', 'Tester'],
    'Developer': ['Tester', 'Manager'],
    'Tester': ['Developer', 'Manager'],
  },
};

Message Routing

Adding Messages Programmatically

// Add a user message
await chat.addMessage({
  role: 'user',
  content: 'Please analyze the latest data.',
  name: 'user',
});

// Add a system message
await chat.addMessage({
  role: 'system',
  content: 'Context updated: New data available.',
  name: 'system',
});

// Add a function call message
await chat.addMessage({
  role: 'assistant',
  content: 'Executing data analysis...',
  name: 'AnalystAgent',
  contentType: 'function_call',
  functionCall: {
    name: 'analyzeData',
    arguments: { dataset: 'q4_2024', metrics: ['revenue', 'growth'] },
  },
});

// Add function result
await chat.addMessage({
  role: 'function',
  content: JSON.stringify({ revenue: 1500000, growth: 0.15 }),
  name: 'analyzeData',
  contentType: 'function_result',
});

Response Generation

import { ResponseGenerator } from '@wundr.io/autogen-orchestrator';

// Set custom response generator
const generator: ResponseGenerator = async (participant, messages, context) => {
  // Build prompt from participant's system prompt and message history
  const systemPrompt = participant.systemPrompt;
  const conversationHistory = messages.map(m => `${m.name}: ${m.content}`).join('\n');

  // Call your LLM provider
  const response = await callLLM({
    system: systemPrompt,
    messages: conversationHistory,
    model: participant.modelConfig?.model || 'default-model',
    temperature: participant.modelConfig?.temperature || 0.7,
  });

  return response;
};

chat.setResponseGenerator(generator);

Conversation History Tracking

Accessing History

// Get all messages
const messages = chat.getMessages();

// Get current context
const context = chat.getContext();

// Get metrics
const metrics = chat.getMetrics();
console.log(metrics);
// {
//   totalTokens: 15000,
//   avgResponseTimeMs: 1250,
//   messagesPerParticipant: { 'Agent1': 5, 'Agent2': 4 },
//   tokensPerParticipant: { 'Agent1': 8000, 'Agent2': 7000 },
//   successfulResponses: 9,
//   failedResponses: 0,
// }

State Management

// Update shared state
chat.updateState('currentTopic', 'performance optimization');
chat.updateState('analysisComplete', true);
chat.updateState('findings', { issues: 3, recommendations: 5 });

// Read state
const topic = chat.getState<string>('currentTopic');
const complete = chat.getState<boolean>('analysisComplete');

Chat Results

interface ChatResult {
  chatId: string;
  status: ChatStatus;
  messages: Message[];
  summary?: string;
  terminationReason?: string;
  totalRounds: number;
  totalMessages: number;
  participants: string[];
  durationMs: number;
  metrics?: ChatMetrics;
  nestedResults?: NestedChatResult[];
  error?: ChatError;
  startedAt: Date;
  endedAt: Date;
}

const result = await chat.start({ initialMessage: 'Begin' });
console.log(`Completed in ${result.durationMs}ms with ${result.totalMessages} messages`);

Termination Handling

Built-in Termination Conditions

import {
  TerminationManager,
  createTerminationHandler,
  TerminationPresets,
} from '@wundr.io/autogen-orchestrator';

// Max rounds
{ type: 'max_rounds', value: 10 }

// Max messages
{ type: 'max_messages', value: 50 }

// Keyword detection
{ type: 'keyword', value: ['DONE', 'COMPLETE', 'TERMINATE'] }

// Timeout (milliseconds)
{ type: 'timeout', value: 300000 }

// Consensus-based
{
  type: 'consensus',
  value: {
    threshold: 0.75,
    agreementKeywords: ['agree', 'approve', 'lgtm'],
    disagreementKeywords: ['disagree', 'reject', 'needs work'],
    minParticipants: 2,
    windowSize: 10,
  }
}

// Custom function
{
  type: 'function',
  evaluator: async (messages, participants, context) => ({
    shouldTerminate: context.state['taskComplete'] === true,
    reason: 'Task marked as complete',
    summary: 'Conversation ended after task completion',
  }),
}

Termination Presets

import { TerminationPresets } from '@wundr.io/autogen-orchestrator';

// Task completion detection
const taskComplete = TerminationPresets.taskCompletion();
// Detects: 'TASK_COMPLETE', 'DONE', 'FINISHED', 'COMPLETED', 'END_TASK'

// Approval workflow
const approval = TerminationPresets.approval();
// Consensus with 75% threshold, detects: 'approve', 'lgtm', 'ship it'

// Quick discussions
const quick = TerminationPresets.quickDiscussion(5);
// Max 5 rounds + manual termination keywords

// Long-running tasks
const longRunning = TerminationPresets.longRunning(30);
// 30-minute timeout + 100 message limit + emergency keywords

Managing Termination Conditions

const manager = new TerminationManager([
  { type: 'max_rounds', value: 10 },
  { type: 'keyword', value: 'STOP' },
]);

// Add condition at runtime
manager.addCondition({ type: 'timeout', value: 60000 });

// Remove condition type
manager.removeCondition('timeout');

// Check if condition exists
const hasKeyword = manager.hasCondition('keyword');

// Evaluate all conditions
const result = await manager.evaluate(messages, participants, context);
if (result.shouldTerminate) {
  console.log(`Terminating: ${result.reason}`);
}

// Get all conditions
const conditions = manager.getConditions();

Nested Chats

Nested chats allow focused sub-discussions within a main conversation.

Configuration

import {
  NestedChatManager,
  NestedChatConfigBuilder,
} from '@wundr.io/autogen-orchestrator';

// Using the builder
const nestedConfig = new NestedChatConfigBuilder()
  .withId('technical-review')
  .withName('Technical Deep Dive')
  .withKeywordTrigger(['technical review', 'deep dive'])
  .withParticipants(['Developer', 'Architect', 'Tester'])
  .withMaxRounds(5)
  .withSummaryMethod('reflection')
  .withPrompt('Focus on technical implementation details.')
  .withSharedContext()
  .build();

// Add to group chat
const chat = new GroupChatBuilder()
  .withParticipant(developer)
  .withParticipant(architect)
  .withParticipant(tester)
  .withParticipant(manager)
  .withNestedChats()
  .withNestedChatConfig(nestedConfig)
  .build();

Trigger Types

// Keyword trigger
new NestedChatConfigBuilder()
  .withKeywordTrigger(['review code', 'code review'])
  .build();

// Participant trigger
new NestedChatConfigBuilder()
  .withParticipantTrigger(['SecurityExpert', 'ComplianceOfficer'])
  .build();

// Condition trigger
new NestedChatConfigBuilder()
  .withConditionTrigger((message, context) => {
    return context.messageCount > 10 && message.content.includes('complex');
  })
  .build();

// Manual trigger
new NestedChatConfigBuilder()
  .withManualTrigger('startNestedDiscussion')
  .build();

// Trigger manually via state
chat.updateState('startNestedDiscussion', true);

Summary Methods

// 'last' - Use the last message as summary
// 'llm' - Generate summary using LLM (requires implementation)
// 'reflection' - Structured reflection summary
// 'custom' - Custom summary logic

const config = new NestedChatConfigBuilder()
  .withSummaryMethod('reflection')
  .build();

Nested Chat Events

chat.on('nested:started', ({ chatId, nestedChatId }) => {
  console.log(`Nested chat ${nestedChatId} started`);
});

chat.on('nested:ended', ({ chatId, nestedChatId, result }) => {
  console.log(`Nested chat summary: ${result.summary}`);
});

Integration with Other Orchestrators

With Task Orchestrators

import { GroupChatManager } from '@wundr.io/autogen-orchestrator';
import { TaskOrchestrator } from '@wundr.io/task-orchestrator';

const taskOrchestrator = new TaskOrchestrator();

// Create a chat for each complex task
taskOrchestrator.on('task:complex', async (task) => {
  const chat = new GroupChatBuilder()
    .withName(`Task: ${task.name}`)
    .withParticipant(createParticipant('Planner', 'Plan the task execution'))
    .withParticipant(createParticipant('Executor', 'Execute the planned steps'))
    .withParticipant(createParticipant('Validator', 'Validate results'))
    .withSpeakerSelection('priority')
    .withTerminationCondition({ type: 'keyword', value: 'TASK_COMPLETE' })
    .build();

  const result = await chat.start({
    initialMessage: `Execute task: ${task.description}`,
    initialState: { taskId: task.id },
  });

  return result;
});

With Workflow Engines

import { GroupChatManager } from '@wundr.io/autogen-orchestrator';

class WorkflowStep {
  async executeWithAgents(stepConfig: StepConfig) {
    const participants = stepConfig.roles.map(role =>
      createParticipant(role.name, role.prompt, role.capabilities)
    );

    const chat = new GroupChatBuilder()
      .withName(stepConfig.name)
      .withSpeakerSelection('auto')
      .withMaxRounds(stepConfig.maxIterations || 10)
      .build();

    participants.forEach(p => chat.addParticipant(p));

    chat.setResponseGenerator(this.createResponseGenerator(stepConfig));

    return await chat.start({
      initialMessage: stepConfig.objective,
      initialState: stepConfig.context,
    });
  }
}

With Event-Driven Systems

import { EventEmitter } from 'events';
import { GroupChatManager, ChatEvent } from '@wundr.io/autogen-orchestrator';

class AgentEventBridge extends EventEmitter {
  private chat: GroupChatManager;

  constructor(chat: GroupChatManager) {
    super();
    this.chat = chat;
    this.setupBridge();
  }

  private setupBridge() {
    // Forward chat events to external system
    this.chat.on('message:received', ({ message }) => {
      this.emit('agent:message', {
        agent: message.name,
        content: message.content,
        timestamp: message.timestamp,
      });
    });

    this.chat.on('chat:ended', ({ result }) => {
      this.emit('conversation:complete', {
        summary: result.summary,
        metrics: result.metrics,
        duration: result.durationMs,
      });
    });
  }

  // Inject external events into the chat
  async injectExternalMessage(source: string, content: string) {
    await this.chat.addMessage({
      role: 'system',
      content: `[External: ${source}] ${content}`,
      name: 'system',
    });
  }
}

API Reference

GroupChatManager

| Method | Description | |--------|-------------| | constructor(config: GroupChatConfig) | Create a new chat manager | | setResponseGenerator(generator: ResponseGenerator) | Set the LLM response generator | | start(options?: StartChatOptions) | Start the conversation | | pause() | Pause the conversation | | resume() | Resume a paused conversation | | stop(reason?: string) | Stop the conversation | | addMessage(options: CreateMessageOptions) | Add a message | | addParticipant(options: AddParticipantOptions) | Add a participant | | removeParticipant(name: string) | Remove a participant | | updateParticipantStatus(name: string, status: ParticipantStatus) | Update participant status | | addTerminationCondition(condition: TerminationCondition) | Add termination condition | | addNestedChatConfig(config: NestedChatConfig) | Add nested chat configuration | | getStatus() | Get current chat status | | getChatId() | Get the chat ID | | getMessages() | Get all messages | | getParticipants() | Get all participants | | getContext() | Get current context | | getMetrics() | Get chat metrics | | updateState(key: string, value: T) | Update context state | | getState<T>(key: string) | Get context state value |

SpeakerSelectionManager

| Method | Description | |--------|-------------| | constructor(method?: SpeakerSelectionMethod) | Create with initial method | | selectSpeaker(participants, messages, context, config?) | Select next speaker | | setMethod(method: SpeakerSelectionMethod) | Change selection method | | getMethod() | Get current method | | getStrategy(method: SpeakerSelectionMethod) | Get strategy instance |

TerminationManager

| Method | Description | |--------|-------------| | constructor(conditions?: TerminationCondition[]) | Create with initial conditions | | addCondition(condition: TerminationCondition) | Add a condition | | removeCondition(type: TerminationConditionType) | Remove conditions by type | | clearConditions() | Clear all conditions | | evaluate(messages, participants, context) | Evaluate all conditions | | getConditions() | Get all conditions | | hasCondition(type: TerminationConditionType) | Check if type exists |

NestedChatManager

| Method | Description | |--------|-------------| | constructor(configs?: NestedChatConfig[]) | Create with initial configs | | addConfig(config: NestedChatConfig) | Add configuration | | removeConfig(configId: string) | Remove configuration | | checkTrigger(message, participants, context) | Check for triggers | | startNestedChat(config, parentChatId, parentMessageId, participants, context) | Start nested chat | | addMessage(nestedChatId: string, message: Message) | Add message to nested chat | | endNestedChat(nestedChatId, status?, reason?) | End nested chat | | getActiveChats() | Get active nested chat IDs | | getCompletedChats() | Get completed results | | hasActiveChats() | Check for active chats |

Examples

Code Review Workflow

import {
  GroupChatBuilder,
  createParticipant,
  TerminationPresets,
} from '@wundr.io/autogen-orchestrator';

const codeAuthor = createParticipant(
  'CodeAuthor',
  'You wrote the code and can explain design decisions.',
  ['code', 'architecture', 'explanation']
);

const securityReviewer = createParticipant(
  'SecurityReviewer',
  'You review code for security vulnerabilities.',
  ['security', 'vulnerabilities', 'compliance']
);

const performanceReviewer = createParticipant(
  'PerformanceReviewer',
  'You review code for performance issues.',
  ['performance', 'optimization', 'efficiency']
);

const chat = new GroupChatBuilder()
  .withName('Code Review')
  .withParticipant(codeAuthor)
  .withParticipant(securityReviewer)
  .withParticipant(performanceReviewer)
  .withSpeakerSelection('priority')
  .withTerminationCondition(TerminationPresets.approval())
  .withMaxRounds(20)
  .build();

const result = await chat.start({
  initialMessage: `Review this code:\n\`\`\`javascript\n${codeToReview}\n\`\`\``,
});

Research Collaboration

const researcher = createParticipant(
  'Researcher',
  'You search for and analyze relevant information.',
  ['research', 'analysis', 'citations']
);

const critic = createParticipant(
  'Critic',
  'You critically evaluate claims and identify weaknesses.',
  ['evaluation', 'logic', 'counterarguments']
);

const synthesizer = createParticipant(
  'Synthesizer',
  'You combine findings into coherent conclusions.',
  ['synthesis', 'summary', 'conclusions']
);

const chat = new GroupChatBuilder()
  .withName('Research Collaboration')
  .withParticipant(researcher)
  .withParticipant(critic)
  .withParticipant(synthesizer)
  .withSpeakerSelection('llm_selected')
  .withTerminationCondition({
    type: 'keyword',
    value: ['CONCLUSION REACHED', 'RESEARCH COMPLETE'],
  })
  .build();

Customer Support Escalation

const frontlineAgent = createParticipant(
  'FrontlineSupport',
  'You handle initial customer inquiries.',
  ['support', 'troubleshooting', 'empathy']
);

const technicalSpecialist = createParticipant(
  'TechnicalSpecialist',
  'You handle complex technical issues.',
  ['technical', 'debugging', 'systems']
);

const supervisor = createParticipant(
  'Supervisor',
  'You handle escalations and make final decisions.',
  ['escalation', 'decisions', 'policies']
);

const chat = new GroupChatBuilder()
  .withName('Support Ticket #12345')
  .withParticipant(frontlineAgent)
  .withParticipant(technicalSpecialist)
  .withParticipant(supervisor)
  .withSpeakerSelection('auto')
  .withNestedChats()
  .withNestedChatConfig(
    new NestedChatConfigBuilder()
      .withId('escalation')
      .withName('Supervisor Escalation')
      .withKeywordTrigger(['escalate', 'supervisor'])
      .withParticipants(['TechnicalSpecialist', 'Supervisor'])
      .withMaxRounds(3)
      .build()
  )
  .build();

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting pull requests.

Support