lex-default-mode-network 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.
- checksums.yaml +7 -0
- data/Gemfile +11 -0
- data/lex-default-mode-network.gemspec +31 -0
- data/lib/legion/extensions/default_mode_network/actors/idle.rb +41 -0
- data/lib/legion/extensions/default_mode_network/client.rb +24 -0
- data/lib/legion/extensions/default_mode_network/helpers/constants.rb +49 -0
- data/lib/legion/extensions/default_mode_network/helpers/dmn_engine.rb +217 -0
- data/lib/legion/extensions/default_mode_network/helpers/wandering_thought.rb +56 -0
- data/lib/legion/extensions/default_mode_network/runners/default_mode_network.rb +118 -0
- data/lib/legion/extensions/default_mode_network/version.rb +9 -0
- data/lib/legion/extensions/default_mode_network.rb +17 -0
- data/spec/legion/extensions/default_mode_network/client_spec.rb +69 -0
- data/spec/legion/extensions/default_mode_network/helpers/constants_spec.rb +76 -0
- data/spec/legion/extensions/default_mode_network/helpers/dmn_engine_spec.rb +321 -0
- data/spec/legion/extensions/default_mode_network/helpers/wandering_thought_spec.rb +145 -0
- data/spec/legion/extensions/default_mode_network/runners/default_mode_network_spec.rb +269 -0
- data/spec/spec_helper.rb +20 -0
- metadata +78 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::DefaultModeNetwork::Runners::DefaultModeNetwork do
|
|
4
|
+
let(:client) { Legion::Extensions::DefaultModeNetwork::Client.new }
|
|
5
|
+
|
|
6
|
+
describe '#register_external_stimulus' do
|
|
7
|
+
it 'returns success' do
|
|
8
|
+
result = client.register_external_stimulus(source: :user_request)
|
|
9
|
+
expect(result[:success]).to be true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'returns mode fields' do
|
|
13
|
+
result = client.register_external_stimulus(source: :test)
|
|
14
|
+
expect(result).to have_key(:previous_mode)
|
|
15
|
+
expect(result).to have_key(:current_mode)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'resets to :active mode' do
|
|
19
|
+
result = client.register_external_stimulus
|
|
20
|
+
expect(result[:current_mode]).to eq(:active)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'includes source in result' do
|
|
24
|
+
result = client.register_external_stimulus(source: :webhook)
|
|
25
|
+
expect(result[:source]).to eq(:webhook)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe '#generate_idle_thought' do
|
|
30
|
+
it 'returns success' do
|
|
31
|
+
result = client.generate_idle_thought
|
|
32
|
+
expect(result[:success]).to be true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns a thought hash' do
|
|
36
|
+
result = client.generate_idle_thought
|
|
37
|
+
expect(result[:thought]).to be_a(Hash)
|
|
38
|
+
expect(result[:thought]).to include(:id, :seed, :thought_type, :salience)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'thought has a valid type' do
|
|
42
|
+
valid_types = %w[self_referential social_replay spontaneous_plan wandering]
|
|
43
|
+
result = client.generate_idle_thought
|
|
44
|
+
expect(valid_types).to include(result[:thought][:thought_type].to_s)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe '#trigger_self_reflection' do
|
|
49
|
+
it 'returns success' do
|
|
50
|
+
result = client.trigger_self_reflection
|
|
51
|
+
expect(result[:success]).to be true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'returns a self_referential thought' do
|
|
55
|
+
result = client.trigger_self_reflection
|
|
56
|
+
expect(result[:thought][:thought_type]).to eq(:self_referential)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'thought has domain :self' do
|
|
60
|
+
result = client.trigger_self_reflection
|
|
61
|
+
expect(result[:thought][:domain]).to eq(:self)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it 'includes association chain' do
|
|
65
|
+
result = client.trigger_self_reflection
|
|
66
|
+
expect(result[:thought][:association_chain]).to be_an(Array)
|
|
67
|
+
expect(result[:thought][:association_chain]).not_to be_empty
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe '#trigger_social_replay' do
|
|
72
|
+
it 'returns success' do
|
|
73
|
+
result = client.trigger_social_replay(interaction: :standup)
|
|
74
|
+
expect(result[:success]).to be true
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'returns a social_replay thought' do
|
|
78
|
+
result = client.trigger_social_replay
|
|
79
|
+
expect(result[:thought][:thought_type]).to eq(:social_replay)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'uses provided interaction as seed' do
|
|
83
|
+
result = client.trigger_social_replay(interaction: :team_meeting)
|
|
84
|
+
expect(result[:thought][:seed]).to eq(:team_meeting)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'uses default seed when interaction is nil' do
|
|
88
|
+
result = client.trigger_social_replay
|
|
89
|
+
expect(result[:thought][:seed]).not_to be_nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'thought domain is :social' do
|
|
93
|
+
result = client.trigger_social_replay
|
|
94
|
+
expect(result[:thought][:domain]).to eq(:social)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe '#trigger_spontaneous_plan' do
|
|
99
|
+
it 'returns success' do
|
|
100
|
+
result = client.trigger_spontaneous_plan(goal: :reduce_latency)
|
|
101
|
+
expect(result[:success]).to be true
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it 'returns a spontaneous_plan thought' do
|
|
105
|
+
result = client.trigger_spontaneous_plan
|
|
106
|
+
expect(result[:thought][:thought_type]).to eq(:spontaneous_plan)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'uses provided goal as seed' do
|
|
110
|
+
result = client.trigger_spontaneous_plan(goal: :scale_out)
|
|
111
|
+
expect(result[:thought][:seed]).to eq(:scale_out)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'thought domain is :planning' do
|
|
115
|
+
result = client.trigger_spontaneous_plan
|
|
116
|
+
expect(result[:thought][:domain]).to eq(:planning)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'salience is in range 0..1' do
|
|
120
|
+
result = client.trigger_spontaneous_plan
|
|
121
|
+
expect(result[:thought][:salience]).to be_between(0.0, 1.0)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe '#trigger_wandering' do
|
|
126
|
+
it 'returns success' do
|
|
127
|
+
result = client.trigger_wandering(seed: :curiosity)
|
|
128
|
+
expect(result[:success]).to be true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'returns a wandering thought' do
|
|
132
|
+
result = client.trigger_wandering
|
|
133
|
+
expect(result[:thought][:thought_type]).to eq(:wandering)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'uses provided seed' do
|
|
137
|
+
result = client.trigger_wandering(seed: :pattern)
|
|
138
|
+
expect(result[:thought][:seed]).to eq(:pattern)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'thought domain is :associative' do
|
|
142
|
+
result = client.trigger_wandering
|
|
143
|
+
expect(result[:thought][:domain]).to eq(:associative)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'association chain starts with the seed' do
|
|
147
|
+
result = client.trigger_wandering(seed: :creativity)
|
|
148
|
+
expect(result[:thought][:association_chain].first).to eq(:creativity)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe '#salient_thoughts' do
|
|
153
|
+
before do
|
|
154
|
+
3.times { client.generate_idle_thought }
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'returns success' do
|
|
158
|
+
result = client.salient_thoughts(count: 2)
|
|
159
|
+
expect(result[:success]).to be true
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it 'returns up to count thoughts' do
|
|
163
|
+
result = client.salient_thoughts(count: 2)
|
|
164
|
+
expect(result[:thoughts].size).to be <= 2
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'includes count in result' do
|
|
168
|
+
result = client.salient_thoughts(count: 3)
|
|
169
|
+
expect(result[:count]).to eq(result[:thoughts].size)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'thoughts are hashes with expected keys' do
|
|
173
|
+
result = client.salient_thoughts(count: 1)
|
|
174
|
+
result[:thoughts].each do |t|
|
|
175
|
+
expect(t).to include(:id, :thought_type, :salience)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it 'returns empty array when no thoughts exist' do
|
|
180
|
+
fresh_client = Legion::Extensions::DefaultModeNetwork::Client.new
|
|
181
|
+
result = fresh_client.salient_thoughts
|
|
182
|
+
expect(result[:thoughts]).to be_empty
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
describe '#dmn_mode_status' do
|
|
187
|
+
it 'returns success' do
|
|
188
|
+
result = client.dmn_mode_status
|
|
189
|
+
expect(result[:success]).to be true
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'returns mode as symbol' do
|
|
193
|
+
result = client.dmn_mode_status
|
|
194
|
+
expect(%i[active transitioning idle deep_idle]).to include(result[:mode])
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it 'includes mode_label' do
|
|
198
|
+
result = client.dmn_mode_status
|
|
199
|
+
labels = Legion::Extensions::DefaultModeNetwork::Helpers::Constants::ACTIVITY_LABELS.values
|
|
200
|
+
expect(labels).to include(result[:mode_label])
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it 'includes idle_duration as float' do
|
|
204
|
+
result = client.dmn_mode_status
|
|
205
|
+
expect(result[:idle_duration]).to be_a(Float)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it 'includes thought_count' do
|
|
209
|
+
result = client.dmn_mode_status
|
|
210
|
+
expect(result).to have_key(:thought_count)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe '#update_dmn' do
|
|
215
|
+
it 'returns success' do
|
|
216
|
+
result = client.update_dmn
|
|
217
|
+
expect(result[:success]).to be true
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'returns mode after tick' do
|
|
221
|
+
result = client.update_dmn
|
|
222
|
+
expect(%i[active transitioning idle deep_idle]).to include(result[:mode])
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it 'returns previous_mode' do
|
|
226
|
+
result = client.update_dmn
|
|
227
|
+
expect(result).to have_key(:previous_mode)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it 'returns faded_count' do
|
|
231
|
+
result = client.update_dmn
|
|
232
|
+
expect(result[:faded_count]).to be_a(Integer)
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
it 'returns thought_count after decay' do
|
|
236
|
+
result = client.update_dmn
|
|
237
|
+
expect(result[:thought_count]).to be_a(Integer)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it 'generates a new thought when idle' do
|
|
241
|
+
engine = Legion::Extensions::DefaultModeNetwork::Helpers::DmnEngine.new
|
|
242
|
+
allow(engine).to receive(:idle_duration).and_return(60.0)
|
|
243
|
+
engine.tick_mode # force to :idle
|
|
244
|
+
idle_client = Legion::Extensions::DefaultModeNetwork::Client.new(dmn_engine: engine)
|
|
245
|
+
result = idle_client.update_dmn
|
|
246
|
+
expect(result[:new_thought]).not_to be_nil
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it 'new_thought is nil when active' do
|
|
250
|
+
result = client.update_dmn
|
|
251
|
+
# When just initialized, mode is active — no thought generated by update_dmn
|
|
252
|
+
# (may be nil or a thought depending on mode after tick)
|
|
253
|
+
expect(result).to have_key(:new_thought)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe '#dmn_stats' do
|
|
258
|
+
it 'returns success' do
|
|
259
|
+
result = client.dmn_stats
|
|
260
|
+
expect(result[:success]).to be true
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'includes stats hash' do
|
|
264
|
+
result = client.dmn_stats
|
|
265
|
+
expect(result[:stats]).to be_a(Hash)
|
|
266
|
+
expect(result[:stats]).to include(:mode, :mode_label, :idle_duration, :thought_count)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -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/default_mode_network'
|
|
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,78 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lex-default-mode-network
|
|
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: Raichle (2001) Default Mode Network for brain-modeled agentic AI — resting-state
|
|
27
|
+
activation for self-referential processing, mind-wandering, spontaneous planning,
|
|
28
|
+
and social replay when the agent is not task-focused.
|
|
29
|
+
email:
|
|
30
|
+
- matthewdiverson@gmail.com
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- Gemfile
|
|
36
|
+
- lex-default-mode-network.gemspec
|
|
37
|
+
- lib/legion/extensions/default_mode_network.rb
|
|
38
|
+
- lib/legion/extensions/default_mode_network/actors/idle.rb
|
|
39
|
+
- lib/legion/extensions/default_mode_network/client.rb
|
|
40
|
+
- lib/legion/extensions/default_mode_network/helpers/constants.rb
|
|
41
|
+
- lib/legion/extensions/default_mode_network/helpers/dmn_engine.rb
|
|
42
|
+
- lib/legion/extensions/default_mode_network/helpers/wandering_thought.rb
|
|
43
|
+
- lib/legion/extensions/default_mode_network/runners/default_mode_network.rb
|
|
44
|
+
- lib/legion/extensions/default_mode_network/version.rb
|
|
45
|
+
- spec/legion/extensions/default_mode_network/client_spec.rb
|
|
46
|
+
- spec/legion/extensions/default_mode_network/helpers/constants_spec.rb
|
|
47
|
+
- spec/legion/extensions/default_mode_network/helpers/dmn_engine_spec.rb
|
|
48
|
+
- spec/legion/extensions/default_mode_network/helpers/wandering_thought_spec.rb
|
|
49
|
+
- spec/legion/extensions/default_mode_network/runners/default_mode_network_spec.rb
|
|
50
|
+
- spec/spec_helper.rb
|
|
51
|
+
homepage: https://github.com/LegionIO/lex-default-mode-network
|
|
52
|
+
licenses:
|
|
53
|
+
- MIT
|
|
54
|
+
metadata:
|
|
55
|
+
homepage_uri: https://github.com/LegionIO/lex-default-mode-network
|
|
56
|
+
source_code_uri: https://github.com/LegionIO/lex-default-mode-network
|
|
57
|
+
documentation_uri: https://github.com/LegionIO/lex-default-mode-network
|
|
58
|
+
changelog_uri: https://github.com/LegionIO/lex-default-mode-network
|
|
59
|
+
bug_tracker_uri: https://github.com/LegionIO/lex-default-mode-network/issues
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
61
|
+
rdoc_options: []
|
|
62
|
+
require_paths:
|
|
63
|
+
- lib
|
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.4'
|
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0'
|
|
74
|
+
requirements: []
|
|
75
|
+
rubygems_version: 3.6.9
|
|
76
|
+
specification_version: 4
|
|
77
|
+
summary: LEX Default Mode Network
|
|
78
|
+
test_files: []
|