lex-apollo 0.4.17 → 0.4.19
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 +4 -4
- data/CHANGELOG.md +20 -0
- data/lib/legion/extensions/apollo/gaia_integration.rb +1 -1
- data/lib/legion/extensions/apollo/helpers/confidence.rb +8 -3
- data/lib/legion/extensions/apollo/runners/knowledge.rb +33 -6
- data/lib/legion/extensions/apollo/runners/maintenance.rb +13 -4
- data/lib/legion/extensions/apollo/version.rb +1 -1
- data/spec/legion/extensions/apollo/contradiction_spec.rb +21 -0
- data/spec/legion/extensions/apollo/gaia_integration_spec.rb +14 -0
- data/spec/legion/extensions/apollo/helpers/confidence_spec.rb +15 -6
- data/spec/legion/extensions/apollo/runners/decay_cycle_spec.rb +6 -2
- data/spec/legion/extensions/apollo/runners/knowledge_spec.rb +35 -4
- data/spec/legion/extensions/apollo/runners/maintenance_spec.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1bf0ca8790d13fc3d262ede810ce50a47146dc37743e8806696de970b8a0385a
|
|
4
|
+
data.tar.gz: 1f1a9115e1a1bb36423150a7290a82352f07aef7aa41f0b4b7da8e0ff5b76f94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3d92269898b53825fff831ef253fc44ac9e9a45602da25628f32fc95c1e6a53edfd86add2f02f7131c449cd1b940258d2c8fc4df3b90ca6306affbf8a76d4ccb
|
|
7
|
+
data.tar.gz: d6c98fc7a7f351dc929e2d2dac4c9d7d119e32328706c9880e19a6bc3edb53448b008d8a8fefd7f7e8b8a201084f4ec78006088954cb7e56ee72cb312f0d5ce6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.19] - 2026-04-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- `store_knowledge` no longer rejects LLM-provided content_type values — normalizes free-form strings (`"reasoning"`, `"text"`, `"text/plain"`, `":fact"`, `"inference"`) to valid symbols via alias map with `:observation` fallback
|
|
7
|
+
- `GaiaIntegration.publish_insight` now passes `:observation` instead of the domain string as content_type (was sending `"general"` or domain names which failed validation)
|
|
8
|
+
- `llm_detects_conflict?` truncates content to 4000 chars before sending to LLM to prevent context overflow errors (was passing full entry content, hitting 65536-token limit)
|
|
9
|
+
|
|
10
|
+
## [0.4.18] - 2026-04-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- `store_knowledge`, `query_knowledge`, `related_entries` now execute directly when PostgreSQL is available instead of returning unexecuted command hashes — MCP tool calls were returning dispatch payloads (`{action: :query, ...}`) as their result, making the knowledge base unsearchable via LLM tools
|
|
14
|
+
- `query_knowledge` and `retrieve_relevant` now include `candidate` status in default search filters so newly stored entries are immediately retrievable (previously only `confirmed` entries were returned)
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Reduce `POWER_LAW_ALPHA` from 0.5 to 0.05 — decay was compounding hourly and crushing entry confidence within a day
|
|
18
|
+
- Reduce `DECAY_THRESHOLD` from 0.1 to 0.05 — entries were being archived too eagerly
|
|
19
|
+
- Decay cycle now operates on age in **days** instead of hours, preventing aggressive per-cycle compounding
|
|
20
|
+
- Add `DECAY_MIN_AGE_HOURS` (168h / 7 days) — entries younger than this are completely exempt from decay and archival
|
|
21
|
+
- `apply_decay` Ruby helper matches the new SQL behavior (days-based, minimum age guard)
|
|
22
|
+
|
|
3
23
|
## [0.4.17] - 2026-04-03
|
|
4
24
|
|
|
5
25
|
### Changed
|
|
@@ -15,7 +15,7 @@ module Legion
|
|
|
15
15
|
client = Legion::Extensions::Apollo::Client.new(agent_id: agent_id)
|
|
16
16
|
client.store_knowledge(
|
|
17
17
|
content: insight[:content],
|
|
18
|
-
content_type:
|
|
18
|
+
content_type: :observation,
|
|
19
19
|
source_agent: agent_id,
|
|
20
20
|
tags: Array(insight[:tags])
|
|
21
21
|
)
|
|
@@ -8,12 +8,13 @@ module Legion
|
|
|
8
8
|
INITIAL_CONFIDENCE = 0.5
|
|
9
9
|
CORROBORATION_BOOST = 0.3
|
|
10
10
|
RETRIEVAL_BOOST = 0.02
|
|
11
|
-
POWER_LAW_ALPHA = 0.
|
|
12
|
-
DECAY_THRESHOLD = 0.
|
|
11
|
+
POWER_LAW_ALPHA = 0.05
|
|
12
|
+
DECAY_THRESHOLD = 0.05
|
|
13
13
|
CORROBORATION_SIMILARITY_THRESHOLD = 0.9
|
|
14
14
|
WRITE_CONFIDENCE_GATE = 0.6
|
|
15
15
|
WRITE_NOVELTY_GATE = 0.3
|
|
16
16
|
STALE_DAYS = 90
|
|
17
|
+
DECAY_MIN_AGE_HOURS = 168
|
|
17
18
|
CONTENT_TYPES = %i[fact concept procedure association observation].freeze
|
|
18
19
|
STATUSES = %w[candidate confirmed disputed decayed archived].freeze
|
|
19
20
|
RELATION_TYPES = %w[is_a has_a part_of causes similar_to contradicts supersedes depends_on].freeze
|
|
@@ -41,14 +42,18 @@ module Legion
|
|
|
41
42
|
def write_confidence_gate = apollo_setting(:confidence, :write_gate, default: WRITE_CONFIDENCE_GATE)
|
|
42
43
|
def write_novelty_gate = apollo_setting(:confidence, :novelty_gate, default: WRITE_NOVELTY_GATE)
|
|
43
44
|
def stale_days = apollo_setting(:stale_days, default: STALE_DAYS)
|
|
45
|
+
def decay_min_age_hours = apollo_setting(:decay_min_age_hours, default: DECAY_MIN_AGE_HOURS)
|
|
44
46
|
|
|
45
47
|
def corroboration_similarity_threshold
|
|
46
48
|
apollo_setting(:confidence, :corroboration_similarity, default: CORROBORATION_SIMILARITY_THRESHOLD)
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def apply_decay(confidence:, age_hours: nil, alpha: power_law_alpha, **)
|
|
52
|
+
return confidence if age_hours && age_hours < decay_min_age_hours
|
|
53
|
+
|
|
50
54
|
if age_hours
|
|
51
|
-
|
|
55
|
+
age_days = age_hours / 24.0
|
|
56
|
+
[confidence * ((age_days.clamp(1, Float::INFINITY) + 1.0)**(-alpha)) / (age_days.clamp(1, Float::INFINITY)**(-alpha)), 0.0].max
|
|
52
57
|
else
|
|
53
58
|
factor = 1.0 / (1.0 + alpha)
|
|
54
59
|
[confidence * factor, 0.0].max
|
|
@@ -14,10 +14,20 @@ module Legion
|
|
|
14
14
|
'general' => :all
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
|
+
CONTENT_TYPE_ALIASES = {
|
|
18
|
+
reasoning: :concept, analysis: :concept, explanation: :concept,
|
|
19
|
+
text: :observation, general: :observation, note: :observation, summary: :observation,
|
|
20
|
+
rule: :procedure, step: :procedure, instruction: :procedure,
|
|
21
|
+
link: :association, relation: :association, connection: :association,
|
|
22
|
+
inference: :association, implication: :association
|
|
23
|
+
}.freeze
|
|
24
|
+
|
|
17
25
|
def store_knowledge(content:, content_type:, tags: [], source_agent: nil, context: {}, **)
|
|
18
|
-
content_type = content_type
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
content_type = normalize_content_type(content_type)
|
|
27
|
+
|
|
28
|
+
if defined?(Legion::Data::Model::ApolloEntry)
|
|
29
|
+
return handle_ingest(content: content, content_type: content_type,
|
|
30
|
+
tags: Array(tags), source_agent: source_agent, context: context, **)
|
|
21
31
|
end
|
|
22
32
|
|
|
23
33
|
{
|
|
@@ -30,7 +40,12 @@ module Legion
|
|
|
30
40
|
}
|
|
31
41
|
end
|
|
32
42
|
|
|
33
|
-
def query_knowledge(query:, limit: Helpers::GraphQuery.default_query_limit, min_confidence: Helpers::GraphQuery.default_query_min_confidence, status: [
|
|
43
|
+
def query_knowledge(query:, limit: Helpers::GraphQuery.default_query_limit, min_confidence: Helpers::GraphQuery.default_query_min_confidence, status: %i[confirmed candidate], tags: nil, **) # rubocop:disable Layout/LineLength
|
|
44
|
+
if defined?(Legion::Data::Model::ApolloEntry)
|
|
45
|
+
return handle_query(query: query, limit: limit, min_confidence: min_confidence,
|
|
46
|
+
status: status, tags: tags, **)
|
|
47
|
+
end
|
|
48
|
+
|
|
34
49
|
{
|
|
35
50
|
action: :query,
|
|
36
51
|
query: query,
|
|
@@ -42,6 +57,8 @@ module Legion
|
|
|
42
57
|
end
|
|
43
58
|
|
|
44
59
|
def related_entries(entry_id:, relation_types: nil, depth: Helpers::GraphQuery.default_depth, **)
|
|
60
|
+
return handle_traverse(entry_id: entry_id, depth: depth, relation_types: relation_types, **) if defined?(Legion::Data::Model::ApolloEntry)
|
|
61
|
+
|
|
45
62
|
{
|
|
46
63
|
action: :traverse,
|
|
47
64
|
entry_id: entry_id,
|
|
@@ -235,7 +252,7 @@ module Legion
|
|
|
235
252
|
embedding = embed_text(query)
|
|
236
253
|
sql = Helpers::GraphQuery.build_semantic_search_sql(
|
|
237
254
|
limit: limit, min_confidence: min_confidence,
|
|
238
|
-
statuses: [
|
|
255
|
+
statuses: %w[confirmed candidate], tags: tags, domain: domain
|
|
239
256
|
)
|
|
240
257
|
|
|
241
258
|
db = Legion::Data::Model::ApolloEntry.db
|
|
@@ -312,8 +329,16 @@ module Legion
|
|
|
312
329
|
{ deleted: 0, redacted: 0, error: e.message }
|
|
313
330
|
end
|
|
314
331
|
|
|
332
|
+
CONFLICT_CHECK_MAX_CHARS = 4000
|
|
333
|
+
|
|
315
334
|
private
|
|
316
335
|
|
|
336
|
+
def normalize_content_type(raw)
|
|
337
|
+
sym = raw.to_s.delete_prefix(':').gsub(%r{[/\s]}, '_').strip.downcase.to_sym
|
|
338
|
+
sym = CONTENT_TYPE_ALIASES.fetch(sym, sym)
|
|
339
|
+
Helpers::Confidence::CONTENT_TYPES.include?(sym) ? sym : :observation
|
|
340
|
+
end
|
|
341
|
+
|
|
317
342
|
def embed_text(text)
|
|
318
343
|
text = normalize_text_input(text)
|
|
319
344
|
result = Legion::LLM::Embeddings.generate(text: text)
|
|
@@ -387,10 +412,12 @@ module Legion
|
|
|
387
412
|
def llm_detects_conflict?(content_a, content_b)
|
|
388
413
|
return false unless defined?(Legion::LLM) && Legion::LLM.respond_to?(:structured)
|
|
389
414
|
|
|
415
|
+
a = content_a.to_s[0, CONFLICT_CHECK_MAX_CHARS]
|
|
416
|
+
b = content_b.to_s[0, CONFLICT_CHECK_MAX_CHARS]
|
|
390
417
|
result = Legion::LLM.structured(
|
|
391
418
|
messages: [
|
|
392
419
|
{ role: 'system', content: 'Do these two statements contradict each other? Return JSON.' },
|
|
393
|
-
{ role: 'user', content: "A: #{
|
|
420
|
+
{ role: 'user', content: "A: #{a}\n\nB: #{b}" }
|
|
394
421
|
],
|
|
395
422
|
schema: { type: 'object', properties: { contradicts: { type: 'boolean' } } },
|
|
396
423
|
caller: { extension: 'lex-apollo', runner: 'knowledge' }
|
|
@@ -23,28 +23,37 @@ module Legion
|
|
|
23
23
|
def run_decay_cycle(alpha: nil, min_confidence: nil, **)
|
|
24
24
|
alpha ||= Helpers::Confidence.power_law_alpha
|
|
25
25
|
min_confidence ||= Helpers::Confidence.decay_threshold
|
|
26
|
+
min_age_hours = Helpers::Confidence.decay_min_age_hours
|
|
26
27
|
|
|
27
28
|
return { decayed: 0, archived: 0 } unless defined?(Legion::Data) && Legion::Data.respond_to?(:connection) && Legion::Data.connection
|
|
28
29
|
|
|
29
30
|
conn = Legion::Data.connection
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
'GREATEST(EXTRACT(EPOCH FROM (NOW() - COALESCE(updated_at, created_at))) /
|
|
32
|
+
age_days_expr = Sequel.lit(
|
|
33
|
+
'GREATEST(EXTRACT(EPOCH FROM (NOW() - COALESCE(updated_at, created_at))) / 86400.0, 1.0)'
|
|
33
34
|
)
|
|
34
35
|
decay_factor = Sequel.lit(
|
|
35
|
-
'POWER(CAST(? AS double precision) / (CAST(? AS double precision) + 1.0), ?)',
|
|
36
|
+
'POWER(CAST(? AS double precision) / (CAST(? AS double precision) + 1.0), ?)',
|
|
37
|
+
age_days_expr, age_days_expr, alpha
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
min_age_filter = Sequel.lit(
|
|
41
|
+
"COALESCE(updated_at, created_at) < NOW() - INTERVAL '? hours'", min_age_hours
|
|
36
42
|
)
|
|
37
43
|
|
|
38
44
|
decayed = conn[:apollo_entries]
|
|
39
45
|
.exclude(status: 'archived')
|
|
46
|
+
.where(min_age_filter)
|
|
40
47
|
.update(confidence: Sequel[:confidence] * decay_factor)
|
|
41
48
|
|
|
42
49
|
archived = conn[:apollo_entries]
|
|
43
50
|
.where { confidence < min_confidence }
|
|
51
|
+
.where(min_age_filter)
|
|
44
52
|
.exclude(status: 'archived')
|
|
45
53
|
.update(status: 'archived')
|
|
46
54
|
|
|
47
|
-
{ decayed: decayed, archived: archived, alpha: alpha, threshold: min_confidence
|
|
55
|
+
{ decayed: decayed, archived: archived, alpha: alpha, threshold: min_confidence,
|
|
56
|
+
min_age_hours: min_age_hours }
|
|
48
57
|
rescue Sequel::Error => e
|
|
49
58
|
{ decayed: 0, archived: 0, error: e.message }
|
|
50
59
|
end
|
|
@@ -9,6 +9,27 @@ RSpec.describe 'Apollo Contradiction Detection' do
|
|
|
9
9
|
it 'returns false when LLM unavailable' do
|
|
10
10
|
expect(knowledge.send(:llm_detects_conflict?, 'sky is blue', 'sky is red')).to be false
|
|
11
11
|
end
|
|
12
|
+
|
|
13
|
+
context 'when LLM is available' do
|
|
14
|
+
let(:llm_mod) do
|
|
15
|
+
Module.new do
|
|
16
|
+
def self.respond_to?(*) = true
|
|
17
|
+
def self.structured(**) = { data: { contradicts: true } }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
before { stub_const('Legion::LLM', llm_mod) }
|
|
22
|
+
|
|
23
|
+
it 'truncates content longer than CONFLICT_CHECK_MAX_CHARS' do
|
|
24
|
+
long_text = 'x' * 10_000
|
|
25
|
+
allow(llm_mod).to receive(:structured).and_return({ data: { contradicts: false } })
|
|
26
|
+
knowledge.send(:llm_detects_conflict?, long_text, long_text)
|
|
27
|
+
expect(llm_mod).to have_received(:structured) do |**kwargs|
|
|
28
|
+
user_msg = kwargs[:messages].find { |m| m[:role] == 'user' }[:content]
|
|
29
|
+
expect(user_msg.length).to be < 10_000
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
12
33
|
end
|
|
13
34
|
|
|
14
35
|
describe '#detect_contradictions' do
|
|
@@ -44,6 +44,20 @@ RSpec.describe Legion::Extensions::Apollo::GaiaIntegration do
|
|
|
44
44
|
)
|
|
45
45
|
expect(result).to eq({ success: true })
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
it 'passes :observation as content_type regardless of domain' do
|
|
49
|
+
client_double = instance_double(Legion::Extensions::Apollo::Client)
|
|
50
|
+
allow(Legion::Extensions::Apollo::Client).to receive(:new).and_return(client_double)
|
|
51
|
+
allow(client_double).to receive(:store_knowledge).and_return({ success: true })
|
|
52
|
+
|
|
53
|
+
described_class.publish_insight(
|
|
54
|
+
{ confidence: 0.9, novelty: 0.5, content: 'insight', domain: 'clinical' },
|
|
55
|
+
agent_id: 'test-agent'
|
|
56
|
+
)
|
|
57
|
+
expect(client_double).to have_received(:store_knowledge).with(
|
|
58
|
+
hash_including(content_type: :observation)
|
|
59
|
+
)
|
|
60
|
+
end
|
|
47
61
|
end
|
|
48
62
|
|
|
49
63
|
describe 'entity watchdog phase handler' do
|
|
@@ -18,11 +18,15 @@ RSpec.describe Legion::Extensions::Apollo::Helpers::Confidence do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'defines POWER_LAW_ALPHA' do
|
|
21
|
-
expect(described_class::POWER_LAW_ALPHA).to eq(0.
|
|
21
|
+
expect(described_class::POWER_LAW_ALPHA).to eq(0.05)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'defines DECAY_THRESHOLD' do
|
|
25
|
-
expect(described_class::DECAY_THRESHOLD).to eq(0.
|
|
25
|
+
expect(described_class::DECAY_THRESHOLD).to eq(0.05)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'defines DECAY_MIN_AGE_HOURS' do
|
|
29
|
+
expect(described_class::DECAY_MIN_AGE_HOURS).to eq(168)
|
|
26
30
|
end
|
|
27
31
|
|
|
28
32
|
it 'defines CORROBORATION_SIMILARITY_THRESHOLD' do
|
|
@@ -45,12 +49,17 @@ RSpec.describe Legion::Extensions::Apollo::Helpers::Confidence do
|
|
|
45
49
|
describe '.apply_decay' do
|
|
46
50
|
it 'applies power-law decay with default alpha when no age given' do
|
|
47
51
|
result = described_class.apply_decay(confidence: 1.0)
|
|
48
|
-
expected = 1.0 / (1.0 + 0.
|
|
52
|
+
expected = 1.0 / (1.0 + 0.05) # ~0.9524
|
|
49
53
|
expect(result).to be_within(0.0001).of(expected)
|
|
50
54
|
end
|
|
51
55
|
|
|
52
|
-
it '
|
|
56
|
+
it 'skips decay when age_hours is below minimum age' do
|
|
53
57
|
result = described_class.apply_decay(confidence: 1.0, age_hours: 10)
|
|
58
|
+
expect(result).to eq(1.0)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'applies age-based power-law decay when age_hours exceeds minimum' do
|
|
62
|
+
result = described_class.apply_decay(confidence: 1.0, age_hours: 500)
|
|
54
63
|
expect(result).to be > 0.0
|
|
55
64
|
expect(result).to be < 1.0
|
|
56
65
|
end
|
|
@@ -98,11 +107,11 @@ RSpec.describe Legion::Extensions::Apollo::Helpers::Confidence do
|
|
|
98
107
|
|
|
99
108
|
describe '.decayed?' do
|
|
100
109
|
it 'returns true when confidence below threshold' do
|
|
101
|
-
expect(described_class.decayed?(confidence: 0.
|
|
110
|
+
expect(described_class.decayed?(confidence: 0.01)).to be true
|
|
102
111
|
end
|
|
103
112
|
|
|
104
113
|
it 'returns false when confidence at or above threshold' do
|
|
105
|
-
expect(described_class.decayed?(confidence: 0.
|
|
114
|
+
expect(described_class.decayed?(confidence: 0.05)).to be false
|
|
106
115
|
end
|
|
107
116
|
end
|
|
108
117
|
|
|
@@ -14,11 +14,15 @@ RSpec.describe 'Apollo Decay Cycle' do
|
|
|
14
14
|
|
|
15
15
|
describe 'configurable decay parameters' do
|
|
16
16
|
it 'returns POWER_LAW_ALPHA as default' do
|
|
17
|
-
expect(Legion::Extensions::Apollo::Helpers::Confidence.power_law_alpha).to eq(0.
|
|
17
|
+
expect(Legion::Extensions::Apollo::Helpers::Confidence.power_law_alpha).to eq(0.05)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it 'returns default decay threshold' do
|
|
21
|
-
expect(Legion::Extensions::Apollo::Helpers::Confidence.decay_threshold).to eq(0.
|
|
21
|
+
expect(Legion::Extensions::Apollo::Helpers::Confidence.decay_threshold).to eq(0.05)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'returns default decay minimum age hours' do
|
|
25
|
+
expect(Legion::Extensions::Apollo::Helpers::Confidence.decay_min_age_hours).to eq(168)
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -45,10 +45,41 @@ RSpec.describe Legion::Extensions::Apollo::Runners::Knowledge do
|
|
|
45
45
|
expect(result[:source_agent]).to eq('worker-1')
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
it '
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
it 'falls back to :observation for unrecognized content_type' do
|
|
49
|
+
result = runner.store_knowledge(content: 'test', content_type: 'invalid_type')
|
|
50
|
+
expect(result[:content_type]).to eq(:observation)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'normalizes LLM-provided content_type "reasoning" to :concept' do
|
|
54
|
+
result = runner.store_knowledge(content: 'test', content_type: 'reasoning')
|
|
55
|
+
expect(result[:content_type]).to eq(:concept)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'normalizes "text" to :observation' do
|
|
59
|
+
result = runner.store_knowledge(content: 'test', content_type: 'text')
|
|
60
|
+
expect(result[:content_type]).to eq(:observation)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'normalizes "text/plain" to :observation' do
|
|
64
|
+
result = runner.store_knowledge(content: 'test', content_type: 'text/plain')
|
|
65
|
+
expect(result[:content_type]).to eq(:observation)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'strips leading colon from ":fact"' do
|
|
69
|
+
result = runner.store_knowledge(content: 'test', content_type: ':fact')
|
|
70
|
+
expect(result[:content_type]).to eq(:fact)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'normalizes "inference" to :association' do
|
|
74
|
+
result = runner.store_knowledge(content: 'test', content_type: 'inference')
|
|
75
|
+
expect(result[:content_type]).to eq(:association)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'accepts all valid CONTENT_TYPES unchanged' do
|
|
79
|
+
%i[fact concept procedure association observation].each do |ct|
|
|
80
|
+
result = runner.store_knowledge(content: 'test', content_type: ct)
|
|
81
|
+
expect(result[:content_type]).to eq(ct)
|
|
82
|
+
end
|
|
52
83
|
end
|
|
53
84
|
end
|
|
54
85
|
|
|
@@ -71,7 +71,7 @@ RSpec.describe Legion::Extensions::Apollo::Runners::Maintenance do
|
|
|
71
71
|
|
|
72
72
|
it 'returns alpha in result hash' do
|
|
73
73
|
result = host.run_decay_cycle
|
|
74
|
-
expect(result[:alpha]).to eq(0.
|
|
74
|
+
expect(result[:alpha]).to eq(0.05)
|
|
75
75
|
expect(result).not_to have_key(:rate)
|
|
76
76
|
end
|
|
77
77
|
|