societyai 0.0.1
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/CHANGELOG.md +111 -0
- package/LICENSE +21 -0
- package/README.md +879 -0
- package/dist/builder.d.ts +181 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +667 -0
- package/dist/builder.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +107 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +319 -0
- package/dist/context.js.map +1 -0
- package/dist/errors.d.ts +31 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +85 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +219 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +395 -0
- package/dist/events.js.map +1 -0
- package/dist/graph.d.ts +104 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +366 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +78 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory.d.ts +146 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +353 -0
- package/dist/memory.js.map +1 -0
- package/dist/metrics.d.ts +143 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +271 -0
- package/dist/metrics.js.map +1 -0
- package/dist/middleware.d.ts +147 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +484 -0
- package/dist/middleware.js.map +1 -0
- package/dist/models.d.ts +32 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +211 -0
- package/dist/models.js.map +1 -0
- package/dist/patterns.d.ts +6 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/patterns.js +68 -0
- package/dist/patterns.js.map +1 -0
- package/dist/pipeline.d.ts +84 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +569 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/retry.d.ts +5 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +70 -0
- package/dist/retry.js.map +1 -0
- package/dist/society.d.ts +94 -0
- package/dist/society.d.ts.map +1 -0
- package/dist/society.js +721 -0
- package/dist/society.js.map +1 -0
- package/dist/strategies.d.ts +55 -0
- package/dist/strategies.d.ts.map +1 -0
- package/dist/strategies.js +678 -0
- package/dist/strategies.js.map +1 -0
- package/dist/tools.d.ts +88 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +366 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +64 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +334 -0
- package/dist/validation.js.map +1 -0
- package/dist/worker-pool.d.ts +17 -0
- package/dist/worker-pool.d.ts.map +1 -0
- package/dist/worker-pool.js +80 -0
- package/dist/worker-pool.js.map +1 -0
- package/docs/README.md +468 -0
- package/docs/advanced.md +616 -0
- package/docs/aggregation-strategies.md +926 -0
- package/docs/api-reference.md +771 -0
- package/docs/architecture.md +648 -0
- package/docs/context-system.md +642 -0
- package/docs/event-system.md +1047 -0
- package/docs/examples.md +576 -0
- package/docs/getting-started.md +564 -0
- package/docs/graph-execution.md +389 -0
- package/docs/memory-system.md +497 -0
- package/docs/metrics-observability.md +560 -0
- package/docs/middleware-system.md +1038 -0
- package/docs/migration.md +296 -0
- package/docs/pipeline-patterns.md +761 -0
- package/docs/structured-output.md +612 -0
- package/docs/tool-calling.md +491 -0
- package/docs/workflows.md +740 -0
- package/examples/README.md +234 -0
- package/examples/advanced-patterns.ts +115 -0
- package/examples/complete-integration.ts +327 -0
- package/examples/graph-workflow.ts +161 -0
- package/examples/memory-system.ts +155 -0
- package/examples/metrics-tracking.ts +243 -0
- package/examples/structured-output.ts +231 -0
- package/examples/tool-calling.ts +163 -0
- package/package.json +94 -0
|
@@ -0,0 +1,678 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Strategies = exports.StrategyBuilder = void 0;
|
|
4
|
+
exports.createStrategy = createStrategy;
|
|
5
|
+
exports.chainStrategies = chainStrategies;
|
|
6
|
+
exports.parallelStrategies = parallelStrategies;
|
|
7
|
+
class StrategyBuilder {
|
|
8
|
+
constructor() {
|
|
9
|
+
this._name = 'custom';
|
|
10
|
+
}
|
|
11
|
+
static create() {
|
|
12
|
+
return new StrategyBuilder();
|
|
13
|
+
}
|
|
14
|
+
withName(name) {
|
|
15
|
+
this._name = name;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
withDescription(description) {
|
|
19
|
+
this._description = description;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
withAggregator(fn) {
|
|
23
|
+
this._aggregateFn = fn;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
build() {
|
|
27
|
+
if (!this._aggregateFn) {
|
|
28
|
+
throw new Error('Aggregator function is required');
|
|
29
|
+
}
|
|
30
|
+
const aggregateFn = this._aggregateFn;
|
|
31
|
+
const name = this._name;
|
|
32
|
+
return {
|
|
33
|
+
name: this._name,
|
|
34
|
+
description: this._description,
|
|
35
|
+
aggregate: aggregateFn,
|
|
36
|
+
aggregateFull: (results) => {
|
|
37
|
+
const successful = results.filter((r) => r.success);
|
|
38
|
+
return {
|
|
39
|
+
output: aggregateFn(results),
|
|
40
|
+
metadata: {
|
|
41
|
+
successCount: successful.length,
|
|
42
|
+
failedCount: results.length - successful.length,
|
|
43
|
+
strategy: name,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.StrategyBuilder = StrategyBuilder;
|
|
51
|
+
exports.Strategies = {
|
|
52
|
+
concat: (separator = '\n\n') => ({
|
|
53
|
+
name: 'concat',
|
|
54
|
+
description: `Concatenates all successful results with "${separator}"`,
|
|
55
|
+
aggregate: (results) => results
|
|
56
|
+
.filter((r) => r.success)
|
|
57
|
+
.map((r) => r.content)
|
|
58
|
+
.join(separator),
|
|
59
|
+
aggregateFull: (results) => {
|
|
60
|
+
const successful = results.filter((r) => r.success);
|
|
61
|
+
return {
|
|
62
|
+
output: successful.map((r) => r.content).join(separator),
|
|
63
|
+
metadata: {
|
|
64
|
+
successCount: successful.length,
|
|
65
|
+
failedCount: results.length - successful.length,
|
|
66
|
+
strategy: 'concat',
|
|
67
|
+
separator,
|
|
68
|
+
},
|
|
69
|
+
contributions: results.map((r) => ({
|
|
70
|
+
agentId: r.agentId,
|
|
71
|
+
included: r.success,
|
|
72
|
+
})),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
first: () => ({
|
|
77
|
+
name: 'first',
|
|
78
|
+
description: 'Returns only the first successful result',
|
|
79
|
+
aggregate: (results) => {
|
|
80
|
+
const first = results.find((r) => r.success);
|
|
81
|
+
return first?.content ?? '';
|
|
82
|
+
},
|
|
83
|
+
aggregateFull: (results) => {
|
|
84
|
+
const first = results.find((r) => r.success);
|
|
85
|
+
return {
|
|
86
|
+
output: first?.content ?? '',
|
|
87
|
+
metadata: {
|
|
88
|
+
successCount: first ? 1 : 0,
|
|
89
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
90
|
+
strategy: 'first',
|
|
91
|
+
selectedAgent: first?.agentId,
|
|
92
|
+
},
|
|
93
|
+
contributions: results.map((r) => ({
|
|
94
|
+
agentId: r.agentId,
|
|
95
|
+
included: r === first,
|
|
96
|
+
})),
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
last: () => ({
|
|
101
|
+
name: 'last',
|
|
102
|
+
description: 'Returns only the last successful result',
|
|
103
|
+
aggregate: (results) => {
|
|
104
|
+
const successful = results.filter((r) => r.success);
|
|
105
|
+
return successful[successful.length - 1]?.content ?? '';
|
|
106
|
+
},
|
|
107
|
+
aggregateFull: (results) => {
|
|
108
|
+
const successful = results.filter((r) => r.success);
|
|
109
|
+
const last = successful[successful.length - 1];
|
|
110
|
+
return {
|
|
111
|
+
output: last?.content ?? '',
|
|
112
|
+
metadata: {
|
|
113
|
+
successCount: last ? 1 : 0,
|
|
114
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
115
|
+
strategy: 'last',
|
|
116
|
+
selectedAgent: last?.agentId,
|
|
117
|
+
},
|
|
118
|
+
contributions: results.map((r) => ({
|
|
119
|
+
agentId: r.agentId,
|
|
120
|
+
included: r === last,
|
|
121
|
+
})),
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
longest: () => ({
|
|
126
|
+
name: 'longest',
|
|
127
|
+
description: 'Returns the longest successful result',
|
|
128
|
+
aggregate: (results) => {
|
|
129
|
+
const successful = results.filter((r) => r.success);
|
|
130
|
+
if (successful.length === 0)
|
|
131
|
+
return '';
|
|
132
|
+
return successful.reduce((a, b) => (a.content.length > b.content.length ? a : b)).content;
|
|
133
|
+
},
|
|
134
|
+
aggregateFull: (results) => {
|
|
135
|
+
const successful = results.filter((r) => r.success);
|
|
136
|
+
const longest = successful.length > 0
|
|
137
|
+
? successful.reduce((a, b) => (a.content.length > b.content.length ? a : b))
|
|
138
|
+
: null;
|
|
139
|
+
return {
|
|
140
|
+
output: longest?.content ?? '',
|
|
141
|
+
metadata: {
|
|
142
|
+
successCount: longest ? 1 : 0,
|
|
143
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
144
|
+
strategy: 'longest',
|
|
145
|
+
selectedAgent: longest?.agentId,
|
|
146
|
+
contentLength: longest?.content.length ?? 0,
|
|
147
|
+
},
|
|
148
|
+
contributions: results.map((r) => ({
|
|
149
|
+
agentId: r.agentId,
|
|
150
|
+
included: r === longest,
|
|
151
|
+
})),
|
|
152
|
+
};
|
|
153
|
+
},
|
|
154
|
+
}),
|
|
155
|
+
shortest: () => ({
|
|
156
|
+
name: 'shortest',
|
|
157
|
+
description: 'Returns the shortest successful result',
|
|
158
|
+
aggregate: (results) => {
|
|
159
|
+
const successful = results.filter((r) => r.success);
|
|
160
|
+
if (successful.length === 0)
|
|
161
|
+
return '';
|
|
162
|
+
return successful.reduce((a, b) => (a.content.length < b.content.length ? a : b)).content;
|
|
163
|
+
},
|
|
164
|
+
aggregateFull: (results) => {
|
|
165
|
+
const successful = results.filter((r) => r.success);
|
|
166
|
+
const shortest = successful.length > 0
|
|
167
|
+
? successful.reduce((a, b) => (a.content.length < b.content.length ? a : b))
|
|
168
|
+
: null;
|
|
169
|
+
return {
|
|
170
|
+
output: shortest?.content ?? '',
|
|
171
|
+
metadata: {
|
|
172
|
+
successCount: shortest ? 1 : 0,
|
|
173
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
174
|
+
strategy: 'shortest',
|
|
175
|
+
selectedAgent: shortest?.agentId,
|
|
176
|
+
contentLength: shortest?.content.length ?? 0,
|
|
177
|
+
},
|
|
178
|
+
contributions: results.map((r) => ({
|
|
179
|
+
agentId: r.agentId,
|
|
180
|
+
included: r === shortest,
|
|
181
|
+
})),
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
}),
|
|
185
|
+
best: (scorer) => ({
|
|
186
|
+
name: 'best',
|
|
187
|
+
description: 'Selects the best result based on a scoring function',
|
|
188
|
+
aggregate: (results) => {
|
|
189
|
+
const successful = results.filter((r) => r.success);
|
|
190
|
+
if (successful.length === 0)
|
|
191
|
+
return '';
|
|
192
|
+
const scored = successful.map((r) => ({ result: r, score: scorer(r) }));
|
|
193
|
+
scored.sort((a, b) => b.score - a.score);
|
|
194
|
+
return scored[0].result.content;
|
|
195
|
+
},
|
|
196
|
+
aggregateFull: (results) => {
|
|
197
|
+
const successful = results.filter((r) => r.success);
|
|
198
|
+
const scored = successful.map((r) => ({ result: r, score: scorer(r) }));
|
|
199
|
+
scored.sort((a, b) => b.score - a.score);
|
|
200
|
+
const best = scored[0];
|
|
201
|
+
return {
|
|
202
|
+
output: best?.result.content ?? '',
|
|
203
|
+
metadata: {
|
|
204
|
+
successCount: best ? 1 : 0,
|
|
205
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
206
|
+
strategy: 'best',
|
|
207
|
+
selectedAgent: best?.result.agentId,
|
|
208
|
+
score: best?.score ?? 0,
|
|
209
|
+
scores: Object.fromEntries(scored.map((s) => [s.result.agentId, s.score])),
|
|
210
|
+
},
|
|
211
|
+
contributions: results.map((r) => ({
|
|
212
|
+
agentId: r.agentId,
|
|
213
|
+
weight: scorer(r),
|
|
214
|
+
included: r === best?.result,
|
|
215
|
+
})),
|
|
216
|
+
};
|
|
217
|
+
},
|
|
218
|
+
}),
|
|
219
|
+
random: () => ({
|
|
220
|
+
name: 'random',
|
|
221
|
+
description: 'Randomly selects one successful result',
|
|
222
|
+
aggregate: (results) => {
|
|
223
|
+
const successful = results.filter((r) => r.success);
|
|
224
|
+
if (successful.length === 0)
|
|
225
|
+
return '';
|
|
226
|
+
const randomIndex = Math.floor(Math.random() * successful.length);
|
|
227
|
+
return successful[randomIndex].content;
|
|
228
|
+
},
|
|
229
|
+
aggregateFull: (results) => {
|
|
230
|
+
const successful = results.filter((r) => r.success);
|
|
231
|
+
const randomIndex = successful.length > 0 ? Math.floor(Math.random() * successful.length) : -1;
|
|
232
|
+
const selected = successful[randomIndex];
|
|
233
|
+
return {
|
|
234
|
+
output: selected?.content ?? '',
|
|
235
|
+
metadata: {
|
|
236
|
+
successCount: selected ? 1 : 0,
|
|
237
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
238
|
+
strategy: 'random',
|
|
239
|
+
selectedAgent: selected?.agentId,
|
|
240
|
+
selectedIndex: randomIndex,
|
|
241
|
+
},
|
|
242
|
+
contributions: results.map((r) => ({
|
|
243
|
+
agentId: r.agentId,
|
|
244
|
+
included: r === selected,
|
|
245
|
+
})),
|
|
246
|
+
};
|
|
247
|
+
},
|
|
248
|
+
}),
|
|
249
|
+
weighted: (weights) => ({
|
|
250
|
+
name: 'weighted',
|
|
251
|
+
description: 'Concatenates results weighted by agent importance',
|
|
252
|
+
aggregate: (results) => {
|
|
253
|
+
const successful = results.filter((r) => r.success);
|
|
254
|
+
const sorted = successful.sort((a, b) => (weights[b.agentId] ?? 1) - (weights[a.agentId] ?? 1));
|
|
255
|
+
return sorted.map((r) => r.content).join('\n\n');
|
|
256
|
+
},
|
|
257
|
+
aggregateFull: (results) => {
|
|
258
|
+
const successful = results.filter((r) => r.success);
|
|
259
|
+
const sorted = successful.sort((a, b) => (weights[b.agentId] ?? 1) - (weights[a.agentId] ?? 1));
|
|
260
|
+
return {
|
|
261
|
+
output: sorted.map((r) => r.content).join('\n\n'),
|
|
262
|
+
metadata: {
|
|
263
|
+
successCount: successful.length,
|
|
264
|
+
failedCount: results.length - successful.length,
|
|
265
|
+
strategy: 'weighted',
|
|
266
|
+
weights,
|
|
267
|
+
},
|
|
268
|
+
contributions: results.map((r) => ({
|
|
269
|
+
agentId: r.agentId,
|
|
270
|
+
weight: weights[r.agentId] ?? 1,
|
|
271
|
+
included: r.success,
|
|
272
|
+
})),
|
|
273
|
+
};
|
|
274
|
+
},
|
|
275
|
+
}),
|
|
276
|
+
weightedVote: (weights) => ({
|
|
277
|
+
name: 'weightedVote',
|
|
278
|
+
description: 'Selects the result with highest weighted vote',
|
|
279
|
+
aggregate: (results) => {
|
|
280
|
+
const successful = results.filter((r) => r.success);
|
|
281
|
+
if (successful.length === 0)
|
|
282
|
+
return '';
|
|
283
|
+
const votes = new Map();
|
|
284
|
+
for (const result of successful) {
|
|
285
|
+
const weight = weights[result.agentId] ?? 1;
|
|
286
|
+
const key = result.content.trim().toLowerCase().substring(0, 100);
|
|
287
|
+
const existing = votes.get(key);
|
|
288
|
+
if (existing) {
|
|
289
|
+
existing.weight += weight;
|
|
290
|
+
existing.agents.push(result.agentId);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
votes.set(key, { content: result.content, weight, agents: [result.agentId] });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
let best = { content: '', weight: 0, agents: [] };
|
|
297
|
+
for (const vote of votes.values()) {
|
|
298
|
+
if (vote.weight > best.weight) {
|
|
299
|
+
best = vote;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return best.content;
|
|
303
|
+
},
|
|
304
|
+
aggregateFull: (results) => {
|
|
305
|
+
const successful = results.filter((r) => r.success);
|
|
306
|
+
const votes = new Map();
|
|
307
|
+
for (const result of successful) {
|
|
308
|
+
const weight = weights[result.agentId] ?? 1;
|
|
309
|
+
const key = result.content.trim().toLowerCase().substring(0, 100);
|
|
310
|
+
const existing = votes.get(key);
|
|
311
|
+
if (existing) {
|
|
312
|
+
existing.weight += weight;
|
|
313
|
+
existing.agents.push(result.agentId);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
votes.set(key, { content: result.content, weight, agents: [result.agentId] });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
let best = { content: '', weight: 0, agents: [] };
|
|
320
|
+
for (const vote of votes.values()) {
|
|
321
|
+
if (vote.weight > best.weight) {
|
|
322
|
+
best = vote;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
output: best.content,
|
|
327
|
+
metadata: {
|
|
328
|
+
successCount: successful.length,
|
|
329
|
+
failedCount: results.length - successful.length,
|
|
330
|
+
strategy: 'weightedVote',
|
|
331
|
+
winningWeight: best.weight,
|
|
332
|
+
winningAgents: best.agents,
|
|
333
|
+
totalGroups: votes.size,
|
|
334
|
+
},
|
|
335
|
+
contributions: results.map((r) => ({
|
|
336
|
+
agentId: r.agentId,
|
|
337
|
+
weight: weights[r.agentId] ?? 1,
|
|
338
|
+
included: best.agents.includes(r.agentId),
|
|
339
|
+
})),
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
}),
|
|
343
|
+
majority: () => ({
|
|
344
|
+
name: 'majority',
|
|
345
|
+
description: 'Selects the most common response (simple majority)',
|
|
346
|
+
aggregate: (results) => {
|
|
347
|
+
const successful = results.filter((r) => r.success);
|
|
348
|
+
if (successful.length === 0)
|
|
349
|
+
return '';
|
|
350
|
+
const votes = new Map();
|
|
351
|
+
for (const result of successful) {
|
|
352
|
+
const key = result.content.trim().toLowerCase().substring(0, 200);
|
|
353
|
+
votes.set(key, (votes.get(key) ?? 0) + 1);
|
|
354
|
+
}
|
|
355
|
+
let maxVotes = 0;
|
|
356
|
+
let winner = '';
|
|
357
|
+
for (const [content, count] of votes) {
|
|
358
|
+
if (count > maxVotes) {
|
|
359
|
+
maxVotes = count;
|
|
360
|
+
winner = content;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return successful.find((r) => r.content.trim().toLowerCase().substring(0, 200) === winner)?.content ?? '';
|
|
364
|
+
},
|
|
365
|
+
aggregateFull: (results) => {
|
|
366
|
+
const successful = results.filter((r) => r.success);
|
|
367
|
+
const votes = new Map();
|
|
368
|
+
for (const result of successful) {
|
|
369
|
+
const key = result.content.trim().toLowerCase().substring(0, 200);
|
|
370
|
+
const existing = votes.get(key);
|
|
371
|
+
if (existing) {
|
|
372
|
+
existing.count++;
|
|
373
|
+
existing.agents.push(result.agentId);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
votes.set(key, { count: 1, original: result.content, agents: [result.agentId] });
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
let maxVotes = 0;
|
|
380
|
+
let winner = { count: 0, original: '', agents: [] };
|
|
381
|
+
for (const vote of votes.values()) {
|
|
382
|
+
if (vote.count > maxVotes) {
|
|
383
|
+
maxVotes = vote.count;
|
|
384
|
+
winner = vote;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
output: winner.original,
|
|
389
|
+
metadata: {
|
|
390
|
+
successCount: successful.length,
|
|
391
|
+
failedCount: results.length - successful.length,
|
|
392
|
+
strategy: 'majority',
|
|
393
|
+
winningVotes: winner.count,
|
|
394
|
+
totalVotes: successful.length,
|
|
395
|
+
uniqueResponses: votes.size,
|
|
396
|
+
},
|
|
397
|
+
contributions: results.map((r) => ({
|
|
398
|
+
agentId: r.agentId,
|
|
399
|
+
included: winner.agents.includes(r.agentId),
|
|
400
|
+
})),
|
|
401
|
+
};
|
|
402
|
+
},
|
|
403
|
+
}),
|
|
404
|
+
consensus: (threshold = 0.5) => ({
|
|
405
|
+
name: 'consensus',
|
|
406
|
+
description: `Requires ${threshold * 100}% agreement for consensus`,
|
|
407
|
+
aggregate: (results) => {
|
|
408
|
+
const successful = results.filter((r) => r.success);
|
|
409
|
+
if (successful.length === 0)
|
|
410
|
+
return '';
|
|
411
|
+
const votes = new Map();
|
|
412
|
+
for (const result of successful) {
|
|
413
|
+
const key = result.content.trim().toLowerCase().substring(0, 200);
|
|
414
|
+
votes.set(key, (votes.get(key) ?? 0) + 1);
|
|
415
|
+
}
|
|
416
|
+
for (const [content, count] of votes) {
|
|
417
|
+
if (count / successful.length >= threshold) {
|
|
418
|
+
return successful.find((r) => r.content.trim().toLowerCase().substring(0, 200) === content)?.content ?? '';
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return '';
|
|
422
|
+
},
|
|
423
|
+
aggregateFull: (results) => {
|
|
424
|
+
const successful = results.filter((r) => r.success);
|
|
425
|
+
const votes = new Map();
|
|
426
|
+
for (const result of successful) {
|
|
427
|
+
const key = result.content.trim().toLowerCase().substring(0, 200);
|
|
428
|
+
const existing = votes.get(key);
|
|
429
|
+
if (existing) {
|
|
430
|
+
existing.count++;
|
|
431
|
+
existing.agents.push(result.agentId);
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
votes.set(key, { count: 1, original: result.content, agents: [result.agentId] });
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
let consensus = { count: 0, original: '', agents: [], achieved: false };
|
|
438
|
+
for (const vote of votes.values()) {
|
|
439
|
+
if (vote.count / successful.length >= threshold && vote.count > consensus.count) {
|
|
440
|
+
consensus = { ...vote, achieved: true };
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
output: consensus.original,
|
|
445
|
+
metadata: {
|
|
446
|
+
successCount: successful.length,
|
|
447
|
+
failedCount: results.length - successful.length,
|
|
448
|
+
strategy: 'consensus',
|
|
449
|
+
threshold,
|
|
450
|
+
consensusAchieved: consensus.achieved,
|
|
451
|
+
agreementLevel: successful.length > 0 ? consensus.count / successful.length : 0,
|
|
452
|
+
},
|
|
453
|
+
contributions: results.map((r) => ({
|
|
454
|
+
agentId: r.agentId,
|
|
455
|
+
included: consensus.agents.includes(r.agentId),
|
|
456
|
+
})),
|
|
457
|
+
};
|
|
458
|
+
},
|
|
459
|
+
}),
|
|
460
|
+
format: (style = 'markdown') => ({
|
|
461
|
+
name: `format-${style}`,
|
|
462
|
+
description: `Formats results as ${style}`,
|
|
463
|
+
aggregate: (results) => {
|
|
464
|
+
const successful = results.filter((r) => r.success);
|
|
465
|
+
switch (style) {
|
|
466
|
+
case 'json':
|
|
467
|
+
return JSON.stringify(successful.map((r) => ({ agent: r.agentId, content: r.content })), null, 2);
|
|
468
|
+
case 'list':
|
|
469
|
+
return successful.map((r) => `- ${r.content}`).join('\n');
|
|
470
|
+
case 'numbered':
|
|
471
|
+
return successful.map((r, i) => `${i + 1}. ${r.content}`).join('\n');
|
|
472
|
+
case 'table': {
|
|
473
|
+
const header = '| Agent | Response |\n|-------|----------|';
|
|
474
|
+
const rows = successful.map((r) => `| ${r.agentId} | ${r.content.replace(/\n/g, ' ').substring(0, 100)} |`);
|
|
475
|
+
return [header, ...rows].join('\n');
|
|
476
|
+
}
|
|
477
|
+
case 'markdown':
|
|
478
|
+
default:
|
|
479
|
+
return successful.map((r) => `## ${r.agentId}\n\n${r.content}`).join('\n\n---\n\n');
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
aggregateFull: (results) => {
|
|
483
|
+
const successful = results.filter((r) => r.success);
|
|
484
|
+
return {
|
|
485
|
+
output: exports.Strategies.format(style).aggregate(results),
|
|
486
|
+
metadata: {
|
|
487
|
+
successCount: successful.length,
|
|
488
|
+
failedCount: results.length - successful.length,
|
|
489
|
+
strategy: `format-${style}`,
|
|
490
|
+
style,
|
|
491
|
+
},
|
|
492
|
+
contributions: results.map((r) => ({
|
|
493
|
+
agentId: r.agentId,
|
|
494
|
+
included: r.success,
|
|
495
|
+
})),
|
|
496
|
+
};
|
|
497
|
+
},
|
|
498
|
+
}),
|
|
499
|
+
reduce: (reducer, initial, finalize) => ({
|
|
500
|
+
name: 'reduce',
|
|
501
|
+
description: 'Custom reduction of results',
|
|
502
|
+
aggregate: (results) => {
|
|
503
|
+
const successful = results.filter((r) => r.success);
|
|
504
|
+
const accumulated = successful.reduce(reducer, initial);
|
|
505
|
+
return finalize(accumulated);
|
|
506
|
+
},
|
|
507
|
+
aggregateFull: (results) => {
|
|
508
|
+
const successful = results.filter((r) => r.success);
|
|
509
|
+
const accumulated = successful.reduce(reducer, initial);
|
|
510
|
+
return {
|
|
511
|
+
output: finalize(accumulated),
|
|
512
|
+
metadata: {
|
|
513
|
+
successCount: successful.length,
|
|
514
|
+
failedCount: results.length - successful.length,
|
|
515
|
+
strategy: 'reduce',
|
|
516
|
+
},
|
|
517
|
+
contributions: results.map((r) => ({
|
|
518
|
+
agentId: r.agentId,
|
|
519
|
+
included: r.success,
|
|
520
|
+
})),
|
|
521
|
+
};
|
|
522
|
+
},
|
|
523
|
+
}),
|
|
524
|
+
mapReduce: (mapper, reducer, initial, finalize) => ({
|
|
525
|
+
name: 'mapReduce',
|
|
526
|
+
description: 'Map-reduce pattern for result aggregation',
|
|
527
|
+
aggregate: (results) => {
|
|
528
|
+
const successful = results.filter((r) => r.success);
|
|
529
|
+
const mapped = successful.map(mapper);
|
|
530
|
+
const reduced = mapped.reduce(reducer, initial);
|
|
531
|
+
return finalize(reduced);
|
|
532
|
+
},
|
|
533
|
+
aggregateFull: (results) => {
|
|
534
|
+
const successful = results.filter((r) => r.success);
|
|
535
|
+
const mapped = successful.map(mapper);
|
|
536
|
+
const reduced = mapped.reduce(reducer, initial);
|
|
537
|
+
return {
|
|
538
|
+
output: finalize(reduced),
|
|
539
|
+
metadata: {
|
|
540
|
+
successCount: successful.length,
|
|
541
|
+
failedCount: results.length - successful.length,
|
|
542
|
+
strategy: 'mapReduce',
|
|
543
|
+
},
|
|
544
|
+
contributions: results.map((r) => ({
|
|
545
|
+
agentId: r.agentId,
|
|
546
|
+
included: r.success,
|
|
547
|
+
})),
|
|
548
|
+
};
|
|
549
|
+
},
|
|
550
|
+
}),
|
|
551
|
+
filter: (predicate) => ({
|
|
552
|
+
name: 'filter',
|
|
553
|
+
description: 'Filters results before aggregation',
|
|
554
|
+
aggregate: (results) => {
|
|
555
|
+
return results
|
|
556
|
+
.filter(predicate)
|
|
557
|
+
.map((r) => r.content)
|
|
558
|
+
.join('\n\n');
|
|
559
|
+
},
|
|
560
|
+
aggregateFull: (results) => {
|
|
561
|
+
const filtered = results.filter(predicate);
|
|
562
|
+
return {
|
|
563
|
+
output: filtered.map((r) => r.content).join('\n\n'),
|
|
564
|
+
metadata: {
|
|
565
|
+
successCount: filtered.length,
|
|
566
|
+
failedCount: results.length - filtered.length,
|
|
567
|
+
strategy: 'filter',
|
|
568
|
+
originalCount: results.length,
|
|
569
|
+
filteredCount: filtered.length,
|
|
570
|
+
},
|
|
571
|
+
contributions: results.map((r) => ({
|
|
572
|
+
agentId: r.agentId,
|
|
573
|
+
included: predicate(r),
|
|
574
|
+
})),
|
|
575
|
+
};
|
|
576
|
+
},
|
|
577
|
+
}),
|
|
578
|
+
compose: (...strategies) => ({
|
|
579
|
+
name: 'composed',
|
|
580
|
+
description: `Composed strategy: ${strategies.map((s) => s.name).join(' → ')}`,
|
|
581
|
+
aggregate: (results) => {
|
|
582
|
+
const currentResults = results;
|
|
583
|
+
let finalOutput = '';
|
|
584
|
+
for (const strategy of strategies) {
|
|
585
|
+
finalOutput = strategy.aggregate(currentResults);
|
|
586
|
+
}
|
|
587
|
+
return finalOutput;
|
|
588
|
+
},
|
|
589
|
+
aggregateFull: (results) => {
|
|
590
|
+
let finalOutput = '';
|
|
591
|
+
const allMetadata = [];
|
|
592
|
+
for (const strategy of strategies) {
|
|
593
|
+
const result = strategy.aggregateFull(results);
|
|
594
|
+
finalOutput = result.output;
|
|
595
|
+
allMetadata.push(result.metadata);
|
|
596
|
+
}
|
|
597
|
+
return {
|
|
598
|
+
output: finalOutput,
|
|
599
|
+
metadata: {
|
|
600
|
+
successCount: results.filter((r) => r.success).length,
|
|
601
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
602
|
+
strategy: 'composed',
|
|
603
|
+
composedStrategies: strategies.map((s) => s.name),
|
|
604
|
+
stepMetadata: allMetadata,
|
|
605
|
+
},
|
|
606
|
+
};
|
|
607
|
+
},
|
|
608
|
+
}),
|
|
609
|
+
fallback: (primary, backup) => ({
|
|
610
|
+
name: 'fallback',
|
|
611
|
+
description: `${primary.name} with fallback to ${backup.name}`,
|
|
612
|
+
aggregate: (results) => {
|
|
613
|
+
const primaryResult = primary.aggregate(results);
|
|
614
|
+
if (primaryResult && primaryResult.trim() !== '') {
|
|
615
|
+
return primaryResult;
|
|
616
|
+
}
|
|
617
|
+
return backup.aggregate(results);
|
|
618
|
+
},
|
|
619
|
+
aggregateFull: (results) => {
|
|
620
|
+
const primaryResult = primary.aggregateFull(results);
|
|
621
|
+
if (primaryResult.output && primaryResult.output.trim() !== '') {
|
|
622
|
+
return {
|
|
623
|
+
...primaryResult,
|
|
624
|
+
metadata: {
|
|
625
|
+
...primaryResult.metadata,
|
|
626
|
+
usedFallback: false,
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
const backupResult = backup.aggregateFull(results);
|
|
631
|
+
return {
|
|
632
|
+
...backupResult,
|
|
633
|
+
metadata: {
|
|
634
|
+
...backupResult.metadata,
|
|
635
|
+
usedFallback: true,
|
|
636
|
+
primaryStrategy: primary.name,
|
|
637
|
+
backupStrategy: backup.name,
|
|
638
|
+
},
|
|
639
|
+
};
|
|
640
|
+
},
|
|
641
|
+
}),
|
|
642
|
+
};
|
|
643
|
+
function createStrategy(name, aggregator, description) {
|
|
644
|
+
return StrategyBuilder.create()
|
|
645
|
+
.withName(name)
|
|
646
|
+
.withDescription(description ?? name)
|
|
647
|
+
.withAggregator(aggregator)
|
|
648
|
+
.build();
|
|
649
|
+
}
|
|
650
|
+
function chainStrategies(...strategies) {
|
|
651
|
+
return (results) => {
|
|
652
|
+
return exports.Strategies.compose(...strategies).aggregate(results);
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
function parallelStrategies(strategies, merger = (outputs) => outputs.join('\n\n')) {
|
|
656
|
+
return {
|
|
657
|
+
name: 'parallel',
|
|
658
|
+
description: `Parallel execution of: ${strategies.map((s) => s.name).join(', ')}`,
|
|
659
|
+
aggregate: (results) => {
|
|
660
|
+
const outputs = strategies.map((s) => s.aggregate(results));
|
|
661
|
+
return merger(outputs);
|
|
662
|
+
},
|
|
663
|
+
aggregateFull: (results) => {
|
|
664
|
+
const outputs = strategies.map((s) => s.aggregateFull(results));
|
|
665
|
+
return {
|
|
666
|
+
output: merger(outputs.map((o) => o.output)),
|
|
667
|
+
metadata: {
|
|
668
|
+
successCount: results.filter((r) => r.success).length,
|
|
669
|
+
failedCount: results.filter((r) => !r.success).length,
|
|
670
|
+
strategy: 'parallel',
|
|
671
|
+
parallelStrategies: strategies.map((s) => s.name),
|
|
672
|
+
parallelResults: outputs.map((o) => o.metadata),
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
//# sourceMappingURL=strategies.js.map
|