claude_swarm 1.0.6 → 1.0.8

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +27 -0
  4. data/README.md +336 -1037
  5. data/docs/V1_TO_V2_MIGRATION_GUIDE.md +1120 -0
  6. data/docs/v1/README.md +1197 -0
  7. data/docs/v2/CHANGELOG.swarm_cli.md +22 -0
  8. data/docs/v2/CHANGELOG.swarm_memory.md +20 -0
  9. data/docs/v2/CHANGELOG.swarm_sdk.md +287 -10
  10. data/docs/v2/README.md +32 -6
  11. data/docs/v2/guides/complete-tutorial.md +133 -37
  12. data/docs/v2/guides/composable-swarms.md +1178 -0
  13. data/docs/v2/guides/getting-started.md +42 -1
  14. data/docs/v2/guides/snapshots.md +1498 -0
  15. data/docs/v2/reference/architecture-flow.md +5 -3
  16. data/docs/v2/reference/event_payload_structures.md +249 -12
  17. data/docs/v2/reference/execution-flow.md +1 -1
  18. data/docs/v2/reference/ruby-dsl.md +368 -22
  19. data/docs/v2/reference/yaml.md +314 -63
  20. data/examples/snapshot_demo.rb +119 -0
  21. data/examples/v2/dsl/01_basic.rb +0 -2
  22. data/examples/v2/dsl/02_core_parameters.rb +0 -2
  23. data/examples/v2/dsl/03_capabilities.rb +0 -2
  24. data/examples/v2/dsl/04_llm_parameters.rb +0 -2
  25. data/examples/v2/dsl/05_advanced_flags.rb +0 -3
  26. data/examples/v2/dsl/06_permissions.rb +0 -4
  27. data/examples/v2/dsl/07_mcp_server.rb +0 -2
  28. data/examples/v2/dsl/08_swarm_hooks.rb +0 -2
  29. data/examples/v2/dsl/09_agent_hooks.rb +0 -2
  30. data/examples/v2/dsl/10_all_agents_hooks.rb +0 -3
  31. data/examples/v2/dsl/11_delegation.rb +0 -2
  32. data/examples/v2/dsl/12_complete_integration.rb +2 -6
  33. data/examples/v2/node_context_demo.rb +1 -1
  34. data/examples/v2/node_workflow.rb +2 -4
  35. data/examples/v2/plan_and_execute.rb +157 -0
  36. data/lib/claude_swarm/cli.rb +0 -18
  37. data/lib/claude_swarm/configuration.rb +28 -18
  38. data/lib/claude_swarm/openai/chat_completion.rb +2 -11
  39. data/lib/claude_swarm/openai/responses.rb +2 -11
  40. data/lib/claude_swarm/version.rb +1 -1
  41. data/lib/swarm_cli/formatters/human_formatter.rb +103 -0
  42. data/lib/swarm_cli/interactive_repl.rb +9 -3
  43. data/lib/swarm_cli/version.rb +1 -1
  44. data/lib/swarm_memory/core/storage_read_tracker.rb +51 -14
  45. data/lib/swarm_memory/integration/cli_registration.rb +3 -2
  46. data/lib/swarm_memory/integration/sdk_plugin.rb +11 -5
  47. data/lib/swarm_memory/tools/memory_edit.rb +2 -2
  48. data/lib/swarm_memory/tools/memory_multi_edit.rb +2 -2
  49. data/lib/swarm_memory/tools/memory_read.rb +3 -3
  50. data/lib/swarm_memory/version.rb +1 -1
  51. data/lib/swarm_memory.rb +5 -0
  52. data/lib/swarm_sdk/agent/builder.rb +33 -0
  53. data/lib/swarm_sdk/agent/chat/context_tracker.rb +33 -0
  54. data/lib/swarm_sdk/agent/chat/hook_integration.rb +49 -3
  55. data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +11 -27
  56. data/lib/swarm_sdk/agent/chat.rb +200 -51
  57. data/lib/swarm_sdk/agent/context.rb +6 -2
  58. data/lib/swarm_sdk/agent/context_manager.rb +6 -0
  59. data/lib/swarm_sdk/agent/definition.rb +14 -2
  60. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +180 -0
  61. data/lib/swarm_sdk/configuration.rb +387 -94
  62. data/lib/swarm_sdk/events_to_messages.rb +181 -0
  63. data/lib/swarm_sdk/log_collector.rb +31 -5
  64. data/lib/swarm_sdk/log_stream.rb +37 -8
  65. data/lib/swarm_sdk/model_aliases.json +4 -1
  66. data/lib/swarm_sdk/node/agent_config.rb +33 -8
  67. data/lib/swarm_sdk/node/builder.rb +39 -18
  68. data/lib/swarm_sdk/node_orchestrator.rb +293 -26
  69. data/lib/swarm_sdk/proc_helpers.rb +53 -0
  70. data/lib/swarm_sdk/providers/openai_with_responses.rb +22 -15
  71. data/lib/swarm_sdk/restore_result.rb +65 -0
  72. data/lib/swarm_sdk/snapshot.rb +156 -0
  73. data/lib/swarm_sdk/snapshot_from_events.rb +386 -0
  74. data/lib/swarm_sdk/state_restorer.rb +491 -0
  75. data/lib/swarm_sdk/state_snapshot.rb +369 -0
  76. data/lib/swarm_sdk/swarm/agent_initializer.rb +360 -55
  77. data/lib/swarm_sdk/swarm/all_agents_builder.rb +28 -1
  78. data/lib/swarm_sdk/swarm/builder.rb +208 -12
  79. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +67 -0
  80. data/lib/swarm_sdk/swarm/tool_configurator.rb +46 -11
  81. data/lib/swarm_sdk/swarm.rb +338 -42
  82. data/lib/swarm_sdk/swarm_loader.rb +145 -0
  83. data/lib/swarm_sdk/swarm_registry.rb +136 -0
  84. data/lib/swarm_sdk/tools/delegate.rb +92 -7
  85. data/lib/swarm_sdk/tools/read.rb +17 -5
  86. data/lib/swarm_sdk/tools/stores/read_tracker.rb +47 -12
  87. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +45 -0
  88. data/lib/swarm_sdk/utils.rb +18 -0
  89. data/lib/swarm_sdk/validation_result.rb +33 -0
  90. data/lib/swarm_sdk/version.rb +1 -1
  91. data/lib/swarm_sdk.rb +40 -8
  92. data/swarm_cli.gemspec +1 -1
  93. data/swarm_memory.gemspec +2 -2
  94. data/swarm_sdk.gemspec +2 -2
  95. metadata +21 -13
  96. data/examples/learning-assistant/assistant.md +0 -7
  97. data/examples/learning-assistant/example-memories/concept-example.md +0 -90
  98. data/examples/learning-assistant/example-memories/experience-example.md +0 -66
  99. data/examples/learning-assistant/example-memories/fact-example.md +0 -76
  100. data/examples/learning-assistant/example-memories/memory-index.md +0 -78
  101. data/examples/learning-assistant/example-memories/skill-example.md +0 -168
  102. data/examples/learning-assistant/learning_assistant.rb +0 -34
  103. data/examples/learning-assistant/learning_assistant.yml +0 -20
  104. data/lib/swarm_sdk/mcp.rb +0 -16
  105. data/llm.v2.txt +0 -13407
  106. /data/docs/v2/guides/{MEMORY_DEFRAG_GUIDE.md → memory-defrag-guide.md} +0 -0
  107. /data/{llms.txt → llms.claude-swarm.txt} +0 -0
@@ -65,7 +65,7 @@ flowchart TB
65
65
  BASH_TOOL["Bash Tool"]
66
66
  DELEGATE_TOOL["Delegation Tools<br/>(call other agents)"]
67
67
  PLUGIN_TOOLS["Plugin Tools<br/>(from PluginRegistry)"]
68
- DEFAULT_TOOLS["Default Tools<br/>(Think, TodoWrite, Clock)"]
68
+ DEFAULT_TOOLS["Default Tools<br/>(Read, Grep, Glob)"]
69
69
  SCRATCHPAD["Scratchpad Tools<br/>(volatile storage)"]
70
70
  end
71
71
 
@@ -82,7 +82,7 @@ flowchart TB
82
82
  subgraph "Logging & Events"
83
83
  LOG_STREAM["LogStream<br/>(event emitter)"]
84
84
  LOG_COLLECTOR["LogCollector<br/>(aggregates events)"]
85
- LOG_EVENTS["Events: swarm_start, user_prompt,<br/>tool_call, tool_result,<br/>agent_step, agent_stop, swarm_stop"]
85
+ LOG_EVENTS["Events: swarm_start, user_prompt,<br/>llm_api_request, llm_api_response,<br/>tool_call, tool_result,<br/>agent_step, agent_stop, swarm_stop"]
86
86
  end
87
87
 
88
88
  subgraph "Hooks System"
@@ -269,7 +269,9 @@ Swarm.execute → AgentInitializer →
269
269
  ```
270
270
  Agent.ask(prompt) →
271
271
  user_prompt hooks →
272
+ llm_api_request event (captures request to LLM) →
272
273
  RubyLLM (rate limited) →
274
+ llm_api_response event (captures response from LLM) →
273
275
  Tool calls →
274
276
  pre_tool_use hooks →
275
277
  Tool execution (with permissions) →
@@ -283,7 +285,7 @@ Agent.ask(prompt) →
283
285
  - **Bash Tool**: Execute shell commands
284
286
  - **Delegation Tools**: Recursively call other Agent::Chat instances
285
287
  - **Plugin Tools**: PluginRegistry → create_tool → (e.g., MemoryWrite → Storage)
286
- - **Default Tools**: Think (reasoning), TodoWrite (task mgmt), Clock (time)
288
+ - **Default Tools**: Read, Grep, Glob (file operations and search)
287
289
  - **Scratchpad Tools**: Volatile shared storage across agents
288
290
 
289
291
  ### 6. Memory Integration Flow
@@ -2,7 +2,28 @@
2
2
 
3
3
  This document describes the exact structure of all SwarmSDK event payloads emitted via `LogStream.emit()`.
4
4
 
5
- All events automatically include a `timestamp` field (ISO8601 format) added by `LogStream.emit()`.
5
+ ## Common Fields
6
+
7
+ All events automatically include these fields:
8
+
9
+ - `timestamp` (String): ISO8601 format timestamp, added by `LogStream.emit()`
10
+ - `swarm_id` (String): Unique identifier for the swarm that emitted this event
11
+ - `parent_swarm_id` (String | nil): Parent swarm ID (null for root swarms)
12
+
13
+ **Hierarchical Tracking:**
14
+ For composable swarms, events include hierarchical swarm IDs:
15
+ - Root swarm: `swarm_id: "main"`, `parent_swarm_id: null`
16
+ - Child swarm: `swarm_id: "main/code_review"`, `parent_swarm_id: "main"`
17
+ - Grandchild: `swarm_id: "main/code_review/security"`, `parent_swarm_id: "main/code_review"`
18
+
19
+ **Agent Identification:**
20
+ Most events include an `agent` field (Symbol) that identifies which agent emitted the event:
21
+ - **Primary agents**: Simple name like `:backend`, `:frontend`
22
+ - **Delegation instances**: Compound name like `:"backend@lead"`, `:"backend@frontend"`
23
+ - Format: `:"target@delegator"` where target is the delegated-to agent and delegator is the delegating agent
24
+ - Created when multiple agents delegate to the same target (unless `shared_across_delegations: true`)
25
+ - Each instance has isolated conversation history and tool state
26
+ - See the `agent_start` event documentation for more details
6
27
 
7
28
  ## Event Types
8
29
 
@@ -17,6 +38,8 @@ Emitted when `Swarm.execute()` is called, before any agent execution begins.
17
38
  type: "swarm_start",
18
39
  timestamp: "2025-01-15T10:30:45Z", # Auto-added by LogStream
19
40
  agent: :lead_agent_name, # Lead agent name (for consistency)
41
+ swarm_id: "main", # Swarm ID
42
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
20
43
  swarm_name: "Development Team", # Swarm name
21
44
  lead_agent: :lead_agent_name, # Lead agent name
22
45
  prompt: "Build authentication system" # User's task prompt
@@ -24,7 +47,7 @@ Emitted when `Swarm.execute()` is called, before any agent execution begins.
24
47
  ```
25
48
 
26
49
  **Field Locations**:
27
- - Root level: `type`, `timestamp`, `agent`, `swarm_name`, `lead_agent`, `prompt`
50
+ - Root level: `type`, `timestamp`, `agent`, `swarm_id`, `parent_swarm_id`, `swarm_name`, `lead_agent`, `prompt`
28
51
  - No nested metadata
29
52
 
30
53
  ---
@@ -39,6 +62,8 @@ Emitted when swarm execution completes (success or error).
39
62
  {
40
63
  type: "swarm_stop",
41
64
  timestamp: "2025-01-15T10:35:22Z",
65
+ swarm_id: "main", # Swarm ID
66
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
42
67
  swarm_name: "Development Team",
43
68
  lead_agent: :lead_agent_name,
44
69
  last_agent: "backend", # Agent that produced final response
@@ -52,7 +77,7 @@ Emitted when swarm execution completes (success or error).
52
77
  ```
53
78
 
54
79
  **Field Locations**:
55
- - Root level: All fields are at root level
80
+ - Root level: All fields including `swarm_id` and `parent_swarm_id`
56
81
  - No nested metadata for this event
57
82
 
58
83
  ---
@@ -67,7 +92,9 @@ Emitted once per agent when agents are initialized (lazy initialization).
67
92
  {
68
93
  type: "agent_start",
69
94
  timestamp: "2025-01-15T10:30:46Z",
70
- agent: :backend, # Agent name
95
+ agent: :backend, # Agent name (or delegation instance name)
96
+ swarm_id: "main", # Swarm ID
97
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
71
98
  swarm_name: "Development Team",
72
99
  model: "gpt-5", # Model ID
73
100
  provider: "openai", # Provider name
@@ -80,14 +107,55 @@ Emitted once per agent when agents are initialized (lazy initialization).
80
107
  enabled: true,
81
108
  config: { directory: ".swarm/backend-memory" }
82
109
  }
83
- }
110
+ },
111
+ is_delegation_instance: false, # True if this is a delegation instance
112
+ base_agent: nil # Base agent name (if delegation instance)
84
113
  }
85
114
  ```
86
115
 
87
116
  **Field Locations**:
88
- - Root level: All fields except plugin configs
117
+ - Root level: All fields including `swarm_id` and `parent_swarm_id`
89
118
  - Nested in `plugin_storages`: Per-plugin configuration
90
119
 
120
+ **Delegation Instances:**
121
+
122
+ When multiple agents delegate to the same target agent, SwarmSDK creates isolated instances by default (controlled by `shared_across_delegations` config). These instances have unique names and separate state:
123
+
124
+ ```ruby
125
+ # Primary agent
126
+ {
127
+ type: "agent_start",
128
+ agent: :backend,
129
+ is_delegation_instance: false,
130
+ base_agent: nil,
131
+ ...
132
+ }
133
+
134
+ # Delegation instance (when lead delegates to backend)
135
+ {
136
+ type: "agent_start",
137
+ agent: :"backend@lead", # Format: target@delegator
138
+ is_delegation_instance: true,
139
+ base_agent: :backend, # Original agent definition
140
+ ...
141
+ }
142
+
143
+ # Another delegation instance (when frontend delegates to backend)
144
+ {
145
+ type: "agent_start",
146
+ agent: :"backend@frontend", # Separate isolated instance
147
+ is_delegation_instance: true,
148
+ base_agent: :backend,
149
+ ...
150
+ }
151
+ ```
152
+
153
+ **Key Points:**
154
+ - Each delegation instance has **isolated conversation history** and **separate tool state**
155
+ - All instances use the **same configuration** (model, tools, prompts) from the base agent
156
+ - The `agent` field shows the full instance name for proper tracking
157
+ - Set `shared_across_delegations: true` on the base agent to share one instance across all delegators
158
+
91
159
  ---
92
160
 
93
161
  ### 4. agent_stop
@@ -101,6 +169,8 @@ Emitted when an agent completes with a final response (no more tool calls).
101
169
  type: "agent_stop",
102
170
  timestamp: "2025-01-15T10:31:20Z",
103
171
  agent: "backend",
172
+ swarm_id: "main", # Swarm ID
173
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
104
174
  model: "gpt-5",
105
175
  content: "I've implemented the auth system", # Final response text
106
176
  tool_calls: nil, # Always nil for agent_stop
@@ -127,7 +197,7 @@ Emitted when an agent completes with a final response (no more tool calls).
127
197
  ```
128
198
 
129
199
  **Field Locations**:
130
- - Root level: `type`, `timestamp`, `agent`, `model`, `content`, `tool_calls`, `finish_reason`, `tool_executions`, `metadata`
200
+ - Root level: `type`, `timestamp`, `agent`, `swarm_id`, `parent_swarm_id`, `model`, `content`, `tool_calls`, `finish_reason`, `tool_executions`, `metadata`
131
201
  - Nested in `usage`: All token counts, costs, and context tracking
132
202
  - Nested in `metadata`: Minimal (most fields promoted to root)
133
203
 
@@ -203,6 +273,7 @@ Emitted when a user message is about to be sent to the LLM.
203
273
  message_count: 5, # Number of messages in conversation so far
204
274
  tools: [:Read, :Edit, :Bash], # Available tools (excluding delegation tools)
205
275
  delegates_to: ["frontend"], # Agents this agent can delegate to
276
+ source: "user", # Source of prompt: "user" or "delegation"
206
277
  metadata: { # Full context available here
207
278
  prompt: "Build authentication",
208
279
  message_count: 5,
@@ -210,14 +281,19 @@ Emitted when a user message is about to be sent to the LLM.
210
281
  provider: "openai",
211
282
  tools: [:Read, :Edit, :Bash],
212
283
  delegates_to: ["frontend"],
284
+ source: "user",
213
285
  timestamp: "2025-01-15T10:31:10Z"
214
286
  }
215
287
  }
216
288
  ```
217
289
 
218
290
  **Field Locations**:
219
- - Root level: `type`, `timestamp`, `agent`, `model`, `provider`, `message_count`, `tools`, `delegates_to`, `metadata`
220
- - Nested in `metadata`: Complete copy of all context fields (including prompt)
291
+ - Root level: `type`, `timestamp`, `agent`, `model`, `provider`, `message_count`, `tools`, `delegates_to`, `source`, `metadata`
292
+ - Nested in `metadata`: Complete copy of all context fields (including prompt and source)
293
+
294
+ **Source Field**:
295
+ - `"user"` - Direct user interaction (default)
296
+ - `"delegation"` - Prompt originated from delegation tool (one agent delegating to another)
221
297
 
222
298
  **Important**: The `metadata` hash contains the original context from the hook, including the `prompt` field which is NOT promoted to root level for this event type.
223
299
 
@@ -329,7 +405,7 @@ Emitted when context usage crosses threshold percentages (60%, 80%, 90%, 95%).
329
405
 
330
406
  ### 11. agent_delegation
331
407
 
332
- Emitted when an agent delegates work to another agent.
408
+ Emitted when an agent delegates work to another agent or swarm.
333
409
 
334
410
  **Location**: `lib/swarm_sdk/agent/chat/context_tracker.rb:186-193`
335
411
 
@@ -338,8 +414,10 @@ Emitted when an agent delegates work to another agent.
338
414
  type: "agent_delegation",
339
415
  timestamp: "2025-01-15T10:31:30Z",
340
416
  agent: "backend",
417
+ swarm_id: "main", # Swarm ID
418
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
341
419
  tool_call_id: "call_xyz789",
342
- delegate_to: "frontend", # Target agent name
420
+ delegate_to: "frontend", # Target agent or swarm name
343
421
  arguments: { # Delegation parameters
344
422
  prompt: "Build the login UI"
345
423
  },
@@ -347,6 +425,8 @@ Emitted when an agent delegates work to another agent.
347
425
  }
348
426
  ```
349
427
 
428
+ **Note**: `delegate_to` can be either a local agent name or a registered swarm name when using composable swarms.
429
+
350
430
  ---
351
431
 
352
432
  ### 12. delegation_result
@@ -360,7 +440,9 @@ Emitted when a delegated task completes and returns to the delegating agent.
360
440
  type: "delegation_result",
361
441
  timestamp: "2025-01-15T10:32:15Z",
362
442
  agent: "backend", # Agent that delegated
363
- delegate_from: "frontend", # Agent that was delegated to
443
+ swarm_id: "main", # Swarm ID
444
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
445
+ delegate_from: "frontend", # Agent or swarm that was delegated to
364
446
  tool_call_id: "call_xyz789", # Matches delegation tool_call_id
365
447
  result: "Login UI implemented", # Result from delegate
366
448
  metadata: {} # Agent context metadata
@@ -369,6 +451,32 @@ Emitted when a delegated task completes and returns to the delegating agent.
369
451
 
370
452
  ---
371
453
 
454
+ ### 12a. delegation_circular_dependency
455
+
456
+ Emitted when circular delegation is detected (prevents infinite loops).
457
+
458
+ **Location**: `lib/swarm_sdk/tools/delegate.rb:192-200`
459
+
460
+ ```ruby
461
+ {
462
+ type: "delegation_circular_dependency",
463
+ timestamp: "2025-01-15T10:31:45Z",
464
+ agent: "agent_b", # Agent attempting delegation
465
+ swarm_id: "main", # Swarm ID
466
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
467
+ target: "agent_a", # Target that would create cycle
468
+ call_stack: ["agent_a", "agent_b"] # Current delegation chain
469
+ }
470
+ ```
471
+
472
+ **Description**: Emitted when runtime circular dependency detection prevents an infinite delegation loop. The delegation is blocked and an error message is returned to the LLM.
473
+
474
+ **Example Scenarios:**
475
+ - Agent A → Agent B → Agent A (circular within swarm)
476
+ - Swarm S1 → Swarm S2 → Swarm S1 (circular across swarms)
477
+
478
+ ---
479
+
372
480
  ### 13. context_compression
373
481
 
374
482
  Emitted when automatic context compression is triggered at 60% threshold.
@@ -433,6 +541,130 @@ Emitted when all LLM API retry attempts are exhausted.
433
541
 
434
542
  ---
435
543
 
544
+ ### 16. llm_api_request
545
+
546
+ Emitted before sending HTTP request to LLM API provider (only when logging is enabled).
547
+
548
+ **Location**: `lib/swarm_sdk/agent/llm_instrumentation_middleware.rb:57-68`
549
+
550
+ ```ruby
551
+ {
552
+ type: "llm_api_request",
553
+ timestamp: "2025-01-15T10:31:15Z",
554
+ agent: "backend",
555
+ swarm_id: "main", # Swarm ID
556
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
557
+ provider: "openai", # Provider name (e.g., "anthropic", "openai")
558
+ body: { # Complete request payload
559
+ model: "gpt-5",
560
+ messages: [
561
+ { role: "system", content: "You are..." },
562
+ { role: "user", content: "Build authentication" }
563
+ ],
564
+ temperature: 0.7,
565
+ max_tokens: 4096,
566
+ tools: [ # Tool definitions (if any)
567
+ {
568
+ name: "Read",
569
+ description: "Read a file",
570
+ input_schema: { ... }
571
+ }
572
+ ]
573
+ }
574
+ }
575
+ ```
576
+
577
+ **Field Locations**:
578
+ - Root level: `type`, `timestamp`, `agent`, `swarm_id`, `parent_swarm_id`, `provider`, `body`
579
+ - Nested in `body`: Complete LLM request payload (model, messages, parameters, tools)
580
+
581
+ **Notes**:
582
+ - Only emitted when logging is enabled (`swarm.execute` with block)
583
+ - Body structure varies by provider (OpenAI, Anthropic, etc.)
584
+ - HTTP-level details (method, URL, headers) are not included to reduce noise
585
+ - Captures the exact request sent to the LLM API
586
+
587
+ **Delegation Instance Example:**
588
+
589
+ When a delegation instance makes an LLM API call, the `agent` field shows the full instance name:
590
+
591
+ ```ruby
592
+ {
593
+ type: "llm_api_request",
594
+ agent: :"backend@lead", # Delegation instance identifier
595
+ swarm_id: "main",
596
+ parent_swarm_id: nil,
597
+ provider: "openai",
598
+ body: { ... }
599
+ }
600
+ ```
601
+
602
+ This allows you to track which specific delegation instance (and therefore which delegation path) triggered the API call.
603
+
604
+ ---
605
+
606
+ ### 17. llm_api_response
607
+
608
+ Emitted after receiving HTTP response from LLM API provider (only when logging is enabled).
609
+
610
+ **Location**: `lib/swarm_sdk/agent/llm_instrumentation_middleware.rb:77-101`
611
+
612
+ ```ruby
613
+ {
614
+ type: "llm_api_response",
615
+ timestamp: "2025-01-15T10:31:17Z",
616
+ agent: "backend",
617
+ swarm_id: "main", # Swarm ID
618
+ parent_swarm_id: nil, # Parent swarm ID (nil for root)
619
+ provider: "openai", # Provider name
620
+ body: { # Complete response payload
621
+ id: "chatcmpl-123",
622
+ object: "chat.completion",
623
+ created: 1642234567,
624
+ model: "gpt-5",
625
+ choices: [
626
+ {
627
+ index: 0,
628
+ message: {
629
+ role: "assistant",
630
+ content: "I'll implement the authentication system...",
631
+ tool_calls: [...]
632
+ },
633
+ finish_reason: "tool_calls"
634
+ }
635
+ ],
636
+ usage: {
637
+ prompt_tokens: 1850,
638
+ completion_tokens: 156,
639
+ total_tokens: 2006
640
+ }
641
+ },
642
+ duration_seconds: 2.145, # Request duration
643
+ usage: { # Extracted from body
644
+ input_tokens: 1850,
645
+ output_tokens: 156,
646
+ total_tokens: 2006
647
+ },
648
+ model: "gpt-5", # Extracted from body
649
+ finish_reason: "tool_calls" # Extracted from body
650
+ }
651
+ ```
652
+
653
+ **Field Locations**:
654
+ - Root level: `type`, `timestamp`, `agent`, `swarm_id`, `parent_swarm_id`, `provider`, `body`, `duration_seconds`, `usage`, `model`, `finish_reason`
655
+ - Nested in `body`: Complete LLM response payload (varies by provider)
656
+ - Nested in `usage`: Token counts (extracted from body for convenience)
657
+
658
+ **Notes**:
659
+ - Only emitted when logging is enabled (`swarm.execute` with block)
660
+ - `usage`, `model`, and `finish_reason` are extracted from the body for convenience
661
+ - Body structure varies by provider (OpenAI, Anthropic, etc.)
662
+ - HTTP-level details (status, headers) are not included to reduce noise
663
+ - Captures the exact response received from the LLM API
664
+ - Duration includes full round-trip time (request + network + response)
665
+
666
+ ---
667
+
436
668
  ## Summary: Field Location Guide
437
669
 
438
670
  ### Always at Root Level
@@ -452,6 +684,8 @@ Emitted when all LLM API retry attempts are exhausted.
452
684
  | `user_prompt` | model, provider, message_count, tools, delegates_to | metadata.* (includes prompt) |
453
685
  | `tool_call` | tool_call_id, tool | arguments.*, metadata.* |
454
686
  | `tool_result` | tool_call_id, tool, result | metadata.* |
687
+ | `llm_api_request` | provider | body.* |
688
+ | `llm_api_response` | provider, duration_seconds, usage, model, finish_reason | body.*, usage.* |
455
689
 
456
690
  ### Important Notes
457
691
 
@@ -459,6 +693,8 @@ Emitted when all LLM API retry attempts are exhausted.
459
693
  2. **Tool Calls**: Nested as array of objects in `tool_calls` field within `agent_step` events
460
694
  3. **Prompt Location**: For `user_prompt` events, the prompt is in `metadata.prompt`, NOT at root level
461
695
  4. **Metadata Deduplication**: `agent_step` and `agent_stop` events have minimal metadata because most fields are promoted to root level (see `swarm.rb:723` and `swarm.rb:744`)
696
+ 5. **LLM API Events**: `llm_api_request` and `llm_api_response` events are only emitted when logging is enabled and capture the raw LLM API communication for debugging and monitoring
697
+ 6. **Delegation Instances**: The `agent` field can be either a simple agent name (`:backend`) or a delegation instance name (`:"backend@lead"`). Delegation instances are created automatically when multiple agents delegate to the same target (unless `shared_across_delegations: true`). Each instance has isolated state and appears as a distinct agent in all events, allowing you to track behavior and costs per delegation path.
462
698
 
463
699
  ---
464
700
 
@@ -469,3 +705,4 @@ Emitted when all LLM API retry attempts are exhausted.
469
705
  - **Agent Events**: `lib/swarm_sdk/agent/chat/context_tracker.rb` - Agent-level event tracking
470
706
  - **Hook Integration**: `lib/swarm_sdk/agent/chat/hook_integration.rb` - User prompt event preparation
471
707
  - **Logging Helpers**: `lib/swarm_sdk/agent/chat/logging_helpers.rb` - Tool call/result formatting
708
+ - **LLM Instrumentation**: `lib/swarm_sdk/agent/llm_instrumentation_middleware.rb` - LLM API request/response capture
@@ -301,7 +301,7 @@ flowchart TD
301
301
  **Pass 1: Create Agents**
302
302
  - Create `Agent::Chat` instance for each agent
303
303
  - Register explicit tools (from config)
304
- - Register default tools (Read, Grep, Glob, Think, TodoWrite, etc.)
304
+ - Register default tools (Read, Grep, Glob)
305
305
  - Wrap tools with permissions validators
306
306
  - Connect to MCP servers for external tools
307
307
  - Initialize plugins (create memory storage if enabled)