swarm_memory 2.2.3 → 2.2.4
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 768a8a8cd1d0ab5a3edff5e6e0c54e3fdce1e6c6af281d6a39285019167b87c8
|
|
4
|
+
data.tar.gz: aa9e396d3c72e53bf49459828c635148205c523e6d16bb42e7f6e4e5856a1d4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c35aad639f910180b0bcd73db10b8db18f4cb9bde3d136789e77b26ac1a1a2a66fc476b1cce9731bf06566ad8bf9bfbc8edfe0c513b62a303c79346c6efb5b52
|
|
7
|
+
data.tar.gz: 18f0c1c5fc97d2946174e43d61c86493cbaa31626a8c6ecbf019ad12ca9654ebdeb77475305a79fb1c11ed85eb85b35be44fad349bb56806e039ea6afafea247
|
|
@@ -138,7 +138,7 @@ module SwarmMemory
|
|
|
138
138
|
result << "Memory entries matching '#{pattern}' (#{entries.size} #{entries.size == 1 ? "entry" : "entries"}):"
|
|
139
139
|
|
|
140
140
|
entries.each do |entry|
|
|
141
|
-
result << "
|
|
141
|
+
result << "- memory://#{entry[:path]} \"#{entry[:title]}\" (#{format_bytes(entry[:size])})"
|
|
142
142
|
end
|
|
143
143
|
|
|
144
144
|
output = result.join("\n")
|
|
@@ -7,6 +7,8 @@ module SwarmMemory
|
|
|
7
7
|
# Searches content stored in memory entries using regex patterns.
|
|
8
8
|
# Each agent has its own isolated memory storage.
|
|
9
9
|
class MemoryGrep < RubyLLM::Tool
|
|
10
|
+
include TitleLookup
|
|
11
|
+
|
|
10
12
|
description <<~DESC
|
|
11
13
|
Search your memory content using regular expression patterns (like grep).
|
|
12
14
|
|
|
@@ -197,7 +199,7 @@ module SwarmMemory
|
|
|
197
199
|
result = []
|
|
198
200
|
result << "Memory entries matching #{search_desc} (#{paths.size} #{paths.size == 1 ? "entry" : "entries"}):"
|
|
199
201
|
paths.each do |path|
|
|
200
|
-
result << "
|
|
202
|
+
result << "- #{format_memory_path_with_title(path)}"
|
|
201
203
|
end
|
|
202
204
|
result.join("\n")
|
|
203
205
|
end
|
|
@@ -7,8 +7,10 @@ module SwarmMemory
|
|
|
7
7
|
# Retrieves content stored by this agent using memory_write.
|
|
8
8
|
# Each agent has its own isolated memory storage.
|
|
9
9
|
class MemoryRead < RubyLLM::Tool
|
|
10
|
+
include TitleLookup
|
|
11
|
+
|
|
10
12
|
description <<~DESC
|
|
11
|
-
Read content from your memory storage
|
|
13
|
+
Read content from your memory storage.
|
|
12
14
|
|
|
13
15
|
REQUIRED: Provide the file_path parameter - the path to the memory entry you want to read.
|
|
14
16
|
|
|
@@ -25,9 +27,8 @@ module SwarmMemory
|
|
|
25
27
|
INVALID: documentation/, reference/, tutorial/, parallel/, analysis/, notes/
|
|
26
28
|
|
|
27
29
|
**Returns:**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- metadata: All metadata (title, type, tags, tools, permissions, confidence, etc.)
|
|
30
|
+
Markdown content with line numbers (same format as 'cat -n').
|
|
31
|
+
If the entry has related memories, a system-reminder section is appended listing them.
|
|
31
32
|
|
|
32
33
|
**Examples:**
|
|
33
34
|
- MemoryRead(file_path: "concept/ruby/classes.md") - Read a concept
|
|
@@ -38,6 +39,7 @@ module SwarmMemory
|
|
|
38
39
|
- Always read entries before editing them with MemoryEdit
|
|
39
40
|
- Line numbers in output are for reference only - don't include them when editing
|
|
40
41
|
- Each read is tracked to enforce read-before-edit patterns
|
|
42
|
+
- Related memories in the system-reminder can be read with MemoryRead for additional context
|
|
41
43
|
DESC
|
|
42
44
|
|
|
43
45
|
param :file_path,
|
|
@@ -62,7 +64,7 @@ module SwarmMemory
|
|
|
62
64
|
# Execute the tool
|
|
63
65
|
#
|
|
64
66
|
# @param file_path [String] Path to read from
|
|
65
|
-
# @return [String]
|
|
67
|
+
# @return [String] Content with line numbers and optional related memories reminder
|
|
66
68
|
def execute(file_path:)
|
|
67
69
|
# Read full entry with metadata
|
|
68
70
|
entry = @storage.read_entry(file_path: file_path)
|
|
@@ -70,8 +72,14 @@ module SwarmMemory
|
|
|
70
72
|
# Register this read in the tracker with content digest
|
|
71
73
|
Core::StorageReadTracker.register_read(@agent_name, file_path, entry.content)
|
|
72
74
|
|
|
73
|
-
#
|
|
74
|
-
|
|
75
|
+
# Return plain text with line numbers
|
|
76
|
+
result = format_with_line_numbers(entry.content)
|
|
77
|
+
|
|
78
|
+
# Append related memories reminder if present
|
|
79
|
+
related_paths = entry.metadata&.dig("related") || []
|
|
80
|
+
result += format_related_memories_reminder(related_paths) if related_paths.any?
|
|
81
|
+
|
|
82
|
+
result
|
|
75
83
|
rescue ArgumentError => e
|
|
76
84
|
validation_error(e.message)
|
|
77
85
|
end
|
|
@@ -82,29 +90,6 @@ module SwarmMemory
|
|
|
82
90
|
"<tool_use_error>InputValidationError: #{message}</tool_use_error>"
|
|
83
91
|
end
|
|
84
92
|
|
|
85
|
-
# Format entry as JSON with content and metadata
|
|
86
|
-
#
|
|
87
|
-
# Returns a clean JSON format separating content from metadata.
|
|
88
|
-
# This prevents agents from mimicking metadata format when writing.
|
|
89
|
-
#
|
|
90
|
-
# Content includes line numbers (same format as Read tool).
|
|
91
|
-
# Metadata always includes at least title (from Entry).
|
|
92
|
-
# Additional metadata comes from the metadata hash (type, tags, tools, etc.)
|
|
93
|
-
#
|
|
94
|
-
# @param entry [Core::Entry] Entry with content and metadata
|
|
95
|
-
# @return [String] Pretty-printed JSON
|
|
96
|
-
def format_as_json(entry)
|
|
97
|
-
# Build metadata hash with title included
|
|
98
|
-
metadata_hash = { "title" => entry.title }
|
|
99
|
-
metadata_hash.merge!(entry.metadata) if entry.metadata
|
|
100
|
-
|
|
101
|
-
result = {
|
|
102
|
-
content: format_with_line_numbers(entry.content),
|
|
103
|
-
metadata: metadata_hash,
|
|
104
|
-
}
|
|
105
|
-
JSON.pretty_generate(result)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
93
|
# Format content with line numbers (same format as Read tool)
|
|
109
94
|
#
|
|
110
95
|
# @param content [String] Content to format
|
|
@@ -114,10 +99,29 @@ module SwarmMemory
|
|
|
114
99
|
output_lines = lines.each_with_index.map do |line, idx|
|
|
115
100
|
line_number = idx + 1
|
|
116
101
|
display_line = line.chomp
|
|
117
|
-
"#{line_number.to_s.rjust(6)}
|
|
102
|
+
"#{line_number.to_s.rjust(6)} #{display_line}"
|
|
118
103
|
end
|
|
119
104
|
output_lines.join("\n")
|
|
120
105
|
end
|
|
106
|
+
|
|
107
|
+
# Format related memories as a system-reminder section
|
|
108
|
+
#
|
|
109
|
+
# Looks up titles for each related memory path and formats
|
|
110
|
+
# them as a system reminder to help agents discover related content.
|
|
111
|
+
#
|
|
112
|
+
# @param related_paths [Array<String>] Array of memory paths (with or without memory:// prefix)
|
|
113
|
+
# @return [String] Formatted system-reminder section
|
|
114
|
+
def format_related_memories_reminder(related_paths)
|
|
115
|
+
lines = ["\n\n<system-reminder>"]
|
|
116
|
+
lines << "Related memories that may provide additional context:"
|
|
117
|
+
|
|
118
|
+
related_paths.each do |path|
|
|
119
|
+
lines << "- #{format_memory_path_with_title(path)}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
lines << "</system-reminder>"
|
|
123
|
+
lines.join("\n")
|
|
124
|
+
end
|
|
121
125
|
end
|
|
122
126
|
end
|
|
123
127
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SwarmMemory
|
|
4
|
+
module Tools
|
|
5
|
+
# Shared module for looking up memory entry titles
|
|
6
|
+
#
|
|
7
|
+
# Provides a consistent way to look up titles for memory entries
|
|
8
|
+
# across different tools (MemoryRead, MemoryGrep, etc.)
|
|
9
|
+
#
|
|
10
|
+
# @example Including in a tool
|
|
11
|
+
# class MemoryGrep < RubyLLM::Tool
|
|
12
|
+
# include TitleLookup
|
|
13
|
+
#
|
|
14
|
+
# def some_method
|
|
15
|
+
# title = lookup_title("concept/ruby/classes.md")
|
|
16
|
+
# end
|
|
17
|
+
# end
|
|
18
|
+
module TitleLookup
|
|
19
|
+
# Look up the title of a memory entry
|
|
20
|
+
#
|
|
21
|
+
# @param path [String] Path to the memory entry
|
|
22
|
+
# @return [String, nil] Title if found, nil otherwise
|
|
23
|
+
#
|
|
24
|
+
# @example
|
|
25
|
+
# title = lookup_title("concept/ruby/classes.md")
|
|
26
|
+
# # => "Ruby Classes"
|
|
27
|
+
def lookup_title(path)
|
|
28
|
+
entry = @storage.read_entry(file_path: path)
|
|
29
|
+
entry.title
|
|
30
|
+
rescue StandardError
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Format a memory path with its title
|
|
35
|
+
#
|
|
36
|
+
# Normalizes the path (removes memory:// prefix if present) and
|
|
37
|
+
# formats it with the title in quotes if available.
|
|
38
|
+
#
|
|
39
|
+
# @param path [String] Path to the memory entry (with or without memory:// prefix)
|
|
40
|
+
# @return [String] Formatted string like 'memory://path "Title"' or 'memory://path'
|
|
41
|
+
#
|
|
42
|
+
# @example With title found
|
|
43
|
+
# format_memory_path_with_title("concept/ruby/classes.md")
|
|
44
|
+
# # => 'memory://concept/ruby/classes.md "Ruby Classes"'
|
|
45
|
+
#
|
|
46
|
+
# @example With memory:// prefix
|
|
47
|
+
# format_memory_path_with_title("memory://concept/ruby/classes.md")
|
|
48
|
+
# # => 'memory://concept/ruby/classes.md "Ruby Classes"'
|
|
49
|
+
#
|
|
50
|
+
# @example When title not found
|
|
51
|
+
# format_memory_path_with_title("nonexistent.md")
|
|
52
|
+
# # => 'memory://nonexistent.md'
|
|
53
|
+
def format_memory_path_with_title(path)
|
|
54
|
+
normalized_path = path.sub(%r{^memory://}, "")
|
|
55
|
+
title = lookup_title(normalized_path)
|
|
56
|
+
|
|
57
|
+
if title
|
|
58
|
+
"memory://#{normalized_path} \"#{title}\""
|
|
59
|
+
else
|
|
60
|
+
"memory://#{normalized_path}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/lib/swarm_memory/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: swarm_memory
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.2.
|
|
4
|
+
version: 2.2.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paulo Arruda
|
|
@@ -71,14 +71,14 @@ dependencies:
|
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: 2.5.
|
|
74
|
+
version: 2.5.2
|
|
75
75
|
type: :runtime
|
|
76
76
|
prerelease: false
|
|
77
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
|
79
79
|
- - "~>"
|
|
80
80
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 2.5.
|
|
81
|
+
version: 2.5.2
|
|
82
82
|
- !ruby/object:Gem::Dependency
|
|
83
83
|
name: zeitwerk
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -140,14 +140,15 @@ files:
|
|
|
140
140
|
- lib/swarm_memory/tools/memory_grep.rb
|
|
141
141
|
- lib/swarm_memory/tools/memory_read.rb
|
|
142
142
|
- lib/swarm_memory/tools/memory_write.rb
|
|
143
|
+
- lib/swarm_memory/tools/title_lookup.rb
|
|
143
144
|
- lib/swarm_memory/utils.rb
|
|
144
145
|
- lib/swarm_memory/version.rb
|
|
145
|
-
homepage: https://github.com/parruda/
|
|
146
|
+
homepage: https://github.com/parruda/swarm
|
|
146
147
|
licenses:
|
|
147
148
|
- MIT
|
|
148
149
|
metadata:
|
|
149
|
-
source_code_uri: https://github.com/parruda/
|
|
150
|
-
changelog_uri: https://github.com/parruda/
|
|
150
|
+
source_code_uri: https://github.com/parruda/swarm
|
|
151
|
+
changelog_uri: https://github.com/parruda/swarm/blob/main/docs/v2/CHANGELOG.swarm_memory.md
|
|
151
152
|
rdoc_options: []
|
|
152
153
|
require_paths:
|
|
153
154
|
- lib
|