@gotza02/seq-thinking 1.1.5 → 1.1.7

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.
Files changed (49) hide show
  1. package/README.md +4 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/mcp-server.js +1 -1
  5. package/package.json +9 -3
  6. package/agents_test.log +0 -15
  7. package/data/agents/1770106504306-dljh9ef.json +0 -68
  8. package/data/agents/1770106504310-4oarrst.json +0 -58
  9. package/data/agents/1770106540588-pvitt55.json +0 -68
  10. package/data/agents/1770106540595-z2ya871.json +0 -58
  11. package/data/agents/1770106710890-0e2naq1.json +0 -68
  12. package/data/agents/1770106710893-r076yxx.json +0 -58
  13. package/data/agents/1770109212161-4ybd0i7.json +0 -68
  14. package/data/agents/1770109212166-gkhya8h.json +0 -58
  15. package/data/agents/1770117726716-lrnm415.json +0 -68
  16. package/data/agents/1770117726719-w6hsf3v.json +0 -58
  17. package/data/sessions/1770100622009-5afiuyv.json +0 -499
  18. package/data/sessions/1770106504312-75zk750.json +0 -107
  19. package/data/sessions/1770106540597-z8e8soo.json +0 -150
  20. package/data/sessions/1770106710894-0kxgy5x.json +0 -150
  21. package/data/sessions/1770109212169-zpddeb9.json +0 -150
  22. package/data/sessions/1770117726720-frcwj99.json +0 -150
  23. package/real_world_test.log +0 -200
  24. package/real_world_test_dynamic.log +0 -184
  25. package/real_world_test_real.log +0 -184
  26. package/src/__tests__/agents.test.ts +0 -858
  27. package/src/__tests__/mcp-server.test.ts +0 -380
  28. package/src/__tests__/sequential-thinking.test.ts +0 -687
  29. package/src/__tests__/swarm-coordinator.test.ts +0 -903
  30. package/src/__tests__/types.test.ts +0 -839
  31. package/src/__tests__/utils.test.ts +0 -322
  32. package/src/agents/base-agent.ts +0 -288
  33. package/src/agents/critic-agent.ts +0 -582
  34. package/src/agents/index.ts +0 -11
  35. package/src/agents/meta-reasoning-agent.ts +0 -314
  36. package/src/agents/reasoner-agent.ts +0 -312
  37. package/src/agents/synthesizer-agent.ts +0 -641
  38. package/src/index.ts +0 -118
  39. package/src/mcp-server.ts +0 -391
  40. package/src/real_world_test.ts +0 -89
  41. package/src/sequential-thinking.ts +0 -614
  42. package/src/swarm-coordinator.ts +0 -772
  43. package/src/types/index.ts +0 -915
  44. package/src/utils/index.ts +0 -1004
  45. package/src/utils/llm-adapter.ts +0 -110
  46. package/src/utils/logger.ts +0 -56
  47. package/src/utils/persistence.ts +0 -109
  48. package/test_output.log +0 -0
  49. package/tsconfig.json +0 -21
@@ -1,641 +0,0 @@
1
- /**
2
- * Synthesizer Agent Implementation
3
- * @module agents/synthesizer-agent
4
- * @version 1.0.0
5
- */
6
-
7
- import { BaseAgent } from './base-agent.js';
8
- import {
9
- AgentType,
10
- SynthesizerType,
11
- type Task,
12
- type TaskResult,
13
- type AgentCapability
14
- } from '../types/index.js';
15
- import { LLMAdapter } from '../utils/llm-adapter.js';
16
-
17
- /**
18
- * Synthesis input
19
- */
20
- interface SynthesisInput {
21
- outputs: Array<{
22
- agentId: string;
23
- output: unknown;
24
- confidence: number;
25
- }>;
26
- context?: unknown;
27
- }
28
-
29
- /**
30
- * Synthesis result
31
- */
32
- interface Synthesis {
33
- synthesizedOutput: unknown;
34
- confidence: number;
35
- contributingAgents: string[];
36
- synthesisMethod: string;
37
- consensusLevel?: number;
38
- dissentPoints?: unknown[];
39
- }
40
-
41
- /**
42
- * Synthesizer agent that combines multiple agent outputs
43
- */
44
- export class SynthesizerAgent extends BaseAgent {
45
- /** Synthesizer type */
46
- private synthesizerType: SynthesizerType;
47
-
48
- /**
49
- * Create a new synthesizer agent
50
- * @param config - Agent configuration
51
- */
52
- constructor(config: {
53
- name: string;
54
- synthesizerType?: SynthesizerType;
55
- capabilities?: AgentCapability[];
56
- }) {
57
- const defaultCapabilities: AgentCapability[] = [
58
- {
59
- name: 'consensus_building',
60
- description: 'Build consensus from multiple outputs',
61
- confidence: 0.9,
62
- performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 }
63
- },
64
- {
65
- name: 'conflict_resolution',
66
- description: 'Resolve conflicts between outputs',
67
- confidence: 0.85,
68
- performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 }
69
- },
70
- {
71
- name: 'creative_synthesis',
72
- description: 'Create creative combinations',
73
- confidence: 0.8,
74
- performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 }
75
- },
76
- {
77
- name: 'integration',
78
- description: 'Integrate multiple perspectives',
79
- confidence: 0.9,
80
- performanceMetrics: { tasksCompleted: 0, averageQuality: 0, averageTimeMs: 0 }
81
- }
82
- ];
83
-
84
- super({
85
- name: config.name,
86
- type: AgentType.SYNTHESIZER,
87
- subtype: config.synthesizerType || SynthesizerType.CONSENSUS,
88
- capabilities: config.capabilities || defaultCapabilities,
89
- maxConcurrentTasks: 3,
90
- confidenceThreshold: 0.7
91
- });
92
-
93
- this.synthesizerType = config.synthesizerType || SynthesizerType.CONSENSUS;
94
- }
95
-
96
- /**
97
- * Get agent type
98
- * @returns Agent type
99
- */
100
- getType(): string {
101
- return AgentType.SYNTHESIZER;
102
- }
103
-
104
- /**
105
- * Get agent capabilities
106
- * @returns Array of capabilities
107
- */
108
- getCapabilities(): AgentCapability[] {
109
- return this.config.capabilities;
110
- }
111
-
112
- /**
113
- * Process a task - synthesize inputs using LLM
114
- * @param task - Task to process
115
- * @returns Task result
116
- */
117
- async process(task: Task): Promise<TaskResult> {
118
- const startTime = Date.now();
119
- const input = task.input as SynthesisInput;
120
-
121
- if (!input.outputs || input.outputs.length === 0) {
122
- return this.createTaskResult(task.id, { error: 'No outputs to synthesize' }, 0, Date.now() - startTime);
123
- }
124
-
125
- const contextStr = input.context ? `Context: ${JSON.stringify(input.context)}\n` : '';
126
- const outputsStr = input.outputs.map((o, i) => `Agent ${o.agentId} (Confidence: ${o.confidence}):\n${JSON.stringify(o.output)}`).join('\n\n');
127
-
128
- const provider = (task.context as any)?.modelProvider;
129
-
130
- let prompt = '';
131
- let systemPrompt = 'You are an expert synthesizer agent in a swarm intelligence system. Your goal is to combine multiple agent outputs into a coherent, high-quality result.';
132
-
133
- switch (this.synthesizerType) {
134
- case SynthesizerType.CONSENSUS:
135
- prompt = `Build a consensus from the following agent outputs. Identify common points, resolve minor discrepancies, and provide a unified conclusion.\n\n${contextStr}\n${outputsStr}`;
136
- break;
137
- case SynthesizerType.CREATIVE:
138
- prompt = `Perform a creative synthesis of these agent outputs. Look for unexpected connections, combine ideas in novel ways, and provide a unique integrated insight.\n\n${contextStr}\n${outputsStr}`;
139
- systemPrompt = 'You are a creative synthesizer agent. You excel at finding novel connections and unique perspectives by combining diverse ideas.';
140
- break;
141
- case SynthesizerType.CONFLICT_RESOLUTION:
142
- prompt = `Resolve the conflicts between these agent outputs. Analyze the reasoning behind each conflicting point and determine the most logically sound resolution based on the evidence and confidence levels.\n\n${contextStr}\n${outputsStr}`;
143
- systemPrompt = 'You are a conflict resolution specialist agent. You excel at analyzing differing perspectives and finding the most accurate resolution based on logic and evidence.';
144
- break;
145
- default:
146
- prompt = `Integrate the following agent outputs into a comprehensive final result.\n\n${contextStr}\n${outputsStr}`;
147
- }
148
-
149
- const response = await LLMAdapter.call(prompt, systemPrompt, provider);
150
-
151
- if (response.error) {
152
- // Fallback to heuristic if LLM fails
153
- const heuristicResult = await this.heuristicSynthesis(input);
154
- return this.createTaskResult(task.id, heuristicResult, heuristicResult.confidence, Date.now() - startTime, { error: response.error });
155
- }
156
-
157
- const synthesizedOutput = response.content;
158
- const avgConfidence = input.outputs.reduce((sum, o) => sum + o.confidence, 0) / input.outputs.length;
159
-
160
- const result: Synthesis = {
161
- synthesizedOutput,
162
- confidence: Math.min(0.95, avgConfidence + 0.1), // Boost confidence for successful synthesis
163
- contributingAgents: input.outputs.map(o => o.agentId),
164
- synthesisMethod: `llm_${this.synthesizerType.toLowerCase()}`
165
- };
166
-
167
- return this.createTaskResult(
168
- task.id,
169
- result,
170
- result.confidence,
171
- Date.now() - startTime,
172
- {
173
- reasoningSteps: input.outputs.length + 1,
174
- intermediateResults: input.outputs.map(o => o.output)
175
- }
176
- );
177
- }
178
-
179
- /**
180
- * Fallback heuristic synthesis
181
- */
182
- private async heuristicSynthesis(input: SynthesisInput): Promise<Synthesis> {
183
- const { outputs } = input;
184
- // Simplified version of the previous heuristic logic
185
- return {
186
- synthesizedOutput: outputs.map(o => JSON.stringify(o.output)).join('\n---\n'),
187
- confidence: outputs.reduce((sum, o) => sum + o.confidence, 0) / outputs.length,
188
- contributingAgents: outputs.map(o => o.agentId),
189
- synthesisMethod: 'heuristic_fallback'
190
- };
191
- }
192
-
193
-
194
- // ============================================================================
195
- // Helper Methods
196
- // ============================================================================
197
-
198
- /**
199
- * Extract key points from output
200
- * @param output - Output to extract from
201
- * @returns Array of key points
202
- */
203
- private extractKeyPoints(output: unknown): string[] {
204
- if (typeof output === 'string') {
205
- return output.split(/[.!?]+/).filter(s => s.trim().length > 10);
206
- }
207
-
208
- if (output && typeof output === 'object') {
209
- const obj = output as Record<string, unknown>;
210
-
211
- if ('conclusion' in obj && typeof obj.conclusion === 'string') {
212
- return [obj.conclusion];
213
- }
214
-
215
- if ('keyPoints' in obj && Array.isArray(obj.keyPoints)) {
216
- return obj.keyPoints as string[];
217
- }
218
-
219
- return [JSON.stringify(output)];
220
- }
221
-
222
- return [String(output)];
223
- }
224
-
225
- /**
226
- * Find consensus points
227
- * @param keyPointsArray - Array of key points arrays
228
- * @returns Consensus points
229
- */
230
- private findConsensusPoints(keyPointsArray: string[][]): string[] {
231
- if (keyPointsArray.length === 0) return [];
232
- if (keyPointsArray.length === 1) return keyPointsArray[0];
233
-
234
- const consensus: string[] = [];
235
- const firstSet = keyPointsArray[0];
236
-
237
- for (const point of firstSet) {
238
- const normalizedPoint = this.normalizePoint(point);
239
- let matchCount = 1;
240
-
241
- for (let i = 1; i < keyPointsArray.length; i++) {
242
- const otherSet = keyPointsArray[i];
243
- const hasMatch = otherSet.some(otherPoint =>
244
- this.pointsAreSimilar(normalizedPoint, this.normalizePoint(otherPoint))
245
- );
246
- if (hasMatch) matchCount++;
247
- }
248
-
249
- // Point is in consensus if it appears in majority
250
- if (matchCount > keyPointsArray.length / 2) {
251
- consensus.push(point);
252
- }
253
- }
254
-
255
- return consensus;
256
- }
257
-
258
- /**
259
- * Find divergence points
260
- * @param keyPointsArray - Array of key points arrays
261
- * @returns Divergence points
262
- */
263
- private findDivergencePoints(keyPointsArray: string[][]): string[] {
264
- if (keyPointsArray.length <= 1) return [];
265
-
266
- const allPoints = keyPointsArray.flat();
267
- const uniquePoints = [...new Set(allPoints.map(p => this.normalizePoint(p)))];
268
- const divergence: string[] = [];
269
-
270
- for (const point of uniquePoints) {
271
- let matchCount = 0;
272
-
273
- for (const pointSet of keyPointsArray) {
274
- const hasMatch = pointSet.some(p =>
275
- this.pointsAreSimilar(point, this.normalizePoint(p))
276
- );
277
- if (hasMatch) matchCount++;
278
- }
279
-
280
- // Point diverges if not in majority
281
- if (matchCount <= keyPointsArray.length / 2) {
282
- const original = allPoints.find(p => this.normalizePoint(p) === point);
283
- if (original) divergence.push(original);
284
- }
285
- }
286
-
287
- return divergence;
288
- }
289
-
290
- /**
291
- * Normalize a point for comparison
292
- * @param point - Point to normalize
293
- * @returns Normalized point
294
- */
295
- private normalizePoint(point: string): string {
296
- return point.toLowerCase().trim().replace(/\s+/g, ' ');
297
- }
298
-
299
- /**
300
- * Check if two points are similar
301
- * @param a - First point
302
- * @param b - Second point
303
- * @returns True if similar
304
- */
305
- private pointsAreSimilar(a: string, b: string): boolean {
306
- // Simple similarity check
307
- if (a === b) return true;
308
-
309
- const wordsA = new Set(a.split(' '));
310
- const wordsB = new Set(b.split(' '));
311
- const intersection = [...wordsA].filter(w => wordsB.has(w));
312
- const union = new Set([...wordsA, ...wordsB]);
313
-
314
- return union.size > 0 && intersection.length / union.size > 0.6;
315
- }
316
-
317
- /**
318
- * Apply confidence weights to points
319
- * @param points - Points to weight
320
- * @param outputs - Outputs with confidence
321
- * @returns Weighted points
322
- */
323
- private applyConfidenceWeights(
324
- points: string[],
325
- outputs: Array<{ confidence: number }>
326
- ): Array<{ point: string; weight: number }> {
327
- const avgConfidence = outputs.reduce((sum, o) => sum + o.confidence, 0) / outputs.length;
328
-
329
- return points.map(point => ({
330
- point,
331
- weight: avgConfidence
332
- }));
333
- }
334
-
335
- /**
336
- * Generate unified output
337
- * @param weightedPoints - Weighted points
338
- * @param divergencePoints - Divergence points
339
- * @returns Unified output
340
- */
341
- private generateUnifiedOutput(
342
- weightedPoints: Array<{ point: string; weight: number }>,
343
- divergencePoints: string[]
344
- ): Record<string, unknown> {
345
- return {
346
- consensus: weightedPoints.map(wp => wp.point),
347
- consensusWeights: weightedPoints.map(wp => wp.weight),
348
- pointsOfDivergence: divergencePoints,
349
- summary: `Consensus reached on ${weightedPoints.length} points with ${divergencePoints.length} points of divergence`
350
- };
351
- }
352
-
353
- /**
354
- * Extract creative elements
355
- * @param output - Output to extract from
356
- * @returns Creative elements
357
- */
358
- private extractCreativeElements(output: unknown): string[] {
359
- if (typeof output === 'string') {
360
- // Extract novel phrases, metaphors, etc.
361
- return output.split(/[.!?]+/).filter(s => s.trim().length > 5);
362
- }
363
-
364
- if (output && typeof output === 'object') {
365
- const obj = output as Record<string, unknown>;
366
-
367
- if ('creativeElements' in obj && Array.isArray(obj.creativeElements)) {
368
- return obj.creativeElements as string[];
369
- }
370
-
371
- if ('ideas' in obj && Array.isArray(obj.ideas)) {
372
- return obj.ideas as string[];
373
- }
374
- }
375
-
376
- return [String(output)];
377
- }
378
-
379
- /**
380
- * Find unexpected connections
381
- * @param elementsArray - Array of element arrays
382
- * @returns Connections
383
- */
384
- private findUnexpectedConnections(elementsArray: string[][]): Array<{
385
- elements: [string, string];
386
- connection: string;
387
- }> {
388
- const connections: Array<{ elements: [string, string]; connection: string }> = [];
389
-
390
- // Compare elements from different sources
391
- for (let i = 0; i < elementsArray.length; i++) {
392
- for (let j = i + 1; j < elementsArray.length; j++) {
393
- const setA = elementsArray[i];
394
- const setB = elementsArray[j];
395
-
396
- for (const elemA of setA) {
397
- for (const elemB of setB) {
398
- const connection = this.findConnection(elemA, elemB);
399
- if (connection) {
400
- connections.push({
401
- elements: [elemA, elemB],
402
- connection
403
- });
404
- }
405
- }
406
- }
407
- }
408
- }
409
-
410
- return connections;
411
- }
412
-
413
- /**
414
- * Find connection between two elements
415
- * @param a - First element
416
- * @param b - Second element
417
- * @returns Connection description or null
418
- */
419
- private findConnection(a: string, b: string): string | null {
420
- const wordsA = new Set(a.toLowerCase().split(/\s+/));
421
- const wordsB = new Set(b.toLowerCase().split(/\s+/));
422
- const common = [...wordsA].filter(w => wordsB.has(w) && w.length > 3);
423
-
424
- if (common.length > 0) {
425
- return `Connected through: ${common.join(', ')}`;
426
- }
427
-
428
- return null;
429
- }
430
-
431
- /**
432
- * Generate novel combinations
433
- * @param elementsArray - Array of element arrays
434
- * @param connections - Connections
435
- * @returns Combinations
436
- */
437
- private generateNovelCombinations(
438
- elementsArray: string[][],
439
- connections: Array<{ elements: [string, string]; connection: string }>
440
- ): string[] {
441
- const combinations: string[] = [];
442
-
443
- for (const connection of connections) {
444
- const [elemA, elemB] = connection.elements;
445
- combinations.push(`Combining "${elemA.substring(0, 30)}..." with "${elemB.substring(0, 30)}..."`);
446
- }
447
-
448
- // Cross-pollinate ideas
449
- for (let i = 0; i < elementsArray.length && i < 3; i++) {
450
- for (let j = i + 1; j < elementsArray.length && j < 3; j++) {
451
- const elemA = elementsArray[i][0];
452
- const elemB = elementsArray[j][0];
453
- if (elemA && elemB) {
454
- combinations.push(`Cross: ${elemA.substring(0, 20)}... + ${elemB.substring(0, 20)}...`);
455
- }
456
- }
457
- }
458
-
459
- return combinations;
460
- }
461
-
462
- /**
463
- * Generate novel insights
464
- * @param combinations - Combinations
465
- * @returns Insights
466
- */
467
- private generateNovelInsights(combinations: string[]): string[] {
468
- return combinations.map((combo, i) =>
469
- `Insight ${i + 1}: ${combo} suggests a new approach`
470
- );
471
- }
472
-
473
- /**
474
- * Calculate diversity score
475
- * @param elementsArray - Array of element arrays
476
- * @returns Diversity score (0-1)
477
- */
478
- private calculateDiversity(elementsArray: string[][]): number {
479
- const allElements = elementsArray.flat();
480
- const uniqueElements = new Set(allElements);
481
-
482
- if (allElements.length === 0) return 0;
483
-
484
- return uniqueElements.size / allElements.length;
485
- }
486
-
487
- /**
488
- * Identify conflicts
489
- * @param outputs - Outputs to analyze
490
- * @returns Conflicts
491
- */
492
- private identifyConflicts(outputs: Array<{ agentId: string; output: unknown }>): Array<{
493
- type: string;
494
- description: string;
495
- involvedAgents: string[];
496
- }> {
497
- const conflicts: Array<{
498
- type: string;
499
- description: string;
500
- involvedAgents: string[];
501
- }> = [];
502
-
503
- // Check for contradictory conclusions
504
- const conclusions: Array<{ agentId: string; conclusion: string }> = [];
505
-
506
- for (const output of outputs) {
507
- const conclusion = this.extractConclusion(output.output);
508
- if (conclusion) {
509
- conclusions.push({ agentId: output.agentId, conclusion });
510
- }
511
- }
512
-
513
- // Find contradictions
514
- for (let i = 0; i < conclusions.length; i++) {
515
- for (let j = i + 1; j < conclusions.length; j++) {
516
- const a = conclusions[i];
517
- const b = conclusions[j];
518
-
519
- if (this.areContradictory(a.conclusion, b.conclusion)) {
520
- conflicts.push({
521
- type: 'contradiction',
522
- description: `Contradictory conclusions: "${a.conclusion.substring(0, 30)}..." vs "${b.conclusion.substring(0, 30)}..."`,
523
- involvedAgents: [a.agentId, b.agentId]
524
- });
525
- }
526
- }
527
- }
528
-
529
- return conflicts;
530
- }
531
-
532
- /**
533
- * Extract conclusion from output
534
- * @param output - Output to extract from
535
- * @returns Conclusion string or null
536
- */
537
- private extractConclusion(output: unknown): string | null {
538
- if (typeof output === 'string') return output;
539
-
540
- if (output && typeof output === 'object') {
541
- const obj = output as Record<string, unknown>;
542
-
543
- if ('conclusion' in obj && typeof obj.conclusion === 'string') {
544
- return obj.conclusion;
545
- }
546
- }
547
-
548
- return null;
549
- }
550
-
551
- /**
552
- * Check if two conclusions are contradictory
553
- * @param a - First conclusion
554
- * @param b - Second conclusion
555
- * @returns True if contradictory
556
- */
557
- private areContradictory(a: string, b: string): boolean {
558
- const lowerA = a.toLowerCase();
559
- const lowerB = b.toLowerCase();
560
-
561
- // Check for direct opposites
562
- const oppositePatterns = [
563
- { pos: /\b(is|are|was|were)\b/gi, neg: /\b(is not|are not|was not|were not)\b/gi },
564
- { pos: /\bshould\b/gi, neg: /\bshould not\b/gi },
565
- { pos: /\bcan\b/gi, neg: /\bcannot\b/gi }
566
- ];
567
-
568
- for (const { pos, neg } of oppositePatterns) {
569
- const aHasPos = pos.test(lowerA);
570
- const aHasNeg = neg.test(lowerA);
571
- const bHasPos = pos.test(lowerB);
572
- const bHasNeg = neg.test(lowerB);
573
-
574
- if ((aHasPos && bHasNeg) || (aHasNeg && bHasPos)) {
575
- return true;
576
- }
577
- }
578
-
579
- return false;
580
- }
581
-
582
- /**
583
- * Resolve a conflict
584
- * @param conflict - Conflict to resolve
585
- * @param outputs - All outputs
586
- * @returns Resolution
587
- */
588
- private resolveConflict(
589
- conflict: { type: string; involvedAgents: string[] },
590
- outputs: Array<{ agentId: string; output: unknown; confidence: number }>
591
- ): { resolution: unknown; confidence: number } {
592
- // Get conflicting outputs
593
- const conflictingOutputs = outputs.filter(o =>
594
- conflict.involvedAgents.includes(o.agentId)
595
- );
596
-
597
- // Select based on confidence
598
- const best = conflictingOutputs.reduce((max, o) =>
599
- o.confidence > max.confidence ? o : max,
600
- conflictingOutputs[0]
601
- );
602
-
603
- if (!best) {
604
- return { resolution: null, confidence: 0 };
605
- }
606
-
607
- return {
608
- resolution: best.output,
609
- confidence: best.confidence
610
- };
611
- }
612
-
613
- /**
614
- * Merge resolutions with non-conflicting content
615
- * @param outputs - All outputs
616
- * @param resolutions - Resolutions
617
- * @returns Merged output
618
- */
619
- private mergeResolutions(
620
- outputs: Array<{ agentId: string; output: unknown }>,
621
- resolutions: Array<{ conflict: { involvedAgents: string[] }; resolution: { resolution: unknown } }>
622
- ): Record<string, unknown> {
623
- const merged: Record<string, unknown> = {
624
- resolvedConflicts: resolutions.length,
625
- agentOutputs: {}
626
- };
627
-
628
- // Add all outputs
629
- for (const output of outputs) {
630
- (merged.agentOutputs as Record<string, unknown>)[output.agentId] = output.output;
631
- }
632
-
633
- // Add resolutions
634
- merged.resolutions = resolutions.map(r => ({
635
- conflict: r.conflict,
636
- selectedResolution: r.resolution.resolution
637
- }));
638
-
639
- return merged;
640
- }
641
- }