swarm_memory 2.1.5 → 2.1.6
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_memory/version.rb +1 -1
- metadata +5 -184
- data/lib/claude_swarm/base_executor.rb +0 -133
- data/lib/claude_swarm/claude_code_executor.rb +0 -349
- data/lib/claude_swarm/claude_mcp_server.rb +0 -78
- data/lib/claude_swarm/cli.rb +0 -697
- data/lib/claude_swarm/commands/ps.rb +0 -215
- data/lib/claude_swarm/commands/show.rb +0 -139
- data/lib/claude_swarm/configuration.rb +0 -373
- data/lib/claude_swarm/hooks/session_start_hook.rb +0 -42
- data/lib/claude_swarm/json_handler.rb +0 -91
- data/lib/claude_swarm/mcp_generator.rb +0 -230
- data/lib/claude_swarm/openai/chat_completion.rb +0 -256
- data/lib/claude_swarm/openai/executor.rb +0 -256
- data/lib/claude_swarm/openai/responses.rb +0 -319
- data/lib/claude_swarm/orchestrator.rb +0 -878
- data/lib/claude_swarm/process_tracker.rb +0 -78
- data/lib/claude_swarm/session_cost_calculator.rb +0 -209
- data/lib/claude_swarm/session_path.rb +0 -42
- data/lib/claude_swarm/settings_generator.rb +0 -77
- data/lib/claude_swarm/system_utils.rb +0 -46
- data/lib/claude_swarm/templates/generation_prompt.md.erb +0 -230
- data/lib/claude_swarm/tools/reset_session_tool.rb +0 -24
- data/lib/claude_swarm/tools/session_info_tool.rb +0 -24
- data/lib/claude_swarm/tools/task_tool.rb +0 -63
- data/lib/claude_swarm/version.rb +0 -5
- data/lib/claude_swarm/worktree_manager.rb +0 -475
- data/lib/claude_swarm/yaml_loader.rb +0 -22
- data/lib/claude_swarm.rb +0 -67
- data/lib/swarm_cli/cli.rb +0 -201
- data/lib/swarm_cli/command_registry.rb +0 -61
- data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
- data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
- data/lib/swarm_cli/commands/migrate.rb +0 -55
- data/lib/swarm_cli/commands/run.rb +0 -173
- data/lib/swarm_cli/config_loader.rb +0 -98
- data/lib/swarm_cli/formatters/human_formatter.rb +0 -781
- data/lib/swarm_cli/formatters/json_formatter.rb +0 -51
- data/lib/swarm_cli/interactive_repl.rb +0 -924
- data/lib/swarm_cli/mcp_serve_options.rb +0 -44
- data/lib/swarm_cli/mcp_tools_options.rb +0 -59
- data/lib/swarm_cli/migrate_options.rb +0 -54
- data/lib/swarm_cli/migrator.rb +0 -132
- data/lib/swarm_cli/options.rb +0 -151
- data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
- data/lib/swarm_cli/ui/components/content_block.rb +0 -120
- data/lib/swarm_cli/ui/components/divider.rb +0 -57
- data/lib/swarm_cli/ui/components/panel.rb +0 -62
- data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
- data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
- data/lib/swarm_cli/ui/formatters/number.rb +0 -58
- data/lib/swarm_cli/ui/formatters/text.rb +0 -77
- data/lib/swarm_cli/ui/formatters/time.rb +0 -73
- data/lib/swarm_cli/ui/icons.rb +0 -36
- data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
- data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
- data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
- data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
- data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
- data/lib/swarm_cli/version.rb +0 -5
- data/lib/swarm_cli.rb +0 -46
- data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -127
- data/lib/swarm_sdk/agent/builder.rb +0 -552
- data/lib/swarm_sdk/agent/chat.rb +0 -774
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -268
- 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 -78
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -233
- 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 -136
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -98
- data/lib/swarm_sdk/agent/context.rb +0 -116
- data/lib/swarm_sdk/agent/context_manager.rb +0 -315
- data/lib/swarm_sdk/agent/definition.rb +0 -477
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -182
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
- data/lib/swarm_sdk/builders/base_builder.rb +0 -409
- data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
- data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
- data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
- data/lib/swarm_sdk/concerns/validatable.rb +0 -55
- data/lib/swarm_sdk/configuration/parser.rb +0 -353
- data/lib/swarm_sdk/configuration/translator.rb +0 -255
- data/lib/swarm_sdk/configuration.rb +0 -135
- data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
- data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -106
- 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/defaults.rb +0 -196
- 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 -255
- 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 -1
- data/lib/swarm_sdk/models.rb +0 -120
- 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 -236
- 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 -117
- data/lib/swarm_sdk/restore_result.rb +0 -65
- data/lib/swarm_sdk/result.rb +0 -123
- 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 -683
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -167
- data/lib/swarm_sdk/swarm/builder.rb +0 -249
- data/lib/swarm_sdk/swarm/executor.rb +0 -213
- data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -150
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -340
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -154
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
- data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -358
- data/lib/swarm_sdk/swarm.rb +0 -717
- data/lib/swarm_sdk/swarm_loader.rb +0 -145
- data/lib/swarm_sdk/swarm_registry.rb +0 -136
- data/lib/swarm_sdk/tools/bash.rb +0 -282
- data/lib/swarm_sdk/tools/clock.rb +0 -44
- data/lib/swarm_sdk/tools/delegate.rb +0 -267
- 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 -163
- data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
- 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 -272
- 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 -98
- data/lib/swarm_sdk/tools/todo_write.rb +0 -235
- data/lib/swarm_sdk/tools/web_fetch.rb +0 -262
- data/lib/swarm_sdk/tools/write.rb +0 -112
- 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 -79
- data/lib/swarm_sdk/workflow/builder.rb +0 -143
- data/lib/swarm_sdk/workflow/executor.rb +0 -497
- data/lib/swarm_sdk/workflow/node_builder.rb +0 -555
- data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -249
- data/lib/swarm_sdk/workflow.rb +0 -554
- data/lib/swarm_sdk.rb +0 -524
|
@@ -1,683 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
class Swarm
|
|
5
|
-
# Handles the complex 5-pass agent initialization process
|
|
6
|
-
#
|
|
7
|
-
# Responsibilities:
|
|
8
|
-
# - Create all agent chat instances (pass 1)
|
|
9
|
-
# - Register delegation tools (pass 2)
|
|
10
|
-
# - Setup agent contexts (pass 3)
|
|
11
|
-
# - Configure hook system (pass 4)
|
|
12
|
-
# - Apply YAML hooks if present (pass 5)
|
|
13
|
-
#
|
|
14
|
-
# This encapsulates the complex initialization logic that was previously
|
|
15
|
-
# embedded in Swarm#initialize_agents.
|
|
16
|
-
class AgentInitializer
|
|
17
|
-
# Initialize with swarm reference (all data accessible via swarm)
|
|
18
|
-
#
|
|
19
|
-
# @param swarm [Swarm] The parent swarm instance
|
|
20
|
-
def initialize(swarm)
|
|
21
|
-
@swarm = swarm
|
|
22
|
-
@agents = {}
|
|
23
|
-
@agent_contexts = {}
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# Initialize all agents with their chat instances and tools
|
|
27
|
-
#
|
|
28
|
-
# This implements a 5-pass algorithm:
|
|
29
|
-
# 1. Create all Agent::Chat instances
|
|
30
|
-
# 2. Register delegation tools (agents can call each other)
|
|
31
|
-
# 3. Setup agent contexts for tracking
|
|
32
|
-
# 4. Configure hook system
|
|
33
|
-
# 5. Apply YAML hooks (if loaded from YAML)
|
|
34
|
-
#
|
|
35
|
-
# @return [Hash] agents hash { agent_name => Agent::Chat }
|
|
36
|
-
def initialize_all
|
|
37
|
-
pass_1_create_agents
|
|
38
|
-
pass_2_register_delegation_tools
|
|
39
|
-
pass_3_setup_contexts
|
|
40
|
-
pass_4_configure_hooks
|
|
41
|
-
pass_5_apply_yaml_hooks
|
|
42
|
-
|
|
43
|
-
@agents
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Provide access to agent contexts for Swarm
|
|
47
|
-
attr_reader :agent_contexts
|
|
48
|
-
|
|
49
|
-
# Initialize a single agent in isolation (for observer agents)
|
|
50
|
-
#
|
|
51
|
-
# Creates an isolated agent chat without delegation tools,
|
|
52
|
-
# suitable for observer agents that don't need to delegate.
|
|
53
|
-
# Reuses existing create_agent_chat infrastructure.
|
|
54
|
-
#
|
|
55
|
-
# @param agent_name [Symbol] Name of agent to initialize
|
|
56
|
-
# @return [Agent::Chat] Isolated agent chat instance
|
|
57
|
-
# @raise [ConfigurationError] If agent not found
|
|
58
|
-
#
|
|
59
|
-
# @example
|
|
60
|
-
# initializer = AgentInitializer.new(swarm)
|
|
61
|
-
# chat = initializer.initialize_isolated_agent(:profiler)
|
|
62
|
-
# chat.ask("Analyze this prompt")
|
|
63
|
-
def initialize_isolated_agent(agent_name)
|
|
64
|
-
agent_def = @swarm.agent_definitions[agent_name]
|
|
65
|
-
raise ConfigurationError, "Agent '#{agent_name}' not found" unless agent_def
|
|
66
|
-
|
|
67
|
-
# Ensure plugin storages are created (needed by ToolConfigurator)
|
|
68
|
-
create_plugin_storages if @swarm.plugin_storages.empty?
|
|
69
|
-
|
|
70
|
-
# Reuse existing create_agent_chat infrastructure
|
|
71
|
-
tool_configurator = ToolConfigurator.new(
|
|
72
|
-
@swarm,
|
|
73
|
-
@swarm.scratchpad_storage,
|
|
74
|
-
@swarm.plugin_storages,
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
# Create chat using same method as pass_1_create_agents
|
|
78
|
-
# This gives us full tool setup, MCP servers, etc.
|
|
79
|
-
create_agent_chat(agent_name, agent_def, tool_configurator)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Create a tool that delegates work to another agent
|
|
83
|
-
#
|
|
84
|
-
# This method is public for testing delegation from Swarm.
|
|
85
|
-
#
|
|
86
|
-
# @param name [String] Delegate agent name
|
|
87
|
-
# @param description [String] Delegate agent description
|
|
88
|
-
# @param delegate_chat [Agent::Chat] The delegate's chat instance
|
|
89
|
-
# @param agent_name [Symbol] Name of the delegating agent
|
|
90
|
-
# @param delegating_chat [Agent::Chat, nil] The chat instance of the agent doing the delegating
|
|
91
|
-
# @return [Tools::Delegate] Delegation tool
|
|
92
|
-
def create_delegation_tool(name:, description:, delegate_chat:, agent_name:, delegating_chat: nil)
|
|
93
|
-
Tools::Delegate.new(
|
|
94
|
-
delegate_name: name,
|
|
95
|
-
delegate_description: description,
|
|
96
|
-
delegate_chat: delegate_chat,
|
|
97
|
-
agent_name: agent_name,
|
|
98
|
-
swarm: @swarm,
|
|
99
|
-
delegating_chat: delegating_chat,
|
|
100
|
-
)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
# Pass 1: Create primary agent chat instances
|
|
106
|
-
#
|
|
107
|
-
# Only creates agents that will actually be used as primaries:
|
|
108
|
-
# - The lead agent
|
|
109
|
-
# - Agents with shared_across_delegations: true (shared delegates)
|
|
110
|
-
# - Agents not used as delegates (standalone agents)
|
|
111
|
-
#
|
|
112
|
-
# Agents that are ONLY delegates with shared_across_delegations: false
|
|
113
|
-
# are NOT created here - they'll be created as delegation instances in pass 2a.
|
|
114
|
-
def pass_1_create_agents
|
|
115
|
-
# Create plugin storages for agents
|
|
116
|
-
create_plugin_storages
|
|
117
|
-
|
|
118
|
-
tool_configurator = ToolConfigurator.new(@swarm, @swarm.scratchpad_storage, @swarm.plugin_storages)
|
|
119
|
-
|
|
120
|
-
@swarm.agent_definitions.each do |name, agent_definition|
|
|
121
|
-
# Skip if this agent will only exist as delegation instances
|
|
122
|
-
next if should_skip_primary_creation?(name, agent_definition)
|
|
123
|
-
|
|
124
|
-
chat = create_agent_chat(name, agent_definition, tool_configurator)
|
|
125
|
-
@agents[name] = chat
|
|
126
|
-
|
|
127
|
-
# Notify plugins that agent was initialized
|
|
128
|
-
notify_plugins_agent_initialized(name, chat, agent_definition, tool_configurator)
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# Pass 2: Create delegation instances and wire delegation tools
|
|
133
|
-
#
|
|
134
|
-
# This pass has three sub-steps that must happen in order:
|
|
135
|
-
# 2a. Create delegation instances (ONLY for agents with shared_across_delegations: false)
|
|
136
|
-
# 2b. Wire primary agents to delegation instances OR shared primaries
|
|
137
|
-
# 2c. Wire delegation instances to their delegates (nested delegation support)
|
|
138
|
-
def pass_2_register_delegation_tools
|
|
139
|
-
tool_configurator = ToolConfigurator.new(@swarm, @swarm.scratchpad_storage, @swarm.plugin_storages)
|
|
140
|
-
|
|
141
|
-
# Sub-pass 2a: Create delegation instances for isolated agents
|
|
142
|
-
@swarm.agent_definitions.each do |delegator_name, delegator_def|
|
|
143
|
-
delegator_def.delegates_to.each do |delegate_base_name|
|
|
144
|
-
delegate_base_name = delegate_base_name.to_sym
|
|
145
|
-
|
|
146
|
-
unless @swarm.agent_definitions.key?(delegate_base_name)
|
|
147
|
-
raise ConfigurationError,
|
|
148
|
-
"Agent '#{delegator_name}' delegates to unknown agent '#{delegate_base_name}'"
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
delegate_definition = @swarm.agent_definitions[delegate_base_name]
|
|
152
|
-
|
|
153
|
-
# Check isolation mode of the DELEGATE agent
|
|
154
|
-
# If delegate wants to be shared, skip instance creation (use primary)
|
|
155
|
-
next if delegate_definition.shared_across_delegations
|
|
156
|
-
|
|
157
|
-
# Create unique delegation instance (isolated mode)
|
|
158
|
-
instance_name = "#{delegate_base_name}@#{delegator_name}"
|
|
159
|
-
|
|
160
|
-
# V7.0: Use existing register_all_tools (no new method needed!)
|
|
161
|
-
delegation_chat = create_agent_chat_for_delegation(
|
|
162
|
-
instance_name: instance_name,
|
|
163
|
-
base_name: delegate_base_name,
|
|
164
|
-
agent_definition: delegate_definition,
|
|
165
|
-
tool_configurator: tool_configurator,
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
# Store in delegation_instances hash
|
|
169
|
-
@swarm.delegation_instances[instance_name] = delegation_chat
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Sub-pass 2b: Wire primary agents to delegation instances OR shared primaries OR registered swarms
|
|
174
|
-
@swarm.agent_definitions.each do |delegator_name, delegator_def|
|
|
175
|
-
delegator_chat = @agents[delegator_name]
|
|
176
|
-
|
|
177
|
-
# Skip if delegator doesn't exist as primary (wasn't created in pass_1)
|
|
178
|
-
next unless delegator_chat
|
|
179
|
-
|
|
180
|
-
delegator_def.delegates_to.each do |delegate_name|
|
|
181
|
-
wire_delegation(
|
|
182
|
-
delegator_name: delegator_name,
|
|
183
|
-
delegator_chat: delegator_chat,
|
|
184
|
-
delegate_name: delegate_name,
|
|
185
|
-
tool_configurator: tool_configurator,
|
|
186
|
-
create_nested_instances: false,
|
|
187
|
-
)
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# Sub-pass 2c: Wire delegation instances to their delegates (nested delegation)
|
|
192
|
-
# Convert to array first to avoid "can't add key during iteration" error
|
|
193
|
-
@swarm.delegation_instances.to_a.each do |instance_name, delegation_chat|
|
|
194
|
-
base_name = extract_base_name(instance_name)
|
|
195
|
-
delegate_definition = @swarm.agent_definitions[base_name]
|
|
196
|
-
|
|
197
|
-
# Register delegation tools for THIS instance's delegates_to
|
|
198
|
-
delegate_definition.delegates_to.each do |nested_delegate_name|
|
|
199
|
-
wire_delegation(
|
|
200
|
-
delegator_name: instance_name.to_sym,
|
|
201
|
-
delegator_chat: delegation_chat,
|
|
202
|
-
delegate_name: nested_delegate_name,
|
|
203
|
-
tool_configurator: tool_configurator,
|
|
204
|
-
create_nested_instances: true,
|
|
205
|
-
)
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
# Wire a single delegation from one agent/instance to a delegate
|
|
211
|
-
#
|
|
212
|
-
# This is the unified logic for delegation wiring used by both:
|
|
213
|
-
# - Sub-pass 2b: Primary agents → delegates
|
|
214
|
-
# - Sub-pass 2c: Delegation instances → nested delegates
|
|
215
|
-
#
|
|
216
|
-
# @param delegator_name [Symbol, String] Name of the agent doing the delegating
|
|
217
|
-
# @param delegator_chat [Agent::Chat] Chat instance of the delegator
|
|
218
|
-
# @param delegate_name [Symbol, String] Name of the delegate target
|
|
219
|
-
# @param tool_configurator [ToolConfigurator] Tool configuration helper
|
|
220
|
-
# @param create_nested_instances [Boolean] Whether to create new instances for nested delegation
|
|
221
|
-
# @return [void]
|
|
222
|
-
def wire_delegation(delegator_name:, delegator_chat:, delegate_name:, tool_configurator:, create_nested_instances:)
|
|
223
|
-
delegate_name_str = delegate_name.to_s
|
|
224
|
-
delegate_name_sym = delegate_name.to_sym
|
|
225
|
-
|
|
226
|
-
# Check if target is a registered swarm
|
|
227
|
-
if @swarm.swarm_registry&.registered?(delegate_name_str)
|
|
228
|
-
wire_swarm_delegation(delegator_name, delegator_chat, delegate_name_str)
|
|
229
|
-
elsif @swarm.agent_definitions.key?(delegate_name_sym)
|
|
230
|
-
wire_agent_delegation(
|
|
231
|
-
delegator_name: delegator_name,
|
|
232
|
-
delegator_chat: delegator_chat,
|
|
233
|
-
delegate_name_sym: delegate_name_sym,
|
|
234
|
-
tool_configurator: tool_configurator,
|
|
235
|
-
create_nested_instances: create_nested_instances,
|
|
236
|
-
)
|
|
237
|
-
else
|
|
238
|
-
raise ConfigurationError,
|
|
239
|
-
"Agent '#{delegator_name}' delegates to unknown target '#{delegate_name_str}' (not a local agent or registered swarm)"
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
# Wire delegation to an external swarm
|
|
244
|
-
#
|
|
245
|
-
# @param delegator_name [Symbol, String] Name of the delegating agent
|
|
246
|
-
# @param delegator_chat [Agent::Chat] Chat instance of the delegator
|
|
247
|
-
# @param swarm_name [String] Name of the registered swarm
|
|
248
|
-
# @return [void]
|
|
249
|
-
def wire_swarm_delegation(delegator_name, delegator_chat, swarm_name)
|
|
250
|
-
tool = create_delegation_tool(
|
|
251
|
-
name: swarm_name,
|
|
252
|
-
description: "External swarm: #{swarm_name}",
|
|
253
|
-
delegate_chat: nil, # Swarm delegation - no direct chat
|
|
254
|
-
agent_name: delegator_name,
|
|
255
|
-
delegating_chat: delegator_chat,
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
delegator_chat.add_tool(tool)
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
# Wire delegation to a local agent
|
|
262
|
-
#
|
|
263
|
-
# Determines whether to use shared primary or isolated instance based on
|
|
264
|
-
# the delegate's shared_across_delegations setting.
|
|
265
|
-
#
|
|
266
|
-
# @param delegator_name [Symbol, String] Name of the delegating agent
|
|
267
|
-
# @param delegator_chat [Agent::Chat] Chat instance of the delegator
|
|
268
|
-
# @param delegate_name_sym [Symbol] Name of the delegate agent
|
|
269
|
-
# @param tool_configurator [ToolConfigurator] Tool configuration helper
|
|
270
|
-
# @param create_nested_instances [Boolean] Whether to create new instances if not found
|
|
271
|
-
# @return [void]
|
|
272
|
-
def wire_agent_delegation(delegator_name:, delegator_chat:, delegate_name_sym:, tool_configurator:, create_nested_instances:)
|
|
273
|
-
delegate_definition = @swarm.agent_definitions[delegate_name_sym]
|
|
274
|
-
|
|
275
|
-
# Determine which chat instance to use
|
|
276
|
-
target_chat = if delegate_definition.shared_across_delegations
|
|
277
|
-
# Shared mode: use primary agent (semaphore-protected)
|
|
278
|
-
@agents[delegate_name_sym]
|
|
279
|
-
else
|
|
280
|
-
# Isolated mode: use delegation instance
|
|
281
|
-
instance_name = "#{delegate_name_sym}@#{delegator_name}"
|
|
282
|
-
|
|
283
|
-
if create_nested_instances
|
|
284
|
-
# For nested delegation: create if not exists
|
|
285
|
-
@swarm.delegation_instances[instance_name] ||= create_agent_chat_for_delegation(
|
|
286
|
-
instance_name: instance_name,
|
|
287
|
-
base_name: delegate_name_sym,
|
|
288
|
-
agent_definition: delegate_definition,
|
|
289
|
-
tool_configurator: tool_configurator,
|
|
290
|
-
)
|
|
291
|
-
else
|
|
292
|
-
# For primary delegation: instance was pre-created in 2a
|
|
293
|
-
@swarm.delegation_instances[instance_name]
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
# Create delegation tool pointing to chosen instance
|
|
298
|
-
tool = create_delegation_tool(
|
|
299
|
-
name: delegate_name_sym.to_s,
|
|
300
|
-
description: delegate_definition.description,
|
|
301
|
-
delegate_chat: target_chat,
|
|
302
|
-
agent_name: delegator_name,
|
|
303
|
-
delegating_chat: delegator_chat,
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
delegator_chat.add_tool(tool)
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
# Pass 3: Setup agent contexts
|
|
310
|
-
#
|
|
311
|
-
# Create Agent::Context for each agent to track delegations and metadata.
|
|
312
|
-
# This is needed regardless of whether logging is enabled.
|
|
313
|
-
def pass_3_setup_contexts
|
|
314
|
-
# Setup contexts for PRIMARY agents
|
|
315
|
-
@agents.each do |agent_name, chat|
|
|
316
|
-
setup_agent_context(agent_name, @swarm.agent_definitions[agent_name], chat, is_delegation: false)
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
# Setup contexts for DELEGATION instances
|
|
320
|
-
@swarm.delegation_instances.each do |instance_name, chat|
|
|
321
|
-
base_name = extract_base_name(instance_name)
|
|
322
|
-
agent_definition = @swarm.agent_definitions[base_name]
|
|
323
|
-
setup_agent_context(instance_name.to_sym, agent_definition, chat, is_delegation: true)
|
|
324
|
-
end
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
# Setup context for an agent (primary or delegation instance)
|
|
328
|
-
def setup_agent_context(agent_name, agent_definition, chat, is_delegation: false)
|
|
329
|
-
delegate_tool_names = agent_definition.delegates_to.map do |delegate_name|
|
|
330
|
-
Tools::Delegate.tool_name_for(delegate_name)
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
context = Agent::Context.new(
|
|
334
|
-
name: agent_name,
|
|
335
|
-
swarm_id: @swarm.swarm_id,
|
|
336
|
-
parent_swarm_id: @swarm.parent_swarm_id,
|
|
337
|
-
delegation_tools: delegate_tool_names,
|
|
338
|
-
metadata: { is_delegation_instance: is_delegation },
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
# Store context (only for primaries)
|
|
342
|
-
@agent_contexts[agent_name] = context unless is_delegation
|
|
343
|
-
|
|
344
|
-
# Always set agent context on chat
|
|
345
|
-
chat.setup_context(context) if chat.respond_to?(:setup_context)
|
|
346
|
-
|
|
347
|
-
# Configure logging if enabled
|
|
348
|
-
return unless LogStream.emitter
|
|
349
|
-
|
|
350
|
-
chat.setup_logging if chat.respond_to?(:setup_logging)
|
|
351
|
-
|
|
352
|
-
# Emit validation warnings (only for primaries, not each delegation instance)
|
|
353
|
-
emit_validation_warnings(agent_name, agent_definition) unless is_delegation
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# Emit validation warnings as log events
|
|
357
|
-
#
|
|
358
|
-
# This validates the agent definition and emits any warnings as log events
|
|
359
|
-
# through LogStream (so formatters can handle them).
|
|
360
|
-
#
|
|
361
|
-
# @param agent_name [Symbol] Agent name
|
|
362
|
-
# @param agent_definition [Agent::Definition] Agent definition to validate
|
|
363
|
-
# @return [void]
|
|
364
|
-
def emit_validation_warnings(agent_name, agent_definition)
|
|
365
|
-
warnings = agent_definition.validate
|
|
366
|
-
|
|
367
|
-
warnings.each do |warning|
|
|
368
|
-
case warning[:type]
|
|
369
|
-
when :model_not_found
|
|
370
|
-
LogStream.emit(
|
|
371
|
-
type: "model_lookup_warning",
|
|
372
|
-
agent: agent_name,
|
|
373
|
-
model: warning[:model],
|
|
374
|
-
error_message: warning[:error_message],
|
|
375
|
-
suggestions: warning[:suggestions],
|
|
376
|
-
timestamp: Time.now.utc.iso8601,
|
|
377
|
-
)
|
|
378
|
-
end
|
|
379
|
-
end
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
# Pass 4: Configure hook system
|
|
383
|
-
#
|
|
384
|
-
# Setup the callback system for each agent, integrating with RubyLLM callbacks.
|
|
385
|
-
def pass_4_configure_hooks
|
|
386
|
-
# Configure hooks for PRIMARY agents
|
|
387
|
-
@agents.each do |agent_name, chat|
|
|
388
|
-
configure_hooks_for_agent(agent_name, chat)
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
# Configure hooks for DELEGATION instances
|
|
392
|
-
@swarm.delegation_instances.each do |instance_name, chat|
|
|
393
|
-
configure_hooks_for_agent(instance_name.to_sym, chat)
|
|
394
|
-
end
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
# Configure hooks for an agent (primary or delegation instance)
|
|
398
|
-
def configure_hooks_for_agent(agent_name, chat)
|
|
399
|
-
base_name = extract_base_name(agent_name)
|
|
400
|
-
agent_definition = @swarm.agent_definitions[base_name]
|
|
401
|
-
|
|
402
|
-
chat.setup_hooks(
|
|
403
|
-
registry: @swarm.hook_registry,
|
|
404
|
-
agent_definition: agent_definition,
|
|
405
|
-
swarm: @swarm,
|
|
406
|
-
) if chat.respond_to?(:setup_hooks)
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
# Pass 5: Apply YAML hooks
|
|
410
|
-
#
|
|
411
|
-
# If the swarm was loaded from YAML with agent-specific hooks,
|
|
412
|
-
# apply them now via HooksAdapter.
|
|
413
|
-
def pass_5_apply_yaml_hooks
|
|
414
|
-
return unless @swarm.config_for_hooks
|
|
415
|
-
|
|
416
|
-
# Apply YAML hooks to PRIMARY agents
|
|
417
|
-
@agents.each do |agent_name, chat|
|
|
418
|
-
apply_yaml_hooks_for_agent(agent_name, chat)
|
|
419
|
-
end
|
|
420
|
-
|
|
421
|
-
# Apply YAML hooks to DELEGATION instances
|
|
422
|
-
@swarm.delegation_instances.each do |instance_name, chat|
|
|
423
|
-
apply_yaml_hooks_for_agent(instance_name.to_sym, chat)
|
|
424
|
-
end
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
# Apply YAML hooks for an agent (primary or delegation instance)
|
|
428
|
-
def apply_yaml_hooks_for_agent(agent_name, chat)
|
|
429
|
-
base_name = extract_base_name(agent_name)
|
|
430
|
-
agent_config = @swarm.config_for_hooks.agents[base_name]
|
|
431
|
-
return unless agent_config
|
|
432
|
-
|
|
433
|
-
# Configuration.agents now returns hashes, not Definitions
|
|
434
|
-
hooks = agent_config.is_a?(Hash) ? agent_config[:hooks] : agent_config.hooks
|
|
435
|
-
return unless hooks&.any?
|
|
436
|
-
|
|
437
|
-
Hooks::Adapter.apply_agent_hooks(chat, agent_name, hooks, @swarm.name)
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
# Create Agent::Chat instance with rate limiting
|
|
441
|
-
#
|
|
442
|
-
# @param agent_name [Symbol] Agent name
|
|
443
|
-
# @param agent_definition [Agent::Definition] Agent definition object
|
|
444
|
-
# @param tool_configurator [ToolConfigurator] Tool configuration helper
|
|
445
|
-
# @return [Agent::Chat] Configured agent chat instance
|
|
446
|
-
def create_agent_chat(agent_name, agent_definition, tool_configurator)
|
|
447
|
-
chat = Agent::Chat.new(
|
|
448
|
-
definition: agent_definition.to_h,
|
|
449
|
-
agent_name: agent_name,
|
|
450
|
-
global_semaphore: @swarm.global_semaphore,
|
|
451
|
-
)
|
|
452
|
-
|
|
453
|
-
# Set agent name on provider for logging (if provider supports it)
|
|
454
|
-
chat.provider.agent_name = agent_name if chat.provider.respond_to?(:agent_name=)
|
|
455
|
-
|
|
456
|
-
# Register tools using ToolConfigurator
|
|
457
|
-
tool_configurator.register_all_tools(
|
|
458
|
-
chat: chat,
|
|
459
|
-
agent_name: agent_name,
|
|
460
|
-
agent_definition: agent_definition,
|
|
461
|
-
)
|
|
462
|
-
|
|
463
|
-
# Register MCP servers using McpConfigurator
|
|
464
|
-
if agent_definition.mcp_servers.any?
|
|
465
|
-
mcp_configurator = McpConfigurator.new(@swarm)
|
|
466
|
-
mcp_configurator.register_mcp_servers(chat, agent_definition.mcp_servers, agent_name: agent_name)
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
chat
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
# Create a delegation-specific instance of an agent
|
|
473
|
-
#
|
|
474
|
-
# V7.0: Simplified - just calls register_all_tools with instance_name
|
|
475
|
-
#
|
|
476
|
-
# @param instance_name [String] Unique instance name ("base@delegator")
|
|
477
|
-
# @param base_name [Symbol] Base agent name (for definition lookup)
|
|
478
|
-
# @param agent_definition [Agent::Definition] Base agent definition
|
|
479
|
-
# @param tool_configurator [ToolConfigurator] Shared tool configurator
|
|
480
|
-
# @return [Agent::Chat] Delegation-specific chat instance
|
|
481
|
-
def create_agent_chat_for_delegation(instance_name:, base_name:, agent_definition:, tool_configurator:)
|
|
482
|
-
# Create chat with instance_name for isolated conversation + tool state
|
|
483
|
-
chat = Agent::Chat.new(
|
|
484
|
-
definition: agent_definition.to_h,
|
|
485
|
-
agent_name: instance_name.to_sym, # Full instance name for isolation
|
|
486
|
-
global_semaphore: @swarm.global_semaphore,
|
|
487
|
-
)
|
|
488
|
-
|
|
489
|
-
# Set provider agent name for logging
|
|
490
|
-
chat.provider.agent_name = instance_name if chat.provider.respond_to?(:agent_name=)
|
|
491
|
-
|
|
492
|
-
# V7.0 SIMPLIFIED: Just call register_all_tools with instance_name!
|
|
493
|
-
# Base name extraction happens automatically in create_plugin_tool
|
|
494
|
-
tool_configurator.register_all_tools(
|
|
495
|
-
chat: chat,
|
|
496
|
-
agent_name: instance_name.to_sym,
|
|
497
|
-
agent_definition: agent_definition,
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
# Register MCP servers (tracked by instance_name automatically)
|
|
501
|
-
if agent_definition.mcp_servers.any?
|
|
502
|
-
mcp_configurator = McpConfigurator.new(@swarm)
|
|
503
|
-
mcp_configurator.register_mcp_servers(
|
|
504
|
-
chat,
|
|
505
|
-
agent_definition.mcp_servers,
|
|
506
|
-
agent_name: instance_name,
|
|
507
|
-
)
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
# Notify plugins (use instance_name, plugins extract base_name if needed)
|
|
511
|
-
notify_plugins_agent_initialized(instance_name.to_sym, chat, agent_definition, tool_configurator)
|
|
512
|
-
|
|
513
|
-
chat
|
|
514
|
-
end
|
|
515
|
-
|
|
516
|
-
# Register agent delegation tools
|
|
517
|
-
#
|
|
518
|
-
# Creates delegation tools that allow one agent to call another.
|
|
519
|
-
#
|
|
520
|
-
# @param chat [Agent::Chat] The chat instance
|
|
521
|
-
# @param delegate_names [Array<Symbol>] Names of agents to delegate to
|
|
522
|
-
# @param agent_name [Symbol] Name of the agent doing the delegating
|
|
523
|
-
def register_delegation_tools(chat, delegate_names, agent_name:)
|
|
524
|
-
return if delegate_names.empty?
|
|
525
|
-
|
|
526
|
-
delegate_names.each do |delegate_name|
|
|
527
|
-
delegate_name_sym = delegate_name.to_sym
|
|
528
|
-
delegate_name_str = delegate_name.to_s
|
|
529
|
-
|
|
530
|
-
# Check if target is a local agent
|
|
531
|
-
if @agents.key?(delegate_name_sym)
|
|
532
|
-
# Delegate to local agent
|
|
533
|
-
delegate_agent = @agents[delegate_name_sym]
|
|
534
|
-
delegate_definition = @swarm.agent_definitions[delegate_name_sym]
|
|
535
|
-
|
|
536
|
-
tool = create_delegation_tool(
|
|
537
|
-
name: delegate_name_str,
|
|
538
|
-
description: delegate_definition.description,
|
|
539
|
-
delegate_chat: delegate_agent,
|
|
540
|
-
agent_name: agent_name,
|
|
541
|
-
delegating_chat: chat,
|
|
542
|
-
)
|
|
543
|
-
|
|
544
|
-
chat.add_tool(tool)
|
|
545
|
-
elsif @swarm.swarm_registry&.registered?(delegate_name_str)
|
|
546
|
-
# Delegate to registered swarm
|
|
547
|
-
tool = create_delegation_tool(
|
|
548
|
-
name: delegate_name_str,
|
|
549
|
-
description: "External swarm: #{delegate_name_str}",
|
|
550
|
-
delegate_chat: nil, # Swarm delegation - no direct chat
|
|
551
|
-
agent_name: agent_name,
|
|
552
|
-
delegating_chat: chat,
|
|
553
|
-
)
|
|
554
|
-
|
|
555
|
-
chat.add_tool(tool)
|
|
556
|
-
else
|
|
557
|
-
raise ConfigurationError, "Agent '#{agent_name}' delegates to unknown target '#{delegate_name_str}' (not a local agent or registered swarm)"
|
|
558
|
-
end
|
|
559
|
-
end
|
|
560
|
-
end
|
|
561
|
-
|
|
562
|
-
# Create plugin storages for all agents
|
|
563
|
-
#
|
|
564
|
-
# Iterates through all registered plugins and asks each to create
|
|
565
|
-
# storage for agents that need it.
|
|
566
|
-
#
|
|
567
|
-
# @return [void]
|
|
568
|
-
def create_plugin_storages
|
|
569
|
-
PluginRegistry.all.each do |plugin|
|
|
570
|
-
@swarm.agent_definitions.each do |agent_name, agent_definition|
|
|
571
|
-
# Check if this plugin needs storage for this agent
|
|
572
|
-
next unless plugin.storage_enabled?(agent_definition)
|
|
573
|
-
|
|
574
|
-
# Get plugin config for this agent
|
|
575
|
-
config = get_plugin_config(agent_definition, plugin.name)
|
|
576
|
-
next unless config
|
|
577
|
-
|
|
578
|
-
# Parse config through plugin
|
|
579
|
-
parsed_config = plugin.parse_config(config)
|
|
580
|
-
|
|
581
|
-
# Create plugin storage
|
|
582
|
-
storage = plugin.create_storage(agent_name: agent_name, config: parsed_config)
|
|
583
|
-
|
|
584
|
-
# Store in plugin_storages: { plugin_name => { agent_name => storage } }
|
|
585
|
-
@swarm.plugin_storages[plugin.name] ||= {}
|
|
586
|
-
@swarm.plugin_storages[plugin.name][agent_name] = storage
|
|
587
|
-
end
|
|
588
|
-
end
|
|
589
|
-
end
|
|
590
|
-
|
|
591
|
-
# Get plugin-specific config from agent definition
|
|
592
|
-
#
|
|
593
|
-
# Uses the generic plugin_configs accessor to retrieve plugin-specific config.
|
|
594
|
-
# E.g., memory plugin config is accessed via `agent_definition.plugin_config(:memory)`
|
|
595
|
-
#
|
|
596
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
597
|
-
# @param plugin_name [Symbol] Plugin name
|
|
598
|
-
# @return [Object, nil] Plugin config or nil
|
|
599
|
-
def get_plugin_config(agent_definition, plugin_name)
|
|
600
|
-
# Use generic plugin config accessor
|
|
601
|
-
agent_definition.plugin_config(plugin_name)
|
|
602
|
-
end
|
|
603
|
-
|
|
604
|
-
# Notify all plugins that an agent was initialized
|
|
605
|
-
#
|
|
606
|
-
# Plugins can register additional tools, mark tools immutable, etc.
|
|
607
|
-
#
|
|
608
|
-
# @param agent_name [Symbol] Agent name
|
|
609
|
-
# @param chat [Agent::Chat] Chat instance
|
|
610
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
611
|
-
# @param tool_configurator [ToolConfigurator] Tool configurator
|
|
612
|
-
# @return [void]
|
|
613
|
-
def notify_plugins_agent_initialized(agent_name, chat, agent_definition, tool_configurator)
|
|
614
|
-
PluginRegistry.all.each do |plugin|
|
|
615
|
-
# Get plugin storage for this agent (if any)
|
|
616
|
-
plugin_storages = @swarm.plugin_storages[plugin.name] || {}
|
|
617
|
-
storage = plugin_storages[agent_name]
|
|
618
|
-
|
|
619
|
-
# Build context for plugin
|
|
620
|
-
context = {
|
|
621
|
-
storage: storage,
|
|
622
|
-
agent_definition: agent_definition,
|
|
623
|
-
tool_configurator: tool_configurator,
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
# Notify plugin
|
|
627
|
-
plugin.on_agent_initialized(agent_name: agent_name, agent: chat, context: context)
|
|
628
|
-
end
|
|
629
|
-
end
|
|
630
|
-
|
|
631
|
-
# Determine if we should skip creating a primary agent
|
|
632
|
-
#
|
|
633
|
-
# Skip if:
|
|
634
|
-
# - NOT the lead agent, AND
|
|
635
|
-
# - Has shared_across_delegations: false (isolated mode), AND
|
|
636
|
-
# - Is only referenced as a delegate (not used standalone)
|
|
637
|
-
#
|
|
638
|
-
# @param name [Symbol] Agent name
|
|
639
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
640
|
-
# @return [Boolean] True if should skip primary creation
|
|
641
|
-
def should_skip_primary_creation?(name, agent_definition)
|
|
642
|
-
# Always create lead agent
|
|
643
|
-
return false if name == @swarm.lead_agent
|
|
644
|
-
|
|
645
|
-
# If shared mode, create primary (delegates will use it)
|
|
646
|
-
return false if agent_definition.shared_across_delegations
|
|
647
|
-
|
|
648
|
-
# Skip if only used as a delegate
|
|
649
|
-
only_referenced_as_delegate?(name)
|
|
650
|
-
end
|
|
651
|
-
|
|
652
|
-
# Check if an agent is only referenced as a delegate
|
|
653
|
-
#
|
|
654
|
-
# @param name [Symbol] Agent name
|
|
655
|
-
# @return [Boolean] True if only referenced as delegate
|
|
656
|
-
def only_referenced_as_delegate?(name)
|
|
657
|
-
# Check if any agent delegates to this one
|
|
658
|
-
referenced_as_delegate = @swarm.agent_definitions.any? do |_agent_name, definition|
|
|
659
|
-
definition.delegates_to.include?(name)
|
|
660
|
-
end
|
|
661
|
-
|
|
662
|
-
# Skip if referenced as delegate (and not lead, already checked above)
|
|
663
|
-
referenced_as_delegate
|
|
664
|
-
end
|
|
665
|
-
|
|
666
|
-
# Extract base agent name from instance name
|
|
667
|
-
#
|
|
668
|
-
# @param instance_name [Symbol, String] Instance name (may be delegation instance)
|
|
669
|
-
# @return [Symbol] Base agent name
|
|
670
|
-
def extract_base_name(instance_name)
|
|
671
|
-
instance_name.to_s.split("@").first.to_sym
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
# Check if instance name is a delegation instance
|
|
675
|
-
#
|
|
676
|
-
# @param instance_name [Symbol, String] Instance name
|
|
677
|
-
# @return [Boolean] True if delegation instance (contains '@')
|
|
678
|
-
def delegation_instance?(instance_name)
|
|
679
|
-
instance_name.to_s.include?("@")
|
|
680
|
-
end
|
|
681
|
-
end
|
|
682
|
-
end
|
|
683
|
-
end
|