swarm_memory 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/lib/claude_swarm/base_executor.rb +133 -0
  4. data/lib/claude_swarm/claude_code_executor.rb +349 -0
  5. data/lib/claude_swarm/claude_mcp_server.rb +77 -0
  6. data/lib/claude_swarm/cli.rb +712 -0
  7. data/lib/claude_swarm/commands/ps.rb +216 -0
  8. data/lib/claude_swarm/commands/show.rb +139 -0
  9. data/lib/claude_swarm/configuration.rb +363 -0
  10. data/lib/claude_swarm/hooks/session_start_hook.rb +42 -0
  11. data/lib/claude_swarm/json_handler.rb +91 -0
  12. data/lib/claude_swarm/mcp_generator.rb +248 -0
  13. data/lib/claude_swarm/openai/chat_completion.rb +264 -0
  14. data/lib/claude_swarm/openai/executor.rb +254 -0
  15. data/lib/claude_swarm/openai/responses.rb +338 -0
  16. data/lib/claude_swarm/orchestrator.rb +879 -0
  17. data/lib/claude_swarm/process_tracker.rb +78 -0
  18. data/lib/claude_swarm/session_cost_calculator.rb +209 -0
  19. data/lib/claude_swarm/session_path.rb +42 -0
  20. data/lib/claude_swarm/settings_generator.rb +77 -0
  21. data/lib/claude_swarm/system_utils.rb +46 -0
  22. data/lib/claude_swarm/templates/generation_prompt.md.erb +230 -0
  23. data/lib/claude_swarm/tools/reset_session_tool.rb +24 -0
  24. data/lib/claude_swarm/tools/session_info_tool.rb +24 -0
  25. data/lib/claude_swarm/tools/task_tool.rb +63 -0
  26. data/lib/claude_swarm/version.rb +5 -0
  27. data/lib/claude_swarm/worktree_manager.rb +475 -0
  28. data/lib/claude_swarm/yaml_loader.rb +22 -0
  29. data/lib/claude_swarm.rb +69 -0
  30. data/lib/swarm_cli/cli.rb +201 -0
  31. data/lib/swarm_cli/command_registry.rb +61 -0
  32. data/lib/swarm_cli/commands/mcp_serve.rb +130 -0
  33. data/lib/swarm_cli/commands/mcp_tools.rb +148 -0
  34. data/lib/swarm_cli/commands/migrate.rb +55 -0
  35. data/lib/swarm_cli/commands/run.rb +173 -0
  36. data/lib/swarm_cli/config_loader.rb +97 -0
  37. data/lib/swarm_cli/formatters/human_formatter.rb +711 -0
  38. data/lib/swarm_cli/formatters/json_formatter.rb +51 -0
  39. data/lib/swarm_cli/interactive_repl.rb +918 -0
  40. data/lib/swarm_cli/mcp_serve_options.rb +44 -0
  41. data/lib/swarm_cli/mcp_tools_options.rb +59 -0
  42. data/lib/swarm_cli/migrate_options.rb +54 -0
  43. data/lib/swarm_cli/migrator.rb +132 -0
  44. data/lib/swarm_cli/options.rb +151 -0
  45. data/lib/swarm_cli/ui/components/agent_badge.rb +33 -0
  46. data/lib/swarm_cli/ui/components/content_block.rb +120 -0
  47. data/lib/swarm_cli/ui/components/divider.rb +57 -0
  48. data/lib/swarm_cli/ui/components/panel.rb +62 -0
  49. data/lib/swarm_cli/ui/components/usage_stats.rb +70 -0
  50. data/lib/swarm_cli/ui/formatters/cost.rb +49 -0
  51. data/lib/swarm_cli/ui/formatters/number.rb +58 -0
  52. data/lib/swarm_cli/ui/formatters/text.rb +77 -0
  53. data/lib/swarm_cli/ui/formatters/time.rb +73 -0
  54. data/lib/swarm_cli/ui/icons.rb +59 -0
  55. data/lib/swarm_cli/ui/renderers/event_renderer.rb +188 -0
  56. data/lib/swarm_cli/ui/state/agent_color_cache.rb +45 -0
  57. data/lib/swarm_cli/ui/state/depth_tracker.rb +40 -0
  58. data/lib/swarm_cli/ui/state/spinner_manager.rb +170 -0
  59. data/lib/swarm_cli/ui/state/usage_tracker.rb +62 -0
  60. data/lib/swarm_cli/version.rb +5 -0
  61. data/lib/swarm_cli.rb +45 -0
  62. data/lib/swarm_memory/adapters/base.rb +140 -0
  63. data/lib/swarm_memory/adapters/filesystem_adapter.rb +789 -0
  64. data/lib/swarm_memory/chat_extension.rb +34 -0
  65. data/lib/swarm_memory/cli/commands.rb +306 -0
  66. data/lib/swarm_memory/core/entry.rb +37 -0
  67. data/lib/swarm_memory/core/frontmatter_parser.rb +108 -0
  68. data/lib/swarm_memory/core/metadata_extractor.rb +68 -0
  69. data/lib/swarm_memory/core/path_normalizer.rb +75 -0
  70. data/lib/swarm_memory/core/semantic_index.rb +244 -0
  71. data/lib/swarm_memory/core/storage.rb +286 -0
  72. data/lib/swarm_memory/core/storage_read_tracker.rb +63 -0
  73. data/lib/swarm_memory/dsl/builder_extension.rb +40 -0
  74. data/lib/swarm_memory/dsl/memory_config.rb +113 -0
  75. data/lib/swarm_memory/embeddings/embedder.rb +36 -0
  76. data/lib/swarm_memory/embeddings/informers_embedder.rb +152 -0
  77. data/lib/swarm_memory/errors.rb +21 -0
  78. data/lib/swarm_memory/integration/cli_registration.rb +30 -0
  79. data/lib/swarm_memory/integration/configuration.rb +43 -0
  80. data/lib/swarm_memory/integration/registration.rb +31 -0
  81. data/lib/swarm_memory/integration/sdk_plugin.rb +531 -0
  82. data/lib/swarm_memory/optimization/analyzer.rb +244 -0
  83. data/lib/swarm_memory/optimization/defragmenter.rb +863 -0
  84. data/lib/swarm_memory/prompts/memory.md.erb +109 -0
  85. data/lib/swarm_memory/prompts/memory_assistant.md.erb +139 -0
  86. data/lib/swarm_memory/prompts/memory_researcher.md.erb +201 -0
  87. data/lib/swarm_memory/prompts/memory_retrieval.md.erb +76 -0
  88. data/lib/swarm_memory/search/semantic_search.rb +112 -0
  89. data/lib/swarm_memory/search/text_search.rb +40 -0
  90. data/lib/swarm_memory/search/text_similarity.rb +80 -0
  91. data/lib/swarm_memory/skills/meta/deep-learning.md +101 -0
  92. data/lib/swarm_memory/skills/meta/deep-learning.yml +14 -0
  93. data/lib/swarm_memory/tools/load_skill.rb +313 -0
  94. data/lib/swarm_memory/tools/memory_defrag.rb +382 -0
  95. data/lib/swarm_memory/tools/memory_delete.rb +99 -0
  96. data/lib/swarm_memory/tools/memory_edit.rb +185 -0
  97. data/lib/swarm_memory/tools/memory_glob.rb +145 -0
  98. data/lib/swarm_memory/tools/memory_grep.rb +209 -0
  99. data/lib/swarm_memory/tools/memory_multi_edit.rb +281 -0
  100. data/lib/swarm_memory/tools/memory_read.rb +123 -0
  101. data/lib/swarm_memory/tools/memory_write.rb +215 -0
  102. data/lib/swarm_memory/utils.rb +50 -0
  103. data/lib/swarm_memory/version.rb +5 -0
  104. data/lib/swarm_memory.rb +166 -0
  105. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +127 -0
  106. data/lib/swarm_sdk/agent/builder.rb +461 -0
  107. data/lib/swarm_sdk/agent/chat/context_tracker.rb +314 -0
  108. data/lib/swarm_sdk/agent/chat/hook_integration.rb +372 -0
  109. data/lib/swarm_sdk/agent/chat/logging_helpers.rb +116 -0
  110. data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +152 -0
  111. data/lib/swarm_sdk/agent/chat.rb +1144 -0
  112. data/lib/swarm_sdk/agent/context.rb +112 -0
  113. data/lib/swarm_sdk/agent/context_manager.rb +309 -0
  114. data/lib/swarm_sdk/agent/definition.rb +556 -0
  115. data/lib/swarm_sdk/claude_code_agent_adapter.rb +205 -0
  116. data/lib/swarm_sdk/configuration.rb +296 -0
  117. data/lib/swarm_sdk/context_compactor/metrics.rb +147 -0
  118. data/lib/swarm_sdk/context_compactor/token_counter.rb +106 -0
  119. data/lib/swarm_sdk/context_compactor.rb +340 -0
  120. data/lib/swarm_sdk/hooks/adapter.rb +359 -0
  121. data/lib/swarm_sdk/hooks/context.rb +197 -0
  122. data/lib/swarm_sdk/hooks/definition.rb +80 -0
  123. data/lib/swarm_sdk/hooks/error.rb +29 -0
  124. data/lib/swarm_sdk/hooks/executor.rb +146 -0
  125. data/lib/swarm_sdk/hooks/registry.rb +147 -0
  126. data/lib/swarm_sdk/hooks/result.rb +150 -0
  127. data/lib/swarm_sdk/hooks/shell_executor.rb +254 -0
  128. data/lib/swarm_sdk/hooks/tool_call.rb +35 -0
  129. data/lib/swarm_sdk/hooks/tool_result.rb +62 -0
  130. data/lib/swarm_sdk/log_collector.rb +51 -0
  131. data/lib/swarm_sdk/log_stream.rb +69 -0
  132. data/lib/swarm_sdk/markdown_parser.rb +75 -0
  133. data/lib/swarm_sdk/model_aliases.json +5 -0
  134. data/lib/swarm_sdk/models.json +1 -0
  135. data/lib/swarm_sdk/models.rb +120 -0
  136. data/lib/swarm_sdk/node/agent_config.rb +49 -0
  137. data/lib/swarm_sdk/node/builder.rb +439 -0
  138. data/lib/swarm_sdk/node/transformer_executor.rb +248 -0
  139. data/lib/swarm_sdk/node_context.rb +170 -0
  140. data/lib/swarm_sdk/node_orchestrator.rb +384 -0
  141. data/lib/swarm_sdk/permissions/config.rb +239 -0
  142. data/lib/swarm_sdk/permissions/error_formatter.rb +121 -0
  143. data/lib/swarm_sdk/permissions/path_matcher.rb +35 -0
  144. data/lib/swarm_sdk/permissions/validator.rb +173 -0
  145. data/lib/swarm_sdk/permissions_builder.rb +122 -0
  146. data/lib/swarm_sdk/plugin.rb +147 -0
  147. data/lib/swarm_sdk/plugin_registry.rb +101 -0
  148. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +243 -0
  149. data/lib/swarm_sdk/providers/openai_with_responses.rb +582 -0
  150. data/lib/swarm_sdk/result.rb +97 -0
  151. data/lib/swarm_sdk/swarm/agent_initializer.rb +334 -0
  152. data/lib/swarm_sdk/swarm/all_agents_builder.rb +140 -0
  153. data/lib/swarm_sdk/swarm/builder.rb +586 -0
  154. data/lib/swarm_sdk/swarm/mcp_configurator.rb +151 -0
  155. data/lib/swarm_sdk/swarm/tool_configurator.rb +416 -0
  156. data/lib/swarm_sdk/swarm.rb +982 -0
  157. data/lib/swarm_sdk/tools/bash.rb +274 -0
  158. data/lib/swarm_sdk/tools/clock.rb +44 -0
  159. data/lib/swarm_sdk/tools/delegate.rb +164 -0
  160. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +83 -0
  161. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +99 -0
  162. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
  163. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +78 -0
  164. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +194 -0
  165. data/lib/swarm_sdk/tools/edit.rb +150 -0
  166. data/lib/swarm_sdk/tools/glob.rb +158 -0
  167. data/lib/swarm_sdk/tools/grep.rb +228 -0
  168. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +43 -0
  169. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +163 -0
  170. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +65 -0
  171. data/lib/swarm_sdk/tools/multi_edit.rb +232 -0
  172. data/lib/swarm_sdk/tools/path_resolver.rb +43 -0
  173. data/lib/swarm_sdk/tools/read.rb +251 -0
  174. data/lib/swarm_sdk/tools/registry.rb +93 -0
  175. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
  176. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
  177. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
  178. data/lib/swarm_sdk/tools/stores/read_tracker.rb +61 -0
  179. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
  180. data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
  181. data/lib/swarm_sdk/tools/stores/todo_manager.rb +65 -0
  182. data/lib/swarm_sdk/tools/think.rb +95 -0
  183. data/lib/swarm_sdk/tools/todo_write.rb +216 -0
  184. data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
  185. data/lib/swarm_sdk/tools/write.rb +117 -0
  186. data/lib/swarm_sdk/utils.rb +50 -0
  187. data/lib/swarm_sdk/version.rb +5 -0
  188. data/lib/swarm_sdk.rb +167 -0
  189. metadata +313 -0
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SwarmSDK
4
+ module Tools
5
+ # Write tool for writing content to files
6
+ #
7
+ # Creates new files or overwrites existing files.
8
+ # Enforces read-before-write rule for existing files.
9
+ # Includes validation and usage guidelines via system reminders.
10
+ class Write < RubyLLM::Tool
11
+ include PathResolver
12
+
13
+ description <<~DESC
14
+ Writes a file to the local filesystem.
15
+ This tool will overwrite the existing file if there is one at the provided path.
16
+ If this is an existing file, you MUST use the Read tool first to read the file's contents.
17
+ This tool will fail if you did not read the file first.
18
+ ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
19
+ NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.
20
+ Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.
21
+
22
+ IMPORTANT - Path Handling:
23
+ - Relative paths (e.g., "tmp/file.txt", "src/main.rb") are resolved relative to your agent's working directory
24
+ - Absolute paths (e.g., "/tmp/file.txt", "/etc/passwd") are treated as system absolute paths
25
+ - When the user says "tmp/file.txt" they mean the tmp directory in your working directory, NOT /tmp
26
+ - Only use absolute paths (starting with /) when explicitly referring to system-level paths
27
+ DESC
28
+
29
+ param :file_path,
30
+ type: "string",
31
+ desc: "Path to the file. Use relative paths (e.g., 'tmp/file.txt') for files in your working directory, or absolute paths (e.g., '/etc/passwd') for system files.",
32
+ required: true
33
+
34
+ param :content,
35
+ type: "string",
36
+ desc: "The content to write to the file",
37
+ required: true
38
+
39
+ # Initialize the Write tool for a specific agent
40
+ #
41
+ # @param agent_name [Symbol, String] The agent identifier
42
+ # @param directory [String] Agent's working directory
43
+ def initialize(agent_name:, directory:)
44
+ super()
45
+ @agent_name = agent_name.to_sym
46
+ @directory = File.expand_path(directory)
47
+ end
48
+
49
+ # Override name to return simple "Write" instead of full class path
50
+ def name
51
+ "Write"
52
+ end
53
+
54
+ def execute(file_path:, content:)
55
+ # Validate inputs
56
+ return validation_error("file_path is required") if file_path.nil? || file_path.to_s.strip.empty?
57
+ return validation_error("content is required") if content.nil?
58
+
59
+ # CRITICAL: Resolve path against agent directory
60
+ resolved_path = resolve_path(file_path)
61
+
62
+ # Check if file already exists (use resolved path)
63
+ file_exists = File.exist?(resolved_path)
64
+
65
+ # Enforce read-before-write for existing files (use resolved path)
66
+ if file_exists && !Stores::ReadTracker.file_read?(@agent_name, resolved_path)
67
+ return validation_error(
68
+ "Cannot write to existing file without reading it first. " \
69
+ "You must use the Read tool on '#{file_path}' before overwriting it. " \
70
+ "This ensures you have context about the file's current contents.",
71
+ )
72
+ end
73
+
74
+ # Create parent directory if it doesn't exist (use resolved path)
75
+ parent_dir = File.dirname(resolved_path)
76
+ FileUtils.mkdir_p(parent_dir) unless File.directory?(parent_dir)
77
+
78
+ # Write the file (use resolved path)
79
+ File.write(resolved_path, content, encoding: "UTF-8")
80
+
81
+ # Build success message
82
+ byte_size = content.bytesize
83
+ line_count = content.lines.count
84
+ action = file_exists ? "overwrote" : "created"
85
+
86
+ message = "Successfully #{action} file: #{file_path} (#{line_count} lines, #{byte_size} bytes)"
87
+
88
+ # Add system reminder for overwritten files
89
+ if file_exists
90
+ reminder = "<system-reminder>You overwrote an existing file. Make sure this was intentional and that you read the file first if you needed to preserve any content.</system-reminder>"
91
+ "#{message}\n\n#{reminder}"
92
+ else
93
+ message
94
+ end
95
+ rescue Errno::EACCES
96
+ error("Permission denied: Cannot write to file '#{file_path}'")
97
+ rescue Errno::EISDIR
98
+ error("Path is a directory, not a file.")
99
+ rescue Errno::ENOENT => e
100
+ error("Failed to create parent directory: #{e.message}")
101
+ rescue StandardError => e
102
+ error("Unexpected error writing file: #{e.class.name} - #{e.message}")
103
+ end
104
+
105
+ private
106
+
107
+ # Helper methods
108
+ def validation_error(message)
109
+ "<tool_use_error>InputValidationError: #{message}</tool_use_error>"
110
+ end
111
+
112
+ def error(message)
113
+ "Error: #{message}"
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SwarmSDK
4
+ # Shared utility methods for SwarmSDK
5
+ module Utils
6
+ class << self
7
+ # Recursively convert all hash keys to symbols
8
+ #
9
+ # Handles nested hashes and arrays containing hashes.
10
+ #
11
+ # @param obj [Object] Object to symbolize (Hash, Array, or other)
12
+ # @return [Object] Object with symbolized keys (if applicable)
13
+ #
14
+ # @example
15
+ # Utils.symbolize_keys({ "name" => "test", "config" => { "key" => "value" } })
16
+ # # => { name: "test", config: { key: "value" } }
17
+ def symbolize_keys(obj)
18
+ case obj
19
+ when Hash
20
+ obj.transform_keys(&:to_sym).transform_values { |v| symbolize_keys(v) }
21
+ when Array
22
+ obj.map { |item| symbolize_keys(item) }
23
+ else
24
+ obj
25
+ end
26
+ end
27
+
28
+ # Recursively convert all hash keys to strings
29
+ #
30
+ # Handles nested hashes and arrays containing hashes.
31
+ #
32
+ # @param obj [Object] Object to stringify (Hash, Array, or other)
33
+ # @return [Object] Object with stringified keys (if applicable)
34
+ #
35
+ # @example
36
+ # Utils.stringify_keys({ name: "test", config: { key: "value" } })
37
+ # # => { "name" => "test", "config" => { "key" => "value" } }
38
+ def stringify_keys(obj)
39
+ case obj
40
+ when Hash
41
+ obj.transform_keys(&:to_s).transform_values { |v| stringify_keys(v) }
42
+ when Array
43
+ obj.map { |item| stringify_keys(item) }
44
+ else
45
+ obj
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SwarmSDK
4
+ VERSION = "2.0.6"
5
+ end
data/lib/swarm_sdk.rb ADDED
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler"
4
+ require "digest"
5
+ require "English"
6
+ require "erb"
7
+ require "fileutils"
8
+ require "json"
9
+ require "logger"
10
+ require "pathname"
11
+ require "securerandom"
12
+ require "set"
13
+ require "yaml"
14
+
15
+ require "async"
16
+ require "async/semaphore"
17
+ require "ruby_llm"
18
+ require "ruby_llm/mcp"
19
+
20
+ module SwarmSDK
21
+ end
22
+
23
+ require "zeitwerk"
24
+ loader = Zeitwerk::Loader.new
25
+ loader.push_dir("#{__dir__}/swarm_sdk", namespace: SwarmSDK)
26
+ loader.inflector.inflect(
27
+ "cli" => "CLI",
28
+ )
29
+ loader.setup
30
+
31
+ # Load plugin system explicitly (core infrastructure)
32
+ require_relative "swarm_sdk/plugin"
33
+ require_relative "swarm_sdk/plugin_registry"
34
+
35
+ # Load custom providers explicitly (Zeitwerk doesn't eager load by default)
36
+ require_relative "swarm_sdk/providers/openai_with_responses"
37
+
38
+ module SwarmSDK
39
+ class Error < StandardError; end
40
+ class ConfigurationError < Error; end
41
+ class AgentNotFoundError < Error; end
42
+ class CircularDependencyError < Error; end
43
+ class ToolExecutionError < Error; end
44
+ class LLMError < Error; end
45
+ class StateError < Error; end
46
+
47
+ class << self
48
+ # Settings for SwarmSDK (global configuration)
49
+ attr_accessor :settings
50
+
51
+ # Main entry point for DSL
52
+ def build(&block)
53
+ Swarm::Builder.build(&block)
54
+ end
55
+
56
+ # Configure SwarmSDK global settings
57
+ def configure
58
+ self.settings ||= Settings.new
59
+ yield(settings)
60
+ end
61
+
62
+ # Reset settings to defaults
63
+ def reset_settings!
64
+ self.settings = Settings.new
65
+ end
66
+
67
+ # Alias for backward compatibility
68
+ alias_method :configuration, :settings
69
+ alias_method :reset_configuration!, :reset_settings!
70
+ end
71
+
72
+ # Settings class for SwarmSDK global settings (not to be confused with Configuration for YAML loading)
73
+ class Settings
74
+ # WebFetch tool LLM processing configuration
75
+ attr_accessor :webfetch_provider, :webfetch_model, :webfetch_base_url, :webfetch_max_tokens
76
+
77
+ def initialize
78
+ @webfetch_provider = nil
79
+ @webfetch_model = nil
80
+ @webfetch_base_url = nil
81
+ @webfetch_max_tokens = 4096
82
+ end
83
+
84
+ # Check if WebFetch LLM processing is enabled
85
+ def webfetch_llm_enabled?
86
+ !@webfetch_provider.nil? && !@webfetch_model.nil?
87
+ end
88
+ end
89
+
90
+ # Initialize default settings
91
+ self.settings = Settings.new
92
+ end
93
+
94
+ # Automatically configure RubyLLM from environment variables
95
+ # This makes SwarmSDK "just work" when users set standard ENV variables
96
+ RubyLLM.configure do |config|
97
+ # Only set if config not already set (||= handles nil ENV values gracefully)
98
+
99
+ # OpenAI
100
+ config.openai_api_key ||= ENV["OPENAI_API_KEY"]
101
+ config.openai_api_base ||= ENV["OPENAI_API_BASE"]
102
+ config.openai_organization_id ||= ENV["OPENAI_ORG_ID"]
103
+ config.openai_project_id ||= ENV["OPENAI_PROJECT_ID"]
104
+
105
+ # Anthropic
106
+ config.anthropic_api_key ||= ENV["ANTHROPIC_API_KEY"]
107
+
108
+ # Google Gemini
109
+ config.gemini_api_key ||= ENV["GEMINI_API_KEY"]
110
+
111
+ # Google Vertex AI (note: vertexai, not vertex_ai)
112
+ config.vertexai_project_id ||= ENV["GOOGLE_CLOUD_PROJECT"] || ENV["VERTEXAI_PROJECT_ID"]
113
+ config.vertexai_location ||= ENV["GOOGLE_CLOUD_LOCATION"] || ENV["VERTEXAI_LOCATION"]
114
+
115
+ # DeepSeek
116
+ config.deepseek_api_key ||= ENV["DEEPSEEK_API_KEY"]
117
+
118
+ # Mistral
119
+ config.mistral_api_key ||= ENV["MISTRAL_API_KEY"]
120
+
121
+ # Perplexity
122
+ config.perplexity_api_key ||= ENV["PERPLEXITY_API_KEY"]
123
+
124
+ # OpenRouter
125
+ config.openrouter_api_key ||= ENV["OPENROUTER_API_KEY"]
126
+
127
+ # AWS Bedrock
128
+ config.bedrock_api_key ||= ENV["AWS_ACCESS_KEY_ID"]
129
+ config.bedrock_secret_key ||= ENV["AWS_SECRET_ACCESS_KEY"]
130
+ config.bedrock_region ||= ENV["AWS_REGION"]
131
+ config.bedrock_session_token ||= ENV["AWS_SESSION_TOKEN"]
132
+
133
+ # Ollama (local)
134
+ config.ollama_api_base ||= ENV["OLLAMA_API_BASE"]
135
+
136
+ # GPUStack (local)
137
+ config.gpustack_api_base ||= ENV["GPUSTACK_API_BASE"]
138
+ config.gpustack_api_key ||= ENV["GPUSTACK_API_KEY"]
139
+ end
140
+
141
+ # monkey patches
142
+ # ruby_llm/mcp
143
+ # - add `id` when sending "notifications/initialized" message: https://github.com/patvice/ruby_llm-mcp/issues/65
144
+ # - remove `to_sym` on MCP parameter type: https://github.com/patvice/ruby_llm-mcp/issues/62#issuecomment-3421488406
145
+ require "ruby_llm/mcp/notifications/initialize"
146
+ require "ruby_llm/mcp/parameter"
147
+
148
+ module RubyLLM
149
+ module MCP
150
+ class Parameter < RubyLLM::Parameter
151
+ def initialize(name, type: "string", desc: nil, required: true, default: nil, union_type: nil)
152
+ super(name, type: type, desc: desc, required: required)
153
+ @properties = {}
154
+ @union_type = union_type
155
+ @default = default
156
+ end
157
+ end
158
+
159
+ module Notifications
160
+ class Initialize
161
+ def call
162
+ @coordinator.request(notification_body, add_id: true, wait_for_response: false)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
metadata ADDED
@@ -0,0 +1,313 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: swarm_memory
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Paulo Arruda
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-10-26 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: async
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: informers
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.2.1
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.2.1
40
+ - !ruby/object:Gem::Dependency
41
+ name: rice
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 4.6.0
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 4.6.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: ruby_llm
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.8'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.8'
68
+ - !ruby/object:Gem::Dependency
69
+ name: swarm_sdk
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.0'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: zeitwerk
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '2.6'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.6'
96
+ description: Hierarchical persistent memory with semantic search for SwarmSDK AI agents
97
+ email:
98
+ - parrudaj@gmail.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - LICENSE
104
+ - lib/claude_swarm.rb
105
+ - lib/claude_swarm/base_executor.rb
106
+ - lib/claude_swarm/claude_code_executor.rb
107
+ - lib/claude_swarm/claude_mcp_server.rb
108
+ - lib/claude_swarm/cli.rb
109
+ - lib/claude_swarm/commands/ps.rb
110
+ - lib/claude_swarm/commands/show.rb
111
+ - lib/claude_swarm/configuration.rb
112
+ - lib/claude_swarm/hooks/session_start_hook.rb
113
+ - lib/claude_swarm/json_handler.rb
114
+ - lib/claude_swarm/mcp_generator.rb
115
+ - lib/claude_swarm/openai/chat_completion.rb
116
+ - lib/claude_swarm/openai/executor.rb
117
+ - lib/claude_swarm/openai/responses.rb
118
+ - lib/claude_swarm/orchestrator.rb
119
+ - lib/claude_swarm/process_tracker.rb
120
+ - lib/claude_swarm/session_cost_calculator.rb
121
+ - lib/claude_swarm/session_path.rb
122
+ - lib/claude_swarm/settings_generator.rb
123
+ - lib/claude_swarm/system_utils.rb
124
+ - lib/claude_swarm/templates/generation_prompt.md.erb
125
+ - lib/claude_swarm/tools/reset_session_tool.rb
126
+ - lib/claude_swarm/tools/session_info_tool.rb
127
+ - lib/claude_swarm/tools/task_tool.rb
128
+ - lib/claude_swarm/version.rb
129
+ - lib/claude_swarm/worktree_manager.rb
130
+ - lib/claude_swarm/yaml_loader.rb
131
+ - lib/swarm_cli.rb
132
+ - lib/swarm_cli/cli.rb
133
+ - lib/swarm_cli/command_registry.rb
134
+ - lib/swarm_cli/commands/mcp_serve.rb
135
+ - lib/swarm_cli/commands/mcp_tools.rb
136
+ - lib/swarm_cli/commands/migrate.rb
137
+ - lib/swarm_cli/commands/run.rb
138
+ - lib/swarm_cli/config_loader.rb
139
+ - lib/swarm_cli/formatters/human_formatter.rb
140
+ - lib/swarm_cli/formatters/json_formatter.rb
141
+ - lib/swarm_cli/interactive_repl.rb
142
+ - lib/swarm_cli/mcp_serve_options.rb
143
+ - lib/swarm_cli/mcp_tools_options.rb
144
+ - lib/swarm_cli/migrate_options.rb
145
+ - lib/swarm_cli/migrator.rb
146
+ - lib/swarm_cli/options.rb
147
+ - lib/swarm_cli/ui/components/agent_badge.rb
148
+ - lib/swarm_cli/ui/components/content_block.rb
149
+ - lib/swarm_cli/ui/components/divider.rb
150
+ - lib/swarm_cli/ui/components/panel.rb
151
+ - lib/swarm_cli/ui/components/usage_stats.rb
152
+ - lib/swarm_cli/ui/formatters/cost.rb
153
+ - lib/swarm_cli/ui/formatters/number.rb
154
+ - lib/swarm_cli/ui/formatters/text.rb
155
+ - lib/swarm_cli/ui/formatters/time.rb
156
+ - lib/swarm_cli/ui/icons.rb
157
+ - lib/swarm_cli/ui/renderers/event_renderer.rb
158
+ - lib/swarm_cli/ui/state/agent_color_cache.rb
159
+ - lib/swarm_cli/ui/state/depth_tracker.rb
160
+ - lib/swarm_cli/ui/state/spinner_manager.rb
161
+ - lib/swarm_cli/ui/state/usage_tracker.rb
162
+ - lib/swarm_cli/version.rb
163
+ - lib/swarm_memory.rb
164
+ - lib/swarm_memory/adapters/base.rb
165
+ - lib/swarm_memory/adapters/filesystem_adapter.rb
166
+ - lib/swarm_memory/chat_extension.rb
167
+ - lib/swarm_memory/cli/commands.rb
168
+ - lib/swarm_memory/core/entry.rb
169
+ - lib/swarm_memory/core/frontmatter_parser.rb
170
+ - lib/swarm_memory/core/metadata_extractor.rb
171
+ - lib/swarm_memory/core/path_normalizer.rb
172
+ - lib/swarm_memory/core/semantic_index.rb
173
+ - lib/swarm_memory/core/storage.rb
174
+ - lib/swarm_memory/core/storage_read_tracker.rb
175
+ - lib/swarm_memory/dsl/builder_extension.rb
176
+ - lib/swarm_memory/dsl/memory_config.rb
177
+ - lib/swarm_memory/embeddings/embedder.rb
178
+ - lib/swarm_memory/embeddings/informers_embedder.rb
179
+ - lib/swarm_memory/errors.rb
180
+ - lib/swarm_memory/integration/cli_registration.rb
181
+ - lib/swarm_memory/integration/configuration.rb
182
+ - lib/swarm_memory/integration/registration.rb
183
+ - lib/swarm_memory/integration/sdk_plugin.rb
184
+ - lib/swarm_memory/optimization/analyzer.rb
185
+ - lib/swarm_memory/optimization/defragmenter.rb
186
+ - lib/swarm_memory/prompts/memory.md.erb
187
+ - lib/swarm_memory/prompts/memory_assistant.md.erb
188
+ - lib/swarm_memory/prompts/memory_researcher.md.erb
189
+ - lib/swarm_memory/prompts/memory_retrieval.md.erb
190
+ - lib/swarm_memory/search/semantic_search.rb
191
+ - lib/swarm_memory/search/text_search.rb
192
+ - lib/swarm_memory/search/text_similarity.rb
193
+ - lib/swarm_memory/skills/meta/deep-learning.md
194
+ - lib/swarm_memory/skills/meta/deep-learning.yml
195
+ - lib/swarm_memory/tools/load_skill.rb
196
+ - lib/swarm_memory/tools/memory_defrag.rb
197
+ - lib/swarm_memory/tools/memory_delete.rb
198
+ - lib/swarm_memory/tools/memory_edit.rb
199
+ - lib/swarm_memory/tools/memory_glob.rb
200
+ - lib/swarm_memory/tools/memory_grep.rb
201
+ - lib/swarm_memory/tools/memory_multi_edit.rb
202
+ - lib/swarm_memory/tools/memory_read.rb
203
+ - lib/swarm_memory/tools/memory_write.rb
204
+ - lib/swarm_memory/utils.rb
205
+ - lib/swarm_memory/version.rb
206
+ - lib/swarm_sdk.rb
207
+ - lib/swarm_sdk/agent/RETRY_LOGIC.md
208
+ - lib/swarm_sdk/agent/builder.rb
209
+ - lib/swarm_sdk/agent/chat.rb
210
+ - lib/swarm_sdk/agent/chat/context_tracker.rb
211
+ - lib/swarm_sdk/agent/chat/hook_integration.rb
212
+ - lib/swarm_sdk/agent/chat/logging_helpers.rb
213
+ - lib/swarm_sdk/agent/chat/system_reminder_injector.rb
214
+ - lib/swarm_sdk/agent/context.rb
215
+ - lib/swarm_sdk/agent/context_manager.rb
216
+ - lib/swarm_sdk/agent/definition.rb
217
+ - lib/swarm_sdk/claude_code_agent_adapter.rb
218
+ - lib/swarm_sdk/configuration.rb
219
+ - lib/swarm_sdk/context_compactor.rb
220
+ - lib/swarm_sdk/context_compactor/metrics.rb
221
+ - lib/swarm_sdk/context_compactor/token_counter.rb
222
+ - lib/swarm_sdk/hooks/adapter.rb
223
+ - lib/swarm_sdk/hooks/context.rb
224
+ - lib/swarm_sdk/hooks/definition.rb
225
+ - lib/swarm_sdk/hooks/error.rb
226
+ - lib/swarm_sdk/hooks/executor.rb
227
+ - lib/swarm_sdk/hooks/registry.rb
228
+ - lib/swarm_sdk/hooks/result.rb
229
+ - lib/swarm_sdk/hooks/shell_executor.rb
230
+ - lib/swarm_sdk/hooks/tool_call.rb
231
+ - lib/swarm_sdk/hooks/tool_result.rb
232
+ - lib/swarm_sdk/log_collector.rb
233
+ - lib/swarm_sdk/log_stream.rb
234
+ - lib/swarm_sdk/markdown_parser.rb
235
+ - lib/swarm_sdk/model_aliases.json
236
+ - lib/swarm_sdk/models.json
237
+ - lib/swarm_sdk/models.rb
238
+ - lib/swarm_sdk/node/agent_config.rb
239
+ - lib/swarm_sdk/node/builder.rb
240
+ - lib/swarm_sdk/node/transformer_executor.rb
241
+ - lib/swarm_sdk/node_context.rb
242
+ - lib/swarm_sdk/node_orchestrator.rb
243
+ - lib/swarm_sdk/permissions/config.rb
244
+ - lib/swarm_sdk/permissions/error_formatter.rb
245
+ - lib/swarm_sdk/permissions/path_matcher.rb
246
+ - lib/swarm_sdk/permissions/validator.rb
247
+ - lib/swarm_sdk/permissions_builder.rb
248
+ - lib/swarm_sdk/plugin.rb
249
+ - lib/swarm_sdk/plugin_registry.rb
250
+ - lib/swarm_sdk/prompts/base_system_prompt.md.erb
251
+ - lib/swarm_sdk/providers/openai_with_responses.rb
252
+ - lib/swarm_sdk/result.rb
253
+ - lib/swarm_sdk/swarm.rb
254
+ - lib/swarm_sdk/swarm/agent_initializer.rb
255
+ - lib/swarm_sdk/swarm/all_agents_builder.rb
256
+ - lib/swarm_sdk/swarm/builder.rb
257
+ - lib/swarm_sdk/swarm/mcp_configurator.rb
258
+ - lib/swarm_sdk/swarm/tool_configurator.rb
259
+ - lib/swarm_sdk/tools/bash.rb
260
+ - lib/swarm_sdk/tools/clock.rb
261
+ - lib/swarm_sdk/tools/delegate.rb
262
+ - lib/swarm_sdk/tools/document_converters/base_converter.rb
263
+ - lib/swarm_sdk/tools/document_converters/docx_converter.rb
264
+ - lib/swarm_sdk/tools/document_converters/html_converter.rb
265
+ - lib/swarm_sdk/tools/document_converters/pdf_converter.rb
266
+ - lib/swarm_sdk/tools/document_converters/xlsx_converter.rb
267
+ - lib/swarm_sdk/tools/edit.rb
268
+ - lib/swarm_sdk/tools/glob.rb
269
+ - lib/swarm_sdk/tools/grep.rb
270
+ - lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb
271
+ - lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb
272
+ - lib/swarm_sdk/tools/image_formats/tiff_builder.rb
273
+ - lib/swarm_sdk/tools/multi_edit.rb
274
+ - lib/swarm_sdk/tools/path_resolver.rb
275
+ - lib/swarm_sdk/tools/read.rb
276
+ - lib/swarm_sdk/tools/registry.rb
277
+ - lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb
278
+ - lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb
279
+ - lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb
280
+ - lib/swarm_sdk/tools/stores/read_tracker.rb
281
+ - lib/swarm_sdk/tools/stores/scratchpad_storage.rb
282
+ - lib/swarm_sdk/tools/stores/storage.rb
283
+ - lib/swarm_sdk/tools/stores/todo_manager.rb
284
+ - lib/swarm_sdk/tools/think.rb
285
+ - lib/swarm_sdk/tools/todo_write.rb
286
+ - lib/swarm_sdk/tools/web_fetch.rb
287
+ - lib/swarm_sdk/tools/write.rb
288
+ - lib/swarm_sdk/utils.rb
289
+ - lib/swarm_sdk/version.rb
290
+ homepage: https://github.com/parruda/claude-swarm
291
+ licenses:
292
+ - MIT
293
+ metadata:
294
+ source_code_uri: https://github.com/parruda/claude-swarm
295
+ changelog_uri: https://github.com/parruda/claude-swarm/blob/main/docs/v2/CHANGELOG.swarm_memory.md
296
+ rdoc_options: []
297
+ require_paths:
298
+ - lib
299
+ required_ruby_version: !ruby/object:Gem::Requirement
300
+ requirements:
301
+ - - ">="
302
+ - !ruby/object:Gem::Version
303
+ version: 3.2.0
304
+ required_rubygems_version: !ruby/object:Gem::Requirement
305
+ requirements:
306
+ - - ">="
307
+ - !ruby/object:Gem::Version
308
+ version: '0'
309
+ requirements: []
310
+ rubygems_version: 3.6.2
311
+ specification_version: 4
312
+ summary: Persistent memory system for SwarmSDK agents
313
+ test_files: []