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,150 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
module Hooks
|
|
5
|
-
# Result object returned by hooks to control execution flow
|
|
6
|
-
#
|
|
7
|
-
# Hooks can return a Result to:
|
|
8
|
-
# - Continue normal execution (default)
|
|
9
|
-
# - Halt execution and return an error/message
|
|
10
|
-
# - Replace a value (e.g., tool result, delegation result)
|
|
11
|
-
# - Reprompt the agent with a new prompt
|
|
12
|
-
# - Finish the current agent's execution (agent scope)
|
|
13
|
-
# - Finish the entire swarm execution (swarm scope)
|
|
14
|
-
#
|
|
15
|
-
# @example Continue normal execution (default)
|
|
16
|
-
# SwarmSDK::Hooks::Result.continue
|
|
17
|
-
#
|
|
18
|
-
# @example Halt execution with error message
|
|
19
|
-
# SwarmSDK::Hooks::Result.halt("Validation failed: invalid input")
|
|
20
|
-
#
|
|
21
|
-
# @example Replace tool result
|
|
22
|
-
# SwarmSDK::Hooks::Result.replace("Custom tool result")
|
|
23
|
-
#
|
|
24
|
-
# @example Reprompt agent with modified prompt
|
|
25
|
-
# SwarmSDK::Hooks::Result.reprompt("Modified task: #{original_task}")
|
|
26
|
-
#
|
|
27
|
-
# @example Finish current agent with message
|
|
28
|
-
# SwarmSDK::Hooks::Result.finish_agent("Agent task completed")
|
|
29
|
-
#
|
|
30
|
-
# @example Finish entire swarm with message
|
|
31
|
-
# SwarmSDK::Hooks::Result.finish_swarm("All tasks complete!")
|
|
32
|
-
class Result
|
|
33
|
-
attr_reader :action, :value
|
|
34
|
-
|
|
35
|
-
# Valid actions that control execution flow
|
|
36
|
-
VALID_ACTIONS = [:continue, :halt, :replace, :reprompt, :finish_agent, :finish_swarm].freeze
|
|
37
|
-
|
|
38
|
-
# @param action [Symbol] Action to take (:continue, :halt, :replace, :reprompt)
|
|
39
|
-
# @param value [Object, nil] Associated value (context for :continue, message for :halt, etc.)
|
|
40
|
-
def initialize(action:, value: nil)
|
|
41
|
-
unless VALID_ACTIONS.include?(action)
|
|
42
|
-
raise ArgumentError, "Invalid action: #{action}. Valid actions: #{VALID_ACTIONS.join(", ")}"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
@action = action
|
|
46
|
-
@value = value
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Check if this result indicates halting execution
|
|
50
|
-
#
|
|
51
|
-
# @return [Boolean] true if action is :halt
|
|
52
|
-
def halt?
|
|
53
|
-
@action == :halt
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Check if this result provides a replacement value
|
|
57
|
-
#
|
|
58
|
-
# @return [Boolean] true if action is :replace
|
|
59
|
-
def replace?
|
|
60
|
-
@action == :replace
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Check if this result requests reprompting
|
|
64
|
-
#
|
|
65
|
-
# @return [Boolean] true if action is :reprompt
|
|
66
|
-
def reprompt?
|
|
67
|
-
@action == :reprompt
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# Check if this result continues normal execution
|
|
71
|
-
#
|
|
72
|
-
# @return [Boolean] true if action is :continue
|
|
73
|
-
def continue?
|
|
74
|
-
@action == :continue
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Check if this result finishes the current agent
|
|
78
|
-
#
|
|
79
|
-
# @return [Boolean] true if action is :finish_agent
|
|
80
|
-
def finish_agent?
|
|
81
|
-
@action == :finish_agent
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Check if this result finishes the entire swarm
|
|
85
|
-
#
|
|
86
|
-
# @return [Boolean] true if action is :finish_swarm
|
|
87
|
-
def finish_swarm?
|
|
88
|
-
@action == :finish_swarm
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
class << self
|
|
92
|
-
# Create a result that continues normal execution
|
|
93
|
-
#
|
|
94
|
-
# @param context [Context, nil] Updated context (optional)
|
|
95
|
-
# @return [Result] Result with continue action
|
|
96
|
-
def continue(context = nil)
|
|
97
|
-
new(action: :continue, value: context)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Create a result that halts execution
|
|
101
|
-
#
|
|
102
|
-
# @param message [String] Error or halt message
|
|
103
|
-
# @return [Result] Result with halt action
|
|
104
|
-
def halt(message)
|
|
105
|
-
new(action: :halt, value: message)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# Create a result that replaces a value
|
|
109
|
-
#
|
|
110
|
-
# @param value [Object] Replacement value
|
|
111
|
-
# @return [Result] Result with replace action
|
|
112
|
-
def replace(value)
|
|
113
|
-
new(action: :replace, value: value)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# Create a result that reprompts the agent
|
|
117
|
-
#
|
|
118
|
-
# @param prompt [String] New prompt to send to agent
|
|
119
|
-
# @return [Result] Result with reprompt action
|
|
120
|
-
def reprompt(prompt)
|
|
121
|
-
new(action: :reprompt, value: prompt)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Create a result that finishes the current agent
|
|
125
|
-
#
|
|
126
|
-
# Exits the agent's chat loop and returns the message as the agent's
|
|
127
|
-
# final response. If this agent was delegated to, control returns to
|
|
128
|
-
# the calling agent. The swarm continues if there's more work.
|
|
129
|
-
#
|
|
130
|
-
# @param message [String] Final message from the agent
|
|
131
|
-
# @return [Result] Result with finish_agent action
|
|
132
|
-
def finish_agent(message)
|
|
133
|
-
new(action: :finish_agent, value: message)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Create a result that finishes the entire swarm
|
|
137
|
-
#
|
|
138
|
-
# Immediately exits the Swarm.execute() loop and returns the message
|
|
139
|
-
# as the final Result#output. All agent execution stops and the user
|
|
140
|
-
# receives this message.
|
|
141
|
-
#
|
|
142
|
-
# @param message [String] Final message from the swarm
|
|
143
|
-
# @return [Result] Result with finish_swarm action
|
|
144
|
-
def finish_swarm(message)
|
|
145
|
-
new(action: :finish_swarm, value: message)
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
end
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "open3"
|
|
4
|
-
require "json"
|
|
5
|
-
require "timeout"
|
|
6
|
-
|
|
7
|
-
module SwarmSDK
|
|
8
|
-
module Hooks
|
|
9
|
-
# Executes shell command hooks with JSON I/O and exit code handling
|
|
10
|
-
#
|
|
11
|
-
# ShellExecutor runs external shell commands (defined in YAML hooks) and
|
|
12
|
-
# converts their exit codes to Result objects that control execution flow.
|
|
13
|
-
#
|
|
14
|
-
# ## Exit Code Behavior (following Claude Code convention)
|
|
15
|
-
#
|
|
16
|
-
# - **0**: Success - continue execution (Result.continue)
|
|
17
|
-
# - **2**: Block with error feedback to LLM (Result.halt)
|
|
18
|
-
# - **Other**: Non-blocking error - log warning and continue (Result.continue)
|
|
19
|
-
#
|
|
20
|
-
# ## JSON I/O Format
|
|
21
|
-
#
|
|
22
|
-
# **stdin (to hook script)**:
|
|
23
|
-
# ```json
|
|
24
|
-
# {
|
|
25
|
-
# "event": "pre_tool_use",
|
|
26
|
-
# "agent": "backend",
|
|
27
|
-
# "tool": "Write",
|
|
28
|
-
# "parameters": { "file_path": "api.rb", "content": "..." }
|
|
29
|
-
# }
|
|
30
|
-
# ```
|
|
31
|
-
#
|
|
32
|
-
# **stdout (from hook script)**:
|
|
33
|
-
# ```json
|
|
34
|
-
# {
|
|
35
|
-
# "success": false,
|
|
36
|
-
# "error": "Validation failed: syntax error"
|
|
37
|
-
# }
|
|
38
|
-
# ```
|
|
39
|
-
#
|
|
40
|
-
# @example Execute a validation hook
|
|
41
|
-
# result = SwarmSDK::Hooks::ShellExecutor.execute(
|
|
42
|
-
# command: "python scripts/validate.py",
|
|
43
|
-
# input_json: { event: "pre_tool_use", tool: "Write", parameters: {...} },
|
|
44
|
-
# timeout: 10,
|
|
45
|
-
# agent_name: :backend,
|
|
46
|
-
# swarm_name: "Dev Team"
|
|
47
|
-
# )
|
|
48
|
-
# # => Result (continue or halt based on exit code)
|
|
49
|
-
class ShellExecutor
|
|
50
|
-
# Backward compatibility alias - use Defaults module for new code
|
|
51
|
-
DEFAULT_TIMEOUT = Defaults::Timeouts::HOOK_SHELL_SECONDS
|
|
52
|
-
|
|
53
|
-
class << self
|
|
54
|
-
# Execute a shell command hook
|
|
55
|
-
#
|
|
56
|
-
# @param command [String] Shell command to execute
|
|
57
|
-
# @param input_json [Hash] JSON data to provide on stdin
|
|
58
|
-
# @param timeout [Integer] Timeout in seconds (default: 60)
|
|
59
|
-
# @param agent_name [Symbol, String, nil] Agent name for environment variables
|
|
60
|
-
# @param swarm_name [String, nil] Swarm name for environment variables
|
|
61
|
-
# @param event [Symbol] Event type for context-aware behavior
|
|
62
|
-
# @return [Result] Result based on exit code (continue or halt)
|
|
63
|
-
def execute(command:, input_json:, timeout: DEFAULT_TIMEOUT, agent_name: nil, swarm_name: nil, event: nil)
|
|
64
|
-
# Build environment variables
|
|
65
|
-
env = build_environment(agent_name: agent_name, swarm_name: swarm_name)
|
|
66
|
-
|
|
67
|
-
# Execute command with JSON stdin and timeout
|
|
68
|
-
stdout, stderr, status = Timeout.timeout(timeout) do
|
|
69
|
-
Open3.capture3(
|
|
70
|
-
env,
|
|
71
|
-
command,
|
|
72
|
-
stdin_data: JSON.generate(input_json),
|
|
73
|
-
)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Handle exit code per Claude Code convention (context-aware)
|
|
77
|
-
result = handle_exit_code(status.exitstatus, stdout, stderr, event)
|
|
78
|
-
|
|
79
|
-
# Emit log event for hook execution
|
|
80
|
-
case status.exitstatus
|
|
81
|
-
when 0
|
|
82
|
-
# Success - log stdout/stderr
|
|
83
|
-
emit_hook_log(
|
|
84
|
-
event: event,
|
|
85
|
-
agent_name: agent_name,
|
|
86
|
-
command: command,
|
|
87
|
-
exit_code: status.exitstatus,
|
|
88
|
-
success: true,
|
|
89
|
-
stdout: stdout,
|
|
90
|
-
stderr: stderr,
|
|
91
|
-
)
|
|
92
|
-
when 2
|
|
93
|
-
# Blocking error - always log stderr
|
|
94
|
-
emit_hook_log(
|
|
95
|
-
event: event,
|
|
96
|
-
agent_name: agent_name,
|
|
97
|
-
command: command,
|
|
98
|
-
exit_code: status.exitstatus,
|
|
99
|
-
success: false,
|
|
100
|
-
stderr: stderr,
|
|
101
|
-
blocked: true,
|
|
102
|
-
)
|
|
103
|
-
else
|
|
104
|
-
# Non-blocking error - log stderr
|
|
105
|
-
emit_hook_log(
|
|
106
|
-
event: event,
|
|
107
|
-
agent_name: agent_name,
|
|
108
|
-
command: command,
|
|
109
|
-
exit_code: status.exitstatus,
|
|
110
|
-
success: false,
|
|
111
|
-
stderr: stderr,
|
|
112
|
-
blocked: false,
|
|
113
|
-
)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
result
|
|
117
|
-
rescue Timeout::Error
|
|
118
|
-
emit_hook_log(
|
|
119
|
-
event: event,
|
|
120
|
-
agent_name: agent_name,
|
|
121
|
-
command: command,
|
|
122
|
-
exit_code: nil,
|
|
123
|
-
success: false,
|
|
124
|
-
stderr: "Timeout after #{timeout}s",
|
|
125
|
-
)
|
|
126
|
-
# Don't block on timeout - log and continue
|
|
127
|
-
Result.continue
|
|
128
|
-
rescue StandardError => e
|
|
129
|
-
emit_hook_log(
|
|
130
|
-
event: event,
|
|
131
|
-
agent_name: agent_name,
|
|
132
|
-
command: command,
|
|
133
|
-
exit_code: nil,
|
|
134
|
-
success: false,
|
|
135
|
-
stderr: e.message,
|
|
136
|
-
)
|
|
137
|
-
# Don't block on errors - log and continue
|
|
138
|
-
Result.continue
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
private
|
|
142
|
-
|
|
143
|
-
# Build environment variables for hook execution
|
|
144
|
-
#
|
|
145
|
-
# @param agent_name [Symbol, String, nil] Agent name
|
|
146
|
-
# @param swarm_name [String, nil] Swarm name
|
|
147
|
-
# @return [Hash] Environment variables
|
|
148
|
-
def build_environment(agent_name:, swarm_name:)
|
|
149
|
-
{
|
|
150
|
-
"SWARM_SDK_PROJECT_DIR" => Dir.pwd,
|
|
151
|
-
"SWARM_SDK_AGENT_NAME" => agent_name.to_s,
|
|
152
|
-
"SWARM_SDK_SWARM_NAME" => swarm_name.to_s,
|
|
153
|
-
"PATH" => ENV.fetch("PATH", ""),
|
|
154
|
-
}
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# Handle exit code and return appropriate Result
|
|
158
|
-
#
|
|
159
|
-
# @param exit_code [Integer] Process exit code
|
|
160
|
-
# @param stdout [String] Standard output
|
|
161
|
-
# @param stderr [String] Standard error
|
|
162
|
-
# @param event [Symbol] Hook event type
|
|
163
|
-
# @return [Result] Result based on exit code
|
|
164
|
-
def handle_exit_code(exit_code, stdout, stderr, event)
|
|
165
|
-
case exit_code
|
|
166
|
-
when 0
|
|
167
|
-
# Success - continue execution
|
|
168
|
-
# For user_prompt and swarm_start: return stdout to be shown to agent
|
|
169
|
-
if [:user_prompt, :swarm_start].include?(event) && !stdout.strip.empty?
|
|
170
|
-
# Return Result with stdout that will be appended to prompt
|
|
171
|
-
Result.replace(stdout.strip)
|
|
172
|
-
else
|
|
173
|
-
# Normal success
|
|
174
|
-
Result.continue
|
|
175
|
-
end
|
|
176
|
-
when 2
|
|
177
|
-
# Blocking error - behavior depends on event type
|
|
178
|
-
handle_exit_code_2(event, stdout, stderr)
|
|
179
|
-
else
|
|
180
|
-
# Non-blocking error - continue (stderr logged above)
|
|
181
|
-
Result.continue
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Handle exit code 2 (blocking error)
|
|
186
|
-
#
|
|
187
|
-
# @param event [Symbol] Hook event type
|
|
188
|
-
# @param _stdout [String] Standard output (unused)
|
|
189
|
-
# @param stderr [String] Standard error
|
|
190
|
-
# @return [Result] Result based on event type
|
|
191
|
-
def handle_exit_code_2(event, _stdout, stderr)
|
|
192
|
-
error_msg = stderr.strip
|
|
193
|
-
|
|
194
|
-
case event
|
|
195
|
-
when :pre_tool_use
|
|
196
|
-
# Block tool call, show stderr to agent (stderr already logged above)
|
|
197
|
-
Result.halt(error_msg)
|
|
198
|
-
when :post_tool_use
|
|
199
|
-
# Tool already ran, show stderr to agent (stderr already logged above)
|
|
200
|
-
Result.halt(error_msg)
|
|
201
|
-
when :user_prompt
|
|
202
|
-
# Block prompt processing, erase prompt
|
|
203
|
-
# stderr is logged (above) for user to see, but NOT shown to agent
|
|
204
|
-
# Return empty halt (prompt is erased, no message to agent)
|
|
205
|
-
Result.halt("")
|
|
206
|
-
when :agent_stop
|
|
207
|
-
# Block stoppage, show stderr to agent (stderr already logged above)
|
|
208
|
-
Result.halt(error_msg)
|
|
209
|
-
when :context_warning, :swarm_start, :swarm_stop
|
|
210
|
-
# N/A - stderr logged above, don't halt
|
|
211
|
-
Result.continue
|
|
212
|
-
else
|
|
213
|
-
# Default: halt with stderr
|
|
214
|
-
Result.halt(error_msg)
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Emit hook execution log entry
|
|
219
|
-
#
|
|
220
|
-
# @param event [Symbol] Hook event type
|
|
221
|
-
# @param agent_name [String, Symbol, nil] Agent name
|
|
222
|
-
# @param command [String] Shell command executed
|
|
223
|
-
# @param exit_code [Integer, nil] Process exit code
|
|
224
|
-
# @param success [Boolean] Whether execution succeeded
|
|
225
|
-
# @param stdout [String, nil] Standard output
|
|
226
|
-
# @param stderr [String, nil] Standard error
|
|
227
|
-
# @param blocked [Boolean] Whether execution was blocked (exit code 2)
|
|
228
|
-
def emit_hook_log(event:, agent_name:, command:, exit_code:, success:, stdout: nil, stderr: nil, blocked: false)
|
|
229
|
-
# Only emit if LogStream is enabled (has emitter)
|
|
230
|
-
return unless LogStream.enabled?
|
|
231
|
-
|
|
232
|
-
log_entry = {
|
|
233
|
-
type: "hook_executed",
|
|
234
|
-
hook_event: event&.to_s, # Which hook event triggered this (pre_tool_use, swarm_start, etc.)
|
|
235
|
-
agent: agent_name,
|
|
236
|
-
command: command,
|
|
237
|
-
exit_code: exit_code,
|
|
238
|
-
success: success,
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
# Add stdout if present (exit code 0)
|
|
242
|
-
log_entry[:stdout] = stdout.strip if stdout && !stdout.strip.empty?
|
|
243
|
-
|
|
244
|
-
# Add stderr if present (any exit code)
|
|
245
|
-
log_entry[:stderr] = stderr.strip if stderr && !stderr.strip.empty?
|
|
246
|
-
|
|
247
|
-
# Add blocked flag for exit code 2
|
|
248
|
-
log_entry[:blocked] = true if blocked
|
|
249
|
-
|
|
250
|
-
LogStream.emit(**log_entry)
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
module Hooks
|
|
5
|
-
# Represents a tool call in the hooks system
|
|
6
|
-
#
|
|
7
|
-
# This is a simple value object that wraps tool call information
|
|
8
|
-
# from RubyLLM in a consistent, immutable format for hooks.
|
|
9
|
-
#
|
|
10
|
-
# @example Access tool call information in a hook
|
|
11
|
-
# swarm.add_callback(:pre_tool_use) do |context|
|
|
12
|
-
# puts "Tool: #{context.tool_call.name}"
|
|
13
|
-
# puts "Parameters: #{context.tool_call.parameters.inspect}"
|
|
14
|
-
# end
|
|
15
|
-
class ToolCall
|
|
16
|
-
attr_reader :id, :name, :parameters
|
|
17
|
-
|
|
18
|
-
# @param id [String] Unique identifier for this tool call
|
|
19
|
-
# @param name [String] Name of the tool being called
|
|
20
|
-
# @param parameters [Hash] Parameters passed to the tool
|
|
21
|
-
def initialize(id:, name:, parameters:)
|
|
22
|
-
@id = id
|
|
23
|
-
@name = name
|
|
24
|
-
@parameters = parameters
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Convert to hash representation
|
|
28
|
-
#
|
|
29
|
-
# @return [Hash] Hash with id, name, and parameters
|
|
30
|
-
def to_h
|
|
31
|
-
{ id: @id, name: @name, parameters: @parameters }
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module SwarmSDK
|
|
4
|
-
module Hooks
|
|
5
|
-
# Represents the result of a tool execution
|
|
6
|
-
#
|
|
7
|
-
# This is a simple value object that wraps tool execution results
|
|
8
|
-
# in a consistent format for post-tool-use hooks.
|
|
9
|
-
#
|
|
10
|
-
# @example Access tool result in a hook
|
|
11
|
-
# swarm.add_callback(:post_tool_use) do |context|
|
|
12
|
-
# if context.tool_result.success?
|
|
13
|
-
# puts "Tool succeeded: #{context.tool_result.content}"
|
|
14
|
-
# else
|
|
15
|
-
# puts "Tool failed: #{context.tool_result.error}"
|
|
16
|
-
# end
|
|
17
|
-
# end
|
|
18
|
-
class ToolResult
|
|
19
|
-
attr_reader :tool_call_id, :tool_name, :content, :success, :error
|
|
20
|
-
|
|
21
|
-
# @param tool_call_id [String] ID of the tool call this result corresponds to
|
|
22
|
-
# @param tool_name [String] Name of the tool that was executed
|
|
23
|
-
# @param content [String, nil] Result content (if successful)
|
|
24
|
-
# @param success [Boolean] Whether the tool execution succeeded
|
|
25
|
-
# @param error [String, nil] Error message (if failed)
|
|
26
|
-
def initialize(tool_call_id:, tool_name:, content: nil, success: true, error: nil)
|
|
27
|
-
@tool_call_id = tool_call_id
|
|
28
|
-
@tool_name = tool_name
|
|
29
|
-
@content = content
|
|
30
|
-
@success = success
|
|
31
|
-
@error = error
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Check if the tool execution succeeded
|
|
35
|
-
#
|
|
36
|
-
# @return [Boolean] true if successful
|
|
37
|
-
def success?
|
|
38
|
-
@success
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Check if the tool execution failed
|
|
42
|
-
#
|
|
43
|
-
# @return [Boolean] true if failed
|
|
44
|
-
def failure?
|
|
45
|
-
!@success
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Convert to hash representation
|
|
49
|
-
#
|
|
50
|
-
# @return [Hash] Hash with all result attributes
|
|
51
|
-
def to_h
|
|
52
|
-
{
|
|
53
|
-
tool_call_id: @tool_call_id,
|
|
54
|
-
tool_name: @tool_name,
|
|
55
|
-
content: @content,
|
|
56
|
-
success: @success,
|
|
57
|
-
error: @error,
|
|
58
|
-
}
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|