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,648 @@
|
|
|
1
|
+
# Architecture Overview
|
|
2
|
+
|
|
3
|
+
This document explains the core architecture, design principles, and key concepts of SocietyAI.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Design Philosophy](#design-philosophy)
|
|
8
|
+
- [Core Components](#core-components)
|
|
9
|
+
- [System Architecture](#system-architecture)
|
|
10
|
+
- [Data Flow](#data-flow)
|
|
11
|
+
- [Communication Model](#communication-model)
|
|
12
|
+
- [Execution Model](#execution-model)
|
|
13
|
+
|
|
14
|
+
## Design Philosophy
|
|
15
|
+
|
|
16
|
+
SocietyAI is built on several key principles:
|
|
17
|
+
|
|
18
|
+
### 1. **Composability**
|
|
19
|
+
|
|
20
|
+
Every component is designed to be composed with others. Roles, agents, and steps can be mixed and matched to create complex workflows.
|
|
21
|
+
|
|
22
|
+
### 2. **Configurability**
|
|
23
|
+
|
|
24
|
+
Nothing is hardcoded. Users define their own roles, behaviors, and workflows. The library provides the infrastructure, you provide the intelligence.
|
|
25
|
+
|
|
26
|
+
### 3. **Model Agnosticism**
|
|
27
|
+
|
|
28
|
+
SocietyAI doesn't depend on any specific AI provider. You bring your own AI model - OpenAI, Anthropic, Google, local models, or custom APIs.
|
|
29
|
+
|
|
30
|
+
### 4. **Type Safety**
|
|
31
|
+
|
|
32
|
+
Built with TypeScript, providing full type definitions and compile-time safety.
|
|
33
|
+
|
|
34
|
+
### 5. **Observability**
|
|
35
|
+
|
|
36
|
+
Every phase, agent action, and step is observable through hooks and observers.
|
|
37
|
+
|
|
38
|
+
## Core Components
|
|
39
|
+
|
|
40
|
+
### 1. AIModel Interface
|
|
41
|
+
|
|
42
|
+
The foundation of model integration. Any AI service can be wrapped in this interface:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
interface AIModel {
|
|
46
|
+
// Process a prompt and return a response
|
|
47
|
+
process(prompt: unknown, signal?: AbortSignal): Promise<string>;
|
|
48
|
+
|
|
49
|
+
// Return the model name
|
|
50
|
+
name(): string;
|
|
51
|
+
|
|
52
|
+
// Check if the model supports a prompt type
|
|
53
|
+
supportsPromptType(promptType: string): boolean;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**StandardModelBase** provides a convenient base class with built-in:
|
|
58
|
+
|
|
59
|
+
- Timeout handling
|
|
60
|
+
- Retry logic with exponential backoff
|
|
61
|
+
- Model adapters for different prompt formats
|
|
62
|
+
- Cancellation support via AbortSignal
|
|
63
|
+
|
|
64
|
+
### 2. AgentRole
|
|
65
|
+
|
|
66
|
+
Defines the behavior and identity of an agent:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface AgentRole {
|
|
70
|
+
id: string; // Unique identifier
|
|
71
|
+
name: string; // Display name
|
|
72
|
+
systemPrompt: string; // Instructions defining behavior
|
|
73
|
+
capabilities?: string[]; // What the agent can do
|
|
74
|
+
constraints?: string[]; // What the agent should not do
|
|
75
|
+
promptTemplate?: string; // Custom prompt formatting
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Example**:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
const analyst = {
|
|
83
|
+
id: 'data-analyst',
|
|
84
|
+
name: 'Data Analyst',
|
|
85
|
+
systemPrompt: 'You are a data analyst focused on statistical analysis.',
|
|
86
|
+
capabilities: ['data-analysis', 'statistics', 'visualization'],
|
|
87
|
+
constraints: ['Do not make subjective judgments'],
|
|
88
|
+
};
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 3. AgentConfig
|
|
92
|
+
|
|
93
|
+
Combines a role with a model to create a functional agent:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
interface AgentConfig {
|
|
97
|
+
id: string; // Unique agent ID
|
|
98
|
+
name?: string; // Optional display name
|
|
99
|
+
role: AgentRole; // The role this agent plays
|
|
100
|
+
model: AIModel; // The AI model it uses
|
|
101
|
+
canCommunicateWith?: string[]; // Which agents it can message
|
|
102
|
+
priority?: number; // Execution priority (higher = first)
|
|
103
|
+
initialContext?: Record<string, unknown>; // Starting data
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 4. WorkflowStep
|
|
108
|
+
|
|
109
|
+
Defines a single step in a workflow:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
interface WorkflowStep {
|
|
113
|
+
id: string;
|
|
114
|
+
name: string;
|
|
115
|
+
agentIds: string[]; // Which agents participate
|
|
116
|
+
executionType: WorkflowStepExecutionType;
|
|
117
|
+
instructions?: string; // Step-specific instructions
|
|
118
|
+
maxIterations?: number; // For collaborative steps
|
|
119
|
+
completionCondition?: Function; // When to stop iteration
|
|
120
|
+
resultTransformer?: Function; // Transform step results
|
|
121
|
+
condition?: Function; // Conditional execution
|
|
122
|
+
nextSteps?: string[]; // Possible next steps
|
|
123
|
+
nextStepResolver?: Function; // Dynamic step routing
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 5. WorkflowConfig
|
|
128
|
+
|
|
129
|
+
Orchestrates the entire multi-agent system:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface WorkflowConfig {
|
|
133
|
+
id: string;
|
|
134
|
+
name: string;
|
|
135
|
+
steps: WorkflowStep[]; // Ordered workflow steps
|
|
136
|
+
agents: AgentConfig[]; // All participating agents
|
|
137
|
+
entryStepId?: string; // Where to start
|
|
138
|
+
globalContext?: Record<string, unknown>; // Shared data
|
|
139
|
+
onBeforeStep?: Function; // Pre-step hook
|
|
140
|
+
onAfterStep?: Function; // Post-step hook
|
|
141
|
+
finalResultGenerator?: Function; // Custom output generation
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 6. WorkflowExecutor
|
|
146
|
+
|
|
147
|
+
Executes workflows and manages their lifecycle:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
interface WorkflowExecutor {
|
|
151
|
+
execute(workflow: WorkflowConfig, input: string, signal?: AbortSignal): Promise<WorkflowResult>;
|
|
152
|
+
|
|
153
|
+
executeStep(
|
|
154
|
+
step: WorkflowStep,
|
|
155
|
+
agents: Map<string, AgentConfig>,
|
|
156
|
+
context: WorkflowContext,
|
|
157
|
+
signal?: AbortSignal
|
|
158
|
+
): Promise<StepResult[]>;
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**DefaultWorkflowExecutor** provides the standard implementation with support for all execution types.
|
|
163
|
+
|
|
164
|
+
## System Architecture
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
168
|
+
│ User Application │
|
|
169
|
+
└───────────────────────────┬─────────────────────────────────────┘
|
|
170
|
+
│
|
|
171
|
+
┌───────────┴───────────┐
|
|
172
|
+
│ WorkflowConfig │
|
|
173
|
+
│ ┌─────────────────┐ │
|
|
174
|
+
│ │ AgentConfigs │ │
|
|
175
|
+
│ │ ┌────────────┐ │ │
|
|
176
|
+
│ │ │ Role │ │ │
|
|
177
|
+
│ │ │ Model │ │ │
|
|
178
|
+
│ │ └────────────┘ │ │
|
|
179
|
+
│ └─────────────────┘ │
|
|
180
|
+
│ ┌─────────────────┐ │
|
|
181
|
+
│ │ WorkflowSteps │ │
|
|
182
|
+
│ └─────────────────┘ │
|
|
183
|
+
└───────────┬───────────┘
|
|
184
|
+
│
|
|
185
|
+
┌───────────┴───────────────┐
|
|
186
|
+
│ DefaultWorkflowExecutor │
|
|
187
|
+
└───────────┬───────────────┘
|
|
188
|
+
│
|
|
189
|
+
┌───────────────┼───────────────┐
|
|
190
|
+
│ │ │
|
|
191
|
+
┌─────▼─────┐ ┌────▼────┐ ┌─────▼─────┐
|
|
192
|
+
│ Step 1 │ │ Step 2 │ │ Step 3 │
|
|
193
|
+
│(Sequential│ │(Parallel│ │(Collab.) │
|
|
194
|
+
└─────┬─────┘ └────┬────┘ └─────┬─────┘
|
|
195
|
+
│ │ │
|
|
196
|
+
┌─────▼─────┐ ┌────▼──────────┬───▼─────┐
|
|
197
|
+
│ Agent A │ │ Agent B │ Agent C │
|
|
198
|
+
└─────┬─────┘ └────┬──────────┴───┬─────┘
|
|
199
|
+
│ │ │
|
|
200
|
+
┌─────▼─────┐ ┌────▼────┐ ┌────▼────┐
|
|
201
|
+
│ AI Model │ │AI Model │ │AI Model │
|
|
202
|
+
│ (OpenAI) │ │(Claude) │ │(Gemini) │
|
|
203
|
+
└───────────┘ └─────────┘ └─────────┘
|
|
204
|
+
│ │ │
|
|
205
|
+
└──────────────┼───────────────┘
|
|
206
|
+
│
|
|
207
|
+
┌──────▼──────┐
|
|
208
|
+
│ MessageBus │
|
|
209
|
+
│ (Communication)
|
|
210
|
+
└─────────────┘
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Data Flow
|
|
214
|
+
|
|
215
|
+
### 1. Initialization Phase
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
User Code
|
|
219
|
+
│
|
|
220
|
+
├─► Create Roles (RoleBuilder)
|
|
221
|
+
├─► Create Models (StandardModelBase)
|
|
222
|
+
├─► Create Agents (AgentBuilder)
|
|
223
|
+
├─► Define Steps (StepBuilder)
|
|
224
|
+
└─► Build Workflow (WorkflowConfigBuilder)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 2. Execution Phase
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
Input String
|
|
231
|
+
│
|
|
232
|
+
▼
|
|
233
|
+
WorkflowExecutor.execute()
|
|
234
|
+
│
|
|
235
|
+
├─► Initialize WorkflowContext
|
|
236
|
+
│ ├─► sharedData (Map)
|
|
237
|
+
│ ├─► stepResults (Map)
|
|
238
|
+
│ ├─► messageHistory (Array)
|
|
239
|
+
│ └─► metadata (Object)
|
|
240
|
+
│
|
|
241
|
+
├─► For each WorkflowStep:
|
|
242
|
+
│ │
|
|
243
|
+
│ ├─► onBeforeStep hook (if defined)
|
|
244
|
+
│ │
|
|
245
|
+
│ ├─► Build prompts for agents
|
|
246
|
+
│ │ └─► Apply role systemPrompt
|
|
247
|
+
│ │ Apply step instructions
|
|
248
|
+
│ │ Inject context data
|
|
249
|
+
│ │ Replace template placeholders
|
|
250
|
+
│ │
|
|
251
|
+
│ ├─► Execute based on executionType:
|
|
252
|
+
│ │ ├─► Sequential: Run agents one by one
|
|
253
|
+
│ │ ├─► Parallel: Run all agents simultaneously
|
|
254
|
+
│ │ ├─► Collaborative: Iterate with message passing
|
|
255
|
+
│ │ └─► Conditional: Check condition first
|
|
256
|
+
│ │
|
|
257
|
+
│ ├─► Collect StepResults
|
|
258
|
+
│ │ ├─► agentId
|
|
259
|
+
│ │ ├─► stepId
|
|
260
|
+
│ │ ├─► content (AI response)
|
|
261
|
+
│ │ ├─► success/error
|
|
262
|
+
│ │ └─► timestamp
|
|
263
|
+
│ │
|
|
264
|
+
│ ├─► Store results in context.stepResults
|
|
265
|
+
│ │
|
|
266
|
+
│ ├─► Apply resultTransformer (if defined)
|
|
267
|
+
│ │
|
|
268
|
+
│ ├─► onAfterStep hook (if defined)
|
|
269
|
+
│ │
|
|
270
|
+
│ └─► Determine next step
|
|
271
|
+
│ ├─► nextStepResolver (dynamic)
|
|
272
|
+
│ ├─► nextSteps (predefined)
|
|
273
|
+
│ └─► Sequential (default)
|
|
274
|
+
│
|
|
275
|
+
└─► Generate final output
|
|
276
|
+
├─► finalResultGenerator (custom)
|
|
277
|
+
└─► generateDefaultOutput (default)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 3. Result Phase
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
WorkflowResult
|
|
284
|
+
├─► success: boolean
|
|
285
|
+
├─► output: string (final generated result)
|
|
286
|
+
├─► stepResults: Map<stepId, StepResult[]>
|
|
287
|
+
├─► messages: AgentMessage[] (all communications)
|
|
288
|
+
├─► duration: number (milliseconds)
|
|
289
|
+
└─► errors?: Error[] (if any failures)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Communication Model
|
|
293
|
+
|
|
294
|
+
### MessageBus
|
|
295
|
+
|
|
296
|
+
The MessageBus facilitates inter-agent communication:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
interface CommunicationChannel {
|
|
300
|
+
send(message: AgentMessage): Promise<void>;
|
|
301
|
+
subscribe(agentId: string, handler: Function): void;
|
|
302
|
+
unsubscribe(agentId: string): void;
|
|
303
|
+
getHistory(filter?: Filter): AgentMessage[];
|
|
304
|
+
clearHistory(): void;
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Message Structure
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
interface AgentMessage {
|
|
312
|
+
from: string; // Sender agent ID
|
|
313
|
+
to: string; // Recipient (or 'broadcast')
|
|
314
|
+
type: MessageType; // request/response/notification/data/feedback
|
|
315
|
+
content: string; // Message content
|
|
316
|
+
data?: Object; // Structured data
|
|
317
|
+
timestamp: number; // When sent
|
|
318
|
+
messageId: string; // Unique ID
|
|
319
|
+
replyTo?: string; // Parent message ID
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Communication Flow
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
Agent A MessageBus Agent B
|
|
327
|
+
│ │ │
|
|
328
|
+
├──send(message)───────►│ │
|
|
329
|
+
│ ├──notify──────────────►│
|
|
330
|
+
│ │ │
|
|
331
|
+
│ │◄────send(reply)──────┤
|
|
332
|
+
├──notify──────────────►│ │
|
|
333
|
+
│ │ │
|
|
334
|
+
└───getHistory()────────► │
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Execution Model
|
|
338
|
+
|
|
339
|
+
### Sequential Execution
|
|
340
|
+
|
|
341
|
+
Agents run one after another. Each agent can access previous results.
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
Agent 1 → Result 1
|
|
345
|
+
↓
|
|
346
|
+
Context Updated
|
|
347
|
+
↓
|
|
348
|
+
Agent 2 → Result 2
|
|
349
|
+
↓
|
|
350
|
+
Context Updated
|
|
351
|
+
↓
|
|
352
|
+
Agent 3 → Result 3
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Use cases**:
|
|
356
|
+
|
|
357
|
+
- Pipeline processing
|
|
358
|
+
- Dependent tasks
|
|
359
|
+
- Step-by-step refinement
|
|
360
|
+
|
|
361
|
+
### Parallel Execution
|
|
362
|
+
|
|
363
|
+
Multiple agents run simultaneously using a worker pool.
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
┌─ Agent 1 → Result 1 ─┐
|
|
367
|
+
│ │
|
|
368
|
+
Start ─┼─ Agent 2 → Result 2 ─┼─ Collect
|
|
369
|
+
│ │
|
|
370
|
+
└─ Agent 3 → Result 3 ─┘
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
**Use cases**:
|
|
374
|
+
|
|
375
|
+
- Independent analyses
|
|
376
|
+
- Speed optimization
|
|
377
|
+
- Multiple perspectives
|
|
378
|
+
|
|
379
|
+
### Collaborative Execution
|
|
380
|
+
|
|
381
|
+
Agents exchange messages across multiple iterations.
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
Iteration 1:
|
|
385
|
+
Agent 1 → broadcast message → All agents
|
|
386
|
+
Agent 2 → broadcast message → All agents
|
|
387
|
+
Agent 3 → broadcast message → All agents
|
|
388
|
+
|
|
389
|
+
Iteration 2:
|
|
390
|
+
Agent 1 → (considers previous messages) → broadcast
|
|
391
|
+
Agent 2 → (considers previous messages) → broadcast
|
|
392
|
+
Agent 3 → (considers previous messages) → broadcast
|
|
393
|
+
|
|
394
|
+
Iteration 3:
|
|
395
|
+
...continue until maxIterations or completionCondition...
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Use cases**:
|
|
399
|
+
|
|
400
|
+
- Discussions
|
|
401
|
+
- Consensus building
|
|
402
|
+
- Iterative refinement
|
|
403
|
+
- Brainstorming
|
|
404
|
+
|
|
405
|
+
### Conditional Execution
|
|
406
|
+
|
|
407
|
+
Steps execute only when conditions are met.
|
|
408
|
+
|
|
409
|
+
```
|
|
410
|
+
Previous Results
|
|
411
|
+
↓
|
|
412
|
+
Condition?
|
|
413
|
+
├─ true ──► Execute Step
|
|
414
|
+
└─ false ─► Skip Step
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Use cases**:
|
|
418
|
+
|
|
419
|
+
- Error handling
|
|
420
|
+
- Dynamic workflows
|
|
421
|
+
- Branching logic
|
|
422
|
+
- Optimization (skip unnecessary work)
|
|
423
|
+
|
|
424
|
+
## Context Management
|
|
425
|
+
|
|
426
|
+
### WorkflowContext
|
|
427
|
+
|
|
428
|
+
The context is mutable and shared across all steps:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
interface WorkflowContext {
|
|
432
|
+
input: string; // Original input
|
|
433
|
+
sharedData: Map<string, unknown>; // Shared mutable data
|
|
434
|
+
stepResults: Map<string, StepResult[]>; // All step results
|
|
435
|
+
messageHistory: AgentMessage[]; // All messages
|
|
436
|
+
metadata: Record<string, unknown>; // Extra metadata
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Data Sharing
|
|
441
|
+
|
|
442
|
+
**Between steps**:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// Step 1 stores data
|
|
446
|
+
context.sharedData.set('analysis', analysisResult);
|
|
447
|
+
|
|
448
|
+
// Step 2 retrieves it
|
|
449
|
+
const analysis = context.sharedData.get('analysis');
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Accessing previous results**:
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
const previousStep = context.stepResults.get('step-1');
|
|
456
|
+
previousStep.forEach((result) => {
|
|
457
|
+
console.log(result.agentId, result.content);
|
|
458
|
+
});
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Worker Pool
|
|
462
|
+
|
|
463
|
+
For parallel execution, SocietyAI uses a worker pool:
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
class WorkerPool {
|
|
467
|
+
constructor(maxWorkers: number, signal?: AbortSignal);
|
|
468
|
+
submit<T>(task: () => Promise<T>): Promise<T>;
|
|
469
|
+
waitAll(): Promise<void>;
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Features**:
|
|
474
|
+
|
|
475
|
+
- Concurrent task execution
|
|
476
|
+
- Automatic queue management
|
|
477
|
+
- Cancellation support
|
|
478
|
+
- Error propagation
|
|
479
|
+
|
|
480
|
+
## Retry Mechanism
|
|
481
|
+
|
|
482
|
+
Built-in exponential backoff for AI model failures:
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
interface RetryOptions {
|
|
486
|
+
maxRetries: number; // How many times to retry
|
|
487
|
+
initialBackoff: number; // Initial delay (ms)
|
|
488
|
+
maxBackoff: number; // Maximum delay (ms)
|
|
489
|
+
backoffFactor: number; // Multiplier per retry
|
|
490
|
+
jitter: boolean; // Add randomness to prevent thundering herd
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Retry Flow**:
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
Attempt 1 ──fail──► Wait 1s ──► Attempt 2
|
|
498
|
+
│
|
|
499
|
+
fail
|
|
500
|
+
▼
|
|
501
|
+
Wait 2s (backoff × 2)
|
|
502
|
+
│
|
|
503
|
+
▼
|
|
504
|
+
Attempt 3
|
|
505
|
+
│
|
|
506
|
+
fail
|
|
507
|
+
▼
|
|
508
|
+
Wait 4s (backoff × 4)
|
|
509
|
+
│
|
|
510
|
+
▼
|
|
511
|
+
Final attempt or throw
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Error Handling
|
|
515
|
+
|
|
516
|
+
### Error Types
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
SocietyError // Base error class
|
|
520
|
+
├─ ModelNotSupportedError
|
|
521
|
+
├─ ProcessingFailedError
|
|
522
|
+
├─ InvalidAgentCountError
|
|
523
|
+
├─ NoModelsSpecifiedError
|
|
524
|
+
├─ SynthesisModelRequiredError
|
|
525
|
+
├─ OperationCancelledError
|
|
526
|
+
├─ TimeoutError
|
|
527
|
+
└─ InvalidConfigurationError
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Error Propagation
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
Agent fails
|
|
534
|
+
├─► StepResult.success = false
|
|
535
|
+
├─► StepResult.error = Error
|
|
536
|
+
├─► Observer.onAgentError()
|
|
537
|
+
├─► Continue with other agents (parallel)
|
|
538
|
+
│ or stop (sequential, if critical)
|
|
539
|
+
└─► Collected in WorkflowResult.errors
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
## Observability
|
|
543
|
+
|
|
544
|
+
### Observer Pattern
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
interface SocietyObserver {
|
|
548
|
+
onSocietyStart(prompt: string, agentCount: number): void;
|
|
549
|
+
onAgentStart(agentId: number, modelName: string, prompt: unknown): void;
|
|
550
|
+
onAgentComplete(agentId: number, modelName: string, result: string): void;
|
|
551
|
+
onAgentError(agentId: number, modelName: string, error: Error): void;
|
|
552
|
+
onPhaseStart(phase: string): void;
|
|
553
|
+
onPhaseComplete(phase: string): void;
|
|
554
|
+
onSocietyComplete(finalResult: string): void;
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Logging
|
|
559
|
+
|
|
560
|
+
Built-in logger with configurable levels:
|
|
561
|
+
|
|
562
|
+
```typescript
|
|
563
|
+
enum LogLevel {
|
|
564
|
+
SILENT = 0, // No logs
|
|
565
|
+
ERROR = 1, // Only errors
|
|
566
|
+
INFO = 2, // Info + errors
|
|
567
|
+
DEBUG = 3, // All logs
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
import { setGlobalLogLevel, LogLevel } from 'societyai';
|
|
571
|
+
setGlobalLogLevel(LogLevel.DEBUG);
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
## Performance Considerations
|
|
575
|
+
|
|
576
|
+
### 1. Parallel Execution
|
|
577
|
+
|
|
578
|
+
Use parallel execution for independent tasks to reduce total execution time.
|
|
579
|
+
|
|
580
|
+
### 2. Worker Pool
|
|
581
|
+
|
|
582
|
+
The worker pool automatically manages concurrency based on the number of agents.
|
|
583
|
+
|
|
584
|
+
### 3. Timeouts
|
|
585
|
+
|
|
586
|
+
Set appropriate timeouts to prevent hanging on slow API calls:
|
|
587
|
+
|
|
588
|
+
```typescript
|
|
589
|
+
const model = new StandardModelBase(
|
|
590
|
+
{ timeout: 30000 }, // 30 seconds
|
|
591
|
+
processFunc
|
|
592
|
+
);
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### 4. Cancellation
|
|
596
|
+
|
|
597
|
+
Use AbortSignal to cancel long-running operations:
|
|
598
|
+
|
|
599
|
+
```typescript
|
|
600
|
+
const controller = new AbortController();
|
|
601
|
+
setTimeout(() => controller.abort(), 60000);
|
|
602
|
+
await executor.execute(workflow, input, controller.signal);
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### 5. Result Caching
|
|
606
|
+
|
|
607
|
+
Store expensive computation results in `context.sharedData` to avoid recomputation.
|
|
608
|
+
|
|
609
|
+
## Best Practices
|
|
610
|
+
|
|
611
|
+
### 1. Role Design
|
|
612
|
+
|
|
613
|
+
- Keep system prompts clear and specific
|
|
614
|
+
- Define concrete capabilities and constraints
|
|
615
|
+
- Use prompt templates for consistency
|
|
616
|
+
|
|
617
|
+
### 2. Agent Configuration
|
|
618
|
+
|
|
619
|
+
- Use meaningful IDs and names
|
|
620
|
+
- Set appropriate priorities for execution order
|
|
621
|
+
- Limit communication to necessary agents
|
|
622
|
+
|
|
623
|
+
### 3. Workflow Design
|
|
624
|
+
|
|
625
|
+
- Break complex tasks into smaller steps
|
|
626
|
+
- Use appropriate execution types
|
|
627
|
+
- Add completion conditions for collaborative steps
|
|
628
|
+
- Implement error handling in hooks
|
|
629
|
+
|
|
630
|
+
### 4. Performance
|
|
631
|
+
|
|
632
|
+
- Use parallel execution when possible
|
|
633
|
+
- Set reasonable timeouts
|
|
634
|
+
- Implement cancellation for long operations
|
|
635
|
+
- Consider result caching
|
|
636
|
+
|
|
637
|
+
### 5. Observability
|
|
638
|
+
|
|
639
|
+
- Implement observers for production systems
|
|
640
|
+
- Use appropriate log levels
|
|
641
|
+
- Monitor execution duration and errors
|
|
642
|
+
- Store message history for debugging
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
**Next**: [Workflow Patterns](./workflows.md) →
|
|
647
|
+
|
|
648
|
+
**Previous**: [Getting Started](./getting-started.md) ←
|