lex-curiosity 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,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Legion::Extensions::Curiosity::Runners::Curiosity do
4
+ let(:client) { Legion::Extensions::Curiosity::Client.new }
5
+
6
+ describe '#detect_gaps' do
7
+ it 'returns gap detection results' do
8
+ result = client.detect_gaps(prior_results: {})
9
+ expect(result[:gaps_detected]).to eq(0)
10
+ expect(result[:wonders_created]).to eq(0)
11
+ expect(result[:curiosity_intensity]).to eq(0.0)
12
+ end
13
+
14
+ it 'creates wonders from detected gaps' do
15
+ prior = {
16
+ memory_retrieval: { traces: [], domain: :unknown_domain },
17
+ prediction_engine: { confidence: 0.2, domain: :uncertain_domain }
18
+ }
19
+ result = client.detect_gaps(prior_results: prior)
20
+ expect(result[:gaps_detected]).to be >= 2
21
+ expect(result[:wonders_created]).to be >= 1
22
+ expect(result[:curiosity_intensity]).to be > 0.0
23
+ end
24
+
25
+ it 'does not create duplicate wonders' do
26
+ prior = {
27
+ memory_retrieval: { traces: [], domain: :repeated }
28
+ }
29
+ client.detect_gaps(prior_results: prior)
30
+ result = client.detect_gaps(prior_results: prior)
31
+ expect(result[:wonders_created]).to eq(0)
32
+ end
33
+ end
34
+
35
+ describe '#generate_wonder' do
36
+ it 'manually creates a wonder' do
37
+ wonder = client.generate_wonder(
38
+ question: 'How does Consul ACL work?',
39
+ domain: :consul,
40
+ gap_type: :unknown
41
+ )
42
+ expect(wonder[:wonder_id]).to be_a(String)
43
+ expect(wonder[:question]).to eq('How does Consul ACL work?')
44
+ expect(wonder[:domain]).to eq(:consul)
45
+ end
46
+ end
47
+
48
+ describe '#explore_wonder' do
49
+ let(:wonder) do
50
+ client.generate_wonder(question: 'test?', domain: :test)
51
+ end
52
+
53
+ it 'marks a wonder as being explored' do
54
+ result = client.explore_wonder(wonder_id: wonder[:wonder_id])
55
+ expect(result[:exploring]).to be true
56
+ expect(result[:attempt]).to eq(1)
57
+ end
58
+
59
+ it 'returns error for unknown wonder' do
60
+ result = client.explore_wonder(wonder_id: 'nonexistent')
61
+ expect(result[:error]).to eq(:not_found)
62
+ end
63
+
64
+ it 'returns error for resolved wonder' do
65
+ client.resolve_wonder(wonder_id: wonder[:wonder_id], resolution: 'done')
66
+ result = client.explore_wonder(wonder_id: wonder[:wonder_id])
67
+ expect(result[:error]).to eq(:already_resolved)
68
+ end
69
+ end
70
+
71
+ describe '#resolve_wonder' do
72
+ let(:wonder) do
73
+ client.generate_wonder(question: 'test?', domain: :test, information_gain: 0.7)
74
+ end
75
+
76
+ it 'resolves with reward calculation' do
77
+ result = client.resolve_wonder(
78
+ wonder_id: wonder[:wonder_id],
79
+ resolution: 'Found the answer in the docs',
80
+ actual_gain: 0.8
81
+ )
82
+ expect(result[:resolved]).to be true
83
+ expect(result[:actual_gain]).to eq(0.8)
84
+ expect(result[:expected_gain]).to eq(0.7)
85
+ expect(result[:reward]).to eq(0.8 * Legion::Extensions::Curiosity::Helpers::Constants::CURIOSITY_REWARD_MULTIPLIER)
86
+ end
87
+
88
+ it 'returns error for unknown wonder' do
89
+ result = client.resolve_wonder(wonder_id: 'nope', resolution: 'x')
90
+ expect(result[:error]).to eq(:not_found)
91
+ end
92
+
93
+ it 'returns error for already resolved wonder' do
94
+ client.resolve_wonder(wonder_id: wonder[:wonder_id], resolution: 'first')
95
+ result = client.resolve_wonder(wonder_id: wonder[:wonder_id], resolution: 'second')
96
+ expect(result[:error]).to eq(:already_resolved)
97
+ end
98
+ end
99
+
100
+ describe '#curiosity_intensity' do
101
+ it 'returns 0.0 with no wonders' do
102
+ result = client.curiosity_intensity
103
+ expect(result[:intensity]).to eq(0.0)
104
+ end
105
+
106
+ it 'increases with more wonders' do
107
+ 5.times { |i| client.generate_wonder(question: "q#{i}?", domain: :test) }
108
+ result = client.curiosity_intensity
109
+ expect(result[:intensity]).to be > 0.0
110
+ expect(result[:active_wonders]).to eq(5)
111
+ end
112
+ end
113
+
114
+ describe '#top_wonders' do
115
+ it 'returns top wonders by balanced score' do
116
+ client.generate_wonder(question: 'high?', domain: :a, salience: 0.9)
117
+ client.generate_wonder(question: 'low?', domain: :b, salience: 0.2)
118
+ result = client.top_wonders(limit: 5)
119
+ expect(result[:wonders].first[:question]).to eq('high?')
120
+ end
121
+ end
122
+
123
+ describe '#form_agenda' do
124
+ it 'converts top wonders to agenda items' do
125
+ client.generate_wonder(question: 'Why?', domain: :test)
126
+ result = client.form_agenda
127
+ expect(result[:agenda_items].size).to eq(1)
128
+ expect(result[:agenda_items].first[:type]).to eq(:curious)
129
+ expect(result[:agenda_items].first[:source]).to eq(:curiosity)
130
+ end
131
+
132
+ it 'returns empty agenda with no wonders' do
133
+ result = client.form_agenda
134
+ expect(result[:agenda_items]).to be_empty
135
+ end
136
+ end
137
+
138
+ describe '#wonder_stats' do
139
+ it 'returns comprehensive statistics' do
140
+ client.generate_wonder(question: 'q1?', domain: :a)
141
+ w = client.generate_wonder(question: 'q2?', domain: :b)
142
+ client.resolve_wonder(wonder_id: w[:wonder_id], resolution: 'done')
143
+
144
+ stats = client.wonder_stats
145
+ expect(stats[:total_generated]).to eq(2)
146
+ expect(stats[:active]).to eq(1)
147
+ expect(stats[:resolved]).to eq(1)
148
+ expect(stats[:resolution_rate]).to eq(0.5)
149
+ end
150
+ end
151
+
152
+ describe '#decay_wonders' do
153
+ it 'prunes exhausted wonders' do
154
+ client.generate_wonder(question: 'fading?', salience: 0.01)
155
+ result = client.decay_wonders(hours_elapsed: 10.0)
156
+ expect(result[:pruned]).to eq(1)
157
+ end
158
+ end
159
+ 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/curiosity'
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-curiosity
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: Intrinsic curiosity engine for brain-modeled agentic AI
27
+ email:
28
+ - matthewdiverson@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.md
36
+ - lex-curiosity.gemspec
37
+ - lib/legion/extensions/curiosity.rb
38
+ - lib/legion/extensions/curiosity/client.rb
39
+ - lib/legion/extensions/curiosity/helpers/constants.rb
40
+ - lib/legion/extensions/curiosity/helpers/gap_detector.rb
41
+ - lib/legion/extensions/curiosity/helpers/wonder.rb
42
+ - lib/legion/extensions/curiosity/helpers/wonder_store.rb
43
+ - lib/legion/extensions/curiosity/runners/curiosity.rb
44
+ - lib/legion/extensions/curiosity/version.rb
45
+ - spec/legion/extensions/curiosity/client_spec.rb
46
+ - spec/legion/extensions/curiosity/helpers/gap_detector_spec.rb
47
+ - spec/legion/extensions/curiosity/helpers/wonder_spec.rb
48
+ - spec/legion/extensions/curiosity/helpers/wonder_store_spec.rb
49
+ - spec/legion/extensions/curiosity/runners/curiosity_spec.rb
50
+ - spec/spec_helper.rb
51
+ homepage: https://github.com/LegionIO/lex-curiosity
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ homepage_uri: https://github.com/LegionIO/lex-curiosity
56
+ source_code_uri: https://github.com/LegionIO/lex-curiosity
57
+ documentation_uri: https://github.com/LegionIO/lex-curiosity
58
+ changelog_uri: https://github.com/LegionIO/lex-curiosity
59
+ bug_tracker_uri: https://github.com/LegionIO/lex-curiosity/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 Curiosity
78
+ test_files: []