@wundr.io/autogen-orchestrator 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1088 -0
- package/dist/group-chat.d.ts +327 -0
- package/dist/group-chat.d.ts.map +1 -0
- package/dist/group-chat.js +724 -0
- package/dist/group-chat.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/nested-chat.d.ts +296 -0
- package/dist/nested-chat.d.ts.map +1 -0
- package/dist/nested-chat.js +600 -0
- package/dist/nested-chat.js.map +1 -0
- package/dist/speaker-selection.d.ts +195 -0
- package/dist/speaker-selection.d.ts.map +1 -0
- package/dist/speaker-selection.js +569 -0
- package/dist/speaker-selection.js.map +1 -0
- package/dist/termination.d.ts +237 -0
- package/dist/termination.d.ts.map +1 -0
- package/dist/termination.js +566 -0
- package/dist/termination.js.map +1 -0
- package/dist/types.d.ts +1248 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +201 -0
- package/dist/types.js.map +1 -0
- package/package.json +59 -0
- package/src/group-chat.ts +980 -0
- package/src/index.ts +145 -0
- package/src/nested-chat.ts +795 -0
- package/src/speaker-selection.ts +794 -0
- package/src/termination.ts +704 -0
- package/src/types.ts +876 -0
package/README.md
ADDED
|
@@ -0,0 +1,1088 @@
|
|
|
1
|
+
# @wundr.io/autogen-orchestrator
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Quick Start](#quick-start)
|
|
9
|
+
- [Core Concepts](#core-concepts)
|
|
10
|
+
- [Agent Conversation Patterns](#agent-conversation-patterns)
|
|
11
|
+
- [Group Chat Management](#group-chat-management)
|
|
12
|
+
- [Speaker Selection](#speaker-selection)
|
|
13
|
+
- [Message Routing](#message-routing)
|
|
14
|
+
- [Conversation History Tracking](#conversation-history-tracking)
|
|
15
|
+
- [Termination Handling](#termination-handling)
|
|
16
|
+
- [Nested Chats](#nested-chats)
|
|
17
|
+
- [Integration with Other Orchestrators](#integration-with-other-orchestrators)
|
|
18
|
+
- [API Reference](#api-reference)
|
|
19
|
+
- [Examples](#examples)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @wundr.io/autogen-orchestrator
|
|
25
|
+
# or
|
|
26
|
+
yarn add @wundr.io/autogen-orchestrator
|
|
27
|
+
# or
|
|
28
|
+
pnpm add @wundr.io/autogen-orchestrator
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import {
|
|
35
|
+
GroupChatManager,
|
|
36
|
+
GroupChatBuilder,
|
|
37
|
+
createParticipant,
|
|
38
|
+
TerminationPresets,
|
|
39
|
+
} from '@wundr.io/autogen-orchestrator';
|
|
40
|
+
|
|
41
|
+
// Create participants
|
|
42
|
+
const analyst = createParticipant(
|
|
43
|
+
'Analyst',
|
|
44
|
+
'You are a data analyst specializing in market research.',
|
|
45
|
+
['analysis', 'research', 'data']
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const developer = createParticipant(
|
|
49
|
+
'Developer',
|
|
50
|
+
'You are a senior software developer.',
|
|
51
|
+
['coding', 'architecture', 'debugging']
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const reviewer = createParticipant(
|
|
55
|
+
'Reviewer',
|
|
56
|
+
'You are a code reviewer ensuring quality standards.',
|
|
57
|
+
['review', 'testing', 'quality']
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Build and configure the group chat
|
|
61
|
+
const chat = new GroupChatBuilder()
|
|
62
|
+
.withName('Project Discussion')
|
|
63
|
+
.withDescription('Multi-agent collaboration for project planning')
|
|
64
|
+
.withParticipant(analyst)
|
|
65
|
+
.withParticipant(developer)
|
|
66
|
+
.withParticipant(reviewer)
|
|
67
|
+
.withSpeakerSelection('round_robin')
|
|
68
|
+
.withMaxRounds(10)
|
|
69
|
+
.withTerminationCondition(TerminationPresets.taskCompletion())
|
|
70
|
+
.build();
|
|
71
|
+
|
|
72
|
+
// Set up response generator (integrate with your LLM provider)
|
|
73
|
+
chat.setResponseGenerator(async (participant, messages, context) => {
|
|
74
|
+
// Your LLM integration here
|
|
75
|
+
return `Response from ${participant.name}`;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Start the conversation
|
|
79
|
+
const result = await chat.start({
|
|
80
|
+
initialMessage: 'Let us discuss the project requirements.',
|
|
81
|
+
initialSender: 'user',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log('Chat completed:', result.summary);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Core Concepts
|
|
88
|
+
|
|
89
|
+
### Participants
|
|
90
|
+
|
|
91
|
+
Participants represent agents in the conversation. Each participant has:
|
|
92
|
+
|
|
93
|
+
- **name**: Unique identifier in the chat
|
|
94
|
+
- **type**: `'human'` | `'assistant'` | `'agent'` | `'tool'`
|
|
95
|
+
- **systemPrompt**: Instructions defining behavior
|
|
96
|
+
- **capabilities**: Skills/expertise areas
|
|
97
|
+
- **status**: Current state (`'active'` | `'idle'` | `'busy'` | `'offline'` | `'error'`)
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { ChatParticipant, createParticipant } from '@wundr.io/autogen-orchestrator';
|
|
101
|
+
|
|
102
|
+
// Simple creation
|
|
103
|
+
const agent = createParticipant(
|
|
104
|
+
'ResearchAgent',
|
|
105
|
+
'You conduct thorough research and provide citations.',
|
|
106
|
+
['research', 'citations', 'fact-checking']
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Full configuration
|
|
110
|
+
const advancedAgent: ChatParticipant = {
|
|
111
|
+
id: 'agent-001',
|
|
112
|
+
name: 'AdvancedAgent',
|
|
113
|
+
type: 'agent',
|
|
114
|
+
systemPrompt: 'You are an expert in financial analysis.',
|
|
115
|
+
status: 'active',
|
|
116
|
+
capabilities: ['finance', 'analysis', 'forecasting'],
|
|
117
|
+
modelConfig: {
|
|
118
|
+
model: 'claude-3-opus',
|
|
119
|
+
temperature: 0.7,
|
|
120
|
+
maxTokens: 4096,
|
|
121
|
+
},
|
|
122
|
+
maxConsecutiveReplies: 3,
|
|
123
|
+
description: 'Financial analysis specialist',
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Messages
|
|
128
|
+
|
|
129
|
+
Messages track the conversation flow:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { Message, MessageRole, ContentType } from '@wundr.io/autogen-orchestrator';
|
|
133
|
+
|
|
134
|
+
// Message structure
|
|
135
|
+
interface Message {
|
|
136
|
+
id: string;
|
|
137
|
+
role: MessageRole; // 'system' | 'user' | 'assistant' | 'function'
|
|
138
|
+
content: string;
|
|
139
|
+
name: string; // Sender name
|
|
140
|
+
timestamp: Date;
|
|
141
|
+
contentType?: ContentType; // 'text' | 'code' | 'image' | 'function_call' | 'function_result'
|
|
142
|
+
functionCall?: FunctionCall;
|
|
143
|
+
metadata?: MessageMetadata;
|
|
144
|
+
status?: MessageStatus;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Context
|
|
149
|
+
|
|
150
|
+
The `ChatContext` provides state throughout the conversation:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
interface ChatContext {
|
|
154
|
+
chatId: string;
|
|
155
|
+
currentRound: number;
|
|
156
|
+
messageCount: number;
|
|
157
|
+
activeParticipants: string[];
|
|
158
|
+
currentSpeaker?: string;
|
|
159
|
+
previousSpeaker?: string;
|
|
160
|
+
startTime: Date;
|
|
161
|
+
state: Record<string, unknown>; // Custom state storage
|
|
162
|
+
parentContext?: ChatContext; // For nested chats
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Agent Conversation Patterns
|
|
167
|
+
|
|
168
|
+
### Round-Robin Conversations
|
|
169
|
+
|
|
170
|
+
Each participant speaks in order:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const chat = new GroupChatBuilder()
|
|
174
|
+
.withName('Round Robin Discussion')
|
|
175
|
+
.withParticipant(agent1)
|
|
176
|
+
.withParticipant(agent2)
|
|
177
|
+
.withParticipant(agent3)
|
|
178
|
+
.withSpeakerSelection('round_robin')
|
|
179
|
+
.withMaxRounds(5)
|
|
180
|
+
.build();
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Priority-Based Conversations
|
|
184
|
+
|
|
185
|
+
Agents speak based on configured priority:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const chat = new GroupChatManager({
|
|
189
|
+
name: 'Priority Discussion',
|
|
190
|
+
participants: [leader, specialist, assistant],
|
|
191
|
+
speakerSelectionMethod: 'priority',
|
|
192
|
+
speakerSelectionConfig: {
|
|
193
|
+
priorityOrder: ['Leader', 'Specialist', 'Assistant'],
|
|
194
|
+
transitionRules: [
|
|
195
|
+
{ from: 'Leader', to: ['Specialist'], weight: 0.8 },
|
|
196
|
+
{ from: 'Specialist', to: ['Leader', 'Assistant'], weight: 0.5 },
|
|
197
|
+
],
|
|
198
|
+
allowedTransitions: {
|
|
199
|
+
'Leader': ['Specialist', 'Assistant'],
|
|
200
|
+
'Specialist': ['Leader'],
|
|
201
|
+
'Assistant': ['Leader', 'Specialist'],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### LLM-Selected Speakers
|
|
208
|
+
|
|
209
|
+
Let an LLM decide who speaks next based on context:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
const chat = new GroupChatBuilder()
|
|
213
|
+
.withName('Dynamic Discussion')
|
|
214
|
+
.withParticipant(analyst)
|
|
215
|
+
.withParticipant(developer)
|
|
216
|
+
.withParticipant(designer)
|
|
217
|
+
.withSpeakerSelection('llm_selected')
|
|
218
|
+
.build();
|
|
219
|
+
|
|
220
|
+
// The LLM selector analyzes:
|
|
221
|
+
// - Recent message content
|
|
222
|
+
// - Participant capabilities
|
|
223
|
+
// - Conversation flow
|
|
224
|
+
// - Mentions of participant names
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Auto-Adaptive Selection
|
|
228
|
+
|
|
229
|
+
Automatically chooses the best selection strategy:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const chat = new GroupChatBuilder()
|
|
233
|
+
.withSpeakerSelection('auto')
|
|
234
|
+
.build();
|
|
235
|
+
|
|
236
|
+
// Strategy selection logic:
|
|
237
|
+
// - Uses 'priority' if transition rules are configured
|
|
238
|
+
// - Uses 'llm' for complex conversations (>3 participants, >5 messages)
|
|
239
|
+
// - Uses 'llm' if participants have diverse capabilities
|
|
240
|
+
// - Defaults to 'round_robin' for simple cases
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Group Chat Management
|
|
244
|
+
|
|
245
|
+
### Creating a Group Chat
|
|
246
|
+
|
|
247
|
+
Using the builder pattern:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
import { GroupChatBuilder, TerminationPresets } from '@wundr.io/autogen-orchestrator';
|
|
251
|
+
|
|
252
|
+
const chat = new GroupChatBuilder()
|
|
253
|
+
.withName('Code Review Session')
|
|
254
|
+
.withDescription('Multi-agent code review and improvement')
|
|
255
|
+
.withParticipant(codeWriter)
|
|
256
|
+
.withParticipant(reviewer)
|
|
257
|
+
.withParticipant(tester)
|
|
258
|
+
.withSpeakerSelection('priority')
|
|
259
|
+
.withMaxRounds(15)
|
|
260
|
+
.withMaxMessages(50)
|
|
261
|
+
.withTerminationCondition({ type: 'keyword', value: ['APPROVED', 'MERGED'] })
|
|
262
|
+
.withTimeout(300000) // 5 minutes
|
|
263
|
+
.withAdmin('moderator')
|
|
264
|
+
.withNestedChats()
|
|
265
|
+
.build();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Using direct configuration:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { GroupChatManager, GroupChatConfig } from '@wundr.io/autogen-orchestrator';
|
|
272
|
+
|
|
273
|
+
const config: GroupChatConfig = {
|
|
274
|
+
name: 'Analysis Team',
|
|
275
|
+
participants: [analyst, researcher, writer],
|
|
276
|
+
speakerSelectionMethod: 'round_robin',
|
|
277
|
+
maxRounds: 10,
|
|
278
|
+
maxMessages: 100,
|
|
279
|
+
terminationConditions: [
|
|
280
|
+
{ type: 'keyword', value: 'COMPLETE' },
|
|
281
|
+
{ type: 'max_rounds', value: 10 },
|
|
282
|
+
],
|
|
283
|
+
enableHistory: true,
|
|
284
|
+
maxHistoryLength: 500,
|
|
285
|
+
timeoutMs: 600000,
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const chat = new GroupChatManager(config);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Managing Participants Dynamically
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
// Add participant during chat
|
|
295
|
+
const newAgent = chat.addParticipant({
|
|
296
|
+
name: 'ExpertConsultant',
|
|
297
|
+
type: 'agent',
|
|
298
|
+
systemPrompt: 'You provide expert consultation on complex issues.',
|
|
299
|
+
capabilities: ['consulting', 'strategy'],
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Remove participant
|
|
303
|
+
chat.removeParticipant('ExpertConsultant');
|
|
304
|
+
|
|
305
|
+
// Update participant status
|
|
306
|
+
chat.updateParticipantStatus('Analyst', 'busy');
|
|
307
|
+
|
|
308
|
+
// Get all participants
|
|
309
|
+
const participants = chat.getParticipants();
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Chat Lifecycle
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// Start the chat
|
|
316
|
+
const result = await chat.start({
|
|
317
|
+
initialMessage: 'Begin the analysis.',
|
|
318
|
+
initialSender: 'user',
|
|
319
|
+
initialState: { projectId: 'proj-123' },
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Pause and resume
|
|
323
|
+
chat.pause();
|
|
324
|
+
// ... some time later
|
|
325
|
+
chat.resume();
|
|
326
|
+
|
|
327
|
+
// Stop the chat
|
|
328
|
+
const finalResult = await chat.stop('User requested termination');
|
|
329
|
+
|
|
330
|
+
// Get current status
|
|
331
|
+
const status = chat.getStatus(); // 'initializing' | 'active' | 'paused' | 'completed' | 'terminated' | 'error'
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Event Handling
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
import { GroupChatEvents } from '@wundr.io/autogen-orchestrator';
|
|
338
|
+
|
|
339
|
+
// Listen to chat events
|
|
340
|
+
chat.on('chat:started', ({ chatId, config }) => {
|
|
341
|
+
console.log(`Chat ${chatId} started with ${config.participants.length} participants`);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
chat.on('message:received', ({ chatId, message }) => {
|
|
345
|
+
console.log(`[${message.name}]: ${message.content}`);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
chat.on('speaker:selected', ({ chatId, speaker, reason }) => {
|
|
349
|
+
console.log(`Next speaker: ${speaker} (${reason})`);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
chat.on('round:started', ({ chatId, round }) => {
|
|
353
|
+
console.log(`Starting round ${round}`);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
chat.on('termination:triggered', ({ chatId, reason }) => {
|
|
357
|
+
console.log(`Chat terminated: ${reason}`);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
chat.on('chat:ended', ({ chatId, result }) => {
|
|
361
|
+
console.log(`Chat ended. Total messages: ${result.totalMessages}`);
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
chat.on('chat:error', ({ chatId, error }) => {
|
|
365
|
+
console.error(`Error in chat: ${error.message}`);
|
|
366
|
+
});
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Speaker Selection
|
|
370
|
+
|
|
371
|
+
### Available Strategies
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import {
|
|
375
|
+
createSpeakerSelector,
|
|
376
|
+
SpeakerSelectionManager,
|
|
377
|
+
RoundRobinSelector,
|
|
378
|
+
RandomSelector,
|
|
379
|
+
LLMSelector,
|
|
380
|
+
PrioritySelector,
|
|
381
|
+
ManualSelector,
|
|
382
|
+
AutoSelector,
|
|
383
|
+
} from '@wundr.io/autogen-orchestrator';
|
|
384
|
+
|
|
385
|
+
// Factory function
|
|
386
|
+
const selector = createSpeakerSelector('llm_selected');
|
|
387
|
+
|
|
388
|
+
// Using the manager
|
|
389
|
+
const manager = new SpeakerSelectionManager('round_robin');
|
|
390
|
+
|
|
391
|
+
// Select next speaker
|
|
392
|
+
const result = await manager.selectSpeaker(
|
|
393
|
+
participants,
|
|
394
|
+
messages,
|
|
395
|
+
context,
|
|
396
|
+
selectionConfig
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
console.log(result);
|
|
400
|
+
// {
|
|
401
|
+
// speaker: 'AnalystAgent',
|
|
402
|
+
// reason: 'Round-robin selection: position 2 of 3',
|
|
403
|
+
// confidence: 1.0,
|
|
404
|
+
// alternatives: ['DeveloperAgent', 'ReviewerAgent']
|
|
405
|
+
// }
|
|
406
|
+
|
|
407
|
+
// Change strategy at runtime
|
|
408
|
+
manager.setMethod('priority');
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
### Custom Speaker Selection
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
import { SpeakerSelectionStrategy, SpeakerSelectionResult } from '@wundr.io/autogen-orchestrator';
|
|
415
|
+
|
|
416
|
+
class CapabilityMatchSelector implements SpeakerSelectionStrategy {
|
|
417
|
+
async selectSpeaker(
|
|
418
|
+
participants: ChatParticipant[],
|
|
419
|
+
messages: Message[],
|
|
420
|
+
context: ChatContext,
|
|
421
|
+
config?: SpeakerSelectionConfig
|
|
422
|
+
): Promise<SpeakerSelectionResult> {
|
|
423
|
+
const lastMessage = messages[messages.length - 1];
|
|
424
|
+
|
|
425
|
+
// Find participant whose capabilities best match the message content
|
|
426
|
+
let bestMatch = participants[0];
|
|
427
|
+
let bestScore = 0;
|
|
428
|
+
|
|
429
|
+
for (const participant of participants) {
|
|
430
|
+
const score = participant.capabilities.filter(cap =>
|
|
431
|
+
lastMessage?.content.toLowerCase().includes(cap.toLowerCase())
|
|
432
|
+
).length;
|
|
433
|
+
|
|
434
|
+
if (score > bestScore) {
|
|
435
|
+
bestScore = score;
|
|
436
|
+
bestMatch = participant;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
speaker: bestMatch.name,
|
|
442
|
+
reason: `Capability match score: ${bestScore}`,
|
|
443
|
+
confidence: bestScore > 0 ? 0.9 : 0.5,
|
|
444
|
+
alternatives: participants.filter(p => p.name !== bestMatch.name).map(p => p.name),
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Transition Rules
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const config: SpeakerSelectionConfig = {
|
|
454
|
+
priorityOrder: ['Manager', 'Developer', 'Tester'],
|
|
455
|
+
transitionRules: [
|
|
456
|
+
{
|
|
457
|
+
from: 'Manager',
|
|
458
|
+
to: ['Developer', 'Tester'],
|
|
459
|
+
condition: 'after assignment',
|
|
460
|
+
weight: 0.9,
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
from: 'Developer',
|
|
464
|
+
to: ['Tester'],
|
|
465
|
+
weight: 0.7,
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
from: 'Tester',
|
|
469
|
+
to: ['Developer', 'Manager'],
|
|
470
|
+
weight: 0.5,
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
allowedTransitions: {
|
|
474
|
+
'Manager': ['Developer', 'Tester'],
|
|
475
|
+
'Developer': ['Tester', 'Manager'],
|
|
476
|
+
'Tester': ['Developer', 'Manager'],
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## Message Routing
|
|
482
|
+
|
|
483
|
+
### Adding Messages Programmatically
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
// Add a user message
|
|
487
|
+
await chat.addMessage({
|
|
488
|
+
role: 'user',
|
|
489
|
+
content: 'Please analyze the latest data.',
|
|
490
|
+
name: 'user',
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// Add a system message
|
|
494
|
+
await chat.addMessage({
|
|
495
|
+
role: 'system',
|
|
496
|
+
content: 'Context updated: New data available.',
|
|
497
|
+
name: 'system',
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// Add a function call message
|
|
501
|
+
await chat.addMessage({
|
|
502
|
+
role: 'assistant',
|
|
503
|
+
content: 'Executing data analysis...',
|
|
504
|
+
name: 'AnalystAgent',
|
|
505
|
+
contentType: 'function_call',
|
|
506
|
+
functionCall: {
|
|
507
|
+
name: 'analyzeData',
|
|
508
|
+
arguments: { dataset: 'q4_2024', metrics: ['revenue', 'growth'] },
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
// Add function result
|
|
513
|
+
await chat.addMessage({
|
|
514
|
+
role: 'function',
|
|
515
|
+
content: JSON.stringify({ revenue: 1500000, growth: 0.15 }),
|
|
516
|
+
name: 'analyzeData',
|
|
517
|
+
contentType: 'function_result',
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Response Generation
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { ResponseGenerator } from '@wundr.io/autogen-orchestrator';
|
|
525
|
+
|
|
526
|
+
// Set custom response generator
|
|
527
|
+
const generator: ResponseGenerator = async (participant, messages, context) => {
|
|
528
|
+
// Build prompt from participant's system prompt and message history
|
|
529
|
+
const systemPrompt = participant.systemPrompt;
|
|
530
|
+
const conversationHistory = messages.map(m => `${m.name}: ${m.content}`).join('\n');
|
|
531
|
+
|
|
532
|
+
// Call your LLM provider
|
|
533
|
+
const response = await callLLM({
|
|
534
|
+
system: systemPrompt,
|
|
535
|
+
messages: conversationHistory,
|
|
536
|
+
model: participant.modelConfig?.model || 'default-model',
|
|
537
|
+
temperature: participant.modelConfig?.temperature || 0.7,
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
return response;
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
chat.setResponseGenerator(generator);
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Conversation History Tracking
|
|
547
|
+
|
|
548
|
+
### Accessing History
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
// Get all messages
|
|
552
|
+
const messages = chat.getMessages();
|
|
553
|
+
|
|
554
|
+
// Get current context
|
|
555
|
+
const context = chat.getContext();
|
|
556
|
+
|
|
557
|
+
// Get metrics
|
|
558
|
+
const metrics = chat.getMetrics();
|
|
559
|
+
console.log(metrics);
|
|
560
|
+
// {
|
|
561
|
+
// totalTokens: 15000,
|
|
562
|
+
// avgResponseTimeMs: 1250,
|
|
563
|
+
// messagesPerParticipant: { 'Agent1': 5, 'Agent2': 4 },
|
|
564
|
+
// tokensPerParticipant: { 'Agent1': 8000, 'Agent2': 7000 },
|
|
565
|
+
// successfulResponses: 9,
|
|
566
|
+
// failedResponses: 0,
|
|
567
|
+
// }
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### State Management
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
// Update shared state
|
|
574
|
+
chat.updateState('currentTopic', 'performance optimization');
|
|
575
|
+
chat.updateState('analysisComplete', true);
|
|
576
|
+
chat.updateState('findings', { issues: 3, recommendations: 5 });
|
|
577
|
+
|
|
578
|
+
// Read state
|
|
579
|
+
const topic = chat.getState<string>('currentTopic');
|
|
580
|
+
const complete = chat.getState<boolean>('analysisComplete');
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Chat Results
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
interface ChatResult {
|
|
587
|
+
chatId: string;
|
|
588
|
+
status: ChatStatus;
|
|
589
|
+
messages: Message[];
|
|
590
|
+
summary?: string;
|
|
591
|
+
terminationReason?: string;
|
|
592
|
+
totalRounds: number;
|
|
593
|
+
totalMessages: number;
|
|
594
|
+
participants: string[];
|
|
595
|
+
durationMs: number;
|
|
596
|
+
metrics?: ChatMetrics;
|
|
597
|
+
nestedResults?: NestedChatResult[];
|
|
598
|
+
error?: ChatError;
|
|
599
|
+
startedAt: Date;
|
|
600
|
+
endedAt: Date;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const result = await chat.start({ initialMessage: 'Begin' });
|
|
604
|
+
console.log(`Completed in ${result.durationMs}ms with ${result.totalMessages} messages`);
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
## Termination Handling
|
|
608
|
+
|
|
609
|
+
### Built-in Termination Conditions
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
import {
|
|
613
|
+
TerminationManager,
|
|
614
|
+
createTerminationHandler,
|
|
615
|
+
TerminationPresets,
|
|
616
|
+
} from '@wundr.io/autogen-orchestrator';
|
|
617
|
+
|
|
618
|
+
// Max rounds
|
|
619
|
+
{ type: 'max_rounds', value: 10 }
|
|
620
|
+
|
|
621
|
+
// Max messages
|
|
622
|
+
{ type: 'max_messages', value: 50 }
|
|
623
|
+
|
|
624
|
+
// Keyword detection
|
|
625
|
+
{ type: 'keyword', value: ['DONE', 'COMPLETE', 'TERMINATE'] }
|
|
626
|
+
|
|
627
|
+
// Timeout (milliseconds)
|
|
628
|
+
{ type: 'timeout', value: 300000 }
|
|
629
|
+
|
|
630
|
+
// Consensus-based
|
|
631
|
+
{
|
|
632
|
+
type: 'consensus',
|
|
633
|
+
value: {
|
|
634
|
+
threshold: 0.75,
|
|
635
|
+
agreementKeywords: ['agree', 'approve', 'lgtm'],
|
|
636
|
+
disagreementKeywords: ['disagree', 'reject', 'needs work'],
|
|
637
|
+
minParticipants: 2,
|
|
638
|
+
windowSize: 10,
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Custom function
|
|
643
|
+
{
|
|
644
|
+
type: 'function',
|
|
645
|
+
evaluator: async (messages, participants, context) => ({
|
|
646
|
+
shouldTerminate: context.state['taskComplete'] === true,
|
|
647
|
+
reason: 'Task marked as complete',
|
|
648
|
+
summary: 'Conversation ended after task completion',
|
|
649
|
+
}),
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Termination Presets
|
|
654
|
+
|
|
655
|
+
```typescript
|
|
656
|
+
import { TerminationPresets } from '@wundr.io/autogen-orchestrator';
|
|
657
|
+
|
|
658
|
+
// Task completion detection
|
|
659
|
+
const taskComplete = TerminationPresets.taskCompletion();
|
|
660
|
+
// Detects: 'TASK_COMPLETE', 'DONE', 'FINISHED', 'COMPLETED', 'END_TASK'
|
|
661
|
+
|
|
662
|
+
// Approval workflow
|
|
663
|
+
const approval = TerminationPresets.approval();
|
|
664
|
+
// Consensus with 75% threshold, detects: 'approve', 'lgtm', 'ship it'
|
|
665
|
+
|
|
666
|
+
// Quick discussions
|
|
667
|
+
const quick = TerminationPresets.quickDiscussion(5);
|
|
668
|
+
// Max 5 rounds + manual termination keywords
|
|
669
|
+
|
|
670
|
+
// Long-running tasks
|
|
671
|
+
const longRunning = TerminationPresets.longRunning(30);
|
|
672
|
+
// 30-minute timeout + 100 message limit + emergency keywords
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Managing Termination Conditions
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
const manager = new TerminationManager([
|
|
679
|
+
{ type: 'max_rounds', value: 10 },
|
|
680
|
+
{ type: 'keyword', value: 'STOP' },
|
|
681
|
+
]);
|
|
682
|
+
|
|
683
|
+
// Add condition at runtime
|
|
684
|
+
manager.addCondition({ type: 'timeout', value: 60000 });
|
|
685
|
+
|
|
686
|
+
// Remove condition type
|
|
687
|
+
manager.removeCondition('timeout');
|
|
688
|
+
|
|
689
|
+
// Check if condition exists
|
|
690
|
+
const hasKeyword = manager.hasCondition('keyword');
|
|
691
|
+
|
|
692
|
+
// Evaluate all conditions
|
|
693
|
+
const result = await manager.evaluate(messages, participants, context);
|
|
694
|
+
if (result.shouldTerminate) {
|
|
695
|
+
console.log(`Terminating: ${result.reason}`);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Get all conditions
|
|
699
|
+
const conditions = manager.getConditions();
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
## Nested Chats
|
|
703
|
+
|
|
704
|
+
Nested chats allow focused sub-discussions within a main conversation.
|
|
705
|
+
|
|
706
|
+
### Configuration
|
|
707
|
+
|
|
708
|
+
```typescript
|
|
709
|
+
import {
|
|
710
|
+
NestedChatManager,
|
|
711
|
+
NestedChatConfigBuilder,
|
|
712
|
+
} from '@wundr.io/autogen-orchestrator';
|
|
713
|
+
|
|
714
|
+
// Using the builder
|
|
715
|
+
const nestedConfig = new NestedChatConfigBuilder()
|
|
716
|
+
.withId('technical-review')
|
|
717
|
+
.withName('Technical Deep Dive')
|
|
718
|
+
.withKeywordTrigger(['technical review', 'deep dive'])
|
|
719
|
+
.withParticipants(['Developer', 'Architect', 'Tester'])
|
|
720
|
+
.withMaxRounds(5)
|
|
721
|
+
.withSummaryMethod('reflection')
|
|
722
|
+
.withPrompt('Focus on technical implementation details.')
|
|
723
|
+
.withSharedContext()
|
|
724
|
+
.build();
|
|
725
|
+
|
|
726
|
+
// Add to group chat
|
|
727
|
+
const chat = new GroupChatBuilder()
|
|
728
|
+
.withParticipant(developer)
|
|
729
|
+
.withParticipant(architect)
|
|
730
|
+
.withParticipant(tester)
|
|
731
|
+
.withParticipant(manager)
|
|
732
|
+
.withNestedChats()
|
|
733
|
+
.withNestedChatConfig(nestedConfig)
|
|
734
|
+
.build();
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
### Trigger Types
|
|
738
|
+
|
|
739
|
+
```typescript
|
|
740
|
+
// Keyword trigger
|
|
741
|
+
new NestedChatConfigBuilder()
|
|
742
|
+
.withKeywordTrigger(['review code', 'code review'])
|
|
743
|
+
.build();
|
|
744
|
+
|
|
745
|
+
// Participant trigger
|
|
746
|
+
new NestedChatConfigBuilder()
|
|
747
|
+
.withParticipantTrigger(['SecurityExpert', 'ComplianceOfficer'])
|
|
748
|
+
.build();
|
|
749
|
+
|
|
750
|
+
// Condition trigger
|
|
751
|
+
new NestedChatConfigBuilder()
|
|
752
|
+
.withConditionTrigger((message, context) => {
|
|
753
|
+
return context.messageCount > 10 && message.content.includes('complex');
|
|
754
|
+
})
|
|
755
|
+
.build();
|
|
756
|
+
|
|
757
|
+
// Manual trigger
|
|
758
|
+
new NestedChatConfigBuilder()
|
|
759
|
+
.withManualTrigger('startNestedDiscussion')
|
|
760
|
+
.build();
|
|
761
|
+
|
|
762
|
+
// Trigger manually via state
|
|
763
|
+
chat.updateState('startNestedDiscussion', true);
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
### Summary Methods
|
|
767
|
+
|
|
768
|
+
```typescript
|
|
769
|
+
// 'last' - Use the last message as summary
|
|
770
|
+
// 'llm' - Generate summary using LLM (requires implementation)
|
|
771
|
+
// 'reflection' - Structured reflection summary
|
|
772
|
+
// 'custom' - Custom summary logic
|
|
773
|
+
|
|
774
|
+
const config = new NestedChatConfigBuilder()
|
|
775
|
+
.withSummaryMethod('reflection')
|
|
776
|
+
.build();
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### Nested Chat Events
|
|
780
|
+
|
|
781
|
+
```typescript
|
|
782
|
+
chat.on('nested:started', ({ chatId, nestedChatId }) => {
|
|
783
|
+
console.log(`Nested chat ${nestedChatId} started`);
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
chat.on('nested:ended', ({ chatId, nestedChatId, result }) => {
|
|
787
|
+
console.log(`Nested chat summary: ${result.summary}`);
|
|
788
|
+
});
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
## Integration with Other Orchestrators
|
|
792
|
+
|
|
793
|
+
### With Task Orchestrators
|
|
794
|
+
|
|
795
|
+
```typescript
|
|
796
|
+
import { GroupChatManager } from '@wundr.io/autogen-orchestrator';
|
|
797
|
+
import { TaskOrchestrator } from '@wundr.io/task-orchestrator';
|
|
798
|
+
|
|
799
|
+
const taskOrchestrator = new TaskOrchestrator();
|
|
800
|
+
|
|
801
|
+
// Create a chat for each complex task
|
|
802
|
+
taskOrchestrator.on('task:complex', async (task) => {
|
|
803
|
+
const chat = new GroupChatBuilder()
|
|
804
|
+
.withName(`Task: ${task.name}`)
|
|
805
|
+
.withParticipant(createParticipant('Planner', 'Plan the task execution'))
|
|
806
|
+
.withParticipant(createParticipant('Executor', 'Execute the planned steps'))
|
|
807
|
+
.withParticipant(createParticipant('Validator', 'Validate results'))
|
|
808
|
+
.withSpeakerSelection('priority')
|
|
809
|
+
.withTerminationCondition({ type: 'keyword', value: 'TASK_COMPLETE' })
|
|
810
|
+
.build();
|
|
811
|
+
|
|
812
|
+
const result = await chat.start({
|
|
813
|
+
initialMessage: `Execute task: ${task.description}`,
|
|
814
|
+
initialState: { taskId: task.id },
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
return result;
|
|
818
|
+
});
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### With Workflow Engines
|
|
822
|
+
|
|
823
|
+
```typescript
|
|
824
|
+
import { GroupChatManager } from '@wundr.io/autogen-orchestrator';
|
|
825
|
+
|
|
826
|
+
class WorkflowStep {
|
|
827
|
+
async executeWithAgents(stepConfig: StepConfig) {
|
|
828
|
+
const participants = stepConfig.roles.map(role =>
|
|
829
|
+
createParticipant(role.name, role.prompt, role.capabilities)
|
|
830
|
+
);
|
|
831
|
+
|
|
832
|
+
const chat = new GroupChatBuilder()
|
|
833
|
+
.withName(stepConfig.name)
|
|
834
|
+
.withSpeakerSelection('auto')
|
|
835
|
+
.withMaxRounds(stepConfig.maxIterations || 10)
|
|
836
|
+
.build();
|
|
837
|
+
|
|
838
|
+
participants.forEach(p => chat.addParticipant(p));
|
|
839
|
+
|
|
840
|
+
chat.setResponseGenerator(this.createResponseGenerator(stepConfig));
|
|
841
|
+
|
|
842
|
+
return await chat.start({
|
|
843
|
+
initialMessage: stepConfig.objective,
|
|
844
|
+
initialState: stepConfig.context,
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### With Event-Driven Systems
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
import { EventEmitter } from 'events';
|
|
854
|
+
import { GroupChatManager, ChatEvent } from '@wundr.io/autogen-orchestrator';
|
|
855
|
+
|
|
856
|
+
class AgentEventBridge extends EventEmitter {
|
|
857
|
+
private chat: GroupChatManager;
|
|
858
|
+
|
|
859
|
+
constructor(chat: GroupChatManager) {
|
|
860
|
+
super();
|
|
861
|
+
this.chat = chat;
|
|
862
|
+
this.setupBridge();
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
private setupBridge() {
|
|
866
|
+
// Forward chat events to external system
|
|
867
|
+
this.chat.on('message:received', ({ message }) => {
|
|
868
|
+
this.emit('agent:message', {
|
|
869
|
+
agent: message.name,
|
|
870
|
+
content: message.content,
|
|
871
|
+
timestamp: message.timestamp,
|
|
872
|
+
});
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
this.chat.on('chat:ended', ({ result }) => {
|
|
876
|
+
this.emit('conversation:complete', {
|
|
877
|
+
summary: result.summary,
|
|
878
|
+
metrics: result.metrics,
|
|
879
|
+
duration: result.durationMs,
|
|
880
|
+
});
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// Inject external events into the chat
|
|
885
|
+
async injectExternalMessage(source: string, content: string) {
|
|
886
|
+
await this.chat.addMessage({
|
|
887
|
+
role: 'system',
|
|
888
|
+
content: `[External: ${source}] ${content}`,
|
|
889
|
+
name: 'system',
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
## API Reference
|
|
896
|
+
|
|
897
|
+
### GroupChatManager
|
|
898
|
+
|
|
899
|
+
| Method | Description |
|
|
900
|
+
|--------|-------------|
|
|
901
|
+
| `constructor(config: GroupChatConfig)` | Create a new chat manager |
|
|
902
|
+
| `setResponseGenerator(generator: ResponseGenerator)` | Set the LLM response generator |
|
|
903
|
+
| `start(options?: StartChatOptions)` | Start the conversation |
|
|
904
|
+
| `pause()` | Pause the conversation |
|
|
905
|
+
| `resume()` | Resume a paused conversation |
|
|
906
|
+
| `stop(reason?: string)` | Stop the conversation |
|
|
907
|
+
| `addMessage(options: CreateMessageOptions)` | Add a message |
|
|
908
|
+
| `addParticipant(options: AddParticipantOptions)` | Add a participant |
|
|
909
|
+
| `removeParticipant(name: string)` | Remove a participant |
|
|
910
|
+
| `updateParticipantStatus(name: string, status: ParticipantStatus)` | Update participant status |
|
|
911
|
+
| `addTerminationCondition(condition: TerminationCondition)` | Add termination condition |
|
|
912
|
+
| `addNestedChatConfig(config: NestedChatConfig)` | Add nested chat configuration |
|
|
913
|
+
| `getStatus()` | Get current chat status |
|
|
914
|
+
| `getChatId()` | Get the chat ID |
|
|
915
|
+
| `getMessages()` | Get all messages |
|
|
916
|
+
| `getParticipants()` | Get all participants |
|
|
917
|
+
| `getContext()` | Get current context |
|
|
918
|
+
| `getMetrics()` | Get chat metrics |
|
|
919
|
+
| `updateState(key: string, value: T)` | Update context state |
|
|
920
|
+
| `getState<T>(key: string)` | Get context state value |
|
|
921
|
+
|
|
922
|
+
### SpeakerSelectionManager
|
|
923
|
+
|
|
924
|
+
| Method | Description |
|
|
925
|
+
|--------|-------------|
|
|
926
|
+
| `constructor(method?: SpeakerSelectionMethod)` | Create with initial method |
|
|
927
|
+
| `selectSpeaker(participants, messages, context, config?)` | Select next speaker |
|
|
928
|
+
| `setMethod(method: SpeakerSelectionMethod)` | Change selection method |
|
|
929
|
+
| `getMethod()` | Get current method |
|
|
930
|
+
| `getStrategy(method: SpeakerSelectionMethod)` | Get strategy instance |
|
|
931
|
+
|
|
932
|
+
### TerminationManager
|
|
933
|
+
|
|
934
|
+
| Method | Description |
|
|
935
|
+
|--------|-------------|
|
|
936
|
+
| `constructor(conditions?: TerminationCondition[])` | Create with initial conditions |
|
|
937
|
+
| `addCondition(condition: TerminationCondition)` | Add a condition |
|
|
938
|
+
| `removeCondition(type: TerminationConditionType)` | Remove conditions by type |
|
|
939
|
+
| `clearConditions()` | Clear all conditions |
|
|
940
|
+
| `evaluate(messages, participants, context)` | Evaluate all conditions |
|
|
941
|
+
| `getConditions()` | Get all conditions |
|
|
942
|
+
| `hasCondition(type: TerminationConditionType)` | Check if type exists |
|
|
943
|
+
|
|
944
|
+
### NestedChatManager
|
|
945
|
+
|
|
946
|
+
| Method | Description |
|
|
947
|
+
|--------|-------------|
|
|
948
|
+
| `constructor(configs?: NestedChatConfig[])` | Create with initial configs |
|
|
949
|
+
| `addConfig(config: NestedChatConfig)` | Add configuration |
|
|
950
|
+
| `removeConfig(configId: string)` | Remove configuration |
|
|
951
|
+
| `checkTrigger(message, participants, context)` | Check for triggers |
|
|
952
|
+
| `startNestedChat(config, parentChatId, parentMessageId, participants, context)` | Start nested chat |
|
|
953
|
+
| `addMessage(nestedChatId: string, message: Message)` | Add message to nested chat |
|
|
954
|
+
| `endNestedChat(nestedChatId, status?, reason?)` | End nested chat |
|
|
955
|
+
| `getActiveChats()` | Get active nested chat IDs |
|
|
956
|
+
| `getCompletedChats()` | Get completed results |
|
|
957
|
+
| `hasActiveChats()` | Check for active chats |
|
|
958
|
+
|
|
959
|
+
## Examples
|
|
960
|
+
|
|
961
|
+
### Code Review Workflow
|
|
962
|
+
|
|
963
|
+
```typescript
|
|
964
|
+
import {
|
|
965
|
+
GroupChatBuilder,
|
|
966
|
+
createParticipant,
|
|
967
|
+
TerminationPresets,
|
|
968
|
+
} from '@wundr.io/autogen-orchestrator';
|
|
969
|
+
|
|
970
|
+
const codeAuthor = createParticipant(
|
|
971
|
+
'CodeAuthor',
|
|
972
|
+
'You wrote the code and can explain design decisions.',
|
|
973
|
+
['code', 'architecture', 'explanation']
|
|
974
|
+
);
|
|
975
|
+
|
|
976
|
+
const securityReviewer = createParticipant(
|
|
977
|
+
'SecurityReviewer',
|
|
978
|
+
'You review code for security vulnerabilities.',
|
|
979
|
+
['security', 'vulnerabilities', 'compliance']
|
|
980
|
+
);
|
|
981
|
+
|
|
982
|
+
const performanceReviewer = createParticipant(
|
|
983
|
+
'PerformanceReviewer',
|
|
984
|
+
'You review code for performance issues.',
|
|
985
|
+
['performance', 'optimization', 'efficiency']
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
const chat = new GroupChatBuilder()
|
|
989
|
+
.withName('Code Review')
|
|
990
|
+
.withParticipant(codeAuthor)
|
|
991
|
+
.withParticipant(securityReviewer)
|
|
992
|
+
.withParticipant(performanceReviewer)
|
|
993
|
+
.withSpeakerSelection('priority')
|
|
994
|
+
.withTerminationCondition(TerminationPresets.approval())
|
|
995
|
+
.withMaxRounds(20)
|
|
996
|
+
.build();
|
|
997
|
+
|
|
998
|
+
const result = await chat.start({
|
|
999
|
+
initialMessage: `Review this code:\n\`\`\`javascript\n${codeToReview}\n\`\`\``,
|
|
1000
|
+
});
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
### Research Collaboration
|
|
1004
|
+
|
|
1005
|
+
```typescript
|
|
1006
|
+
const researcher = createParticipant(
|
|
1007
|
+
'Researcher',
|
|
1008
|
+
'You search for and analyze relevant information.',
|
|
1009
|
+
['research', 'analysis', 'citations']
|
|
1010
|
+
);
|
|
1011
|
+
|
|
1012
|
+
const critic = createParticipant(
|
|
1013
|
+
'Critic',
|
|
1014
|
+
'You critically evaluate claims and identify weaknesses.',
|
|
1015
|
+
['evaluation', 'logic', 'counterarguments']
|
|
1016
|
+
);
|
|
1017
|
+
|
|
1018
|
+
const synthesizer = createParticipant(
|
|
1019
|
+
'Synthesizer',
|
|
1020
|
+
'You combine findings into coherent conclusions.',
|
|
1021
|
+
['synthesis', 'summary', 'conclusions']
|
|
1022
|
+
);
|
|
1023
|
+
|
|
1024
|
+
const chat = new GroupChatBuilder()
|
|
1025
|
+
.withName('Research Collaboration')
|
|
1026
|
+
.withParticipant(researcher)
|
|
1027
|
+
.withParticipant(critic)
|
|
1028
|
+
.withParticipant(synthesizer)
|
|
1029
|
+
.withSpeakerSelection('llm_selected')
|
|
1030
|
+
.withTerminationCondition({
|
|
1031
|
+
type: 'keyword',
|
|
1032
|
+
value: ['CONCLUSION REACHED', 'RESEARCH COMPLETE'],
|
|
1033
|
+
})
|
|
1034
|
+
.build();
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
### Customer Support Escalation
|
|
1038
|
+
|
|
1039
|
+
```typescript
|
|
1040
|
+
const frontlineAgent = createParticipant(
|
|
1041
|
+
'FrontlineSupport',
|
|
1042
|
+
'You handle initial customer inquiries.',
|
|
1043
|
+
['support', 'troubleshooting', 'empathy']
|
|
1044
|
+
);
|
|
1045
|
+
|
|
1046
|
+
const technicalSpecialist = createParticipant(
|
|
1047
|
+
'TechnicalSpecialist',
|
|
1048
|
+
'You handle complex technical issues.',
|
|
1049
|
+
['technical', 'debugging', 'systems']
|
|
1050
|
+
);
|
|
1051
|
+
|
|
1052
|
+
const supervisor = createParticipant(
|
|
1053
|
+
'Supervisor',
|
|
1054
|
+
'You handle escalations and make final decisions.',
|
|
1055
|
+
['escalation', 'decisions', 'policies']
|
|
1056
|
+
);
|
|
1057
|
+
|
|
1058
|
+
const chat = new GroupChatBuilder()
|
|
1059
|
+
.withName('Support Ticket #12345')
|
|
1060
|
+
.withParticipant(frontlineAgent)
|
|
1061
|
+
.withParticipant(technicalSpecialist)
|
|
1062
|
+
.withParticipant(supervisor)
|
|
1063
|
+
.withSpeakerSelection('auto')
|
|
1064
|
+
.withNestedChats()
|
|
1065
|
+
.withNestedChatConfig(
|
|
1066
|
+
new NestedChatConfigBuilder()
|
|
1067
|
+
.withId('escalation')
|
|
1068
|
+
.withName('Supervisor Escalation')
|
|
1069
|
+
.withKeywordTrigger(['escalate', 'supervisor'])
|
|
1070
|
+
.withParticipants(['TechnicalSpecialist', 'Supervisor'])
|
|
1071
|
+
.withMaxRounds(3)
|
|
1072
|
+
.build()
|
|
1073
|
+
)
|
|
1074
|
+
.build();
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
## License
|
|
1078
|
+
|
|
1079
|
+
MIT License - see LICENSE file for details.
|
|
1080
|
+
|
|
1081
|
+
## Contributing
|
|
1082
|
+
|
|
1083
|
+
Contributions are welcome! Please read our contributing guidelines before submitting pull requests.
|
|
1084
|
+
|
|
1085
|
+
## Support
|
|
1086
|
+
|
|
1087
|
+
- Issues: [GitHub Issues](https://github.com/adapticai/wundr/issues)
|
|
1088
|
+
- Documentation: [Wundr Documentation](https://wundr.io)
|