lex-cognitive-map 0.1.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.
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/cognitive_map/client'
4
+
5
+ RSpec.describe Legion::Extensions::CognitiveMap::Runners::CognitiveMap do
6
+ let(:client) { Legion::Extensions::CognitiveMap::Client.new }
7
+
8
+ def setup_two_locations
9
+ client.add_location(id: 'a', domain: :test)
10
+ client.add_location(id: 'b', domain: :test)
11
+ client.connect_locations(from: 'a', to: 'b', distance: 1.0)
12
+ end
13
+
14
+ describe '#add_location' do
15
+ it 'returns success: true for new location' do
16
+ result = client.add_location(id: 'concept:ruby')
17
+ expect(result[:success]).to be true
18
+ expect(result[:id]).to eq('concept:ruby')
19
+ end
20
+
21
+ it 'returns success: true for duplicate (idempotent)' do
22
+ client.add_location(id: 'concept:ruby')
23
+ result = client.add_location(id: 'concept:ruby')
24
+ expect(result[:success]).to be true
25
+ end
26
+
27
+ it 'passes domain through' do
28
+ result = client.add_location(id: 'loc1', domain: :science)
29
+ expect(result[:domain]).to eq(:science)
30
+ end
31
+ end
32
+
33
+ describe '#connect_locations' do
34
+ before { setup_two_locations }
35
+
36
+ it 'returns success: true' do
37
+ client.add_location(id: 'c')
38
+ result = client.connect_locations(from: 'a', to: 'c')
39
+ expect(result[:success]).to be true
40
+ end
41
+
42
+ it 'returns success: false for missing location' do
43
+ result = client.connect_locations(from: 'a', to: 'ghost')
44
+ expect(result[:success]).to be false
45
+ expect(result[:reason]).to eq(:missing_location)
46
+ end
47
+
48
+ it 'passes distance through' do
49
+ client.add_location(id: 'c')
50
+ result = client.connect_locations(from: 'a', to: 'c', distance: 2.5)
51
+ expect(result[:distance]).to eq(2.5)
52
+ end
53
+ end
54
+
55
+ describe '#visit_location' do
56
+ it 'returns success: true for existing location' do
57
+ client.add_location(id: 'loc1')
58
+ result = client.visit_location(id: 'loc1')
59
+ expect(result[:success]).to be true
60
+ expect(result[:visit_count]).to eq(1)
61
+ end
62
+
63
+ it 'returns success: false for missing location' do
64
+ result = client.visit_location(id: 'ghost')
65
+ expect(result[:success]).to be false
66
+ end
67
+
68
+ it 'increments visit count on repeated visits' do
69
+ client.add_location(id: 'loc1')
70
+ 3.times { client.visit_location(id: 'loc1') }
71
+ result = client.visit_location(id: 'loc1')
72
+ expect(result[:visit_count]).to eq(4)
73
+ end
74
+ end
75
+
76
+ describe '#find_path' do
77
+ before { setup_two_locations }
78
+
79
+ it 'finds path between connected locations' do
80
+ result = client.find_path(from: 'a', to: 'b')
81
+ expect(result[:success]).to be true
82
+ expect(result[:path]).to eq(%w[a b])
83
+ end
84
+
85
+ it 'returns success: false for disconnected locations' do
86
+ client.add_location(id: 'island')
87
+ result = client.find_path(from: 'a', to: 'island')
88
+ expect(result[:success]).to be false
89
+ end
90
+
91
+ it 'returns trivial path for same start and end' do
92
+ result = client.find_path(from: 'a', to: 'a')
93
+ expect(result[:success]).to be true
94
+ expect(result[:distance]).to eq(0.0)
95
+ end
96
+ end
97
+
98
+ describe '#explore_neighborhood' do
99
+ before { setup_two_locations }
100
+
101
+ it 'returns reachable locations' do
102
+ result = client.explore_neighborhood(id: 'a', max_distance: 2.0)
103
+ expect(result[:success]).to be true
104
+ expect(result[:count]).to be >= 1
105
+ end
106
+
107
+ it 'respects max_distance' do
108
+ result = client.explore_neighborhood(id: 'a', max_distance: 0.5)
109
+ expect(result[:count]).to eq(0)
110
+ end
111
+
112
+ it 'returns success: true even for isolated location' do
113
+ client.add_location(id: 'island')
114
+ result = client.explore_neighborhood(id: 'island', max_distance: 5.0)
115
+ expect(result[:success]).to be true
116
+ expect(result[:count]).to eq(0)
117
+ end
118
+ end
119
+
120
+ describe '#map_clusters' do
121
+ it 'returns cluster information' do
122
+ client.add_location(id: 'a')
123
+ client.add_location(id: 'b')
124
+ client.connect_locations(from: 'a', to: 'b')
125
+ result = client.map_clusters
126
+ expect(result[:success]).to be true
127
+ expect(result[:count]).to eq(1)
128
+ end
129
+
130
+ it 'returns zero clusters for empty map' do
131
+ result = client.map_clusters
132
+ expect(result[:count]).to eq(0)
133
+ end
134
+ end
135
+
136
+ describe '#familiar_locations' do
137
+ it 'returns locations sorted by familiarity' do
138
+ 3.times { |i| client.add_location(id: "loc_#{i}") }
139
+ 5.times { client.visit_location(id: 'loc_0') }
140
+ result = client.familiar_locations(limit: 3)
141
+ expect(result[:success]).to be true
142
+ expect(result[:locations].first[:id]).to eq('loc_0')
143
+ end
144
+
145
+ it 'respects limit' do
146
+ 5.times { |i| client.add_location(id: "loc_#{i}") }
147
+ result = client.familiar_locations(limit: 2)
148
+ expect(result[:count]).to be <= 2
149
+ end
150
+ end
151
+
152
+ describe '#switch_context' do
153
+ it 'switches to a new context' do
154
+ result = client.switch_context(context_id: :work)
155
+ expect(result[:success]).to be true
156
+ end
157
+
158
+ it 'new context has empty map' do
159
+ client.add_location(id: 'loc1')
160
+ client.switch_context(context_id: :empty_context)
161
+ stats = client.cognitive_map_stats
162
+ expect(stats[:location_count]).to eq(0)
163
+ end
164
+ end
165
+
166
+ describe '#update_cognitive_map' do
167
+ it 'runs decay cycle and returns counts' do
168
+ client.add_location(id: 'a')
169
+ client.visit_location(id: 'a')
170
+ result = client.update_cognitive_map
171
+ expect(result[:success]).to be true
172
+ expect(result).to include(:decayed, :pruned)
173
+ end
174
+ end
175
+
176
+ describe '#cognitive_map_stats' do
177
+ it 'returns stats with success: true' do
178
+ result = client.cognitive_map_stats
179
+ expect(result[:success]).to be true
180
+ expect(result).to include(:context, :location_count, :edge_count)
181
+ end
182
+
183
+ it 'reflects added locations' do
184
+ client.add_location(id: 'a')
185
+ client.add_location(id: 'b')
186
+ result = client.cognitive_map_stats
187
+ expect(result[:location_count]).to eq(2)
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ module Legion
6
+ module Logging
7
+ def self.debug(_msg); end
8
+ def self.info(_msg); end
9
+ def self.warn(_msg); end
10
+ def self.error(_msg); end
11
+ end
12
+ end
13
+
14
+ require 'legion/extensions/cognitive_map'
15
+
16
+ RSpec.configure do |config|
17
+ config.example_status_persistence_file_path = '.rspec_status'
18
+ config.disable_monkey_patching!
19
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
20
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-cognitive-map
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Esity
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: legion-gaia
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :development
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ description: Tolman's cognitive map + O'Keefe/Moser place and grid cell theory for
27
+ brain-modeled agentic AI
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - lex-cognitive-map.gemspec
36
+ - lib/legion/extensions/cognitive_map.rb
37
+ - lib/legion/extensions/cognitive_map/actors/decay.rb
38
+ - lib/legion/extensions/cognitive_map/client.rb
39
+ - lib/legion/extensions/cognitive_map/helpers/cognitive_map_store.rb
40
+ - lib/legion/extensions/cognitive_map/helpers/constants.rb
41
+ - lib/legion/extensions/cognitive_map/helpers/graph_traversal.rb
42
+ - lib/legion/extensions/cognitive_map/helpers/location.rb
43
+ - lib/legion/extensions/cognitive_map/runners/cognitive_map.rb
44
+ - lib/legion/extensions/cognitive_map/version.rb
45
+ - spec/legion/extensions/cognitive_map/client_spec.rb
46
+ - spec/legion/extensions/cognitive_map/helpers/cognitive_map_store_spec.rb
47
+ - spec/legion/extensions/cognitive_map/helpers/location_spec.rb
48
+ - spec/legion/extensions/cognitive_map/runners/cognitive_map_spec.rb
49
+ - spec/spec_helper.rb
50
+ homepage: https://github.com/LegionIO/lex-cognitive-map
51
+ licenses:
52
+ - MIT
53
+ metadata:
54
+ homepage_uri: https://github.com/LegionIO/lex-cognitive-map
55
+ source_code_uri: https://github.com/LegionIO/lex-cognitive-map
56
+ documentation_uri: https://github.com/LegionIO/lex-cognitive-map
57
+ changelog_uri: https://github.com/LegionIO/lex-cognitive-map
58
+ bug_tracker_uri: https://github.com/LegionIO/lex-cognitive-map/issues
59
+ rubygems_mfa_required: 'true'
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '3.4'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.6.9
75
+ specification_version: 4
76
+ summary: LEX Cognitive Map
77
+ test_files: []