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.
Files changed (114) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/LICENSE +21 -0
  3. package/README.md +879 -0
  4. package/dist/builder.d.ts +181 -0
  5. package/dist/builder.d.ts.map +1 -0
  6. package/dist/builder.js +667 -0
  7. package/dist/builder.js.map +1 -0
  8. package/dist/config.d.ts +43 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +11 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/context.d.ts +107 -0
  13. package/dist/context.d.ts.map +1 -0
  14. package/dist/context.js +319 -0
  15. package/dist/context.js.map +1 -0
  16. package/dist/errors.d.ts +31 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +85 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/events.d.ts +219 -0
  21. package/dist/events.d.ts.map +1 -0
  22. package/dist/events.js +395 -0
  23. package/dist/events.js.map +1 -0
  24. package/dist/graph.d.ts +104 -0
  25. package/dist/graph.d.ts.map +1 -0
  26. package/dist/graph.js +366 -0
  27. package/dist/graph.js.map +1 -0
  28. package/dist/index.d.ts +28 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +113 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/logger.d.ts +13 -0
  33. package/dist/logger.d.ts.map +1 -0
  34. package/dist/logger.js +78 -0
  35. package/dist/logger.js.map +1 -0
  36. package/dist/memory.d.ts +146 -0
  37. package/dist/memory.d.ts.map +1 -0
  38. package/dist/memory.js +353 -0
  39. package/dist/memory.js.map +1 -0
  40. package/dist/metrics.d.ts +143 -0
  41. package/dist/metrics.d.ts.map +1 -0
  42. package/dist/metrics.js +271 -0
  43. package/dist/metrics.js.map +1 -0
  44. package/dist/middleware.d.ts +147 -0
  45. package/dist/middleware.d.ts.map +1 -0
  46. package/dist/middleware.js +484 -0
  47. package/dist/middleware.js.map +1 -0
  48. package/dist/models.d.ts +32 -0
  49. package/dist/models.d.ts.map +1 -0
  50. package/dist/models.js +211 -0
  51. package/dist/models.js.map +1 -0
  52. package/dist/patterns.d.ts +6 -0
  53. package/dist/patterns.d.ts.map +1 -0
  54. package/dist/patterns.js +68 -0
  55. package/dist/patterns.js.map +1 -0
  56. package/dist/pipeline.d.ts +84 -0
  57. package/dist/pipeline.d.ts.map +1 -0
  58. package/dist/pipeline.js +569 -0
  59. package/dist/pipeline.js.map +1 -0
  60. package/dist/retry.d.ts +5 -0
  61. package/dist/retry.d.ts.map +1 -0
  62. package/dist/retry.js +70 -0
  63. package/dist/retry.js.map +1 -0
  64. package/dist/society.d.ts +94 -0
  65. package/dist/society.d.ts.map +1 -0
  66. package/dist/society.js +721 -0
  67. package/dist/society.js.map +1 -0
  68. package/dist/strategies.d.ts +55 -0
  69. package/dist/strategies.d.ts.map +1 -0
  70. package/dist/strategies.js +678 -0
  71. package/dist/strategies.js.map +1 -0
  72. package/dist/tools.d.ts +88 -0
  73. package/dist/tools.d.ts.map +1 -0
  74. package/dist/tools.js +366 -0
  75. package/dist/tools.js.map +1 -0
  76. package/dist/types.d.ts +213 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +19 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/validation.d.ts +64 -0
  81. package/dist/validation.d.ts.map +1 -0
  82. package/dist/validation.js +334 -0
  83. package/dist/validation.js.map +1 -0
  84. package/dist/worker-pool.d.ts +17 -0
  85. package/dist/worker-pool.d.ts.map +1 -0
  86. package/dist/worker-pool.js +80 -0
  87. package/dist/worker-pool.js.map +1 -0
  88. package/docs/README.md +468 -0
  89. package/docs/advanced.md +616 -0
  90. package/docs/aggregation-strategies.md +926 -0
  91. package/docs/api-reference.md +771 -0
  92. package/docs/architecture.md +648 -0
  93. package/docs/context-system.md +642 -0
  94. package/docs/event-system.md +1047 -0
  95. package/docs/examples.md +576 -0
  96. package/docs/getting-started.md +564 -0
  97. package/docs/graph-execution.md +389 -0
  98. package/docs/memory-system.md +497 -0
  99. package/docs/metrics-observability.md +560 -0
  100. package/docs/middleware-system.md +1038 -0
  101. package/docs/migration.md +296 -0
  102. package/docs/pipeline-patterns.md +761 -0
  103. package/docs/structured-output.md +612 -0
  104. package/docs/tool-calling.md +491 -0
  105. package/docs/workflows.md +740 -0
  106. package/examples/README.md +234 -0
  107. package/examples/advanced-patterns.ts +115 -0
  108. package/examples/complete-integration.ts +327 -0
  109. package/examples/graph-workflow.ts +161 -0
  110. package/examples/memory-system.ts +155 -0
  111. package/examples/metrics-tracking.ts +243 -0
  112. package/examples/structured-output.ts +231 -0
  113. package/examples/tool-calling.ts +163 -0
  114. 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