swarm_sdk 2.0.3 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/swarm_sdk/agent/builder.rb +41 -0
- data/lib/swarm_sdk/agent/chat/logging_helpers.rb +22 -5
- data/lib/swarm_sdk/agent/definition.rb +52 -6
- data/lib/swarm_sdk/configuration.rb +3 -1
- data/lib/swarm_sdk/prompts/memory.md.erb +480 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +16 -3
- data/lib/swarm_sdk/swarm/builder.rb +9 -1
- data/lib/swarm_sdk/swarm/tool_configurator.rb +73 -23
- data/lib/swarm_sdk/swarm.rb +51 -7
- data/lib/swarm_sdk/tools/document_converters/html_converter.rb +101 -0
- data/lib/swarm_sdk/tools/memory/memory_delete.rb +64 -0
- data/lib/swarm_sdk/tools/memory/memory_edit.rb +145 -0
- data/lib/swarm_sdk/tools/memory/memory_glob.rb +94 -0
- data/lib/swarm_sdk/tools/memory/memory_grep.rb +147 -0
- data/lib/swarm_sdk/tools/memory/memory_multi_edit.rb +228 -0
- data/lib/swarm_sdk/tools/memory/memory_read.rb +82 -0
- data/lib/swarm_sdk/tools/memory/memory_write.rb +90 -0
- data/lib/swarm_sdk/tools/registry.rb +11 -3
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +96 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +76 -0
- data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +91 -0
- data/lib/swarm_sdk/tools/stores/memory_storage.rb +300 -0
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +224 -0
- data/lib/swarm_sdk/tools/stores/storage.rb +148 -0
- data/lib/swarm_sdk/tools/stores/storage_read_tracker.rb +61 -0
- data/lib/swarm_sdk/tools/web_fetch.rb +261 -0
- data/lib/swarm_sdk/version.rb +1 -1
- data/lib/swarm_sdk.rb +39 -0
- metadata +18 -5
- data/lib/swarm_sdk/tools/scratchpad_list.rb +0 -88
- data/lib/swarm_sdk/tools/scratchpad_read.rb +0 -59
- data/lib/swarm_sdk/tools/scratchpad_write.rb +0 -88
- data/lib/swarm_sdk/tools/stores/scratchpad.rb +0 -153
@@ -1,153 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module SwarmSDK
|
4
|
-
module Tools
|
5
|
-
module Stores
|
6
|
-
# Scratchpad provides session-scoped, in-memory storage for agents
|
7
|
-
# to store detailed outputs that would otherwise bloat tool responses.
|
8
|
-
#
|
9
|
-
# Features:
|
10
|
-
# - Session-scoped: Cleared when swarm execution completes
|
11
|
-
# - Shared: Any agent can read/write any scratchpad address
|
12
|
-
# - Path-based: Hierarchical organization using file-path-like addresses
|
13
|
-
# - In-memory: No filesystem I/O, pure memory storage
|
14
|
-
# - Metadata-rich: Stores content + title + timestamp + size
|
15
|
-
class Scratchpad
|
16
|
-
# Maximum size per scratchpad entry (1MB)
|
17
|
-
MAX_ENTRY_SIZE = 1_000_000
|
18
|
-
|
19
|
-
# Maximum total scratchpad size (100MB)
|
20
|
-
MAX_TOTAL_SIZE = 100_000_000
|
21
|
-
|
22
|
-
# Represents a single scratchpad entry with metadata
|
23
|
-
Entry = Struct.new(:content, :title, :created_at, :size, keyword_init: true)
|
24
|
-
|
25
|
-
def initialize
|
26
|
-
@entries = {}
|
27
|
-
@total_size = 0
|
28
|
-
end
|
29
|
-
|
30
|
-
# Write content to scratchpad
|
31
|
-
#
|
32
|
-
# @param file_path [String] Path to store content
|
33
|
-
# @param content [String] Content to store
|
34
|
-
# @param title [String] Brief title describing the content
|
35
|
-
# @raise [ArgumentError] If size limits are exceeded
|
36
|
-
# @return [Entry] The created entry
|
37
|
-
def write(file_path:, content:, title:)
|
38
|
-
raise ArgumentError, "file_path is required" if file_path.nil? || file_path.to_s.strip.empty?
|
39
|
-
raise ArgumentError, "content is required" if content.nil?
|
40
|
-
raise ArgumentError, "title is required" if title.nil? || title.to_s.strip.empty?
|
41
|
-
|
42
|
-
content_size = content.bytesize
|
43
|
-
|
44
|
-
# Check entry size limit
|
45
|
-
if content_size > MAX_ENTRY_SIZE
|
46
|
-
raise ArgumentError, "Content exceeds maximum size (#{format_bytes(MAX_ENTRY_SIZE)}). " \
|
47
|
-
"Current: #{format_bytes(content_size)}"
|
48
|
-
end
|
49
|
-
|
50
|
-
# Calculate new total size
|
51
|
-
existing_entry = @entries[file_path]
|
52
|
-
existing_size = existing_entry ? existing_entry.size : 0
|
53
|
-
new_total_size = @total_size - existing_size + content_size
|
54
|
-
|
55
|
-
# Check total size limit
|
56
|
-
if new_total_size > MAX_TOTAL_SIZE
|
57
|
-
raise ArgumentError, "Scratchpad full (#{format_bytes(MAX_TOTAL_SIZE)} limit). " \
|
58
|
-
"Current: #{format_bytes(@total_size)}, " \
|
59
|
-
"Would be: #{format_bytes(new_total_size)}. " \
|
60
|
-
"Clear old entries or use smaller content."
|
61
|
-
end
|
62
|
-
|
63
|
-
# Create entry
|
64
|
-
entry = Entry.new(
|
65
|
-
content: content,
|
66
|
-
title: title,
|
67
|
-
created_at: Time.now,
|
68
|
-
size: content_size,
|
69
|
-
)
|
70
|
-
|
71
|
-
# Update storage
|
72
|
-
@entries[file_path] = entry
|
73
|
-
@total_size = new_total_size
|
74
|
-
|
75
|
-
entry
|
76
|
-
end
|
77
|
-
|
78
|
-
# Read content from scratchpad
|
79
|
-
#
|
80
|
-
# @param file_path [String] Path to read from
|
81
|
-
# @raise [ArgumentError] If path not found
|
82
|
-
# @return [String] Content at the path
|
83
|
-
def read(file_path:)
|
84
|
-
raise ArgumentError, "file_path is required" if file_path.nil? || file_path.to_s.strip.empty?
|
85
|
-
|
86
|
-
entry = @entries[file_path]
|
87
|
-
raise ArgumentError, "scratchpad://#{file_path} not found" unless entry
|
88
|
-
|
89
|
-
entry.content
|
90
|
-
end
|
91
|
-
|
92
|
-
# List scratchpad entries, optionally filtered by prefix
|
93
|
-
#
|
94
|
-
# @param prefix [String, nil] Filter by path prefix
|
95
|
-
# @return [Array<Hash>] Array of entry metadata (path, title, size, created_at)
|
96
|
-
def list(prefix: nil)
|
97
|
-
entries = @entries
|
98
|
-
|
99
|
-
# Filter by prefix if provided
|
100
|
-
if prefix && !prefix.empty?
|
101
|
-
entries = entries.select { |path, _| path.start_with?(prefix) }
|
102
|
-
end
|
103
|
-
|
104
|
-
# Return metadata
|
105
|
-
entries.map do |path, entry|
|
106
|
-
{
|
107
|
-
path: path,
|
108
|
-
title: entry.title,
|
109
|
-
size: entry.size,
|
110
|
-
created_at: entry.created_at,
|
111
|
-
}
|
112
|
-
end.sort_by { |e| e[:path] }
|
113
|
-
end
|
114
|
-
|
115
|
-
# Clear all entries
|
116
|
-
#
|
117
|
-
# @return [void]
|
118
|
-
def clear
|
119
|
-
@entries.clear
|
120
|
-
@total_size = 0
|
121
|
-
end
|
122
|
-
|
123
|
-
# Get current total size
|
124
|
-
#
|
125
|
-
# @return [Integer] Total size in bytes
|
126
|
-
attr_reader :total_size
|
127
|
-
|
128
|
-
# Get number of entries
|
129
|
-
#
|
130
|
-
# @return [Integer] Number of entries
|
131
|
-
def size
|
132
|
-
@entries.size
|
133
|
-
end
|
134
|
-
|
135
|
-
private
|
136
|
-
|
137
|
-
# Format bytes to human-readable size
|
138
|
-
#
|
139
|
-
# @param bytes [Integer] Number of bytes
|
140
|
-
# @return [String] Formatted size (e.g., "1.5MB", "500.0KB")
|
141
|
-
def format_bytes(bytes)
|
142
|
-
if bytes >= 1_000_000
|
143
|
-
"#{(bytes.to_f / 1_000_000).round(1)}MB"
|
144
|
-
elsif bytes >= 1_000
|
145
|
-
"#{(bytes.to_f / 1_000).round(1)}KB"
|
146
|
-
else
|
147
|
-
"#{bytes}B"
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|