lex-dual-process 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,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/extensions/dual_process/client'
4
+
5
+ RSpec.describe Legion::Extensions::DualProcess::Runners::DualProcess do
6
+ let(:client) { Legion::Extensions::DualProcess::Client.new }
7
+
8
+ describe '#register_heuristic' do
9
+ it 'returns success: true' do
10
+ result = client.register_heuristic(pattern: 'hello', domain: :social, response: :wave)
11
+ expect(result[:success]).to be true
12
+ end
13
+
14
+ it 'returns heuristic data' do
15
+ result = client.register_heuristic(pattern: 'hello', domain: :social, response: :wave)
16
+ expect(result[:heuristic]).to include(:id, :pattern, :domain, :response, :confidence)
17
+ end
18
+
19
+ it 'accepts custom confidence' do
20
+ result = client.register_heuristic(pattern: :x, domain: :d, response: :r, confidence: 0.9)
21
+ expect(result[:heuristic][:confidence]).to eq(0.9)
22
+ end
23
+
24
+ it 'ignores nil confidence and uses default' do
25
+ result = client.register_heuristic(pattern: :x, domain: :d, response: :r, confidence: nil)
26
+ expect(result[:heuristic][:confidence]).to eq(Legion::Extensions::DualProcess::Helpers::Constants::DEFAULT_CONFIDENCE)
27
+ end
28
+ end
29
+
30
+ describe '#route_decision' do
31
+ it 'returns success: true' do
32
+ result = client.route_decision(query: 'test', domain: :work, complexity: 0.3)
33
+ expect(result[:success]).to be true
34
+ end
35
+
36
+ it 'returns a system key' do
37
+ result = client.route_decision(query: 'test', domain: :work, complexity: 0.3)
38
+ expect(Legion::Extensions::DualProcess::Helpers::Constants::SYSTEMS).to include(result[:system])
39
+ end
40
+
41
+ it 'returns a reason' do
42
+ result = client.route_decision(query: 'test', domain: :work, complexity: 0.3)
43
+ expect(result[:reason]).not_to be_nil
44
+ end
45
+ end
46
+
47
+ describe '#execute_system_one' do
48
+ it 'returns success: true' do
49
+ result = client.execute_system_one(query: 'test', domain: :work)
50
+ expect(result[:success]).to be true
51
+ end
52
+
53
+ it 'returns system: :system_one' do
54
+ result = client.execute_system_one(query: 'test', domain: :work)
55
+ expect(result[:system]).to eq(:system_one)
56
+ end
57
+
58
+ it 'returns a decision_id' do
59
+ result = client.execute_system_one(query: 'test', domain: :work)
60
+ expect(result[:decision_id]).to match(/\A[0-9a-f-]{36}\z/)
61
+ end
62
+ end
63
+
64
+ describe '#execute_system_two' do
65
+ it 'returns success: true' do
66
+ result = client.execute_system_two(query: 'complex', domain: :work)
67
+ expect(result[:success]).to be true
68
+ end
69
+
70
+ it 'returns system: :system_two' do
71
+ result = client.execute_system_two(query: 'complex', domain: :work)
72
+ expect(result[:system]).to eq(:system_two)
73
+ end
74
+
75
+ it 'returns a decision_id' do
76
+ result = client.execute_system_two(query: 'complex', domain: :work)
77
+ expect(result[:decision_id]).to match(/\A[0-9a-f-]{36}\z/)
78
+ end
79
+
80
+ it 'accepts deliberation context' do
81
+ result = client.execute_system_two(
82
+ query: 'complex', domain: :work,
83
+ deliberation: { confidence: 0.9, response: :approved }
84
+ )
85
+ expect(result[:confidence]).to eq(0.9)
86
+ expect(result[:response]).to eq(:approved)
87
+ end
88
+ end
89
+
90
+ describe '#record_decision_outcome' do
91
+ it 'returns success for known decision' do
92
+ exec = client.execute_system_one(query: 'x', domain: :d)
93
+ result = client.record_decision_outcome(decision_id: exec[:decision_id], outcome: :correct)
94
+ expect(result[:success]).to be true
95
+ end
96
+
97
+ it 'returns failure for unknown decision' do
98
+ result = client.record_decision_outcome(decision_id: 'bogus-id', outcome: :correct)
99
+ expect(result[:success]).to be false
100
+ end
101
+ end
102
+
103
+ describe '#effort_assessment' do
104
+ it 'returns success: true' do
105
+ result = client.effort_assessment
106
+ expect(result[:success]).to be true
107
+ end
108
+
109
+ it 'includes effort_level' do
110
+ result = client.effort_assessment
111
+ expect(result[:effort_level]).to be_between(0.0, 1.0)
112
+ end
113
+
114
+ it 'includes routing_label' do
115
+ result = client.effort_assessment
116
+ expect(result[:routing_label]).to be_a(Symbol)
117
+ end
118
+ end
119
+
120
+ describe '#best_heuristics' do
121
+ it 'returns success: true' do
122
+ result = client.best_heuristics
123
+ expect(result[:success]).to be true
124
+ end
125
+
126
+ it 'returns heuristics array' do
127
+ result = client.best_heuristics
128
+ expect(result[:heuristics]).to be_an(Array)
129
+ end
130
+
131
+ it 'respects custom limit' do
132
+ 5.times do |i|
133
+ client.register_heuristic(pattern: "p#{i}", domain: :d, response: :r, confidence: 0.9)
134
+ end
135
+ engine = client.send(:engine)
136
+ engine.instance_variable_get(:@heuristics).each_value do |h|
137
+ 5.times { h.use!(success: true) }
138
+ end
139
+ result = client.best_heuristics(limit: 2)
140
+ expect(result[:heuristics].size).to be <= 2
141
+ end
142
+ end
143
+
144
+ describe '#system_usage_stats' do
145
+ it 'returns success: true' do
146
+ result = client.system_usage_stats
147
+ expect(result[:success]).to be true
148
+ end
149
+
150
+ it 'includes stats hash' do
151
+ result = client.system_usage_stats
152
+ expect(result[:stats]).to include(:system_one, :system_two, :total)
153
+ end
154
+ end
155
+
156
+ describe '#update_dual_process' do
157
+ it 'returns success: true' do
158
+ result = client.update_dual_process
159
+ expect(result[:success]).to be true
160
+ end
161
+
162
+ it 'recovers effort' do
163
+ client.execute_system_two(query: 'x', domain: :d)
164
+ before = client.effort_assessment[:effort_level]
165
+ client.update_dual_process
166
+ after = client.effort_assessment[:effort_level]
167
+ expect(after).to be >= before
168
+ end
169
+
170
+ it 'returns routing_label' do
171
+ result = client.update_dual_process
172
+ expect(result[:routing_label]).to be_a(Symbol)
173
+ end
174
+ end
175
+
176
+ describe '#dual_process_stats' do
177
+ it 'returns success: true' do
178
+ result = client.dual_process_stats
179
+ expect(result[:success]).to be true
180
+ end
181
+
182
+ it 'includes full stats' do
183
+ result = client.dual_process_stats
184
+ expect(result).to include(:effort_budget, :effort_level, :routing_label,
185
+ :heuristic_count, :decision_count, :system_stats)
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,24 @@
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
+
13
+ module Extensions
14
+ module Helpers; end
15
+ end
16
+ end
17
+
18
+ require 'legion/extensions/dual_process'
19
+
20
+ RSpec.configure do |config|
21
+ config.example_status_persistence_file_path = '.rspec_status'
22
+ config.disable_monkey_patching!
23
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
24
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lex-dual-process
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: 'Kahneman''s Dual Process Theory for brain-modeled agentic AI: System
27
+ 1 (fast/intuitive) vs System 2 (slow/deliberate)'
28
+ email:
29
+ - matthewdiverson@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - lex-dual-process.gemspec
38
+ - lib/legion/extensions/dual_process.rb
39
+ - lib/legion/extensions/dual_process/client.rb
40
+ - lib/legion/extensions/dual_process/helpers/constants.rb
41
+ - lib/legion/extensions/dual_process/helpers/decision.rb
42
+ - lib/legion/extensions/dual_process/helpers/dual_process_engine.rb
43
+ - lib/legion/extensions/dual_process/helpers/heuristic.rb
44
+ - lib/legion/extensions/dual_process/runners/dual_process.rb
45
+ - lib/legion/extensions/dual_process/version.rb
46
+ - spec/legion/extensions/dual_process/client_spec.rb
47
+ - spec/legion/extensions/dual_process/helpers/constants_spec.rb
48
+ - spec/legion/extensions/dual_process/helpers/decision_spec.rb
49
+ - spec/legion/extensions/dual_process/helpers/dual_process_engine_spec.rb
50
+ - spec/legion/extensions/dual_process/helpers/heuristic_spec.rb
51
+ - spec/legion/extensions/dual_process/runners/dual_process_spec.rb
52
+ - spec/spec_helper.rb
53
+ homepage: https://github.com/LegionIO/lex-dual-process
54
+ licenses:
55
+ - MIT
56
+ metadata:
57
+ homepage_uri: https://github.com/LegionIO/lex-dual-process
58
+ source_code_uri: https://github.com/LegionIO/lex-dual-process
59
+ documentation_uri: https://github.com/LegionIO/lex-dual-process
60
+ changelog_uri: https://github.com/LegionIO/lex-dual-process
61
+ bug_tracker_uri: https://github.com/LegionIO/lex-dual-process/issues
62
+ rubygems_mfa_required: 'true'
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '3.4'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubygems_version: 3.6.9
78
+ specification_version: 4
79
+ summary: LEX Dual Process
80
+ test_files: []