@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.
@@ -0,0 +1,724 @@
1
+ "use strict";
2
+ /**
3
+ * GroupChatManager - Core orchestration for AutoGen-style multi-agent conversations
4
+ *
5
+ * Implements conversational patterns for coordinating multiple AI agents in a
6
+ * group chat setting with configurable speaker selection and termination conditions.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.GroupChatBuilder = exports.GroupChatManager = void 0;
10
+ exports.createParticipant = createParticipant;
11
+ const eventemitter3_1 = require("eventemitter3");
12
+ const uuid_1 = require("uuid");
13
+ const nested_chat_1 = require("./nested-chat");
14
+ const speaker_selection_1 = require("./speaker-selection");
15
+ const termination_1 = require("./termination");
16
+ const types_1 = require("./types");
17
+ /**
18
+ * GroupChatManager - Orchestrates multi-agent conversations
19
+ */
20
+ class GroupChatManager extends eventemitter3_1.EventEmitter {
21
+ config;
22
+ participants = new Map();
23
+ messages = [];
24
+ context;
25
+ status = 'initializing';
26
+ startTime;
27
+ endTime;
28
+ chatId;
29
+ speakerManager;
30
+ terminationManager;
31
+ nestedChatManager;
32
+ responseGenerator;
33
+ metrics;
34
+ nestedResults = [];
35
+ /**
36
+ * Create a new GroupChatManager
37
+ * @param config - Group chat configuration
38
+ */
39
+ constructor(config) {
40
+ super();
41
+ // Validate configuration
42
+ const validationResult = types_1.GroupChatConfigSchema.safeParse(config);
43
+ if (!validationResult.success) {
44
+ throw new Error(`Invalid GroupChatConfig: ${validationResult.error.message}`);
45
+ }
46
+ this.config = config;
47
+ this.chatId = config.id || (0, uuid_1.v4)();
48
+ // Initialize participants
49
+ for (const participant of config.participants) {
50
+ this.participants.set(participant.name, { ...participant });
51
+ }
52
+ // Initialize context
53
+ this.context = {
54
+ chatId: this.chatId,
55
+ currentRound: 0,
56
+ messageCount: 0,
57
+ activeParticipants: config.participants.map(p => p.name),
58
+ startTime: new Date(),
59
+ state: {},
60
+ };
61
+ // Initialize managers
62
+ this.speakerManager = new speaker_selection_1.SpeakerSelectionManager(config.speakerSelectionMethod);
63
+ this.terminationManager = new termination_1.TerminationManager(config.terminationConditions || []);
64
+ this.nestedChatManager = new nested_chat_1.NestedChatManager(config.nestedChatConfigs || []);
65
+ // Initialize metrics
66
+ this.metrics = {
67
+ totalTokens: 0,
68
+ avgResponseTimeMs: 0,
69
+ messagesPerParticipant: {},
70
+ tokensPerParticipant: {},
71
+ successfulResponses: 0,
72
+ failedResponses: 0,
73
+ };
74
+ // Setup nested chat event forwarding
75
+ this.setupNestedChatEvents();
76
+ }
77
+ /**
78
+ * Setup event forwarding from nested chat manager
79
+ */
80
+ setupNestedChatEvents() {
81
+ this.nestedChatManager.on('nested:started', ({ nestedChatId }) => {
82
+ this.emit('nested:started', { chatId: this.chatId, nestedChatId });
83
+ });
84
+ this.nestedChatManager.on('nested:completed', ({ nestedChatId, result }) => {
85
+ const nestedResult = {
86
+ nestedChatId,
87
+ configId: '', // Will be filled properly
88
+ result,
89
+ parentMessageId: '',
90
+ };
91
+ this.nestedResults.push(nestedResult);
92
+ this.emit('nested:ended', {
93
+ chatId: this.chatId,
94
+ nestedChatId,
95
+ result: nestedResult,
96
+ });
97
+ });
98
+ }
99
+ /**
100
+ * Set the response generator function
101
+ * @param generator - Function to generate participant responses
102
+ */
103
+ setResponseGenerator(generator) {
104
+ this.responseGenerator = generator;
105
+ }
106
+ /**
107
+ * Start the group chat
108
+ * @param options - Optional start options
109
+ * @returns Chat result when completed
110
+ */
111
+ async start(options = {}) {
112
+ if (this.status !== 'initializing') {
113
+ throw new Error(`Cannot start chat in status: ${this.status}`);
114
+ }
115
+ this.status = 'active';
116
+ this.startTime = new Date();
117
+ this.context.startTime = this.startTime;
118
+ // Initialize state if provided
119
+ if (options.initialState) {
120
+ this.context.state = { ...options.initialState };
121
+ }
122
+ this.emitEvent('chat_started', { config: this.config });
123
+ this.emit('chat:started', { chatId: this.chatId, config: this.config });
124
+ try {
125
+ // Add initial message if provided
126
+ if (options.initialMessage) {
127
+ const senderName = options.initialSender || this.config.adminName || 'user';
128
+ await this.addMessage({
129
+ role: 'user',
130
+ content: options.initialMessage,
131
+ name: senderName,
132
+ });
133
+ }
134
+ // Run the conversation loop
135
+ const result = await this.runConversationLoop(options);
136
+ return result;
137
+ }
138
+ catch (error) {
139
+ return this.handleError(error);
140
+ }
141
+ }
142
+ /**
143
+ * Run the main conversation loop
144
+ * @param options - Start options
145
+ * @returns Chat result
146
+ */
147
+ async runConversationLoop(options) {
148
+ const maxRounds = this.config.maxRounds || 100;
149
+ const maxMessages = this.config.maxMessages || 1000;
150
+ while (this.status === 'active') {
151
+ // Check termination conditions
152
+ const terminationResult = await this.terminationManager.evaluate(this.messages, Array.from(this.participants.values()), this.context);
153
+ if (terminationResult.shouldTerminate) {
154
+ return this.endChat('completed', terminationResult.reason);
155
+ }
156
+ // Check limits
157
+ if (this.context.currentRound >= maxRounds) {
158
+ return this.endChat('terminated', `Maximum rounds reached: ${maxRounds}`);
159
+ }
160
+ if (this.messages.length >= maxMessages) {
161
+ return this.endChat('terminated', `Maximum messages reached: ${maxMessages}`);
162
+ }
163
+ // Start new round
164
+ this.context.currentRound++;
165
+ this.emitEvent('round_started', { round: this.context.currentRound });
166
+ this.emit('round:started', {
167
+ chatId: this.chatId,
168
+ round: this.context.currentRound,
169
+ });
170
+ // Select next speaker
171
+ const skipSelection = options.skipInitialSelection && this.context.currentRound === 1;
172
+ if (!skipSelection) {
173
+ const selectionResult = await this.speakerManager.selectSpeaker(Array.from(this.participants.values()), this.messages, this.context, this.config.speakerSelectionConfig);
174
+ this.context.previousSpeaker = this.context.currentSpeaker;
175
+ this.context.currentSpeaker = selectionResult.speaker;
176
+ this.emitEvent('speaker_selected', {
177
+ speaker: selectionResult.speaker,
178
+ reason: selectionResult.reason,
179
+ });
180
+ this.emit('speaker:selected', {
181
+ chatId: this.chatId,
182
+ speaker: selectionResult.speaker,
183
+ reason: selectionResult.reason,
184
+ });
185
+ // Generate and add response
186
+ const participant = this.participants.get(selectionResult.speaker);
187
+ if (participant) {
188
+ const response = await this.generateResponse(participant);
189
+ if (response) {
190
+ const message = await this.addMessage({
191
+ role: 'assistant',
192
+ content: response,
193
+ name: participant.name,
194
+ });
195
+ // Check for nested chat triggers
196
+ if (this.config.allowNestedChats) {
197
+ await this.checkNestedChatTriggers(message);
198
+ }
199
+ }
200
+ }
201
+ }
202
+ // End round
203
+ this.emitEvent('round_ended', { round: this.context.currentRound });
204
+ this.emit('round:ended', {
205
+ chatId: this.chatId,
206
+ round: this.context.currentRound,
207
+ });
208
+ }
209
+ // If we exit the loop due to status change
210
+ return this.endChat(this.status, 'Chat stopped');
211
+ }
212
+ /**
213
+ * Generate a response for a participant
214
+ * @param participant - Participant to generate response for
215
+ * @returns Generated response content
216
+ */
217
+ async generateResponse(participant) {
218
+ const startTime = Date.now();
219
+ try {
220
+ // Update participant status
221
+ participant.status = 'busy';
222
+ let response;
223
+ if (this.responseGenerator) {
224
+ response = await this.responseGenerator(participant, this.messages, this.context);
225
+ }
226
+ else {
227
+ // Default placeholder response
228
+ response = this.generatePlaceholderResponse(participant);
229
+ }
230
+ // Update metrics
231
+ const latency = Date.now() - startTime;
232
+ this.updateMetrics(participant.name, latency, response.length);
233
+ participant.status = 'idle';
234
+ this.metrics.successfulResponses++;
235
+ return response;
236
+ }
237
+ catch (error) {
238
+ participant.status = 'error';
239
+ this.metrics.failedResponses++;
240
+ const errorMessage = error instanceof Error ? error.message : String(error);
241
+ console.error(`Error generating response for ${participant.name}: ${errorMessage}`);
242
+ return null;
243
+ }
244
+ }
245
+ /**
246
+ * Generate a placeholder response when no generator is set
247
+ * @param participant - Participant to generate for
248
+ * @returns Placeholder response
249
+ */
250
+ generatePlaceholderResponse(participant) {
251
+ const prompts = [
252
+ `[${participant.name}]: I acknowledge the message and am ready to contribute.`,
253
+ `[${participant.name}]: Based on my expertise in ${participant.capabilities.join(', ')}, I suggest we proceed.`,
254
+ `[${participant.name}]: Let me analyze this from my perspective.`,
255
+ ];
256
+ return prompts[Math.floor(Math.random() * prompts.length)];
257
+ }
258
+ /**
259
+ * Update metrics after a response
260
+ * @param participantName - Name of the participant
261
+ * @param latencyMs - Response latency
262
+ * @param tokenEstimate - Estimated token count
263
+ */
264
+ updateMetrics(participantName, latencyMs, tokenEstimate) {
265
+ // Update per-participant metrics
266
+ this.metrics.messagesPerParticipant[participantName] =
267
+ (this.metrics.messagesPerParticipant[participantName] || 0) + 1;
268
+ const estimatedTokens = Math.ceil(tokenEstimate / 4); // Rough estimate
269
+ this.metrics.tokensPerParticipant[participantName] =
270
+ (this.metrics.tokensPerParticipant[participantName] || 0) +
271
+ estimatedTokens;
272
+ this.metrics.totalTokens += estimatedTokens;
273
+ // Update average response time
274
+ const totalResponses = this.metrics.successfulResponses + this.metrics.failedResponses;
275
+ this.metrics.avgResponseTimeMs =
276
+ (this.metrics.avgResponseTimeMs * (totalResponses - 1) + latencyMs) /
277
+ totalResponses;
278
+ }
279
+ /**
280
+ * Check if a message triggers a nested chat
281
+ * @param message - Message to check
282
+ */
283
+ async checkNestedChatTriggers(message) {
284
+ const triggeredConfig = this.nestedChatManager.checkTrigger(message, Array.from(this.participants.values()), this.context);
285
+ if (triggeredConfig) {
286
+ await this.runNestedChat(triggeredConfig, message.id);
287
+ }
288
+ }
289
+ /**
290
+ * Run a nested chat session
291
+ * @param config - Nested chat configuration
292
+ * @param triggerMessageId - ID of the triggering message
293
+ */
294
+ async runNestedChat(config, triggerMessageId) {
295
+ const nestedChatId = this.nestedChatManager.startNestedChat(config, this.chatId, triggerMessageId, Array.from(this.participants.values()), this.context);
296
+ // Run nested chat rounds
297
+ const maxRounds = config.maxRounds || 5;
298
+ let round = 0;
299
+ while (round < maxRounds && this.nestedChatManager.hasActiveChats()) {
300
+ const nestedContext = this.nestedChatManager.getContext(nestedChatId);
301
+ if (!nestedContext) {
302
+ break;
303
+ }
304
+ // Select speaker for nested chat
305
+ const nestedState = this.nestedChatManager.getActiveChat(nestedChatId);
306
+ if (!nestedState) {
307
+ break;
308
+ }
309
+ const selectionResult = await this.speakerManager.selectSpeaker(nestedState.participants, nestedState.messages, nestedContext);
310
+ // Generate response
311
+ const participant = nestedState.participants.find(p => p.name === selectionResult.speaker);
312
+ if (participant && this.responseGenerator) {
313
+ const response = await this.responseGenerator(participant, nestedState.messages, nestedContext);
314
+ if (response) {
315
+ this.nestedChatManager.addMessage(nestedChatId, {
316
+ id: (0, uuid_1.v4)(),
317
+ role: 'assistant',
318
+ content: response,
319
+ name: participant.name,
320
+ timestamp: new Date(),
321
+ status: 'delivered',
322
+ });
323
+ }
324
+ }
325
+ this.nestedChatManager.incrementRound(nestedChatId);
326
+ round++;
327
+ }
328
+ // End nested chat
329
+ const result = await this.nestedChatManager.endNestedChat(nestedChatId, 'completed', `Completed after ${round} rounds`);
330
+ this.nestedResults.push(result);
331
+ // Add summary to main chat if available
332
+ if (result.summary) {
333
+ await this.addMessage({
334
+ role: 'system',
335
+ content: `[Nested Chat Summary]: ${result.summary}`,
336
+ name: 'system',
337
+ });
338
+ }
339
+ }
340
+ /**
341
+ * Add a message to the chat
342
+ * @param options - Message options
343
+ * @returns Created message
344
+ */
345
+ async addMessage(options) {
346
+ const message = {
347
+ id: (0, uuid_1.v4)(),
348
+ role: options.role,
349
+ content: options.content,
350
+ name: options.name,
351
+ timestamp: new Date(),
352
+ contentType: options.contentType || 'text',
353
+ functionCall: options.functionCall,
354
+ metadata: {
355
+ ...options.metadata,
356
+ tokenCount: Math.ceil(options.content.length / 4),
357
+ },
358
+ status: 'delivered',
359
+ };
360
+ this.messages.push(message);
361
+ this.context.messageCount = this.messages.length;
362
+ this.emitEvent('message_received', { message });
363
+ this.emit('message:received', { chatId: this.chatId, message });
364
+ return message;
365
+ }
366
+ /**
367
+ * Add a participant to the chat
368
+ * @param options - Participant options
369
+ * @returns Created participant
370
+ */
371
+ addParticipant(options) {
372
+ const participant = {
373
+ id: (0, uuid_1.v4)(),
374
+ name: options.name,
375
+ type: options.type,
376
+ systemPrompt: options.systemPrompt,
377
+ status: 'active',
378
+ capabilities: options.capabilities || [],
379
+ modelConfig: options.modelConfig,
380
+ functions: options.functions,
381
+ maxConsecutiveReplies: options.maxConsecutiveReplies,
382
+ description: options.description,
383
+ };
384
+ this.participants.set(participant.name, participant);
385
+ this.context.activeParticipants.push(participant.name);
386
+ return participant;
387
+ }
388
+ /**
389
+ * Remove a participant from the chat
390
+ * @param name - Participant name
391
+ */
392
+ removeParticipant(name) {
393
+ this.participants.delete(name);
394
+ this.context.activeParticipants = this.context.activeParticipants.filter(n => n !== name);
395
+ }
396
+ /**
397
+ * Update a participant's status
398
+ * @param name - Participant name
399
+ * @param status - New status
400
+ */
401
+ updateParticipantStatus(name, status) {
402
+ const participant = this.participants.get(name);
403
+ if (participant) {
404
+ participant.status = status;
405
+ }
406
+ }
407
+ /**
408
+ * Add a termination condition
409
+ * @param condition - Condition to add
410
+ */
411
+ addTerminationCondition(condition) {
412
+ this.terminationManager.addCondition(condition);
413
+ }
414
+ /**
415
+ * Add a nested chat configuration
416
+ * @param config - Nested chat config
417
+ */
418
+ addNestedChatConfig(config) {
419
+ this.nestedChatManager.addConfig(config);
420
+ }
421
+ /**
422
+ * Pause the chat
423
+ */
424
+ pause() {
425
+ if (this.status === 'active') {
426
+ this.status = 'paused';
427
+ }
428
+ }
429
+ /**
430
+ * Resume the chat
431
+ */
432
+ resume() {
433
+ if (this.status === 'paused') {
434
+ this.status = 'active';
435
+ }
436
+ }
437
+ /**
438
+ * Stop the chat
439
+ * @param reason - Reason for stopping
440
+ * @returns Chat result
441
+ */
442
+ async stop(reason) {
443
+ return this.endChat('terminated', reason || 'Manually stopped');
444
+ }
445
+ /**
446
+ * End the chat and produce a result
447
+ * @param status - Final status
448
+ * @param reason - Termination reason
449
+ * @returns Chat result
450
+ */
451
+ endChat(status, reason) {
452
+ this.status = status;
453
+ this.endTime = new Date();
454
+ const durationMs = this.endTime.getTime() -
455
+ (this.startTime?.getTime() || this.endTime.getTime());
456
+ const result = {
457
+ chatId: this.chatId,
458
+ status,
459
+ messages: [...this.messages],
460
+ summary: this.generateSummary(),
461
+ terminationReason: reason,
462
+ totalRounds: this.context.currentRound,
463
+ totalMessages: this.messages.length,
464
+ participants: Array.from(this.participants.keys()),
465
+ durationMs,
466
+ metrics: { ...this.metrics },
467
+ nestedResults: [...this.nestedResults],
468
+ startedAt: this.startTime || new Date(),
469
+ endedAt: this.endTime,
470
+ };
471
+ if (reason) {
472
+ this.emitEvent('termination_triggered', { reason });
473
+ this.emit('termination:triggered', { chatId: this.chatId, reason });
474
+ }
475
+ this.emitEvent('chat_ended', { result });
476
+ this.emit('chat:ended', { chatId: this.chatId, result });
477
+ return result;
478
+ }
479
+ /**
480
+ * Handle an error during chat execution
481
+ * @param error - Error that occurred
482
+ * @returns Chat result with error
483
+ */
484
+ handleError(error) {
485
+ const chatError = {
486
+ code: 'CHAT_ERROR',
487
+ message: error instanceof Error ? error.message : String(error),
488
+ stack: error instanceof Error ? error.stack : undefined,
489
+ context: {
490
+ round: this.context.currentRound,
491
+ messageCount: this.messages.length,
492
+ },
493
+ recoverable: false,
494
+ };
495
+ this.emit('chat:error', { chatId: this.chatId, error: chatError });
496
+ const result = this.endChat('error', chatError.message);
497
+ result.error = chatError;
498
+ return result;
499
+ }
500
+ /**
501
+ * Generate a summary of the conversation
502
+ * @returns Summary string
503
+ */
504
+ generateSummary() {
505
+ const participantCounts = this.metrics.messagesPerParticipant;
506
+ const topContributors = Object.entries(participantCounts)
507
+ .sort(([, a], [, b]) => b - a)
508
+ .slice(0, 3)
509
+ .map(([name, count]) => `${name} (${count})`)
510
+ .join(', ');
511
+ return (`Chat completed with ${this.messages.length} messages over ${this.context.currentRound} rounds. ` +
512
+ `Top contributors: ${topContributors || 'none'}. ` +
513
+ `Duration: ${Math.round((this.endTime?.getTime() || Date.now()) - (this.startTime?.getTime() || Date.now())) / 1000}s.`);
514
+ }
515
+ /**
516
+ * Emit a chat event
517
+ * @param type - Event type
518
+ * @param data - Event data typed based on event type
519
+ */
520
+ emitEvent(type, data) {
521
+ const event = {
522
+ type,
523
+ timestamp: new Date(),
524
+ chatId: this.chatId,
525
+ data,
526
+ };
527
+ // Internal event tracking if needed
528
+ this.context.state['lastEvent'] = event;
529
+ }
530
+ /**
531
+ * Get the current chat status
532
+ * @returns Current status
533
+ */
534
+ getStatus() {
535
+ return this.status;
536
+ }
537
+ /**
538
+ * Get the chat ID
539
+ * @returns Chat ID
540
+ */
541
+ getChatId() {
542
+ return this.chatId;
543
+ }
544
+ /**
545
+ * Get all messages
546
+ * @returns Message array
547
+ */
548
+ getMessages() {
549
+ return [...this.messages];
550
+ }
551
+ /**
552
+ * Get all participants
553
+ * @returns Participant array
554
+ */
555
+ getParticipants() {
556
+ return Array.from(this.participants.values());
557
+ }
558
+ /**
559
+ * Get the current context
560
+ * @returns Chat context
561
+ */
562
+ getContext() {
563
+ return { ...this.context };
564
+ }
565
+ /**
566
+ * Get current metrics
567
+ * @returns Chat metrics
568
+ */
569
+ getMetrics() {
570
+ return { ...this.metrics };
571
+ }
572
+ /**
573
+ * Update context state
574
+ * @param key - State key
575
+ * @param value - State value (typed for common use cases)
576
+ */
577
+ updateState(key, value) {
578
+ this.context.state[key] = value;
579
+ }
580
+ /**
581
+ * Get context state value
582
+ * @param key - State key
583
+ * @returns State value
584
+ */
585
+ getState(key) {
586
+ return this.context.state[key];
587
+ }
588
+ }
589
+ exports.GroupChatManager = GroupChatManager;
590
+ /**
591
+ * Builder for creating GroupChatManager instances
592
+ */
593
+ class GroupChatBuilder {
594
+ config = {
595
+ participants: [],
596
+ terminationConditions: [],
597
+ nestedChatConfigs: [],
598
+ };
599
+ /**
600
+ * Set the chat name
601
+ * @param name - Chat name
602
+ */
603
+ withName(name) {
604
+ this.config.name = name;
605
+ return this;
606
+ }
607
+ /**
608
+ * Set the chat description
609
+ * @param description - Chat description
610
+ */
611
+ withDescription(description) {
612
+ this.config.description = description;
613
+ return this;
614
+ }
615
+ /**
616
+ * Add a participant
617
+ * @param participant - Participant to add
618
+ */
619
+ withParticipant(participant) {
620
+ this.config.participants = this.config.participants || [];
621
+ this.config.participants.push(participant);
622
+ return this;
623
+ }
624
+ /**
625
+ * Set the speaker selection method
626
+ * @param method - Selection method
627
+ */
628
+ withSpeakerSelection(method) {
629
+ this.config.speakerSelectionMethod = method;
630
+ return this;
631
+ }
632
+ /**
633
+ * Set maximum rounds
634
+ * @param maxRounds - Maximum rounds
635
+ */
636
+ withMaxRounds(maxRounds) {
637
+ this.config.maxRounds = maxRounds;
638
+ return this;
639
+ }
640
+ /**
641
+ * Set maximum messages
642
+ * @param maxMessages - Maximum messages
643
+ */
644
+ withMaxMessages(maxMessages) {
645
+ this.config.maxMessages = maxMessages;
646
+ return this;
647
+ }
648
+ /**
649
+ * Add a termination condition
650
+ * @param condition - Termination condition
651
+ */
652
+ withTerminationCondition(condition) {
653
+ this.config.terminationConditions = this.config.terminationConditions || [];
654
+ this.config.terminationConditions.push(condition);
655
+ return this;
656
+ }
657
+ /**
658
+ * Enable nested chats
659
+ */
660
+ withNestedChats() {
661
+ this.config.allowNestedChats = true;
662
+ return this;
663
+ }
664
+ /**
665
+ * Add a nested chat configuration
666
+ * @param config - Nested chat config
667
+ */
668
+ withNestedChatConfig(config) {
669
+ this.config.nestedChatConfigs = this.config.nestedChatConfigs || [];
670
+ this.config.nestedChatConfigs.push(config);
671
+ return this;
672
+ }
673
+ /**
674
+ * Set the admin name
675
+ * @param name - Admin name
676
+ */
677
+ withAdmin(name) {
678
+ this.config.adminName = name;
679
+ return this;
680
+ }
681
+ /**
682
+ * Set timeout
683
+ * @param timeoutMs - Timeout in milliseconds
684
+ */
685
+ withTimeout(timeoutMs) {
686
+ this.config.timeoutMs = timeoutMs;
687
+ return this;
688
+ }
689
+ /**
690
+ * Build the GroupChatManager
691
+ * @returns Configured GroupChatManager
692
+ */
693
+ build() {
694
+ if (!this.config.name) {
695
+ this.config.name = `group-chat-${(0, uuid_1.v4)().slice(0, 8)}`;
696
+ }
697
+ if (!this.config.speakerSelectionMethod) {
698
+ this.config.speakerSelectionMethod = 'round_robin';
699
+ }
700
+ if (!this.config.participants || this.config.participants.length < 2) {
701
+ throw new Error('GroupChat requires at least 2 participants');
702
+ }
703
+ return new GroupChatManager(this.config);
704
+ }
705
+ }
706
+ exports.GroupChatBuilder = GroupChatBuilder;
707
+ /**
708
+ * Create a simple participant configuration
709
+ * @param name - Participant name
710
+ * @param systemPrompt - System prompt
711
+ * @param capabilities - Participant capabilities
712
+ * @returns Participant configuration
713
+ */
714
+ function createParticipant(name, systemPrompt, capabilities = []) {
715
+ return {
716
+ id: (0, uuid_1.v4)(),
717
+ name,
718
+ type: 'agent',
719
+ systemPrompt,
720
+ status: 'active',
721
+ capabilities,
722
+ };
723
+ }
724
+ //# sourceMappingURL=group-chat.js.map