@evolvingmachines/evolve 0.0.55-project-sable.20260916.db0bc0bb → 0.0.56

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 (73) hide show
  1. package/dist/cli/index.cjs +32 -32
  2. package/dist/cli/index.js +27 -27
  3. package/package.json +4 -6
  4. package/skills/evolve/SKILL.md +4 -3
  5. package/skills/evolve-evals/SKILL.md +112 -0
  6. package/{docs-evals → skills/evolve-evals/references}/cli-reference/run.mdx +1 -1
  7. package/{docs-evals → skills/evolve-evals/references}/cli-reference/skills.mdx +4 -4
  8. package/{docs-evals → skills/evolve-evals/references}/core-concepts/agents.mdx +2 -2
  9. package/{docs-evals → skills/evolve-evals/references}/core-concepts/analyze.mdx +1 -1
  10. package/{docs-evals → skills/evolve-evals/references}/core-concepts/jobs.mdx +3 -3
  11. package/{docs-evals → skills/evolve-evals/references}/core-concepts/models.mdx +1 -1
  12. package/{docs-evals → skills/evolve-evals/references}/core-concepts/sandboxes.mdx +2 -2
  13. package/{docs-evals → skills/evolve-evals/references}/core-concepts/secrets.mdx +1 -1
  14. package/{docs-evals → skills/evolve-evals/references}/core-concepts/trial-outputs.mdx +1 -1
  15. package/{docs-evals → skills/evolve-evals/references}/getting-started/quick-start.mdx +1 -1
  16. package/{docs-evals → skills/evolve-evals/references}/index.mdx +1 -1
  17. package/{docs-evals → skills/evolve-evals/references}/sdk/python.mdx +1 -1
  18. package/{docs-evals → skills/evolve-evals/references}/sdk/typescript.mdx +1 -1
  19. package/{docs-evals → skills/evolve-evals/references}/sdk-reference/errors.mdx +2 -2
  20. package/{docs-evals → skills/evolve-evals/references}/sdk-reference/jobs.mdx +2 -2
  21. package/docs-agents/SKILL.md +0 -138
  22. package/docs-agents/index.md +0 -81
  23. package/docs-agents/python/01-getting-started.md +0 -511
  24. package/docs-agents/python/02-configuration.md +0 -855
  25. package/docs-agents/python/03-runtime.md +0 -899
  26. package/docs-agents/python/04-streaming.md +0 -451
  27. package/docs-agents/python/05-swarm-pipeline.md +0 -953
  28. package/docs-agents/python/index.md +0 -122
  29. package/docs-agents/typescript/01-getting-started.md +0 -494
  30. package/docs-agents/typescript/02-configuration.md +0 -841
  31. package/docs-agents/typescript/03-runtime.md +0 -864
  32. package/docs-agents/typescript/04-streaming.md +0 -478
  33. package/docs-agents/typescript/05-swarm-pipeline.md +0 -957
  34. package/docs-agents/typescript/index.md +0 -121
  35. package/docs-evals/SKILL.md +0 -112
  36. package/docs-evals/docs.json +0 -180
  37. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/agent.mdx +0 -0
  38. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/analysis.mdx +0 -0
  39. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/analyze.mdx +0 -0
  40. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/auth.mdx +0 -0
  41. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/check.mdx +0 -0
  42. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/dataset.mdx +0 -0
  43. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/index.mdx +0 -0
  44. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/job.mdx +0 -0
  45. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/secrets.mdx +0 -0
  46. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/skill.mdx +0 -0
  47. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/trial.mdx +0 -0
  48. /package/{docs-evals → skills/evolve-evals/references}/cli-reference/upload.mdx +0 -0
  49. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/check.mdx +0 -0
  50. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/datasets.mdx +0 -0
  51. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/index.mdx +0 -0
  52. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/skills.mdx +0 -0
  53. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/tasks.mdx +0 -0
  54. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/trials.mdx +0 -0
  55. /package/{docs-evals → skills/evolve-evals/references}/core-concepts/upload.mdx +0 -0
  56. /package/{docs-evals → skills/evolve-evals/references}/dashboard/checks.mdx +0 -0
  57. /package/{docs-evals → skills/evolve-evals/references}/dashboard/datasets.mdx +0 -0
  58. /package/{docs-evals → skills/evolve-evals/references}/dashboard/jobs.mdx +0 -0
  59. /package/{docs-evals → skills/evolve-evals/references}/dashboard/traces.mdx +0 -0
  60. /package/{docs-evals → skills/evolve-evals/references}/dashboard/trial-viewer.mdx +0 -0
  61. /package/{docs-evals → skills/evolve-evals/references}/getting-started/installation.mdx +0 -0
  62. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/agents.mdx +0 -0
  63. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/analyses.mdx +0 -0
  64. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/auth.mdx +0 -0
  65. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/checks.mdx +0 -0
  66. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/datasets.mdx +0 -0
  67. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/index.mdx +0 -0
  68. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/meta.mdx +0 -0
  69. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/skills.mdx +0 -0
  70. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/trials.mdx +0 -0
  71. /package/{docs-evals → skills/evolve-evals/references}/sdk-reference/types.mdx +0 -0
  72. /package/{docs-evals → skills/evolve-evals/references}/snippets/global-options.mdx +0 -0
  73. /package/{docs-evals → skills/evolve-evals/references}/snippets/list-flags.mdx +0 -0
@@ -1,957 +0,0 @@
1
- # Swarm & Pipeline
2
-
3
- Functional programming for AI agents: `map`, `filter`, `reduce`, `bestOf`, `verify`.
4
-
5
- ```ts
6
- import { Swarm } from "@evolvingmachines/evolve";
7
- import { z } from "zod"; // Or use plain JSON Schema objects instead
8
-
9
- const swarm = new Swarm({
10
- agent: { type: "claude" }, // Default agent for all operations
11
- skills: ["anthropics/skills"], // Default skills (skills.sh / git / local references)
12
- integrations: { // Default Integrations config for all workers
13
- userId: "root",
14
- apps: ["github", "linear"],
15
- },
16
- mcpServers: {...}, // Default MCP servers for all workers
17
- concurrency: 4, // Max parallel sandboxes (default: 4)
18
- timeoutMs: 3_600_000, // Default timeout per worker (default: 1 hour)
19
- tag: "my-pipeline", // Tag prefix for observability
20
- retry: { // Default retry config for all operations
21
- maxAttempts: 3,
22
- backoffMs: 1000,
23
- backoffMultiplier: 2,
24
- },
25
- });
26
- ```
27
-
28
- > **Defaults**: `agent`, `skills`, `integrations`, `mcpServers`, `timeoutMs`, and `retry` set here are inherited by all operations (`map`, `filter`, `reduce`, `bestOf`). Pass these options to individual operations to override.
29
-
30
- **SwarmConfig** — configuration for Swarm instance:
31
- ```ts
32
- {
33
- agent?: AgentConfig,
34
- sandbox?: SandboxProvider,
35
- skills?: string[],
36
- integrations?: IntegrationsSetup,
37
- mcpServers?: Record<string, McpServerConfig>,
38
- concurrency?: number,
39
- timeoutMs?: number,
40
- workspaceMode?: "knowledge" | "swe",
41
- tag?: string,
42
- retry?: RetryConfig,
43
- }
44
- ```
45
-
46
- | Option | Default | Notes |
47
- |--------|---------|-------|
48
- | `agent.type` | `'claude'` | Auto-resolved from env |
49
- | `agent.model` | per type | `'opus'` (claude), `'gpt-5.6-sol'` (codex), etc. |
50
- | `sandbox` | auto-resolved | Provider for every worker; falls back to env (`E2B_API_KEY`, `DAYTONA_API_KEY`, `MODAL_TOKEN_*`, `EVOLVE_API_KEY`) |
51
- | `skills` | `undefined` | Set here or per-operation |
52
- | `integrations` | `undefined` | Set here or per-operation |
53
- | `mcpServers` | `undefined` | Set here or per-operation |
54
- | `concurrency` | `4` | Max parallel sandboxes |
55
- | `timeoutMs` | `3_600_000` | 1 hour per worker |
56
- | `workspaceMode` | `'knowledge'` | `'knowledge'` or `'swe'`; `'task'` is not a Swarm mode (the type excludes it) |
57
- | `tag` | `'swarm'` | Observability prefix |
58
- | `retry` | `undefined` | Set here or per-operation |
59
-
60
- The `agent` here is the full `AgentConfig` — the same shape `.withAgent()` takes, so `apiKey`, `providerApiKey`, `oauthToken` and `maxContextSize` all belong on it. The narrower `AgentOverride` (type, model, reasoningEffort) is what individual operations take when they override this default; see [AgentOverride](#agentoverride).
61
-
62
- **Minimal setup** — with `EVOLVE_API_KEY` set (see [Authentication](./01-getting-started.md#authentication)):
63
-
64
- ```ts
65
- import "dotenv/config"; // If using .env file
66
- import { Swarm } from "@evolvingmachines/evolve";
67
-
68
- const swarm = new Swarm(); // Auto-resolves agent (claude) and sandbox from env
69
- ```
70
-
71
- **RetryConfig** — auto-retry on error with exponential backoff:
72
- ```ts
73
- {
74
- maxAttempts?: number,
75
- backoffMs?: number,
76
- backoffMultiplier?: number,
77
- retryOn?: (result) => boolean,
78
- onItemRetry?: (idx, attempt, error) => void,
79
- }
80
- ```
81
-
82
- ## Input Types
83
-
84
- Swarm runs in **knowledge mode** by default—files are uploaded to `context/` in the sandbox.
85
-
86
- **FileMap structure:**
87
-
88
- ```ts
89
- // FileMap: Record<path, content>
90
- // - path: string → file path in context/ folder
91
- // - content: string | Uint8Array → file content
92
-
93
- type FileMap = Record<string, string | Uint8Array>;
94
- ```
95
-
96
- ---
97
-
98
- **Case 1: One file per worker**
99
-
100
- ```ts
101
- // 3 workers, each gets 1 file
102
- const items: FileMap[] = [
103
- { "report.txt": "Q1 revenue..." }, // → Worker 0: context/report.txt
104
- { "report.txt": "Q2 revenue..." }, // → Worker 1: context/report.txt
105
- { "report.txt": "Q3 revenue..." }, // → Worker 2: context/report.txt
106
- ];
107
-
108
- const results = await swarm.map({
109
- items,
110
- prompt: "Summarize this report",
111
- });
112
- ```
113
-
114
- ---
115
-
116
- **Case 2: Multiple files per worker**
117
-
118
- ```ts
119
- // 3 workers, each gets 2 files
120
- const items: FileMap[] = [
121
- { // → Worker 0:
122
- "doc1.pdf": fs.readFileSync("./doc1.pdf"), // context/doc1.pdf
123
- "doc2.pdf": fs.readFileSync("./doc2.pdf"), // context/doc2.pdf
124
- },
125
- { // → Worker 1:
126
- "doc3.pdf": fs.readFileSync("./doc3.pdf"), // context/doc3.pdf
127
- "doc4.pdf": fs.readFileSync("./doc4.pdf"), // context/doc4.pdf
128
- },
129
- { // → Worker 2:
130
- "doc5.pdf": fs.readFileSync("./doc5.pdf"), // context/doc5.pdf
131
- "doc6.pdf": fs.readFileSync("./doc6.pdf"), // context/doc6.pdf
132
- },
133
- ];
134
-
135
- const results = await swarm.map({
136
- items,
137
- prompt: "Compare these two documents",
138
- });
139
- ```
140
-
141
- ---
142
-
143
- **Case 3: Entire folder per worker**
144
-
145
- ```ts
146
- import { readLocalDir } from "@evolvingmachines/evolve";
147
-
148
- // readLocalDir(path, recursive) → returns FileMap with all files
149
- const items: FileMap[] = [
150
- readLocalDir("./project-a", true), // → Worker 0: all files from project-a (recursive)
151
- readLocalDir("./project-b", true), // → Worker 1: all files from project-b (recursive)
152
- readLocalDir("./project-c", true), // → Worker 2: all files from project-c (recursive)
153
- ];
154
-
155
- const results = await swarm.map({
156
- items,
157
- prompt: "Review this codebase",
158
- });
159
- ```
160
-
161
- ## Abstractions
162
-
163
- Two types of operations:
164
-
165
- | Operation | Type | Description | Passes On |
166
- |-----------|------|-------------|-----------|
167
- | `bestOf` | transform + select | `input` → `output` (best of N candidates) | winner output |
168
- | `map` | transform | `input` → `output` (agent produces new data) | agent output |
169
- | `filter` | gate | `input` → `input` (agent evaluates, condition decides) | original input + status (`success` \| `filtered`) |
170
- | `reduce` | transform | `inputs` → `output` (agent synthesizes) | agent output |
171
-
172
- **Transforms** produce new output files. **Filter** passes through original input files unchanged.
173
-
174
- **BestOfConfig** — run N candidates in parallel, judge picks the best:
175
- ```ts
176
- {
177
- n?: number,
178
- judgeCriteria: string,
179
- taskAgents?: AgentOverride[],
180
- judgeAgent?: AgentOverride,
181
- skills?: string[],
182
- judgeSkills?: string[],
183
- integrations?: IntegrationsSetup,
184
- judgeIntegrations?: IntegrationsSetup,
185
- mcpServers?: Record<string, McpServerConfig>,
186
- judgeMcpServers?: Record<string, McpServerConfig>,
187
- onCandidateComplete?: (idx, candIdx, status) => void,
188
- onJudgeComplete?: (idx, winnerIdx, reasoning) => void,
189
- }
190
- ```
191
-
192
- **VerifyConfig** — LLM-as-judge verifies output, retries with feedback if failed:
193
- ```ts
194
- {
195
- criteria: string,
196
- maxAttempts?: number,
197
- verifierAgent?: AgentOverride,
198
- verifierSkills?: string[],
199
- verifierIntegrations?: IntegrationsSetup,
200
- verifierMcpServers?: Record<string, McpServerConfig>,
201
- onWorkerComplete?: (idx, attempt, status) => void,
202
- onVerifierComplete?: (idx, attempt, passed, feedback?) => void,
203
- }
204
- ```
205
-
206
- ### bestOf
207
-
208
- Run N agents on the same `item` in parallel, then a judge picks the best. `Agent[i]` outputs `candidates[i]`, judge selects `winner`.
209
-
210
- ```
211
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
212
- │ Sandbox 0 │ │ Sandbox 1 │ │ Sandbox 2 │
213
- │ Agent 0 │ │ Agent 1 │ │ Agent 2 │
214
- │ │ │ │ │ │
215
- │ context/ │ │ context/ │ │ context/ │
216
- │ item │ │ item │ │ item │
217
- │ output/ │ │ output/ │ │ output/ │
218
- │ candidates[0]│ │ candidates[1]│ │ candidates[2]│
219
- └───────┬─────────┘ └───────┬─────────┘ └───────┬─────────┘
220
- │ │ │
221
- └───────────────────┼───────────────────┘
222
-
223
- ┌───────────────┐
224
- │ Judge │
225
- └───────┬───────┘
226
-
227
-
228
- winner
229
- ```
230
-
231
- ```ts
232
- // Signature
233
- swarm.bestOf<T>({
234
- item: FileMap | SwarmResult,
235
- prompt: string,
236
- config: BestOfConfig, // { n?, judgeCriteria, taskAgents?, judgeAgent?, mcpServers?, judgeMcpServers?, skills?, judgeSkills?, integrations?, judgeIntegrations?, ... }
237
- name?: string, // Operation name for observability (appears in meta.operationName)
238
- schema?: z.ZodType<T> | JsonSchema,
239
- systemPrompt?: string,
240
- retry?: RetryConfig, // Per-candidate retry (judge uses default)
241
- timeoutMs?: number,
242
- }): Promise<BestOfResult<T>>
243
- ```
244
-
245
- ```ts
246
- const input = { "task.txt": "Complex problem..." };
247
-
248
- const result = await swarm.bestOf({
249
- item: input,
250
- prompt: "Solve this problem",
251
- config: {
252
- n: 3,
253
- judgeCriteria: "Most accurate and well-explained solution",
254
- onCandidateComplete: (idx, candIdx, status) => console.log(`Candidate ${candIdx}: ${status}`),
255
- onJudgeComplete: (idx, winnerIdx, reasoning) => console.log(`Winner: ${winnerIdx}`),
256
- },
257
- });
258
-
259
- console.log(result.winner); // Best SwarmResult
260
- console.log(result.winnerIndex); // 0, 1, or 2
261
- console.log(result.judgeReasoning); // Why this was chosen
262
- console.log(result.candidates); // All candidate results
263
- ```
264
-
265
- Use different agents per candidate:
266
-
267
- ```ts
268
- const claudeAgent = { type: "claude", model: "opus" };
269
- const codexAgent = { type: "codex", model: "gpt-5.3-codex" };
270
- const geminiAgent = { type: "gemini", model: "gemini-3.5-flash" };
271
-
272
- const result = await swarm.bestOf({
273
- item: input,
274
- prompt: "Solve this",
275
- config: {
276
- taskAgents: [claudeAgent, codexAgent, geminiAgent],
277
- judgeCriteria: "Best solution quality",
278
- judgeAgent: claudeAgent,
279
- mcpServers: {...}, // (optional) MCP servers for candidates
280
- judgeMcpServers: {...}, // (optional) MCP servers for judge
281
- skills: ["anthropics/skills"], // (optional) Skills for candidates
282
- judgeSkills: ["anthropics/skills"], // (optional) Skills for judge
283
- integrations: {...}, // (optional) Integrations config for candidates
284
- judgeIntegrations: {...}, // (optional) Integrations config for judge
285
- },
286
- });
287
- ```
288
-
289
- ### map
290
-
291
- Process items in parallel. `Agent[i]` sees `items[i]` and outputs `results[i]` (which includes `result.json` if `schema` provided).
292
-
293
- ```
294
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
295
- │ Sandbox 0 │ │ Sandbox 1 │ │ Sandbox 2 │
296
- │ Agent 0 │ │ Agent 1 │ │ Agent 2 │
297
- │ │ │ │ │ │
298
- │ context/ │ │ context/ │ │ context/ │
299
- │ items[0] │ │ items[1] │ │ items[2] │
300
- │ output/ │ │ output/ │ │ output/ │
301
- │ results[0] │ │ results[1] │ │ results[2] │
302
- └───────┬─────────┘ └───────┬─────────┘ └───────┬─────────┘
303
- │ │ │
304
- └───────────────────┼───────────────────┘
305
-
306
- [results[0], results[1], results[2]]
307
- ```
308
-
309
- ```ts
310
- // Signature (schema accepts Zod or JSON Schema object)
311
- swarm.map<T>({
312
- items: FileMap[] | SwarmResult[],
313
- prompt: string | ((files: FileMap, index: number) => string),
314
- name?: string, // Operation name for observability (appears in meta.operationName)
315
- schema?: z.ZodType<T> | JsonSchema,
316
- systemPrompt?: string,
317
- agent?: AgentOverride,
318
- bestOf?: BestOfConfig, // N candidates + judge (mutually exclusive with verify)
319
- verify?: VerifyConfig, // LLM-as-judge quality check with retry loop
320
- retry?: RetryConfig, // Auto-retry on error with backoff
321
- mcpServers?: Record<string, McpServerConfig>,
322
- skills?: string[], // e.g. ["anthropics/skills"]
323
- integrations?: IntegrationsSetup, // managed integrations config
324
- timeoutMs?: number,
325
- }): Promise<SwarmResultList<T>>
326
- ```
327
-
328
- ```ts
329
- // Basic
330
- const results = await swarm.map({
331
- items: documents,
332
- prompt: "Summarize this document",
333
- });
334
- ```
335
-
336
- When `schema` is provided, a structured output prompt is automatically embedded—instructing the agent to write `output/result.json` matching the schema.
337
-
338
- ```ts
339
- // With Zod schema
340
- const SummarySchema = z.object({
341
- title: z.string(),
342
- keyPoints: z.array(z.string()),
343
- });
344
-
345
- const results = await swarm.map({
346
- items: documents,
347
- prompt: "Extract summary",
348
- schema: SummarySchema,
349
- });
350
-
351
- // Or with JSON Schema
352
- const SummaryJsonSchema = {
353
- type: "object",
354
- properties: {
355
- title: { type: "string" },
356
- keyPoints: { type: "array", items: { type: "string" } },
357
- },
358
- required: ["title", "keyPoints"],
359
- };
360
-
361
- const results = await swarm.map({
362
- items: documents,
363
- prompt: "Extract summary",
364
- schema: SummaryJsonSchema,
365
- });
366
-
367
- // With dynamic prompt
368
- const results = await swarm.map({
369
- items: documents,
370
- prompt: (files, index) => `Analyze document ${index + 1}: focus on revenue`,
371
- });
372
-
373
- // Access results
374
- for (const r of results) {
375
- if (r.status === "success") {
376
- console.log(r.data); // Parsed schema or FileMap
377
- console.log(r.files); // Output files from agent
378
- }
379
- }
380
- ```
381
-
382
- ### map + bestOf
383
-
384
- Combine map parallelism with bestOf quality:
385
-
386
- ```ts
387
- const AnalysisSchema = z.object({
388
- findings: z.array(z.string()),
389
- confidence: z.number(),
390
- });
391
-
392
- // Each item gets N candidates, judge picks best per item
393
- const results = await swarm.map({
394
- items: documents,
395
- prompt: "Analyze thoroughly",
396
- schema: AnalysisSchema,
397
- bestOf: {
398
- n: 3,
399
- judgeCriteria: "Most comprehensive analysis",
400
- // taskAgents?: AgentOverride[], // Different agent per candidate
401
- // judgeAgent?: AgentOverride, // Override judge agent
402
- // mcpServers?: {...}, // MCP servers for candidates
403
- // judgeMcpServers?: {...}, // MCP servers for judge
404
- // skills?: [...], // Skills for candidates
405
- // judgeSkills?: [...], // Skills for judge
406
- // integrations?: {...}, // Integrations for candidates
407
- // judgeIntegrations?: {...}, // Integrations for judge
408
- },
409
- });
410
-
411
- // Results contain only winners (one per input item)
412
- ```
413
-
414
- ### filter
415
-
416
- Two-step evaluation (`schema` and `condition` are required):
417
- 1. `Agent[i]` sees `items[i]`, assesses it, outputs `result.json` matching `schema`
418
- 2. SDK parses `result.json` → `data`, your `condition(data)` applies the threshold
419
- 3. Passing items forward their original input files, not agent output
420
-
421
- ```
422
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
423
- │ Sandbox 0 │ │ Sandbox 1 │ │ Sandbox 2 │
424
- │ Agent 0 │ │ Agent 1 │ │ Agent 2 │
425
- │ │ │ │ │ │
426
- │ context/ │ │ context/ │ │ context/ │
427
- │ items[0] │ │ items[1] │ │ items[2] │
428
- │ output/ │ │ output/ │ │ output/ │
429
- │ result.json │ │ result.json │ │ result.json │
430
- └───────┬─────────┘ └───────┬─────────┘ └───────┬─────────┘
431
- │ │ │
432
- └───────────────────┼───────────────────┘
433
-
434
- condition(data)
435
- ✓ ✗ ✓
436
- │ │
437
- ▼ ▼
438
- [items[0], items[2]]
439
- ```
440
-
441
- ```ts
442
- // Signature (schema accepts Zod or JSON Schema object)
443
- swarm.filter<T>({
444
- items: FileMap[] | SwarmResult[],
445
- prompt: string, // Describe what to assess (agent outputs result.json)
446
- name?: string, // Operation name for observability (appears in meta.operationName)
447
- schema: z.ZodType<T> | JsonSchema, // Required - defines evaluation output structure
448
- condition: (data: T) => boolean, // Local function applies threshold
449
- systemPrompt?: string,
450
- agent?: AgentOverride,
451
- verify?: VerifyConfig, // LLM-as-judge quality check with retry loop
452
- retry?: RetryConfig, // Auto-retry on error with backoff
453
- mcpServers?: Record<string, McpServerConfig>,
454
- skills?: string[], // e.g. ["anthropics/skills"]
455
- integrations?: IntegrationsSetup, // managed integrations config
456
- timeoutMs?: number,
457
- }): Promise<SwarmResultList<T>>
458
- ```
459
-
460
- ```ts
461
- const EvalSchema = z.object({
462
- severity: z.enum(["critical", "warning", "info"]),
463
- score: z.number(),
464
- });
465
-
466
- const results = await swarm.filter({
467
- items: documents,
468
- prompt: "Assess the severity of issues in this document", // Agent evaluates
469
- schema: EvalSchema,
470
- condition: (data) => data.severity === "critical", // Code applies threshold
471
- });
472
-
473
- // Three possible statuses:
474
- results.success; // Passed condition
475
- results.filtered; // Evaluated but didn't pass
476
- results.error; // Agent error
477
-
478
- // Chain to next step
479
- await swarm.reduce({
480
- items: results.success,
481
- prompt: "Summarize critical issues",
482
- });
483
- ```
484
-
485
- ### reduce
486
-
487
- Synthesize many items into one. A single agent sees all `items` as `item_0/`, `item_1/`, etc. and outputs a unified `result` (which includes `result.json` if `schema` provided).
488
-
489
- ```
490
- ┌─────────────────────────┐
491
- │ Sandbox │
492
- │ Agent │
493
- │ │
494
- │ context/ │
495
- │ item_0/items[0] │
496
- │ item_1/items[1] │
497
- │ item_2/items[2] │
498
- │ output/ │
499
- │ result │
500
- └────────────┬────────────┘
501
-
502
-
503
- result
504
- ```
505
-
506
- ```ts
507
- // Signature (schema accepts Zod or JSON Schema object)
508
- swarm.reduce<T>({
509
- items: FileMap[] | SwarmResult[],
510
- prompt: string,
511
- name?: string, // Operation name for observability (appears in meta.operationName)
512
- schema?: z.ZodType<T> | JsonSchema,
513
- systemPrompt?: string,
514
- agent?: AgentOverride,
515
- verify?: VerifyConfig, // LLM-as-judge quality check with retry loop
516
- retry?: RetryConfig, // Auto-retry on error with backoff
517
- mcpServers?: Record<string, McpServerConfig>,
518
- skills?: string[], // e.g. ["anthropics/skills"]
519
- integrations?: IntegrationsSetup, // managed integrations config
520
- timeoutMs?: number,
521
- }): Promise<ReduceResult<T>>
522
- ```
523
-
524
- ```ts
525
- // Agent sees: item_0/, item_1/, item_2/, etc.
526
- const report = await swarm.reduce({
527
- items: results.success,
528
- prompt: "Create a unified report from all analyses",
529
- });
530
-
531
- if (report.status === "success") {
532
- console.log(report.files); // Final output files
533
- console.log(report.data); // Parsed schema if provided
534
- }
535
-
536
- // With schema
537
- const ReportSchema = z.object({
538
- summary: z.string(),
539
- recommendations: z.array(z.string()),
540
- });
541
-
542
- const report = await swarm.reduce({
543
- items,
544
- prompt: "Create report",
545
- schema: ReportSchema,
546
- });
547
- ```
548
-
549
- ### verify (quality gate)
550
-
551
- Add a verification loop to any operation (`map`, `filter`, `reduce`). A separate verifier agent checks if the worker's output meets your criteria. On failure, the worker retries with the verifier's feedback — up to `maxAttempts` times.
552
-
553
- ```
554
- ┌───────────────┐ ┌──────────────┐
555
- │ Worker │─────▶│ Verifier │
556
- │ (attempt 1) │ │ │
557
- └───────────────┘ └──────┬───────┘
558
-
559
- pass? │ fail + feedback
560
- │ │ │
561
- ▼ │ ▼
562
- output │ ┌───────────────┐
563
- └─▶│ Worker │──▶ Verifier ──▶ ...
564
- │ (attempt 2) │ (up to maxAttempts)
565
- └───────────────┘
566
- ```
567
-
568
- ```ts
569
- const results = await swarm.map({
570
- items: documents,
571
- prompt: "Write a detailed analysis",
572
- schema: AnalysisSchema,
573
- verify: {
574
- criteria: "Analysis must include specific data points and cite sources",
575
- maxAttempts: 3, // Default: 3
576
- // verifierAgent: { type: "claude", model: "opus" }, // Override verifier agent
577
- // verifierSkills: ["anthropics/skills"], // Skills for verifier
578
- onWorkerComplete: (idx, attempt, status) => {
579
- console.log(`Item ${idx}, attempt ${attempt}: ${status}`);
580
- },
581
- onVerifierComplete: (idx, attempt, passed, feedback) => {
582
- console.log(`Verify item ${idx}: ${passed ? "PASS" : feedback}`);
583
- },
584
- },
585
- });
586
-
587
- // Check verification outcome
588
- for (const r of results) {
589
- if (r.verify) {
590
- console.log(`Passed: ${r.verify.passed}, attempts: ${r.verify.attempts}`);
591
- console.log(`Reasoning: ${r.verify.reasoning}`);
592
- }
593
- }
594
- ```
595
-
596
- On each failed attempt, the verifier's feedback is appended to the worker's prompt so it can address specific issues. The final result includes `verify: VerifyInfo` with the outcome.
597
-
598
- > **Note:** `verify` and `bestOf` are mutually exclusive on `map`. Use one or the other per operation.
599
-
600
- ---
601
-
602
- ## Result Types
603
-
604
- ```ts
605
- // SwarmResult<T> - from map, filter, bestOf candidates
606
- interface SwarmResult<T> {
607
- status: "success" | "filtered" | "error";
608
- data: T | null; // Parsed schema, or null on error
609
- files: FileMap; // Output files (map/bestOf) or input files (filter)
610
- meta: IndexedMeta; // { operationId, operation, tag, sandboxId, itemIndex }
611
- error?: string; // Error message if status === "error"
612
- rawData?: string; // Raw result.json when parse/validation failed (for debugging)
613
- bestOf?: { // Present when map used bestOf option
614
- winnerIndex: number;
615
- judgeReasoning: string;
616
- judgeMeta: JudgeMeta; // { operationId, operation, tag, sandboxId, candidateCount }
617
- candidates: SwarmResult<T>[];
618
- };
619
- verify?: VerifyInfo; // Present when verify option was used
620
- }
621
-
622
- // SwarmResultList<T> - from map, filter (extends Array)
623
- results.success; // SwarmResult[] with status "success"
624
- results.filtered; // SwarmResult[] with status "filtered"
625
- results.error; // SwarmResult[] with status "error"
626
-
627
- // ReduceResult<T> - from reduce
628
- interface ReduceResult<T> {
629
- status: "success" | "error";
630
- data: T | null;
631
- files: FileMap;
632
- meta: ReduceMeta; // { operationId, operation, tag, sandboxId, inputCount, inputIndices }
633
- error?: string;
634
- rawData?: string; // Raw result.json when parse/validation failed (for debugging)
635
- verify?: VerifyInfo; // Present when verify option was used
636
- }
637
-
638
- // VerifyInfo - verification outcome
639
- interface VerifyInfo {
640
- passed: boolean; // Final verification status
641
- reasoning: string; // Verifier's reasoning
642
- verifyMeta: VerifyMeta; // { operationId, operation, tag, sandboxId, attempts }
643
- attempts: number; // Total attempts made
644
- }
645
-
646
- // BestOfResult<T> - from bestOf
647
- interface BestOfResult<T> {
648
- winner: SwarmResult<T>;
649
- winnerIndex: number;
650
- judgeReasoning: string;
651
- judgeMeta: JudgeMeta; // { operationId, operation, tag, sandboxId, candidateCount }
652
- candidates: SwarmResult<T>[];
653
- }
654
- ```
655
-
656
- ## Chaining Operations
657
-
658
- When chaining Swarm operations, `result.json` from a previous step is automatically renamed to `data.json`. This avoids confusion when the downstream agent writes its own `result.json`. This also applies to [Pipeline](#pipeline).
659
-
660
- **Example: map → reduce chain**
661
-
662
- ```
663
- ┌─────────────────────────────────────────────────────────────────────────────┐
664
- │ MAP (parallel) │
665
- │ │
666
- │ item_0 agent writes: item_1 agent writes: │
667
- │ output/ output/ │
668
- │ result.json ← schema result.json ← schema │
669
- │ │
670
- └─────────────────────────────────────────────────────────────────────────────┘
671
-
672
-
673
- ┌─────────────────────────────────────────────────────────────────────────────┐
674
- │ REDUCE (single agent) │
675
- │ │
676
- │ context/ │
677
- │ item_0/ │
678
- │ data.json ← renamed from result.json │
679
- │ item_1/ │
680
- │ data.json ← renamed from result.json │
681
- │ output/ │
682
- │ result.json ← reduce agent writes its own │
683
- │ │
684
- └─────────────────────────────────────────────────────────────────────────────┘
685
- ```
686
-
687
- ```ts
688
- const AnalysisSchema = z.object({ summary: z.string() });
689
- const SeveritySchema = z.object({ severity: z.enum(["critical", "warning", "info"]) });
690
-
691
- // Full pipeline: map → filter → reduce
692
- const analyzed = await swarm.map({
693
- items: documents,
694
- prompt: "Analyze",
695
- schema: AnalysisSchema,
696
- });
697
-
698
- const critical = await swarm.filter({
699
- items: analyzed.success,
700
- prompt: "Evaluate severity",
701
- schema: SeveritySchema,
702
- condition: (d) => d.severity === "critical",
703
- });
704
-
705
- const report = await swarm.reduce({
706
- items: critical.success,
707
- prompt: "Create summary report",
708
- });
709
-
710
- // Combine success and filtered
711
- const allEvaluated = [...critical.success, ...critical.filtered];
712
- await swarm.reduce({
713
- items: allEvaluated,
714
- prompt: "Summarize all evaluated items",
715
- });
716
- ```
717
-
718
- ## AgentOverride
719
-
720
- Override the default agent for any operation (apiKey inherited from Swarm config):
721
-
722
- ```ts
723
- interface AgentOverride {
724
- type: "claude" | "codex" | "gemini" | "qwen" | "kimi" | "opencode" | "droid";
725
- model?: string;
726
- reasoningEffort?: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "thinking" | "no-thinking";
727
- }
728
- ```
729
-
730
- ```ts
731
- const codexAgent: AgentOverride = {
732
- type: "codex",
733
- reasoningEffort: "high",
734
- };
735
-
736
- const results = await swarm.map({
737
- items,
738
- prompt: "Analyze",
739
- agent: codexAgent,
740
- });
741
- ```
742
-
743
- ## Concurrency
744
-
745
- Global semaphore limits parallel sandboxes across all operations.
746
-
747
- ```ts
748
- const swarm = new Swarm({
749
- agent,
750
- sandbox,
751
- concurrency: 4, // Max 4 sandboxes at once (default: 4)
752
- });
753
-
754
- // map(10) with bestOf(5) = 60 agent calls, but only 4 run at any time
755
- ```
756
-
757
- **Ordering guarantees:**
758
- - `bestOf`: Judge runs only after all candidates complete
759
- - `map` → `filter` → `reduce`: Each phase completes before next starts
760
- - Within a phase: Items run in parallel (up to concurrency limit)
761
-
762
- ---
763
-
764
- ## Pipeline
765
-
766
- Fluent wrapper over Swarm for chaining operations. **All Swarm features work in Pipeline steps** — `schema`, `bestOf`, `verify`, `retry`, `agent`, `mcpServers`, `skills`, `integrations`, dynamic prompts.
767
-
768
- ```ts
769
- import "dotenv/config";
770
- import { Swarm, Pipeline } from "@evolvingmachines/evolve";
771
-
772
- const swarm = new Swarm(); // See Swarm Abstractions for full config
773
-
774
- const pipeline = new Pipeline(swarm)
775
- .map({
776
- name: "analyze",
777
- prompt: "Analyze...",
778
- schema: AnalysisSchema,
779
- })
780
- .filter({
781
- name: "critical",
782
- prompt: "Rate...",
783
- schema: SeveritySchema,
784
- condition: d => d.severity === "critical",
785
- })
786
- .reduce({
787
- name: "report",
788
- prompt: "Summarize...",
789
- });
790
-
791
- // Reusable — run with different data
792
- const result1 = await pipeline.run(batch1);
793
- const result2 = await pipeline.run(batch2);
794
- ```
795
-
796
- ### Step Configurations
797
-
798
- Each step accepts the same options as the corresponding Swarm method, plus `name` for observability:
799
-
800
- ```ts
801
- // Map step — same as swarm.map() + name
802
- .map<T>({
803
- name?: string, // Step name (appears in events)
804
- prompt: string | ((files, idx) => string),
805
- schema?: z.ZodType<T> | JsonSchema,
806
- bestOf?: BestOfConfig, // N candidates + judge
807
- verify?: VerifyConfig, // LLM-as-judge quality check
808
- retry?: RetryConfig, // Auto-retry on error
809
- agent?: AgentOverride,
810
- mcpServers?: Record<string, McpServerConfig>,
811
- skills?: string[], // Skills for workers
812
- integrations?: IntegrationsSetup, // managed integrations config
813
- systemPrompt?: string,
814
- timeoutMs?: number,
815
- })
816
-
817
- // Filter step — same as swarm.filter() + name + emit
818
- .filter<T>({
819
- name?: string,
820
- prompt: string,
821
- schema: z.ZodType<T> | JsonSchema, // Required
822
- condition: (data: T) => boolean, // Required
823
- emit?: "success" | "filtered" | "all", // What passes to next step: "success" (default), "filtered", or "all"
824
- verify?: VerifyConfig,
825
- retry?: RetryConfig,
826
- agent?: AgentOverride,
827
- mcpServers?: Record<string, McpServerConfig>,
828
- skills?: string[], // Skills for workers
829
- integrations?: IntegrationsSetup, // managed integrations config
830
- systemPrompt?: string,
831
- timeoutMs?: number,
832
- })
833
-
834
- // Reduce step — same as swarm.reduce() + name (terminal: no steps after)
835
- .reduce<T>({
836
- name?: string,
837
- prompt: string,
838
- schema?: z.ZodType<T> | JsonSchema,
839
- verify?: VerifyConfig,
840
- retry?: RetryConfig,
841
- agent?: AgentOverride,
842
- mcpServers?: Record<string, McpServerConfig>,
843
- skills?: string[], // Skills for workers
844
- integrations?: IntegrationsSetup, // managed integrations config
845
- systemPrompt?: string,
846
- timeoutMs?: number,
847
- })
848
- ```
849
-
850
- ### Full Example
851
-
852
- ```ts
853
- const pipeline = new Pipeline(swarm)
854
-
855
- .map({
856
- name: "analyze",
857
- prompt: (files, idx) => `Analyze document ${idx + 1}`,
858
- schema: AnalysisSchema,
859
- bestOf: {
860
- n: 3,
861
- judgeCriteria: "Most thorough analysis",
862
- },
863
- retry: { maxAttempts: 2 },
864
- agent: { type: "claude", model: "opus" },
865
- })
866
-
867
- .filter({
868
- name: "quality-gate",
869
- prompt: "Rate the analysis quality",
870
- schema: z.object({
871
- score: z.number(),
872
- reasoning: z.string(),
873
- }),
874
- condition: d => d.score >= 8,
875
- emit: "success", // Only high-quality pass through
876
- verify: {
877
- criteria: "Rating must be justified with specific examples",
878
- },
879
- })
880
-
881
- .reduce({
882
- name: "synthesize",
883
- prompt: "Create executive summary from all analyses",
884
- schema: ReportSchema,
885
- verify: {
886
- criteria: "Summary must cover all key findings",
887
- },
888
- })
889
-
890
- .on("stepComplete", e => {
891
- console.log(`${e.name}: ${e.successCount}/${e.successCount + e.errorCount}`);
892
- });
893
-
894
- const result = await pipeline.run(documents);
895
- ```
896
-
897
- ### Events
898
-
899
- Pipeline unifies all Swarm callbacks at the pipeline level, adding `stepIndex` and `stepName`:
900
-
901
- ```ts
902
- pipeline
903
- .on("stepStart", e => {
904
- console.log(`Step ${e.index} started with ${e.itemCount} items`);
905
- })
906
- .on("stepComplete", e => {
907
- console.log(`Step ${e.index} done in ${e.durationMs}ms`);
908
- })
909
- .on("stepError", e => {
910
- console.error(`Step ${e.index} failed:`, e.error);
911
- });
912
-
913
- // Or object style
914
- pipeline.on({
915
- onStepComplete: e => console.log(`${e.name}: ${e.successCount} success`),
916
- onItemRetry: e => console.log(`Retry: step ${e.stepIndex}, item ${e.itemIndex}`),
917
- onVerifierComplete: e => console.log(`Verify: ${e.passed ? "PASS" : e.feedback}`),
918
- });
919
- ```
920
-
921
- | Event | Fields |
922
- |-------|--------|
923
- | `stepStart` | `type`, `index`, `name?`, `itemCount` |
924
- | `stepComplete` | `type`, `index`, `name?`, `durationMs`, `successCount`, `errorCount`, `filteredCount` |
925
- | `stepError` | `type`, `index`, `name?`, `error` |
926
- | `itemRetry` | `stepIndex`, `stepName?`, `itemIndex`, `attempt`, `error` |
927
- | `workerComplete` | `stepIndex`, `stepName?`, `itemIndex`, `attempt`, `status` |
928
- | `verifierComplete` | `stepIndex`, `stepName?`, `itemIndex`, `attempt`, `passed`, `feedback?` |
929
- | `candidateComplete` | `stepIndex`, `stepName?`, `itemIndex`, `candidateIndex`, `status` |
930
- | `judgeComplete` | `stepIndex`, `stepName?`, `itemIndex`, `winnerIndex`, `reasoning` |
931
-
932
- ### Result
933
-
934
- ```ts
935
- interface PipelineResult<T> {
936
- pipelineRunId: string;
937
- steps: StepResult[]; // { type, index, durationMs, results }
938
- output: SwarmResult<T>[] | ReduceResult<T>;
939
- totalDurationMs: number;
940
- }
941
-
942
- // Access step results
943
- for (const step of result.steps) {
944
- console.log(`${step.type} took ${step.durationMs}ms`);
945
- }
946
- ```
947
-
948
- ### Terminal Pipeline
949
-
950
- After `.reduce()`, no more steps can be added (returns `TerminalPipeline`):
951
-
952
- ```ts
953
- const terminal = pipeline.reduce({ prompt: "..." });
954
- terminal.map({ prompt: "..." }); // Throws: "Cannot add steps after reduce"
955
- ```
956
-
957
- ---