swarm_sdk 2.7.14 → 3.0.0.alpha1
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.
- checksums.yaml +4 -4
- data/lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb +16 -0
- data/lib/swarm_sdk/ruby_llm_patches/init.rb +4 -1
- data/lib/swarm_sdk/v3/agent.rb +1165 -0
- data/lib/swarm_sdk/v3/agent_builder.rb +533 -0
- data/lib/swarm_sdk/v3/agent_definition.rb +330 -0
- data/lib/swarm_sdk/v3/configuration.rb +490 -0
- data/lib/swarm_sdk/v3/debug_log.rb +86 -0
- data/lib/swarm_sdk/v3/event_stream.rb +130 -0
- data/lib/swarm_sdk/v3/hooks/context.rb +112 -0
- data/lib/swarm_sdk/v3/hooks/result.rb +115 -0
- data/lib/swarm_sdk/v3/hooks/runner.rb +128 -0
- data/lib/swarm_sdk/v3/mcp/connector.rb +183 -0
- data/lib/swarm_sdk/v3/mcp/mcp_error.rb +15 -0
- data/lib/swarm_sdk/v3/mcp/server_definition.rb +125 -0
- data/lib/swarm_sdk/v3/mcp/ssl_http_transport.rb +103 -0
- data/lib/swarm_sdk/v3/mcp/stdio_transport.rb +135 -0
- data/lib/swarm_sdk/v3/mcp/tool_proxy.rb +53 -0
- data/lib/swarm_sdk/v3/memory/adapters/base.rb +297 -0
- data/lib/swarm_sdk/v3/memory/adapters/faiss_support.rb +194 -0
- data/lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb +212 -0
- data/lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb +507 -0
- data/lib/swarm_sdk/v3/memory/adapters/vector_utils.rb +88 -0
- data/lib/swarm_sdk/v3/memory/card.rb +206 -0
- data/lib/swarm_sdk/v3/memory/cluster.rb +146 -0
- data/lib/swarm_sdk/v3/memory/compressor.rb +496 -0
- data/lib/swarm_sdk/v3/memory/consolidator.rb +427 -0
- data/lib/swarm_sdk/v3/memory/context_builder.rb +339 -0
- data/lib/swarm_sdk/v3/memory/edge.rb +105 -0
- data/lib/swarm_sdk/v3/memory/embedder.rb +185 -0
- data/lib/swarm_sdk/v3/memory/exposure_tracker.rb +104 -0
- data/lib/swarm_sdk/v3/memory/ingestion_pipeline.rb +394 -0
- data/lib/swarm_sdk/v3/memory/retriever.rb +289 -0
- data/lib/swarm_sdk/v3/memory/store.rb +489 -0
- data/lib/swarm_sdk/v3/skills/loader.rb +147 -0
- data/lib/swarm_sdk/v3/skills/manifest.rb +45 -0
- data/lib/swarm_sdk/v3/sub_task_agent.rb +248 -0
- data/lib/swarm_sdk/v3/tools/base.rb +80 -0
- data/lib/swarm_sdk/v3/tools/bash.rb +174 -0
- data/lib/swarm_sdk/v3/tools/clock.rb +32 -0
- data/lib/swarm_sdk/v3/tools/edit.rb +111 -0
- data/lib/swarm_sdk/v3/tools/glob.rb +96 -0
- data/lib/swarm_sdk/v3/tools/grep.rb +200 -0
- data/lib/swarm_sdk/v3/tools/message_teammate.rb +15 -0
- data/lib/swarm_sdk/v3/tools/message_user.rb +15 -0
- data/lib/swarm_sdk/v3/tools/read.rb +181 -0
- data/lib/swarm_sdk/v3/tools/read_tracker.rb +40 -0
- data/lib/swarm_sdk/v3/tools/registry.rb +208 -0
- data/lib/swarm_sdk/v3/tools/sub_task.rb +183 -0
- data/lib/swarm_sdk/v3/tools/think.rb +88 -0
- data/lib/swarm_sdk/v3/tools/write.rb +87 -0
- data/lib/swarm_sdk/v3.rb +145 -0
- metadata +83 -148
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -175
- data/lib/swarm_sdk/agent/builder.rb +0 -705
- data/lib/swarm_sdk/agent/chat.rb +0 -1438
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -375
- data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
- data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -85
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -290
- data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
- data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
- data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -134
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -146
- data/lib/swarm_sdk/agent/context.rb +0 -115
- data/lib/swarm_sdk/agent/context_manager.rb +0 -315
- data/lib/swarm_sdk/agent/definition.rb +0 -588
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -226
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -173
- data/lib/swarm_sdk/agent/tool_registry.rb +0 -189
- data/lib/swarm_sdk/agent_registry.rb +0 -146
- data/lib/swarm_sdk/builders/base_builder.rb +0 -558
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
- data/lib/swarm_sdk/concerns/cleanupable.rb +0 -42
- data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
- data/lib/swarm_sdk/concerns/validatable.rb +0 -55
- data/lib/swarm_sdk/config.rb +0 -368
- data/lib/swarm_sdk/configuration/parser.rb +0 -397
- data/lib/swarm_sdk/configuration/translator.rb +0 -285
- data/lib/swarm_sdk/configuration.rb +0 -165
- data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
- data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -102
- data/lib/swarm_sdk/context_compactor.rb +0 -335
- data/lib/swarm_sdk/context_management/builder.rb +0 -128
- data/lib/swarm_sdk/context_management/context.rb +0 -328
- data/lib/swarm_sdk/custom_tool_registry.rb +0 -226
- data/lib/swarm_sdk/defaults.rb +0 -251
- data/lib/swarm_sdk/events_to_messages.rb +0 -199
- data/lib/swarm_sdk/hooks/adapter.rb +0 -359
- data/lib/swarm_sdk/hooks/context.rb +0 -197
- data/lib/swarm_sdk/hooks/definition.rb +0 -80
- data/lib/swarm_sdk/hooks/error.rb +0 -29
- data/lib/swarm_sdk/hooks/executor.rb +0 -146
- data/lib/swarm_sdk/hooks/registry.rb +0 -147
- data/lib/swarm_sdk/hooks/result.rb +0 -150
- data/lib/swarm_sdk/hooks/shell_executor.rb +0 -256
- data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
- data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
- data/lib/swarm_sdk/log_collector.rb +0 -227
- data/lib/swarm_sdk/log_stream.rb +0 -127
- data/lib/swarm_sdk/markdown_parser.rb +0 -75
- data/lib/swarm_sdk/model_aliases.json +0 -8
- data/lib/swarm_sdk/models.json +0 -44002
- data/lib/swarm_sdk/models.rb +0 -161
- data/lib/swarm_sdk/node_context.rb +0 -245
- data/lib/swarm_sdk/observer/builder.rb +0 -81
- data/lib/swarm_sdk/observer/config.rb +0 -45
- data/lib/swarm_sdk/observer/manager.rb +0 -248
- data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
- data/lib/swarm_sdk/permissions/config.rb +0 -239
- data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
- data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
- data/lib/swarm_sdk/permissions/validator.rb +0 -173
- data/lib/swarm_sdk/permissions_builder.rb +0 -122
- data/lib/swarm_sdk/plugin.rb +0 -309
- data/lib/swarm_sdk/plugin_registry.rb +0 -101
- data/lib/swarm_sdk/proc_helpers.rb +0 -53
- data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -119
- data/lib/swarm_sdk/restore_result.rb +0 -65
- data/lib/swarm_sdk/result.rb +0 -241
- data/lib/swarm_sdk/snapshot.rb +0 -156
- data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
- data/lib/swarm_sdk/state_restorer.rb +0 -476
- data/lib/swarm_sdk/state_snapshot.rb +0 -334
- data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -648
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -204
- data/lib/swarm_sdk/swarm/builder.rb +0 -256
- data/lib/swarm_sdk/swarm/executor.rb +0 -446
- data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -162
- data/lib/swarm_sdk/swarm/lazy_delegate_chat.rb +0 -372
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -361
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -290
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
- data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -392
- data/lib/swarm_sdk/swarm.rb +0 -973
- data/lib/swarm_sdk/swarm_loader.rb +0 -145
- data/lib/swarm_sdk/swarm_registry.rb +0 -136
- data/lib/swarm_sdk/tools/base.rb +0 -63
- data/lib/swarm_sdk/tools/bash.rb +0 -280
- data/lib/swarm_sdk/tools/clock.rb +0 -46
- data/lib/swarm_sdk/tools/delegate.rb +0 -389
- data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
- data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
- data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
- data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
- data/lib/swarm_sdk/tools/edit.rb +0 -145
- data/lib/swarm_sdk/tools/glob.rb +0 -166
- data/lib/swarm_sdk/tools/grep.rb +0 -235
- data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
- data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -167
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
- data/lib/swarm_sdk/tools/mcp_tool_stub.rb +0 -198
- data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
- data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
- data/lib/swarm_sdk/tools/read.rb +0 -261
- data/lib/swarm_sdk/tools/registry.rb +0 -205
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -273
- data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
- data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
- data/lib/swarm_sdk/tools/think.rb +0 -100
- data/lib/swarm_sdk/tools/todo_write.rb +0 -237
- data/lib/swarm_sdk/tools/web_fetch.rb +0 -264
- data/lib/swarm_sdk/tools/write.rb +0 -112
- data/lib/swarm_sdk/transcript_builder.rb +0 -278
- data/lib/swarm_sdk/utils.rb +0 -68
- data/lib/swarm_sdk/validation_result.rb +0 -33
- data/lib/swarm_sdk/version.rb +0 -5
- data/lib/swarm_sdk/workflow/agent_config.rb +0 -95
- data/lib/swarm_sdk/workflow/builder.rb +0 -227
- data/lib/swarm_sdk/workflow/executor.rb +0 -497
- data/lib/swarm_sdk/workflow/node_builder.rb +0 -593
- data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -250
- data/lib/swarm_sdk/workflow.rb +0 -589
- data/lib/swarm_sdk.rb +0 -721
data/lib/swarm_sdk/v3.rb
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler"
|
|
4
|
+
require "cgi"
|
|
5
|
+
require "digest"
|
|
6
|
+
require "English"
|
|
7
|
+
require "fileutils"
|
|
8
|
+
require "json"
|
|
9
|
+
require "open3"
|
|
10
|
+
require "pathname"
|
|
11
|
+
require "securerandom"
|
|
12
|
+
require "set"
|
|
13
|
+
require "time"
|
|
14
|
+
require "timeout"
|
|
15
|
+
|
|
16
|
+
require "async"
|
|
17
|
+
require "async/barrier"
|
|
18
|
+
require "async/semaphore"
|
|
19
|
+
require "mcp"
|
|
20
|
+
require "ruby_llm"
|
|
21
|
+
|
|
22
|
+
# Load ruby_llm compatibility patches (shared gem infrastructure)
|
|
23
|
+
require_relative "ruby_llm_patches/init"
|
|
24
|
+
|
|
25
|
+
require "zeitwerk"
|
|
26
|
+
|
|
27
|
+
module SwarmSDK
|
|
28
|
+
# V3 is the next-generation agent primitive with built-in memory.
|
|
29
|
+
#
|
|
30
|
+
# Self-contained module with its own Zeitwerk loader and zero dependencies
|
|
31
|
+
# on V2 code. The core insight: the LLM's context window is a staging area,
|
|
32
|
+
# not the whole brain. Older turns get consolidated into memory cards, and
|
|
33
|
+
# retrieval brings relevant memory back into working context on demand.
|
|
34
|
+
#
|
|
35
|
+
# @example Basic usage
|
|
36
|
+
# require "swarm_sdk/v3"
|
|
37
|
+
#
|
|
38
|
+
# definition = SwarmSDK::V3::AgentDefinition.new(
|
|
39
|
+
# name: :assistant,
|
|
40
|
+
# description: "A helpful assistant",
|
|
41
|
+
# model: "claude-sonnet-4",
|
|
42
|
+
# tools: [:Read, :Write, :Edit, :Bash, :Grep, :Glob],
|
|
43
|
+
# memory_directory: ".swarm/memory",
|
|
44
|
+
# )
|
|
45
|
+
#
|
|
46
|
+
# agent = SwarmSDK::V3::Agent.new(definition)
|
|
47
|
+
# response = agent.ask("Build a login page")
|
|
48
|
+
#
|
|
49
|
+
# @example Without memory (pure conversation)
|
|
50
|
+
# definition = SwarmSDK::V3::AgentDefinition.new(
|
|
51
|
+
# name: :chat,
|
|
52
|
+
# description: "Simple chat agent",
|
|
53
|
+
# model: "claude-sonnet-4",
|
|
54
|
+
# )
|
|
55
|
+
#
|
|
56
|
+
# agent = SwarmSDK::V3::Agent.new(definition)
|
|
57
|
+
# response = agent.ask("Hello!")
|
|
58
|
+
module V3
|
|
59
|
+
class Error < StandardError; end
|
|
60
|
+
class ConfigurationError < Error; end
|
|
61
|
+
class ToolExecutionError < Error; end
|
|
62
|
+
class MemoryError < Error; end
|
|
63
|
+
|
|
64
|
+
class << self
|
|
65
|
+
# Build a single V3 Agent from a DSL block
|
|
66
|
+
#
|
|
67
|
+
# Convenience entry point that delegates to {AgentBuilder.build}.
|
|
68
|
+
# Returns an initialized Agent ready for use with {Agent#ask}.
|
|
69
|
+
#
|
|
70
|
+
# @yield DSL block evaluated on an {AgentBuilder} instance
|
|
71
|
+
# @return [Agent] Initialized agent
|
|
72
|
+
# @raise [ConfigurationError] If required fields are missing
|
|
73
|
+
#
|
|
74
|
+
# @example
|
|
75
|
+
# agent = SwarmSDK::V3.agent do
|
|
76
|
+
# name :assistant
|
|
77
|
+
# description "A helpful assistant"
|
|
78
|
+
# tools :Read, :Write, :Edit
|
|
79
|
+
# streaming true
|
|
80
|
+
#
|
|
81
|
+
# memory do
|
|
82
|
+
# directory ".swarm/memory"
|
|
83
|
+
# end
|
|
84
|
+
# end
|
|
85
|
+
#
|
|
86
|
+
# agent.ask("Hello!")
|
|
87
|
+
def agent(&block)
|
|
88
|
+
AgentBuilder.build(&block)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Configure V3 global settings
|
|
92
|
+
#
|
|
93
|
+
# Convenience wrapper around {Configuration.configure}. Yields the
|
|
94
|
+
# configuration instance and applies provider settings to RubyLLM.
|
|
95
|
+
#
|
|
96
|
+
# @yield [Configuration] The configuration instance
|
|
97
|
+
# @return [Configuration]
|
|
98
|
+
#
|
|
99
|
+
# @example
|
|
100
|
+
# SwarmSDK::V3.configure do |config|
|
|
101
|
+
# config.default_model = "claude-sonnet-4"
|
|
102
|
+
# config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
|
|
103
|
+
# config.default_tools = [:Think, :Clock]
|
|
104
|
+
# end
|
|
105
|
+
def configure(&block)
|
|
106
|
+
Configuration.configure(&block)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Access the global configuration instance
|
|
110
|
+
#
|
|
111
|
+
# @return [Configuration]
|
|
112
|
+
#
|
|
113
|
+
# @example
|
|
114
|
+
# model = SwarmSDK::V3.configuration.default_model
|
|
115
|
+
def configuration
|
|
116
|
+
Configuration.instance
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Reset configuration to defaults
|
|
120
|
+
#
|
|
121
|
+
# @return [void]
|
|
122
|
+
def reset_configuration!
|
|
123
|
+
Configuration.reset!
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# V3 Zeitwerk setup:
|
|
130
|
+
# When loaded via V2 (require "swarm_sdk"), the V2 loader already manages
|
|
131
|
+
# lib/swarm_sdk/ including v3/, so we skip to avoid conflicts.
|
|
132
|
+
# When loaded standalone (require "swarm_sdk/v3"), creates its own loader.
|
|
133
|
+
v3_dir = File.join(__dir__, "v3")
|
|
134
|
+
already_managed = false
|
|
135
|
+
Zeitwerk::Registry.loaders.each do |loader|
|
|
136
|
+
loader.dirs.each { |dir| already_managed = true if v3_dir.start_with?(dir) }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
unless already_managed
|
|
140
|
+
v3_loader = Zeitwerk::Loader.new
|
|
141
|
+
v3_loader.tag = "swarm_sdk_v3"
|
|
142
|
+
v3_loader.push_dir(v3_dir, namespace: SwarmSDK::V3)
|
|
143
|
+
v3_loader.inflector.inflect("mcp" => "MCP")
|
|
144
|
+
v3_loader.setup
|
|
145
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: swarm_sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0.alpha1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paulo Arruda
|
|
@@ -24,61 +24,75 @@ dependencies:
|
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '2.0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name:
|
|
27
|
+
name: faiss
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 0.5.2
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 0.5.2
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: informers
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
46
|
+
version: 1.2.1
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
53
|
+
version: 1.2.1
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
|
-
name:
|
|
55
|
+
name: mcp
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - "~>"
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version:
|
|
60
|
+
version: 0.6.0
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version:
|
|
67
|
+
version: 0.6.0
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
|
-
name:
|
|
69
|
+
name: rice
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version:
|
|
74
|
+
version: 4.8.0
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version:
|
|
81
|
+
version: 4.8.0
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: ruby_llm
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '1.11'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '1.11'
|
|
82
96
|
- !ruby/object:Gem::Dependency
|
|
83
97
|
name: zeitwerk
|
|
84
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,11 +108,11 @@ dependencies:
|
|
|
94
108
|
- !ruby/object:Gem::Version
|
|
95
109
|
version: '2.6'
|
|
96
110
|
description: |
|
|
97
|
-
SwarmSDK is
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
SwarmSDK V3 is the next-generation agent primitive with built-in memory.
|
|
112
|
+
The core insight: the LLM's context window is a staging area, not the whole brain.
|
|
113
|
+
Older turns get consolidated into memory cards, and retrieval brings relevant
|
|
114
|
+
memory back into working context on demand. Single-process, lightweight, and
|
|
115
|
+
efficient AI agent development with RubyLLM.
|
|
102
116
|
email:
|
|
103
117
|
- parrudaj@gmail.com
|
|
104
118
|
executables: []
|
|
@@ -106,76 +120,6 @@ extensions: []
|
|
|
106
120
|
extra_rdoc_files: []
|
|
107
121
|
files:
|
|
108
122
|
- LICENSE
|
|
109
|
-
- lib/swarm_sdk.rb
|
|
110
|
-
- lib/swarm_sdk/agent/RETRY_LOGIC.md
|
|
111
|
-
- lib/swarm_sdk/agent/builder.rb
|
|
112
|
-
- lib/swarm_sdk/agent/chat.rb
|
|
113
|
-
- lib/swarm_sdk/agent/chat_helpers/context_tracker.rb
|
|
114
|
-
- lib/swarm_sdk/agent/chat_helpers/event_emitter.rb
|
|
115
|
-
- lib/swarm_sdk/agent/chat_helpers/hook_integration.rb
|
|
116
|
-
- lib/swarm_sdk/agent/chat_helpers/instrumentation.rb
|
|
117
|
-
- lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb
|
|
118
|
-
- lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb
|
|
119
|
-
- lib/swarm_sdk/agent/chat_helpers/serialization.rb
|
|
120
|
-
- lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb
|
|
121
|
-
- lib/swarm_sdk/agent/chat_helpers/system_reminders.rb
|
|
122
|
-
- lib/swarm_sdk/agent/chat_helpers/token_tracking.rb
|
|
123
|
-
- lib/swarm_sdk/agent/context.rb
|
|
124
|
-
- lib/swarm_sdk/agent/context_manager.rb
|
|
125
|
-
- lib/swarm_sdk/agent/definition.rb
|
|
126
|
-
- lib/swarm_sdk/agent/llm_instrumentation_middleware.rb
|
|
127
|
-
- lib/swarm_sdk/agent/system_prompt_builder.rb
|
|
128
|
-
- lib/swarm_sdk/agent/tool_registry.rb
|
|
129
|
-
- lib/swarm_sdk/agent_registry.rb
|
|
130
|
-
- lib/swarm_sdk/builders/base_builder.rb
|
|
131
|
-
- lib/swarm_sdk/claude_code_agent_adapter.rb
|
|
132
|
-
- lib/swarm_sdk/concerns/cleanupable.rb
|
|
133
|
-
- lib/swarm_sdk/concerns/snapshotable.rb
|
|
134
|
-
- lib/swarm_sdk/concerns/validatable.rb
|
|
135
|
-
- lib/swarm_sdk/config.rb
|
|
136
|
-
- lib/swarm_sdk/configuration.rb
|
|
137
|
-
- lib/swarm_sdk/configuration/parser.rb
|
|
138
|
-
- lib/swarm_sdk/configuration/translator.rb
|
|
139
|
-
- lib/swarm_sdk/context_compactor.rb
|
|
140
|
-
- lib/swarm_sdk/context_compactor/metrics.rb
|
|
141
|
-
- lib/swarm_sdk/context_compactor/token_counter.rb
|
|
142
|
-
- lib/swarm_sdk/context_management/builder.rb
|
|
143
|
-
- lib/swarm_sdk/context_management/context.rb
|
|
144
|
-
- lib/swarm_sdk/custom_tool_registry.rb
|
|
145
|
-
- lib/swarm_sdk/defaults.rb
|
|
146
|
-
- lib/swarm_sdk/events_to_messages.rb
|
|
147
|
-
- lib/swarm_sdk/hooks/adapter.rb
|
|
148
|
-
- lib/swarm_sdk/hooks/context.rb
|
|
149
|
-
- lib/swarm_sdk/hooks/definition.rb
|
|
150
|
-
- lib/swarm_sdk/hooks/error.rb
|
|
151
|
-
- lib/swarm_sdk/hooks/executor.rb
|
|
152
|
-
- lib/swarm_sdk/hooks/registry.rb
|
|
153
|
-
- lib/swarm_sdk/hooks/result.rb
|
|
154
|
-
- lib/swarm_sdk/hooks/shell_executor.rb
|
|
155
|
-
- lib/swarm_sdk/hooks/tool_call.rb
|
|
156
|
-
- lib/swarm_sdk/hooks/tool_result.rb
|
|
157
|
-
- lib/swarm_sdk/log_collector.rb
|
|
158
|
-
- lib/swarm_sdk/log_stream.rb
|
|
159
|
-
- lib/swarm_sdk/markdown_parser.rb
|
|
160
|
-
- lib/swarm_sdk/model_aliases.json
|
|
161
|
-
- lib/swarm_sdk/models.json
|
|
162
|
-
- lib/swarm_sdk/models.rb
|
|
163
|
-
- lib/swarm_sdk/node_context.rb
|
|
164
|
-
- lib/swarm_sdk/observer/builder.rb
|
|
165
|
-
- lib/swarm_sdk/observer/config.rb
|
|
166
|
-
- lib/swarm_sdk/observer/manager.rb
|
|
167
|
-
- lib/swarm_sdk/patterns/agent_observer.rb
|
|
168
|
-
- lib/swarm_sdk/permissions/config.rb
|
|
169
|
-
- lib/swarm_sdk/permissions/error_formatter.rb
|
|
170
|
-
- lib/swarm_sdk/permissions/path_matcher.rb
|
|
171
|
-
- lib/swarm_sdk/permissions/validator.rb
|
|
172
|
-
- lib/swarm_sdk/permissions_builder.rb
|
|
173
|
-
- lib/swarm_sdk/plugin.rb
|
|
174
|
-
- lib/swarm_sdk/plugin_registry.rb
|
|
175
|
-
- lib/swarm_sdk/proc_helpers.rb
|
|
176
|
-
- lib/swarm_sdk/prompts/base_system_prompt.md.erb
|
|
177
|
-
- lib/swarm_sdk/restore_result.rb
|
|
178
|
-
- lib/swarm_sdk/result.rb
|
|
179
123
|
- lib/swarm_sdk/ruby_llm_patches/chat_callbacks_patch.rb
|
|
180
124
|
- lib/swarm_sdk/ruby_llm_patches/configuration_patch.rb
|
|
181
125
|
- lib/swarm_sdk/ruby_llm_patches/connection_patch.rb
|
|
@@ -185,70 +129,61 @@ files:
|
|
|
185
129
|
- lib/swarm_sdk/ruby_llm_patches/message_management_patch.rb
|
|
186
130
|
- lib/swarm_sdk/ruby_llm_patches/responses_api_patch.rb
|
|
187
131
|
- lib/swarm_sdk/ruby_llm_patches/tool_concurrency_patch.rb
|
|
188
|
-
- lib/swarm_sdk/
|
|
189
|
-
- lib/swarm_sdk/
|
|
190
|
-
- lib/swarm_sdk/
|
|
191
|
-
- lib/swarm_sdk/
|
|
192
|
-
- lib/swarm_sdk/
|
|
193
|
-
- lib/swarm_sdk/
|
|
194
|
-
- lib/swarm_sdk/
|
|
195
|
-
- lib/swarm_sdk/
|
|
196
|
-
- lib/swarm_sdk/
|
|
197
|
-
- lib/swarm_sdk/
|
|
198
|
-
- lib/swarm_sdk/
|
|
199
|
-
- lib/swarm_sdk/
|
|
200
|
-
- lib/swarm_sdk/
|
|
201
|
-
- lib/swarm_sdk/
|
|
202
|
-
- lib/swarm_sdk/
|
|
203
|
-
- lib/swarm_sdk/
|
|
204
|
-
- lib/swarm_sdk/
|
|
205
|
-
- lib/swarm_sdk/
|
|
206
|
-
- lib/swarm_sdk/
|
|
207
|
-
- lib/swarm_sdk/
|
|
208
|
-
- lib/swarm_sdk/
|
|
209
|
-
- lib/swarm_sdk/
|
|
210
|
-
- lib/swarm_sdk/
|
|
211
|
-
- lib/swarm_sdk/
|
|
212
|
-
- lib/swarm_sdk/
|
|
213
|
-
- lib/swarm_sdk/
|
|
214
|
-
- lib/swarm_sdk/
|
|
215
|
-
- lib/swarm_sdk/
|
|
216
|
-
- lib/swarm_sdk/
|
|
217
|
-
- lib/swarm_sdk/
|
|
218
|
-
- lib/swarm_sdk/
|
|
219
|
-
- lib/swarm_sdk/
|
|
220
|
-
- lib/swarm_sdk/
|
|
221
|
-
- lib/swarm_sdk/
|
|
222
|
-
- lib/swarm_sdk/
|
|
223
|
-
- lib/swarm_sdk/tools/
|
|
224
|
-
- lib/swarm_sdk/tools/
|
|
225
|
-
- lib/swarm_sdk/tools/
|
|
226
|
-
- lib/swarm_sdk/tools/
|
|
227
|
-
- lib/swarm_sdk/tools/
|
|
228
|
-
- lib/swarm_sdk/tools/
|
|
229
|
-
- lib/swarm_sdk/tools/
|
|
230
|
-
- lib/swarm_sdk/tools/
|
|
231
|
-
- lib/swarm_sdk/tools/
|
|
232
|
-
- lib/swarm_sdk/tools/
|
|
233
|
-
- lib/swarm_sdk/tools/
|
|
234
|
-
- lib/swarm_sdk/tools/
|
|
235
|
-
- lib/swarm_sdk/tools/
|
|
236
|
-
- lib/swarm_sdk/
|
|
237
|
-
- lib/swarm_sdk/utils.rb
|
|
238
|
-
- lib/swarm_sdk/validation_result.rb
|
|
239
|
-
- lib/swarm_sdk/version.rb
|
|
240
|
-
- lib/swarm_sdk/workflow.rb
|
|
241
|
-
- lib/swarm_sdk/workflow/agent_config.rb
|
|
242
|
-
- lib/swarm_sdk/workflow/builder.rb
|
|
243
|
-
- lib/swarm_sdk/workflow/executor.rb
|
|
244
|
-
- lib/swarm_sdk/workflow/node_builder.rb
|
|
245
|
-
- lib/swarm_sdk/workflow/transformer_executor.rb
|
|
132
|
+
- lib/swarm_sdk/v3.rb
|
|
133
|
+
- lib/swarm_sdk/v3/agent.rb
|
|
134
|
+
- lib/swarm_sdk/v3/agent_builder.rb
|
|
135
|
+
- lib/swarm_sdk/v3/agent_definition.rb
|
|
136
|
+
- lib/swarm_sdk/v3/configuration.rb
|
|
137
|
+
- lib/swarm_sdk/v3/debug_log.rb
|
|
138
|
+
- lib/swarm_sdk/v3/event_stream.rb
|
|
139
|
+
- lib/swarm_sdk/v3/hooks/context.rb
|
|
140
|
+
- lib/swarm_sdk/v3/hooks/result.rb
|
|
141
|
+
- lib/swarm_sdk/v3/hooks/runner.rb
|
|
142
|
+
- lib/swarm_sdk/v3/mcp/connector.rb
|
|
143
|
+
- lib/swarm_sdk/v3/mcp/mcp_error.rb
|
|
144
|
+
- lib/swarm_sdk/v3/mcp/server_definition.rb
|
|
145
|
+
- lib/swarm_sdk/v3/mcp/ssl_http_transport.rb
|
|
146
|
+
- lib/swarm_sdk/v3/mcp/stdio_transport.rb
|
|
147
|
+
- lib/swarm_sdk/v3/mcp/tool_proxy.rb
|
|
148
|
+
- lib/swarm_sdk/v3/memory/adapters/base.rb
|
|
149
|
+
- lib/swarm_sdk/v3/memory/adapters/faiss_support.rb
|
|
150
|
+
- lib/swarm_sdk/v3/memory/adapters/filesystem_adapter.rb
|
|
151
|
+
- lib/swarm_sdk/v3/memory/adapters/sqlite_adapter.rb
|
|
152
|
+
- lib/swarm_sdk/v3/memory/adapters/vector_utils.rb
|
|
153
|
+
- lib/swarm_sdk/v3/memory/card.rb
|
|
154
|
+
- lib/swarm_sdk/v3/memory/cluster.rb
|
|
155
|
+
- lib/swarm_sdk/v3/memory/compressor.rb
|
|
156
|
+
- lib/swarm_sdk/v3/memory/consolidator.rb
|
|
157
|
+
- lib/swarm_sdk/v3/memory/context_builder.rb
|
|
158
|
+
- lib/swarm_sdk/v3/memory/edge.rb
|
|
159
|
+
- lib/swarm_sdk/v3/memory/embedder.rb
|
|
160
|
+
- lib/swarm_sdk/v3/memory/exposure_tracker.rb
|
|
161
|
+
- lib/swarm_sdk/v3/memory/ingestion_pipeline.rb
|
|
162
|
+
- lib/swarm_sdk/v3/memory/retriever.rb
|
|
163
|
+
- lib/swarm_sdk/v3/memory/store.rb
|
|
164
|
+
- lib/swarm_sdk/v3/skills/loader.rb
|
|
165
|
+
- lib/swarm_sdk/v3/skills/manifest.rb
|
|
166
|
+
- lib/swarm_sdk/v3/sub_task_agent.rb
|
|
167
|
+
- lib/swarm_sdk/v3/tools/base.rb
|
|
168
|
+
- lib/swarm_sdk/v3/tools/bash.rb
|
|
169
|
+
- lib/swarm_sdk/v3/tools/clock.rb
|
|
170
|
+
- lib/swarm_sdk/v3/tools/edit.rb
|
|
171
|
+
- lib/swarm_sdk/v3/tools/glob.rb
|
|
172
|
+
- lib/swarm_sdk/v3/tools/grep.rb
|
|
173
|
+
- lib/swarm_sdk/v3/tools/message_teammate.rb
|
|
174
|
+
- lib/swarm_sdk/v3/tools/message_user.rb
|
|
175
|
+
- lib/swarm_sdk/v3/tools/read.rb
|
|
176
|
+
- lib/swarm_sdk/v3/tools/read_tracker.rb
|
|
177
|
+
- lib/swarm_sdk/v3/tools/registry.rb
|
|
178
|
+
- lib/swarm_sdk/v3/tools/sub_task.rb
|
|
179
|
+
- lib/swarm_sdk/v3/tools/think.rb
|
|
180
|
+
- lib/swarm_sdk/v3/tools/write.rb
|
|
246
181
|
homepage: https://github.com/parruda/swarm
|
|
247
182
|
licenses:
|
|
248
183
|
- MIT
|
|
249
184
|
metadata:
|
|
250
185
|
source_code_uri: https://github.com/parruda/swarm
|
|
251
|
-
changelog_uri: https://github.com/parruda/swarm/blob/main/docs/
|
|
186
|
+
changelog_uri: https://github.com/parruda/swarm/blob/main/docs/v3/CHANGELOG.md
|
|
252
187
|
rdoc_options: []
|
|
253
188
|
require_paths:
|
|
254
189
|
- lib
|
|
@@ -265,5 +200,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
265
200
|
requirements: []
|
|
266
201
|
rubygems_version: 3.6.9
|
|
267
202
|
specification_version: 4
|
|
268
|
-
summary:
|
|
203
|
+
summary: Next-generation AI agent primitive with built-in memory
|
|
269
204
|
test_files: []
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
# LLM Call Retry Logic
|
|
2
|
-
|
|
3
|
-
## Feature
|
|
4
|
-
|
|
5
|
-
SwarmSDK automatically retries failed LLM API calls to handle transient failures.
|
|
6
|
-
|
|
7
|
-
## Configuration
|
|
8
|
-
|
|
9
|
-
**Defaults:**
|
|
10
|
-
- Max retries: 10
|
|
11
|
-
- Delay: 10 seconds (fixed, no exponential backoff)
|
|
12
|
-
- Retries ALL StandardError exceptions
|
|
13
|
-
|
|
14
|
-
## Implementation
|
|
15
|
-
|
|
16
|
-
**Location:** `lib/swarm_sdk/agent/chat.rb`
|
|
17
|
-
|
|
18
|
-
The retry logic handles two categories of errors:
|
|
19
|
-
|
|
20
|
-
1. **Transient failures** - Network issues, timeouts, rate limits
|
|
21
|
-
2. **Orphan tool call errors** - Special recovery for malformed conversation history
|
|
22
|
-
|
|
23
|
-
## Error Types Handled
|
|
24
|
-
|
|
25
|
-
- `Faraday::ConnectionFailed` - Network connection issues
|
|
26
|
-
- `Faraday::TimeoutError` - Request timeouts
|
|
27
|
-
- `RubyLLM::APIError` - API errors (500s, etc.)
|
|
28
|
-
- `RubyLLM::RateLimitError` - Rate limit errors
|
|
29
|
-
- `RubyLLM::BadRequestError` - With special handling for orphan tool calls
|
|
30
|
-
- Any other `StandardError` - Catches proxy issues, DNS failures, etc.
|
|
31
|
-
|
|
32
|
-
## Orphan Tool Call Recovery
|
|
33
|
-
|
|
34
|
-
**What are orphan tool calls?**
|
|
35
|
-
|
|
36
|
-
Orphan tool calls occur when an assistant message contains `tool_use` blocks but the conversation lacks corresponding `tool_result` messages. This can happen when:
|
|
37
|
-
- Tool execution is interrupted mid-stream
|
|
38
|
-
- Session state restoration is incomplete
|
|
39
|
-
- Network issues cause partial message delivery
|
|
40
|
-
|
|
41
|
-
**How recovery works:**
|
|
42
|
-
|
|
43
|
-
When a `RubyLLM::BadRequestError` (400) is received with tool-related error messages:
|
|
44
|
-
|
|
45
|
-
1. Clears stale ephemeral content from the failed call
|
|
46
|
-
2. The system scans message history for orphan tool calls
|
|
47
|
-
3. For each assistant message with `tool_calls`:
|
|
48
|
-
- Checks if all `tool_call_id`s have matching `tool_result` messages
|
|
49
|
-
- Any missing results indicate orphan tool calls
|
|
50
|
-
4. Orphan tool calls are pruned:
|
|
51
|
-
- If assistant message has content, keeps content but removes `tool_calls`
|
|
52
|
-
- If assistant message is empty, removes the entire message
|
|
53
|
-
5. **System reminder is added** to inform the agent:
|
|
54
|
-
- Lists which tool calls were interrupted
|
|
55
|
-
- Tells agent they were never executed
|
|
56
|
-
- Suggests re-running them if still needed
|
|
57
|
-
6. Retries the LLM call immediately (doesn't count as a retry)
|
|
58
|
-
7. If no orphans found, falls through to normal retry logic
|
|
59
|
-
|
|
60
|
-
**Tool-related error patterns detected:**
|
|
61
|
-
- `tool_use`, `tool_result`, `tool_use_id`
|
|
62
|
-
- `corresponding tool_result`
|
|
63
|
-
- `must immediately follow`
|
|
64
|
-
|
|
65
|
-
**Logging:**
|
|
66
|
-
|
|
67
|
-
When orphan pruning occurs, emits `orphan_tool_calls_pruned` event:
|
|
68
|
-
```json
|
|
69
|
-
{
|
|
70
|
-
"type": "orphan_tool_calls_pruned",
|
|
71
|
-
"agent": "agent_name",
|
|
72
|
-
"pruned_count": 1,
|
|
73
|
-
"original_error": "tool_use block must have corresponding tool_result"
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**System Reminder Format:**
|
|
78
|
-
|
|
79
|
-
The agent receives a system reminder about the pruned tool calls:
|
|
80
|
-
```
|
|
81
|
-
<system-reminder>
|
|
82
|
-
The following tool calls were interrupted and removed from conversation history:
|
|
83
|
-
|
|
84
|
-
- Read(file_path: "/important/file.rb")
|
|
85
|
-
- Write(file_path: "/output.txt", content: "Hello...")
|
|
86
|
-
|
|
87
|
-
These tools were never executed. If you still need their results, please run them again.
|
|
88
|
-
</system-reminder>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Usage
|
|
92
|
-
|
|
93
|
-
**Automatic - No Configuration Needed:**
|
|
94
|
-
|
|
95
|
-
```ruby
|
|
96
|
-
swarm = SwarmSDK.build do
|
|
97
|
-
agent :my_agent do
|
|
98
|
-
model "gpt-4"
|
|
99
|
-
base_url "http://proxy.example.com/v1" # Can fail
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Automatically retries on failure and recovers from orphan tool calls
|
|
104
|
-
response = swarm.execute("Do something")
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Logging
|
|
108
|
-
|
|
109
|
-
**On Retry:**
|
|
110
|
-
```
|
|
111
|
-
WARN: SwarmSDK: LLM call failed (attempt 1/10): Faraday::ConnectionFailed: Connection failed
|
|
112
|
-
WARN: SwarmSDK: Retrying in 10 seconds...
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
**On Max Retries:**
|
|
116
|
-
```
|
|
117
|
-
ERROR: SwarmSDK: LLM call failed after 10 attempts: Faraday::ConnectionFailed: Connection failed
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Behavior
|
|
121
|
-
|
|
122
|
-
**Scenario 1: Transient failure**
|
|
123
|
-
```
|
|
124
|
-
Attempt 1: ConnectionFailed
|
|
125
|
-
→ Wait 10s
|
|
126
|
-
Attempt 2: ConnectionFailed
|
|
127
|
-
→ Wait 10s
|
|
128
|
-
Attempt 3: Success
|
|
129
|
-
→ Returns response
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**Scenario 2: Persistent failure**
|
|
133
|
-
```
|
|
134
|
-
Attempt 1-10: All fail
|
|
135
|
-
→ Raises original error after attempt 10
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
**Scenario 3: Immediate success**
|
|
139
|
-
```
|
|
140
|
-
Attempt 1: Success
|
|
141
|
-
→ Returns response (no retry needed)
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Scenario 4: Orphan tool call recovery**
|
|
145
|
-
```
|
|
146
|
-
Attempt 1: BadRequestError (tool_use without tool_result)
|
|
147
|
-
→ Detect orphan tool calls
|
|
148
|
-
→ Prune orphan tool calls from message history
|
|
149
|
-
→ Retry immediately (doesn't count as retry)
|
|
150
|
-
Attempt 1: Success
|
|
151
|
-
→ Returns response
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Why No Exponential Backoff
|
|
155
|
-
|
|
156
|
-
**Design Decision:** Fixed 10-second delay
|
|
157
|
-
|
|
158
|
-
**Rationale:**
|
|
159
|
-
- Simpler implementation
|
|
160
|
-
- Predictable retry duration (max 100 seconds)
|
|
161
|
-
- Transient proxy/network issues typically resolve within seconds
|
|
162
|
-
- Rate limit errors are caught by provider-specific handling
|
|
163
|
-
- User explicitly requested fixed delays
|
|
164
|
-
|
|
165
|
-
**Total max time:** 10 retries × 10 seconds = 100 seconds maximum
|
|
166
|
-
|
|
167
|
-
## Future Enhancements (If Needed)
|
|
168
|
-
|
|
169
|
-
- [ ] Configurable retry count per agent
|
|
170
|
-
- [ ] Configurable delay per agent
|
|
171
|
-
- [ ] Selective retry based on error type
|
|
172
|
-
- [ ] Exponential backoff option
|
|
173
|
-
- [ ] Circuit breaker pattern
|
|
174
|
-
|
|
175
|
-
**Current State:** Production-ready with sensible defaults for proxy/network resilience and automatic orphan tool call recovery.
|