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,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
class Swarm
|
|
5
|
-
# Builder for swarm registry in DSL
|
|
6
|
-
#
|
|
7
|
-
# Supports registering external swarms for composable swarms pattern.
|
|
8
|
-
#
|
|
9
|
-
# @example
|
|
10
|
-
# swarms do
|
|
11
|
-
# register "code_review", file: "./swarms/code_review.rb"
|
|
12
|
-
# register "testing", file: "./swarms/testing.yml", keep_context: false
|
|
13
|
-
# end
|
|
14
|
-
#
|
|
15
|
-
# @example Inline swarm definition
|
|
16
|
-
# swarms do
|
|
17
|
-
# register "tester" do
|
|
18
|
-
# lead :tester
|
|
19
|
-
# agent :tester do
|
|
20
|
-
# model "gpt-4o-mini"
|
|
21
|
-
# system "You test code"
|
|
22
|
-
# end
|
|
23
|
-
# end
|
|
24
|
-
# end
|
|
25
|
-
#
|
|
26
|
-
class SwarmRegistryBuilder
|
|
27
|
-
attr_reader :registrations
|
|
28
|
-
|
|
29
|
-
def initialize
|
|
30
|
-
@registrations = []
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Register a swarm from file, YAML string, or inline block
|
|
34
|
-
#
|
|
35
|
-
# @param name [String, Symbol] Registration name
|
|
36
|
-
# @param file [String, nil] Path to swarm file (.rb or .yml)
|
|
37
|
-
# @param yaml [String, nil] YAML content string
|
|
38
|
-
# @param keep_context [Boolean] Whether to preserve conversation state (default: true)
|
|
39
|
-
# @yield Optional block for inline swarm definition
|
|
40
|
-
# @raise [ArgumentError] If neither file, yaml, nor block provided
|
|
41
|
-
def register(name, file: nil, yaml: nil, keep_context: true, &block)
|
|
42
|
-
# Validate that exactly one source is provided
|
|
43
|
-
sources = [file, yaml, block].compact
|
|
44
|
-
if sources.empty?
|
|
45
|
-
raise ArgumentError, "register '#{name}' requires either file:, yaml:, or a block"
|
|
46
|
-
elsif sources.size > 1
|
|
47
|
-
raise ArgumentError, "register '#{name}' accepts only one of: file:, yaml:, or block (got #{sources.size})"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Determine source type and store
|
|
51
|
-
source = if file
|
|
52
|
-
{ type: :file, value: file }
|
|
53
|
-
elsif yaml
|
|
54
|
-
{ type: :yaml, value: yaml }
|
|
55
|
-
else
|
|
56
|
-
{ type: :block, value: block }
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
@registrations << {
|
|
60
|
-
name: name.to_s,
|
|
61
|
-
source: source,
|
|
62
|
-
keep_context: keep_context,
|
|
63
|
-
}
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
class Swarm
|
|
5
|
-
# Handles tool creation, registration, and permissions wrapping
|
|
6
|
-
#
|
|
7
|
-
# Responsibilities:
|
|
8
|
-
# - Register explicit tools for agents
|
|
9
|
-
# - Register default tools (Read, Grep, Glob, etc.)
|
|
10
|
-
# - Create tool instances (with agent context)
|
|
11
|
-
# - Wrap tools with permissions validators
|
|
12
|
-
#
|
|
13
|
-
# This encapsulates all tool-related logic that was previously in Swarm.
|
|
14
|
-
class ToolConfigurator
|
|
15
|
-
# Default tools available to all agents (unless disable_default_tools is set)
|
|
16
|
-
DEFAULT_TOOLS = [
|
|
17
|
-
:Read,
|
|
18
|
-
:Grep,
|
|
19
|
-
:Glob,
|
|
20
|
-
].freeze
|
|
21
|
-
|
|
22
|
-
# Scratchpad tools (added if scratchpad is enabled)
|
|
23
|
-
SCRATCHPAD_TOOLS = [
|
|
24
|
-
:ScratchpadWrite,
|
|
25
|
-
:ScratchpadRead,
|
|
26
|
-
:ScratchpadList,
|
|
27
|
-
].freeze
|
|
28
|
-
|
|
29
|
-
# Filesystem tools that can be globally disabled for security
|
|
30
|
-
FILESYSTEM_TOOLS = [
|
|
31
|
-
:Read,
|
|
32
|
-
:Write,
|
|
33
|
-
:Edit,
|
|
34
|
-
:MultiEdit,
|
|
35
|
-
:Grep,
|
|
36
|
-
:Glob,
|
|
37
|
-
:Bash,
|
|
38
|
-
].freeze
|
|
39
|
-
|
|
40
|
-
def initialize(swarm, scratchpad_storage, plugin_storages = {})
|
|
41
|
-
@swarm = swarm
|
|
42
|
-
@scratchpad_storage = scratchpad_storage
|
|
43
|
-
# Plugin storages: { plugin_name => { agent_name => storage } }
|
|
44
|
-
# e.g., { memory: { agent1: storage1, agent2: storage2 } }
|
|
45
|
-
@plugin_storages = plugin_storages
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Register all tools for an agent (both explicit and default)
|
|
49
|
-
#
|
|
50
|
-
# @param chat [AgentChat] The chat instance to register tools with
|
|
51
|
-
# @param agent_name [Symbol] Name of the agent
|
|
52
|
-
# @param agent_definition [AgentDefinition] Agent definition object
|
|
53
|
-
def register_all_tools(chat:, agent_name:, agent_definition:)
|
|
54
|
-
register_explicit_tools(chat, agent_definition.tools, agent_name: agent_name, agent_definition: agent_definition)
|
|
55
|
-
register_default_tools(chat, agent_name: agent_name, agent_definition: agent_definition)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Create a tool instance by name
|
|
59
|
-
#
|
|
60
|
-
# Uses the Registry factory pattern to instantiate tools based on their
|
|
61
|
-
# declared requirements. This eliminates the need for a giant case statement.
|
|
62
|
-
#
|
|
63
|
-
# File tools and TodoWrite require agent context for tracking state.
|
|
64
|
-
# Scratchpad tools require shared scratchpad instance.
|
|
65
|
-
# Plugin tools are delegated to their respective plugins.
|
|
66
|
-
#
|
|
67
|
-
# This method is public for testing delegation from Swarm.
|
|
68
|
-
#
|
|
69
|
-
# @param tool_name [Symbol, String] Tool name
|
|
70
|
-
# @param agent_name [Symbol] Agent name for context
|
|
71
|
-
# @param directory [String] Agent's working directory
|
|
72
|
-
# @param chat [Agent::Chat, nil] Optional chat instance for tools that need it
|
|
73
|
-
# @param agent_definition [Agent::Definition, nil] Optional agent definition
|
|
74
|
-
# @return [RubyLLM::Tool] Tool instance
|
|
75
|
-
def create_tool_instance(tool_name, agent_name, directory, chat: nil, agent_definition: nil)
|
|
76
|
-
tool_name_sym = tool_name.to_sym
|
|
77
|
-
|
|
78
|
-
# Check if tool is provided by a plugin
|
|
79
|
-
if PluginRegistry.plugin_tool?(tool_name_sym)
|
|
80
|
-
return create_plugin_tool(tool_name_sym, agent_name, directory, chat, agent_definition)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# Use Registry factory pattern - tools declare their own requirements
|
|
84
|
-
context = {
|
|
85
|
-
agent_name: agent_name,
|
|
86
|
-
directory: directory,
|
|
87
|
-
scratchpad_storage: @scratchpad_storage,
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Tools::Registry.create(tool_name_sym, context)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Wrap a tool instance with permissions validator if configured
|
|
94
|
-
#
|
|
95
|
-
# This method is public for testing delegation from Swarm.
|
|
96
|
-
#
|
|
97
|
-
# @param tool_instance [RubyLLM::Tool] Tool instance to wrap
|
|
98
|
-
# @param permissions_config [Hash, nil] Permission configuration
|
|
99
|
-
# @param agent_definition [AgentDefinition] Agent definition
|
|
100
|
-
# @return [RubyLLM::Tool] Either the wrapped tool or original tool
|
|
101
|
-
def wrap_tool_with_permissions(tool_instance, permissions_config, agent_definition)
|
|
102
|
-
# Skip wrapping if no permissions or agent bypasses permissions
|
|
103
|
-
return tool_instance unless permissions_config
|
|
104
|
-
return tool_instance if agent_definition.bypass_permissions
|
|
105
|
-
|
|
106
|
-
# Create permissions config and wrap tool with validator
|
|
107
|
-
permissions = Permissions::Config.new(
|
|
108
|
-
permissions_config,
|
|
109
|
-
base_directory: agent_definition.directory,
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
Permissions::Validator.new(tool_instance, permissions)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
private
|
|
116
|
-
|
|
117
|
-
# Register explicitly configured tools
|
|
118
|
-
#
|
|
119
|
-
# @param chat [AgentChat] The chat instance
|
|
120
|
-
# @param tool_configs [Array<Hash>] Tool configurations with optional permissions
|
|
121
|
-
# @param agent_name [Symbol] Agent name
|
|
122
|
-
# @param agent_definition [AgentDefinition] Agent definition
|
|
123
|
-
def register_explicit_tools(chat, tool_configs, agent_name:, agent_definition:)
|
|
124
|
-
# Validate filesystem tools if globally disabled
|
|
125
|
-
unless @swarm.allow_filesystem_tools
|
|
126
|
-
# Extract tool names from hashes and convert to symbols for comparison
|
|
127
|
-
forbidden = tool_configs.map { |tc| tc[:name].to_sym }.select { |name| FILESYSTEM_TOOLS.include?(name) }
|
|
128
|
-
unless forbidden.empty?
|
|
129
|
-
raise ConfigurationError,
|
|
130
|
-
"Filesystem tools are globally disabled (SwarmSDK.settings.allow_filesystem_tools = false) " \
|
|
131
|
-
"but agent '#{agent_name}' attempts to use: #{forbidden.join(", ")}.\n\n" \
|
|
132
|
-
"This is a system-wide security setting that cannot be overridden by swarm configuration.\n" \
|
|
133
|
-
"To use filesystem tools, set SwarmSDK.settings.allow_filesystem_tools = true before loading the swarm."
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
tool_configs.each do |tool_config|
|
|
138
|
-
tool_name = tool_config[:name]
|
|
139
|
-
permissions_config = tool_config[:permissions]
|
|
140
|
-
|
|
141
|
-
# Create tool instance
|
|
142
|
-
tool_instance = create_tool_instance(tool_name, agent_name, agent_definition.directory)
|
|
143
|
-
|
|
144
|
-
# Wrap with permissions and add to chat
|
|
145
|
-
wrap_and_add_tool(chat, tool_instance, permissions_config, agent_definition)
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# Register default tools for agents (unless disabled)
|
|
150
|
-
#
|
|
151
|
-
# Note: Memory tools are registered separately and are NOT affected by
|
|
152
|
-
# disable_default_tools, since they're configured via memory {} block.
|
|
153
|
-
#
|
|
154
|
-
# @param chat [AgentChat] The chat instance
|
|
155
|
-
# @param agent_name [Symbol] Agent name
|
|
156
|
-
# @param agent_definition [AgentDefinition] Agent definition
|
|
157
|
-
def register_default_tools(chat, agent_name:, agent_definition:)
|
|
158
|
-
# Get explicit tool names to avoid duplicates
|
|
159
|
-
explicit_tool_names = agent_definition.tools.map { |t| t[:name] }.to_set
|
|
160
|
-
|
|
161
|
-
# Register core default tools (unless disabled)
|
|
162
|
-
if agent_definition.disable_default_tools != true
|
|
163
|
-
DEFAULT_TOOLS.each do |tool_name|
|
|
164
|
-
# Skip filesystem tools if globally disabled
|
|
165
|
-
next if !@swarm.allow_filesystem_tools && FILESYSTEM_TOOLS.include?(tool_name)
|
|
166
|
-
|
|
167
|
-
register_tool_if_not_disabled(chat, tool_name, explicit_tool_names, agent_name, agent_definition)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
# Register scratchpad tools if enabled
|
|
171
|
-
if @swarm.scratchpad_enabled?
|
|
172
|
-
SCRATCHPAD_TOOLS.each do |tool_name|
|
|
173
|
-
register_tool_if_not_disabled(chat, tool_name, explicit_tool_names, agent_name, agent_definition)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# Register plugin tools if plugin storage is enabled for this agent
|
|
179
|
-
# Plugin tools ARE affected by disable_default_tools (allows fine-grained control)
|
|
180
|
-
register_plugin_tools(chat, agent_name, agent_definition, explicit_tool_names)
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# Register a tool if not already explicit or disabled
|
|
184
|
-
def register_tool_if_not_disabled(chat, tool_name, explicit_tool_names, agent_name, agent_definition)
|
|
185
|
-
# Skip if already registered explicitly
|
|
186
|
-
return if explicit_tool_names.include?(tool_name)
|
|
187
|
-
|
|
188
|
-
# Skip if tool is in the disable list
|
|
189
|
-
return if tool_disabled?(tool_name, agent_definition.disable_default_tools)
|
|
190
|
-
|
|
191
|
-
tool_instance = create_tool_instance(tool_name, agent_name, agent_definition.directory)
|
|
192
|
-
permissions_config = resolve_default_permissions(tool_name, agent_definition)
|
|
193
|
-
|
|
194
|
-
wrap_and_add_tool(chat, tool_instance, permissions_config, agent_definition)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# Wrap tool with permissions and add to chat
|
|
198
|
-
#
|
|
199
|
-
# This is the common pattern for registering tools:
|
|
200
|
-
# 1. Wrap with permissions validator (if configured)
|
|
201
|
-
# 2. Add to chat
|
|
202
|
-
#
|
|
203
|
-
# @param chat [Agent::Chat] The chat instance
|
|
204
|
-
# @param tool_instance [RubyLLM::Tool] Tool instance
|
|
205
|
-
# @param permissions_config [Hash, nil] Permissions configuration
|
|
206
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
207
|
-
# @return [void]
|
|
208
|
-
def wrap_and_add_tool(chat, tool_instance, permissions_config, agent_definition)
|
|
209
|
-
tool_instance = wrap_tool_with_permissions(tool_instance, permissions_config, agent_definition)
|
|
210
|
-
chat.add_tool(tool_instance)
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# Resolve permissions for a default/plugin tool
|
|
214
|
-
#
|
|
215
|
-
# Looks up permissions in agent-specific config first, falls back to global defaults.
|
|
216
|
-
#
|
|
217
|
-
# @param tool_name [Symbol] Tool name
|
|
218
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
219
|
-
# @return [Hash, nil] Permissions configuration or nil
|
|
220
|
-
def resolve_default_permissions(tool_name, agent_definition)
|
|
221
|
-
agent_definition.agent_permissions[tool_name] || agent_definition.default_permissions[tool_name]
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
# Create a tool instance via plugin
|
|
225
|
-
#
|
|
226
|
-
# @param tool_name [Symbol] Tool name
|
|
227
|
-
# @param agent_name [Symbol] Agent name
|
|
228
|
-
# @param directory [String] Working directory
|
|
229
|
-
# @param chat [Agent::Chat, nil] Chat instance
|
|
230
|
-
# @param agent_definition [Agent::Definition, nil] Agent definition
|
|
231
|
-
# @return [RubyLLM::Tool] Tool instance
|
|
232
|
-
def create_plugin_tool(tool_name, agent_name, directory, chat, agent_definition)
|
|
233
|
-
plugin = PluginRegistry.plugin_for_tool(tool_name)
|
|
234
|
-
raise ConfigurationError, "Tool #{tool_name} is not provided by any plugin" unless plugin
|
|
235
|
-
|
|
236
|
-
# V7.0: Extract base name for storage lookup (handles delegation instances)
|
|
237
|
-
# For primary agents: :tester → :tester (no change)
|
|
238
|
-
# For delegation instances: "tester@frontend" → :tester (extracts base)
|
|
239
|
-
base_name = agent_name.to_s.split("@").first.to_sym
|
|
240
|
-
|
|
241
|
-
# Get plugin storage using BASE NAME (shared across instances)
|
|
242
|
-
plugin_storages = @plugin_storages[plugin.name] || {}
|
|
243
|
-
storage = plugin_storages[base_name] # ← Changed from agent_name to base_name
|
|
244
|
-
|
|
245
|
-
# Build context for tool creation
|
|
246
|
-
# Pass full agent_name for tool state tracking (TodoWrite, ReadTracker, etc.)
|
|
247
|
-
context = {
|
|
248
|
-
agent_name: agent_name, # Full instance name for tool's use
|
|
249
|
-
directory: directory,
|
|
250
|
-
storage: storage, # Shared storage by base name
|
|
251
|
-
agent_definition: agent_definition,
|
|
252
|
-
chat: chat,
|
|
253
|
-
tool_configurator: self,
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
plugin.create_tool(tool_name, context)
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
# Register plugin-provided tools for an agent
|
|
260
|
-
#
|
|
261
|
-
# Asks all plugins if they have tools to register for this agent.
|
|
262
|
-
#
|
|
263
|
-
# @param chat [Agent::Chat] Chat instance
|
|
264
|
-
# @param agent_name [Symbol] Agent name
|
|
265
|
-
# @param agent_definition [Agent::Definition] Agent definition
|
|
266
|
-
# @param explicit_tool_names [Set<Symbol>] Already-registered tool names
|
|
267
|
-
def register_plugin_tools(chat, agent_name, agent_definition, explicit_tool_names)
|
|
268
|
-
PluginRegistry.all.each do |plugin|
|
|
269
|
-
# Check if plugin has storage enabled for this agent
|
|
270
|
-
next unless plugin.storage_enabled?(agent_definition)
|
|
271
|
-
|
|
272
|
-
# Register each tool provided by the plugin
|
|
273
|
-
plugin.tools.each do |tool_name|
|
|
274
|
-
# Skip if already registered explicitly
|
|
275
|
-
next if explicit_tool_names.include?(tool_name)
|
|
276
|
-
|
|
277
|
-
# Skip if tool is disabled via disable_default_tools
|
|
278
|
-
next if tool_disabled?(tool_name, agent_definition.disable_default_tools)
|
|
279
|
-
|
|
280
|
-
tool_instance = create_tool_instance(
|
|
281
|
-
tool_name,
|
|
282
|
-
agent_name,
|
|
283
|
-
agent_definition.directory,
|
|
284
|
-
chat: chat,
|
|
285
|
-
agent_definition: agent_definition,
|
|
286
|
-
)
|
|
287
|
-
|
|
288
|
-
permissions_config = resolve_default_permissions(tool_name, agent_definition)
|
|
289
|
-
|
|
290
|
-
wrap_and_add_tool(chat, tool_instance, permissions_config, agent_definition)
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
# Check if a tool should be disabled based on disable_default_tools config
|
|
296
|
-
#
|
|
297
|
-
# @param tool_name [Symbol] Tool name to check
|
|
298
|
-
# @param disable_config [nil, Boolean, Symbol, Array<Symbol>] Disable configuration
|
|
299
|
-
# @return [Boolean] True if tool should be disabled
|
|
300
|
-
def tool_disabled?(tool_name, disable_config)
|
|
301
|
-
return false if disable_config.nil?
|
|
302
|
-
|
|
303
|
-
# Normalize tool_name to symbol for comparison
|
|
304
|
-
tool_name_sym = tool_name.to_sym
|
|
305
|
-
|
|
306
|
-
if disable_config == true
|
|
307
|
-
# Disable all default tools
|
|
308
|
-
true
|
|
309
|
-
elsif disable_config.is_a?(Symbol)
|
|
310
|
-
# Single tool name
|
|
311
|
-
disable_config == tool_name_sym
|
|
312
|
-
elsif disable_config.is_a?(String)
|
|
313
|
-
# Single tool name as string (from YAML)
|
|
314
|
-
disable_config.to_sym == tool_name_sym
|
|
315
|
-
elsif disable_config.is_a?(Array)
|
|
316
|
-
# Disable only tools in the array - normalize to symbols for comparison
|
|
317
|
-
disable_config.map(&:to_sym).include?(tool_name_sym)
|
|
318
|
-
else
|
|
319
|
-
false
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
# Register agent delegation tools
|
|
324
|
-
#
|
|
325
|
-
# Creates delegation tools that allow one agent to call another.
|
|
326
|
-
#
|
|
327
|
-
# @param chat [AgentChat] The chat instance
|
|
328
|
-
# @param delegate_names [Array<Symbol>] Names of agents to delegate to
|
|
329
|
-
# @param agent_name [Symbol] Name of the agent doing the delegating
|
|
330
|
-
def register_delegation_tools(chat, delegate_names, agent_name:)
|
|
331
|
-
return if delegate_names.empty?
|
|
332
|
-
|
|
333
|
-
delegate_names.each do |delegate_name|
|
|
334
|
-
delegate_name = delegate_name.to_sym
|
|
335
|
-
|
|
336
|
-
unless @agents.key?(delegate_name)
|
|
337
|
-
raise ConfigurationError, "Agent delegates to unknown agent '#{delegate_name}'"
|
|
338
|
-
end
|
|
339
|
-
|
|
340
|
-
# Create a tool that delegates to the specified agent
|
|
341
|
-
delegate_agent = @agents[delegate_name]
|
|
342
|
-
delegate_definition = @agent_definitions[delegate_name]
|
|
343
|
-
|
|
344
|
-
tool = Tools::Delegate.new(
|
|
345
|
-
delegate_name: delegate_name.to_s,
|
|
346
|
-
delegate_description: delegate_definition.description,
|
|
347
|
-
delegate_chat: delegate_agent,
|
|
348
|
-
agent_name: agent_name,
|
|
349
|
-
swarm: @swarm,
|
|
350
|
-
delegating_chat: chat,
|
|
351
|
-
)
|
|
352
|
-
|
|
353
|
-
chat.add_tool(tool)
|
|
354
|
-
end
|
|
355
|
-
end
|
|
356
|
-
end
|
|
357
|
-
end
|
|
358
|
-
end
|