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,389 @@
|
|
|
1
|
+
# Graph-Based Execution Engine
|
|
2
|
+
|
|
3
|
+
SocietyAI includes a powerful graph-based execution engine (`SocietyGraph`) that enables complex workflows with conditional branching, loops, and parallel execution.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `SocietyGraph` system provides:
|
|
8
|
+
|
|
9
|
+
- **DAG/Cyclic Support**: Both directed acyclic graphs (DAG) and cyclic graphs with loops
|
|
10
|
+
- **8 Node Types**: START, END, AGENT, PARALLEL, AGGREGATE, CONDITION, TRANSFORM, LOOP
|
|
11
|
+
- **Conditional Branching**: Dynamic routing based on runtime conditions
|
|
12
|
+
- **Loop Support**: Iteration with termination conditions
|
|
13
|
+
- **Parallel Execution**: Optimized concurrent agent execution
|
|
14
|
+
- **Graph Visualization**: Built-in visualization for debugging
|
|
15
|
+
|
|
16
|
+
## Node Types
|
|
17
|
+
|
|
18
|
+
### START
|
|
19
|
+
|
|
20
|
+
Entry point of the graph execution. Every graph must have at least one START node.
|
|
21
|
+
|
|
22
|
+
### END
|
|
23
|
+
|
|
24
|
+
Exit point of the graph. Execution completes when an END node is reached.
|
|
25
|
+
|
|
26
|
+
### AGENT
|
|
27
|
+
|
|
28
|
+
Executes a single agent with a specific role and model.
|
|
29
|
+
|
|
30
|
+
**Properties:**
|
|
31
|
+
|
|
32
|
+
- `agentId`: ID of the agent to execute
|
|
33
|
+
|
|
34
|
+
### PARALLEL
|
|
35
|
+
|
|
36
|
+
Executes multiple agents simultaneously.
|
|
37
|
+
|
|
38
|
+
**Properties:**
|
|
39
|
+
|
|
40
|
+
- `agentIds`: Array of agent IDs to execute in parallel
|
|
41
|
+
|
|
42
|
+
### AGGREGATE
|
|
43
|
+
|
|
44
|
+
Combines results from multiple previous nodes.
|
|
45
|
+
|
|
46
|
+
**Properties:**
|
|
47
|
+
|
|
48
|
+
- `aggregator`: Function that combines multiple results into one
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
aggregator: (results: GraphStepResult[]) => string;
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### CONDITION
|
|
55
|
+
|
|
56
|
+
Conditional branching based on the current result.
|
|
57
|
+
|
|
58
|
+
**Properties:**
|
|
59
|
+
|
|
60
|
+
- `condition`: Function that returns true/false for routing
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
condition: (result: string, context: GraphContext) => boolean;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Edges:**
|
|
67
|
+
|
|
68
|
+
- Must have edges labeled 'true' and 'false'
|
|
69
|
+
|
|
70
|
+
### TRANSFORM
|
|
71
|
+
|
|
72
|
+
Transforms the current result without calling an agent.
|
|
73
|
+
|
|
74
|
+
**Properties:**
|
|
75
|
+
|
|
76
|
+
- `transformer`: Function that transforms the result
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
transformer: (result: string, context: GraphContext) => string;
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### LOOP
|
|
83
|
+
|
|
84
|
+
Loop control with iteration tracking and termination condition.
|
|
85
|
+
|
|
86
|
+
**Properties:**
|
|
87
|
+
|
|
88
|
+
- `loopCondition`: Function that determines if loop should continue
|
|
89
|
+
- `maxIterations`: Maximum number of loop iterations (safety limit)
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
loopCondition: (iteration: number, result: string, context: GraphContext) => boolean;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Basic Example
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import { GraphBuilder, NodeType, AgentBuilder, RoleBuilder } from 'societyai';
|
|
99
|
+
|
|
100
|
+
// Define agent roles
|
|
101
|
+
const analyzerRole = RoleBuilder.create()
|
|
102
|
+
.withId('analyzer')
|
|
103
|
+
.withName('Analyzer')
|
|
104
|
+
.withSystemPrompt('You analyze code and identify issues.')
|
|
105
|
+
.build();
|
|
106
|
+
|
|
107
|
+
const fixerRole = RoleBuilder.create()
|
|
108
|
+
.withId('fixer')
|
|
109
|
+
.withName('Fixer')
|
|
110
|
+
.withSystemPrompt('You fix identified issues.')
|
|
111
|
+
.build();
|
|
112
|
+
|
|
113
|
+
// Create agents
|
|
114
|
+
const agents = [
|
|
115
|
+
AgentBuilder.create().withId('analyzer').withRole(analyzerRole).withModel(myModel).build(),
|
|
116
|
+
AgentBuilder.create().withId('fixer').withRole(fixerRole).withModel(myModel).build(),
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
// Build the graph
|
|
120
|
+
const graph = GraphBuilder.create()
|
|
121
|
+
.addNode('start', NodeType.START)
|
|
122
|
+
.addNode('analyze', NodeType.AGENT, { agentId: 'analyzer' })
|
|
123
|
+
.addNode('fix', NodeType.AGENT, { agentId: 'fixer' })
|
|
124
|
+
.addNode('end', NodeType.END)
|
|
125
|
+
.addEdge('start', 'analyze')
|
|
126
|
+
.addEdge('analyze', 'fix')
|
|
127
|
+
.addEdge('fix', 'end')
|
|
128
|
+
.build();
|
|
129
|
+
|
|
130
|
+
// Execute
|
|
131
|
+
const result = await graph.execute('Analyze and fix this code: ...', agents);
|
|
132
|
+
console.log(result.output);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Conditional Branching
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const graph = GraphBuilder.create()
|
|
139
|
+
.addNode('start', NodeType.START)
|
|
140
|
+
.addNode('validate', NodeType.AGENT, { agentId: 'validator' })
|
|
141
|
+
.addNode('check', NodeType.CONDITION, {
|
|
142
|
+
condition: (result) => result.includes('valid'),
|
|
143
|
+
})
|
|
144
|
+
.addNode('success', NodeType.END)
|
|
145
|
+
.addNode('retry', NodeType.AGENT, { agentId: 'fixer' })
|
|
146
|
+
.addEdge('start', 'validate')
|
|
147
|
+
.addEdge('validate', 'check')
|
|
148
|
+
.addEdge('check', 'success', { label: 'true' })
|
|
149
|
+
.addEdge('check', 'retry', { label: 'false' })
|
|
150
|
+
.addEdge('retry', 'validate') // Loop back
|
|
151
|
+
.build();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Parallel Execution
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const graph = GraphBuilder.create()
|
|
158
|
+
.addNode('start', NodeType.START)
|
|
159
|
+
.addNode('parallel', NodeType.PARALLEL, {
|
|
160
|
+
agentIds: ['analyst1', 'analyst2', 'analyst3'],
|
|
161
|
+
})
|
|
162
|
+
.addNode('aggregate', NodeType.AGGREGATE, {
|
|
163
|
+
aggregator: (results) => {
|
|
164
|
+
return results.map((r) => r.output).join('\n\n---\n\n');
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
.addNode('end', NodeType.END)
|
|
168
|
+
.addEdge('start', 'parallel')
|
|
169
|
+
.addEdge('parallel', 'aggregate')
|
|
170
|
+
.addEdge('aggregate', 'end')
|
|
171
|
+
.build();
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Loops with Termination
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
const graph = GraphBuilder.create()
|
|
178
|
+
.addNode('start', NodeType.START)
|
|
179
|
+
.addNode('process', NodeType.AGENT, { agentId: 'processor' })
|
|
180
|
+
.addNode('loop', NodeType.LOOP, {
|
|
181
|
+
loopCondition: (iteration, result, context) => {
|
|
182
|
+
// Continue if not complete and under 5 iterations
|
|
183
|
+
return !result.includes('COMPLETE') && iteration < 5;
|
|
184
|
+
},
|
|
185
|
+
maxIterations: 10, // Safety limit
|
|
186
|
+
})
|
|
187
|
+
.addNode('end', NodeType.END)
|
|
188
|
+
.addEdge('start', 'process')
|
|
189
|
+
.addEdge('process', 'loop')
|
|
190
|
+
.addEdge('loop', 'process') // Loop back
|
|
191
|
+
.addEdge('loop', 'end') // Exit when condition false
|
|
192
|
+
.build();
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Transform Nodes
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const graph = GraphBuilder.create()
|
|
199
|
+
.addNode('start', NodeType.START)
|
|
200
|
+
.addNode('agent', NodeType.AGENT, { agentId: 'writer' })
|
|
201
|
+
.addNode('uppercase', NodeType.TRANSFORM, {
|
|
202
|
+
transformer: (result) => result.toUpperCase(),
|
|
203
|
+
})
|
|
204
|
+
.addNode('end', NodeType.END)
|
|
205
|
+
.addEdge('start', 'agent')
|
|
206
|
+
.addEdge('agent', 'uppercase')
|
|
207
|
+
.addEdge('uppercase', 'end')
|
|
208
|
+
.build();
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Conditional Edges Helper
|
|
212
|
+
|
|
213
|
+
The `addConditionalEdge` method provides a shortcut for creating conditional branching:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const graph = GraphBuilder.create()
|
|
217
|
+
.addNode('start', NodeType.START)
|
|
218
|
+
.addNode('validate', NodeType.AGENT, { agentId: 'validator' })
|
|
219
|
+
.addNode('success', NodeType.END)
|
|
220
|
+
.addNode('fix', NodeType.AGENT, { agentId: 'fixer' })
|
|
221
|
+
.addEdge('start', 'validate')
|
|
222
|
+
.addConditionalEdge('validate', {
|
|
223
|
+
condition: (result) => result.includes('valid'),
|
|
224
|
+
truePath: 'success',
|
|
225
|
+
falsePath: 'fix',
|
|
226
|
+
})
|
|
227
|
+
.addEdge('fix', 'validate') // Loop back for retry
|
|
228
|
+
.build();
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Graph Context
|
|
232
|
+
|
|
233
|
+
The `GraphContext` object provides state during execution:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
interface GraphContext {
|
|
237
|
+
input: string; // Original input
|
|
238
|
+
currentResult: string; // Current result
|
|
239
|
+
nodeResults: Map<string, GraphStepResult>; // All results
|
|
240
|
+
sharedData: Map<string, unknown>; // Shared data between nodes
|
|
241
|
+
iterationCounts: Map<string, number>; // Loop iteration counts
|
|
242
|
+
executionPath: string[]; // Nodes executed
|
|
243
|
+
startTime: number; // Execution start time
|
|
244
|
+
signal?: AbortSignal; // Cancellation signal
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
You can access context in conditions, transformers, and aggregators:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
{
|
|
252
|
+
condition: (result, context) => {
|
|
253
|
+
const iterations = context.iterationCounts.get('myLoop') || 0;
|
|
254
|
+
return iterations < 3 && result.includes('continue');
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Graph Result
|
|
260
|
+
|
|
261
|
+
Execution returns a `GraphResult`:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
interface GraphResult {
|
|
265
|
+
output: string; // Final output
|
|
266
|
+
success: boolean; // Execution success
|
|
267
|
+
nodeResults: Map<string, GraphStepResult>; // All node results
|
|
268
|
+
executionPath: string[]; // Path taken
|
|
269
|
+
duration: number; // Total duration (ms)
|
|
270
|
+
errors?: Error[]; // Errors if any
|
|
271
|
+
metadata?: Record<string, unknown>; // Additional data
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Visualization
|
|
276
|
+
|
|
277
|
+
Debug your graph structure with the built-in visualizer:
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const graph = GraphBuilder.create()
|
|
281
|
+
// ... build graph ...
|
|
282
|
+
.build();
|
|
283
|
+
|
|
284
|
+
console.log(graph.visualize());
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Output example:
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
Graph Structure:
|
|
291
|
+
|
|
292
|
+
Nodes:
|
|
293
|
+
[start] START
|
|
294
|
+
[analyze] AGENT (analyzer)
|
|
295
|
+
[check] CONDITION
|
|
296
|
+
[fix] AGENT (fixer)
|
|
297
|
+
[end] END
|
|
298
|
+
|
|
299
|
+
Edges:
|
|
300
|
+
start -> analyze
|
|
301
|
+
analyze -> check
|
|
302
|
+
check -> end (true)
|
|
303
|
+
check -> fix (false)
|
|
304
|
+
fix -> analyze
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Best Practices
|
|
308
|
+
|
|
309
|
+
1. **Always have START and END nodes**: Every graph needs entry and exit points
|
|
310
|
+
2. **Validate graph structure**: The builder automatically validates cycles and connectivity
|
|
311
|
+
3. **Use meaningful node IDs**: Makes debugging easier
|
|
312
|
+
4. **Set max iterations on loops**: Prevents infinite loops
|
|
313
|
+
5. **Use TRANSFORM for simple operations**: No need to call an agent for string manipulation
|
|
314
|
+
6. **Leverage shared data**: Use `context.sharedData` to pass state between nodes
|
|
315
|
+
7. **Monitor execution path**: Check `result.executionPath` to understand the flow taken
|
|
316
|
+
|
|
317
|
+
## Error Handling
|
|
318
|
+
|
|
319
|
+
Errors in nodes are automatically caught and included in the result:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
const result = await graph.execute(input, agents);
|
|
323
|
+
|
|
324
|
+
if (!result.success) {
|
|
325
|
+
console.error('Graph execution failed');
|
|
326
|
+
console.error(result.errors);
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Cancellation
|
|
331
|
+
|
|
332
|
+
Support for cancellation via AbortSignal:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const controller = new AbortController();
|
|
336
|
+
|
|
337
|
+
// Start execution
|
|
338
|
+
const promise = graph.execute(input, agents, controller.signal);
|
|
339
|
+
|
|
340
|
+
// Cancel after 5 seconds
|
|
341
|
+
setTimeout(() => controller.abort(), 5000);
|
|
342
|
+
|
|
343
|
+
try {
|
|
344
|
+
const result = await promise;
|
|
345
|
+
} catch (error) {
|
|
346
|
+
console.log('Execution cancelled');
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Advanced: Custom Aggregators
|
|
351
|
+
|
|
352
|
+
Create sophisticated result aggregation:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
function consensusAggregator(threshold: number = 0.6) {
|
|
356
|
+
return (results: GraphStepResult[]) => {
|
|
357
|
+
// Count occurrences of each result
|
|
358
|
+
const counts = new Map<string, number>();
|
|
359
|
+
|
|
360
|
+
for (const result of results) {
|
|
361
|
+
const count = counts.get(result.output) || 0;
|
|
362
|
+
counts.set(result.output, count + 1);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Find consensus
|
|
366
|
+
for (const [output, count] of counts.entries()) {
|
|
367
|
+
if (count / results.length >= threshold) {
|
|
368
|
+
return output;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// No consensus, return majority
|
|
373
|
+
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1])[0][0];
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const graph = GraphBuilder.create()
|
|
378
|
+
.addNode('aggregate', NodeType.AGGREGATE, {
|
|
379
|
+
aggregator: consensusAggregator(0.7),
|
|
380
|
+
})
|
|
381
|
+
// ...
|
|
382
|
+
.build();
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Next Steps
|
|
386
|
+
|
|
387
|
+
- See [Tool Calling](./tool-calling.md) for integrating external functions
|
|
388
|
+
- See [Memory System](./memory-system.md) for context management
|
|
389
|
+
- See [Examples](./examples.md) for complete workflow examples
|