lex-agentic-self 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/CHANGELOG.md +12 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +13 -0
- data/lex-agentic-self.gemspec +31 -0
- data/lib/legion/extensions/agentic/self/agency/client.rb +21 -0
- data/lib/legion/extensions/agentic/self/agency/helpers/constants.rb +77 -0
- data/lib/legion/extensions/agentic/self/agency/helpers/efficacy_model.rb +136 -0
- data/lib/legion/extensions/agentic/self/agency/helpers/outcome_event.rb +52 -0
- data/lib/legion/extensions/agentic/self/agency/runners/agency.rb +117 -0
- data/lib/legion/extensions/agentic/self/agency/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/agency.rb +19 -0
- data/lib/legion/extensions/agentic/self/anchor/client.rb +15 -0
- data/lib/legion/extensions/agentic/self/anchor/helpers/anchor.rb +92 -0
- data/lib/legion/extensions/agentic/self/anchor/helpers/anchor_engine.rb +123 -0
- data/lib/legion/extensions/agentic/self/anchor/helpers/chain.rb +93 -0
- data/lib/legion/extensions/agentic/self/anchor/helpers/constants.rb +46 -0
- data/lib/legion/extensions/agentic/self/anchor/runners/cognitive_anchor.rb +70 -0
- data/lib/legion/extensions/agentic/self/anchor/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/anchor.rb +22 -0
- data/lib/legion/extensions/agentic/self/anosognosia/client.rb +28 -0
- data/lib/legion/extensions/agentic/self/anosognosia/helpers/anosognosia_engine.rb +153 -0
- data/lib/legion/extensions/agentic/self/anosognosia/helpers/cognitive_deficit.rb +71 -0
- data/lib/legion/extensions/agentic/self/anosognosia/helpers/constants.rb +29 -0
- data/lib/legion/extensions/agentic/self/anosognosia/runners/anosognosia.rb +98 -0
- data/lib/legion/extensions/agentic/self/anosognosia/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/anosognosia.rb +19 -0
- data/lib/legion/extensions/agentic/self/architecture/client.rb +19 -0
- data/lib/legion/extensions/agentic/self/architecture/helpers/architecture_engine.rb +167 -0
- data/lib/legion/extensions/agentic/self/architecture/helpers/connection.rb +57 -0
- data/lib/legion/extensions/agentic/self/architecture/helpers/constants.rb +37 -0
- data/lib/legion/extensions/agentic/self/architecture/helpers/subsystem.rb +80 -0
- data/lib/legion/extensions/agentic/self/architecture/runners/cognitive_architecture.rb +125 -0
- data/lib/legion/extensions/agentic/self/architecture/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/architecture.rb +20 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/actors/idle.rb +45 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/client.rb +28 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/helpers/constants.rb +53 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/helpers/dmn_engine.rb +221 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/helpers/wandering_thought.rb +60 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/runners/default_mode_network.rb +122 -0
- data/lib/legion/extensions/agentic/self/default_mode_network/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/default_mode_network.rb +20 -0
- data/lib/legion/extensions/agentic/self/fingerprint/client.rb +28 -0
- data/lib/legion/extensions/agentic/self/fingerprint/helpers/cognitive_trait.rb +73 -0
- data/lib/legion/extensions/agentic/self/fingerprint/helpers/constants.rb +60 -0
- data/lib/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine.rb +169 -0
- data/lib/legion/extensions/agentic/self/fingerprint/runners/cognitive_fingerprint.rb +86 -0
- data/lib/legion/extensions/agentic/self/fingerprint/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/fingerprint.rb +19 -0
- data/lib/legion/extensions/agentic/self/identity/actors/credential_refresh.rb +49 -0
- data/lib/legion/extensions/agentic/self/identity/actors/orphan_check.rb +52 -0
- data/lib/legion/extensions/agentic/self/identity/client.rb +27 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/dimensions.rb +75 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/fingerprint.rb +170 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/graph_client.rb +29 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/graph_token.rb +36 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/token_cache.rb +59 -0
- data/lib/legion/extensions/agentic/self/identity/helpers/vault_secrets.rb +80 -0
- data/lib/legion/extensions/agentic/self/identity/local_migrations/20260316000030_create_fingerprint.rb +20 -0
- data/lib/legion/extensions/agentic/self/identity/runners/entra.rb +402 -0
- data/lib/legion/extensions/agentic/self/identity/runners/identity.rb +90 -0
- data/lib/legion/extensions/agentic/self/identity/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/identity.rb +28 -0
- data/lib/legion/extensions/agentic/self/metacognition/client.rb +27 -0
- data/lib/legion/extensions/agentic/self/metacognition/helpers/constants.rb +377 -0
- data/lib/legion/extensions/agentic/self/metacognition/helpers/narrator_bridge.rb +85 -0
- data/lib/legion/extensions/agentic/self/metacognition/helpers/registry_store.rb +70 -0
- data/lib/legion/extensions/agentic/self/metacognition/helpers/self_model.rb +160 -0
- data/lib/legion/extensions/agentic/self/metacognition/helpers/snapshot_store.rb +82 -0
- data/lib/legion/extensions/agentic/self/metacognition/runners/metacognition.rb +116 -0
- data/lib/legion/extensions/agentic/self/metacognition/runners/registry.rb +180 -0
- data/lib/legion/extensions/agentic/self/metacognition/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/metacognition.rb +22 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/client.rb +25 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/calibration_tracker.rb +96 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/constants.rb +47 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_engine.rb +141 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_judgment.rb +79 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/runners/metacognitive_monitoring.rb +151 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/metacognitive_monitoring.rb +20 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/client.rb +29 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/helpers/arc.rb +137 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/helpers/arc_engine.rb +119 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/helpers/beat_event.rb +59 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/helpers/constants.rb +66 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/runners/narrative.rb +101 -0
- data/lib/legion/extensions/agentic/self/narrative_arc/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/narrative_arc.rb +20 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/actors/narrative_decay.rb +45 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/client.rb +22 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/helpers/chapter.rb +48 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/helpers/constants.rb +62 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/helpers/episode.rb +67 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb +187 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/helpers/theme.rb +50 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/runners/narrative_identity.rb +158 -0
- data/lib/legion/extensions/agentic/self/narrative_identity/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/narrative_identity.rb +21 -0
- data/lib/legion/extensions/agentic/self/narrative_self/client.rb +27 -0
- data/lib/legion/extensions/agentic/self/narrative_self/helpers/autobiography.rb +187 -0
- data/lib/legion/extensions/agentic/self/narrative_self/helpers/constants.rb +42 -0
- data/lib/legion/extensions/agentic/self/narrative_self/helpers/episode.rb +81 -0
- data/lib/legion/extensions/agentic/self/narrative_self/helpers/narrative_thread.rb +65 -0
- data/lib/legion/extensions/agentic/self/narrative_self/runners/narrative_self.rb +86 -0
- data/lib/legion/extensions/agentic/self/narrative_self/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/narrative_self.rb +20 -0
- data/lib/legion/extensions/agentic/self/personality/client.rb +21 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/constants.rb +84 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/personality_store.rb +126 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/trait_model.rb +147 -0
- data/lib/legion/extensions/agentic/self/personality/runners/personality.rb +102 -0
- data/lib/legion/extensions/agentic/self/personality/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/personality.rb +19 -0
- data/lib/legion/extensions/agentic/self/reflection/client.rb +27 -0
- data/lib/legion/extensions/agentic/self/reflection/helpers/constants.rb +66 -0
- data/lib/legion/extensions/agentic/self/reflection/helpers/llm_enhancer.rb +166 -0
- data/lib/legion/extensions/agentic/self/reflection/helpers/monitors.rb +186 -0
- data/lib/legion/extensions/agentic/self/reflection/helpers/reflection.rb +54 -0
- data/lib/legion/extensions/agentic/self/reflection/helpers/reflection_store.rb +99 -0
- data/lib/legion/extensions/agentic/self/reflection/runners/reflection.rb +199 -0
- data/lib/legion/extensions/agentic/self/reflection/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/reflection.rb +21 -0
- data/lib/legion/extensions/agentic/self/self_model/client.rb +19 -0
- data/lib/legion/extensions/agentic/self/self_model/helpers/capability.rb +93 -0
- data/lib/legion/extensions/agentic/self/self_model/helpers/constants.rb +46 -0
- data/lib/legion/extensions/agentic/self/self_model/helpers/knowledge_domain.rb +82 -0
- data/lib/legion/extensions/agentic/self/self_model/helpers/self_model.rb +150 -0
- data/lib/legion/extensions/agentic/self/self_model/runners/self_model.rb +82 -0
- data/lib/legion/extensions/agentic/self/self_model/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/self_model.rb +21 -0
- data/lib/legion/extensions/agentic/self/self_talk/actors/volume_decay.rb +45 -0
- data/lib/legion/extensions/agentic/self/self_talk/client.rb +30 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/constants.rb +63 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/dialogue.rb +114 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/dialogue_turn.rb +43 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/inner_voice.rb +77 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/llm_enhancer.rb +135 -0
- data/lib/legion/extensions/agentic/self/self_talk/helpers/self_talk_engine.rb +160 -0
- data/lib/legion/extensions/agentic/self/self_talk/runners/self_talk.rb +172 -0
- data/lib/legion/extensions/agentic/self/self_talk/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/self_talk.rb +22 -0
- data/lib/legion/extensions/agentic/self/version.rb +11 -0
- data/lib/legion/extensions/agentic/self.rb +33 -0
- data/spec/legion/extensions/agentic/self/agency/client_spec.rb +67 -0
- data/spec/legion/extensions/agentic/self/agency/helpers/constants_spec.rb +73 -0
- data/spec/legion/extensions/agentic/self/agency/helpers/efficacy_model_spec.rb +190 -0
- data/spec/legion/extensions/agentic/self/agency/helpers/outcome_event_spec.rb +85 -0
- data/spec/legion/extensions/agentic/self/agency/runners/agency_spec.rb +132 -0
- data/spec/legion/extensions/agentic/self/anchor/client_spec.rb +30 -0
- data/spec/legion/extensions/agentic/self/anchor/helpers/anchor_engine_spec.rb +109 -0
- data/spec/legion/extensions/agentic/self/anchor/helpers/anchor_spec.rb +124 -0
- data/spec/legion/extensions/agentic/self/anchor/helpers/chain_spec.rb +106 -0
- data/spec/legion/extensions/agentic/self/anchor/helpers/constants_spec.rb +53 -0
- data/spec/legion/extensions/agentic/self/anchor/runners/cognitive_anchor_spec.rb +70 -0
- data/spec/legion/extensions/agentic/self/anosognosia/anosognosia_spec.rb +15 -0
- data/spec/legion/extensions/agentic/self/anosognosia/client_spec.rb +50 -0
- data/spec/legion/extensions/agentic/self/anosognosia/helpers/anosognosia_engine_spec.rb +266 -0
- data/spec/legion/extensions/agentic/self/anosognosia/helpers/cognitive_deficit_spec.rb +150 -0
- data/spec/legion/extensions/agentic/self/anosognosia/helpers/constants_spec.rb +58 -0
- data/spec/legion/extensions/agentic/self/anosognosia/runners/anosognosia_spec.rb +225 -0
- data/spec/legion/extensions/agentic/self/architecture/client_spec.rb +51 -0
- data/spec/legion/extensions/agentic/self/architecture/helpers/architecture_engine_spec.rb +321 -0
- data/spec/legion/extensions/agentic/self/architecture/helpers/connection_spec.rb +118 -0
- data/spec/legion/extensions/agentic/self/architecture/helpers/subsystem_spec.rb +189 -0
- data/spec/legion/extensions/agentic/self/architecture/runners/cognitive_architecture_spec.rb +181 -0
- data/spec/legion/extensions/agentic/self/default_mode_network/client_spec.rb +69 -0
- data/spec/legion/extensions/agentic/self/default_mode_network/helpers/constants_spec.rb +76 -0
- data/spec/legion/extensions/agentic/self/default_mode_network/helpers/dmn_engine_spec.rb +321 -0
- data/spec/legion/extensions/agentic/self/default_mode_network/helpers/wandering_thought_spec.rb +145 -0
- data/spec/legion/extensions/agentic/self/default_mode_network/runners/default_mode_network_spec.rb +269 -0
- data/spec/legion/extensions/agentic/self/fingerprint/client_spec.rb +54 -0
- data/spec/legion/extensions/agentic/self/fingerprint/helpers/cognitive_trait_spec.rb +180 -0
- data/spec/legion/extensions/agentic/self/fingerprint/helpers/constants_spec.rb +108 -0
- data/spec/legion/extensions/agentic/self/fingerprint/helpers/fingerprint_engine_spec.rb +318 -0
- data/spec/legion/extensions/agentic/self/fingerprint/runners/cognitive_fingerprint_spec.rb +232 -0
- data/spec/legion/extensions/agentic/self/identity/actors/orphan_check_spec.rb +104 -0
- data/spec/legion/extensions/agentic/self/identity/client_spec.rb +32 -0
- data/spec/legion/extensions/agentic/self/identity/helpers/dimensions_spec.rb +51 -0
- data/spec/legion/extensions/agentic/self/identity/helpers/fingerprint_spec.rb +66 -0
- data/spec/legion/extensions/agentic/self/identity/helpers/graph_client_spec.rb +19 -0
- data/spec/legion/extensions/agentic/self/identity/helpers/graph_token_spec.rb +31 -0
- data/spec/legion/extensions/agentic/self/identity/helpers/token_cache_spec.rb +50 -0
- data/spec/legion/extensions/agentic/self/identity/local_persistence_spec.rb +329 -0
- data/spec/legion/extensions/agentic/self/identity/runners/entra_spec.rb +655 -0
- data/spec/legion/extensions/agentic/self/identity/runners/identity_spec.rb +61 -0
- data/spec/legion/extensions/agentic/self/metacognition/client_spec.rb +20 -0
- data/spec/legion/extensions/agentic/self/metacognition/helpers/constants_spec.rb +31 -0
- data/spec/legion/extensions/agentic/self/metacognition/helpers/narrator_bridge_spec.rb +102 -0
- data/spec/legion/extensions/agentic/self/metacognition/helpers/registry_store_spec.rb +227 -0
- data/spec/legion/extensions/agentic/self/metacognition/helpers/self_model_spec.rb +117 -0
- data/spec/legion/extensions/agentic/self/metacognition/helpers/snapshot_store_spec.rb +128 -0
- data/spec/legion/extensions/agentic/self/metacognition/runners/metacognition_spec.rb +110 -0
- data/spec/legion/extensions/agentic/self/metacognition/runners/registry_spec.rb +281 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/client_spec.rb +59 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/calibration_tracker_spec.rb +143 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/constants_spec.rb +91 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_engine_spec.rb +198 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/helpers/monitoring_judgment_spec.rb +172 -0
- data/spec/legion/extensions/agentic/self/metacognitive_monitoring/runners/metacognitive_monitoring_spec.rb +244 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/client_spec.rb +22 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/helpers/arc_engine_spec.rb +183 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/helpers/arc_spec.rb +177 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/helpers/beat_event_spec.rb +96 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/helpers/constants_spec.rb +75 -0
- data/spec/legion/extensions/agentic/self/narrative_arc/runners/narrative_spec.rb +142 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/client_spec.rb +69 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/helpers/chapter_spec.rb +85 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/helpers/constants_spec.rb +83 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/helpers/episode_spec.rb +180 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine_spec.rb +307 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/helpers/theme_spec.rb +107 -0
- data/spec/legion/extensions/agentic/self/narrative_identity/runners/narrative_identity_spec.rb +240 -0
- data/spec/legion/extensions/agentic/self/narrative_self/client_spec.rb +67 -0
- data/spec/legion/extensions/agentic/self/narrative_self/helpers/autobiography_spec.rb +155 -0
- data/spec/legion/extensions/agentic/self/narrative_self/helpers/constants_spec.rb +28 -0
- data/spec/legion/extensions/agentic/self/narrative_self/helpers/episode_spec.rb +144 -0
- data/spec/legion/extensions/agentic/self/narrative_self/helpers/narrative_thread_spec.rb +87 -0
- data/spec/legion/extensions/agentic/self/narrative_self/runners/narrative_self_spec.rb +118 -0
- data/spec/legion/extensions/agentic/self/personality/client_spec.rb +20 -0
- data/spec/legion/extensions/agentic/self/personality/helpers/constants_spec.rb +41 -0
- data/spec/legion/extensions/agentic/self/personality/helpers/personality_store_spec.rb +66 -0
- data/spec/legion/extensions/agentic/self/personality/helpers/trait_model_spec.rb +148 -0
- data/spec/legion/extensions/agentic/self/personality/runners/personality_spec.rb +67 -0
- data/spec/legion/extensions/agentic/self/reflection/client_spec.rb +24 -0
- data/spec/legion/extensions/agentic/self/reflection/helpers/llm_enhancer_spec.rb +191 -0
- data/spec/legion/extensions/agentic/self/reflection/helpers/monitors_spec.rb +120 -0
- data/spec/legion/extensions/agentic/self/reflection/helpers/reflection_spec.rb +49 -0
- data/spec/legion/extensions/agentic/self/reflection/helpers/reflection_store_spec.rb +93 -0
- data/spec/legion/extensions/agentic/self/reflection/runners/reflection_spec.rb +204 -0
- data/spec/legion/extensions/agentic/self/self_model/client_spec.rb +55 -0
- data/spec/legion/extensions/agentic/self/self_model/helpers/capability_spec.rb +160 -0
- data/spec/legion/extensions/agentic/self/self_model/helpers/knowledge_domain_spec.rb +128 -0
- data/spec/legion/extensions/agentic/self/self_model/helpers/self_model_spec.rb +238 -0
- data/spec/legion/extensions/agentic/self/self_model/runners/self_model_spec.rb +143 -0
- data/spec/legion/extensions/agentic/self/self_talk/actors/volume_decay_spec.rb +46 -0
- data/spec/legion/extensions/agentic/self/self_talk/client_spec.rb +26 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/constants_spec.rb +110 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/dialogue_spec.rb +191 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/dialogue_turn_spec.rb +78 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/inner_voice_spec.rb +172 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/llm_enhancer_spec.rb +206 -0
- data/spec/legion/extensions/agentic/self/self_talk/helpers/self_talk_engine_spec.rb +239 -0
- data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_llm_spec.rb +169 -0
- data/spec/legion/extensions/agentic/self/self_talk/runners/self_talk_spec.rb +196 -0
- data/spec/spec_helper.rb +46 -0
- metadata +347 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Client do
|
|
4
|
+
let(:client) { described_class.new }
|
|
5
|
+
|
|
6
|
+
it 'can be instantiated' do
|
|
7
|
+
expect(client).to be_a(described_class)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'includes all runner methods' do
|
|
11
|
+
expect(client).to respond_to(:record_episode)
|
|
12
|
+
expect(client).to respond_to(:recent_episodes)
|
|
13
|
+
expect(client).to respond_to(:significant_episodes)
|
|
14
|
+
expect(client).to respond_to(:create_thread)
|
|
15
|
+
expect(client).to respond_to(:self_summary)
|
|
16
|
+
expect(client).to respond_to(:update_narrative_self)
|
|
17
|
+
expect(client).to respond_to(:narrative_self_stats)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'exposes the autobiography' do
|
|
21
|
+
expect(client.autobiography).to be_a(Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Autobiography)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe 'full lifecycle' do
|
|
25
|
+
it 'builds a narrative from episodes and threads' do
|
|
26
|
+
# Create narrative threads
|
|
27
|
+
client.create_thread(theme: :learning, domain: :cognition)
|
|
28
|
+
client.create_thread(theme: :mastery, domain: :technical)
|
|
29
|
+
|
|
30
|
+
# Record experiences
|
|
31
|
+
client.record_episode(
|
|
32
|
+
description: 'built first extension',
|
|
33
|
+
episode_type: :achievement,
|
|
34
|
+
domain: :technical,
|
|
35
|
+
emotional_valence: 0.7,
|
|
36
|
+
tags: %i[building mastery]
|
|
37
|
+
)
|
|
38
|
+
client.record_episode(
|
|
39
|
+
description: 'learned about EMA',
|
|
40
|
+
episode_type: :insight,
|
|
41
|
+
domain: :cognition,
|
|
42
|
+
tags: %i[learning math]
|
|
43
|
+
)
|
|
44
|
+
client.record_episode(
|
|
45
|
+
description: 'test failure taught me about edge cases',
|
|
46
|
+
episode_type: :discovery,
|
|
47
|
+
domain: :technical,
|
|
48
|
+
emotional_valence: -0.3,
|
|
49
|
+
tags: %i[learning debugging]
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Check timeline
|
|
53
|
+
tl = client.timeline
|
|
54
|
+
expect(tl[:count]).to eq(3)
|
|
55
|
+
|
|
56
|
+
# Check self-summary
|
|
57
|
+
summary = client.self_summary[:summary]
|
|
58
|
+
expect(summary[:total_episodes]).to eq(3)
|
|
59
|
+
expect(summary[:self_concept]).not_to be_empty
|
|
60
|
+
|
|
61
|
+
# Tick
|
|
62
|
+
client.update_narrative_self
|
|
63
|
+
stats = client.narrative_self_stats[:stats]
|
|
64
|
+
expect(stats[:episode_count]).to eq(3)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Autobiography do
|
|
4
|
+
let(:auto) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#record_episode' do
|
|
7
|
+
it 'creates and stores an episode' do
|
|
8
|
+
episode = auto.record_episode(description: 'first task completed', episode_type: :achievement)
|
|
9
|
+
expect(episode).to be_a(Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Episode)
|
|
10
|
+
expect(auto.episodes.size).to eq(1)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'updates self-concept with episode type' do
|
|
14
|
+
auto.record_episode(description: 'test', episode_type: :achievement)
|
|
15
|
+
expect(auto.self_concept).to have_key(:achievement)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'trims episodes when exceeding MAX_EPISODES' do
|
|
19
|
+
max = Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Constants::MAX_EPISODES
|
|
20
|
+
(max + 5).times { |i| auto.record_episode(description: "episode #{i}") }
|
|
21
|
+
expect(auto.episodes.size).to eq(max)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '#find_episode' do
|
|
26
|
+
it 'finds by id' do
|
|
27
|
+
ep = auto.record_episode(description: 'test')
|
|
28
|
+
expect(auto.find_episode(ep.id)).to eq(ep)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'returns nil for unknown id' do
|
|
32
|
+
expect(auto.find_episode('nonexistent')).to be_nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe '#recent_episodes' do
|
|
37
|
+
it 'returns the last N episodes' do
|
|
38
|
+
5.times { |i| auto.record_episode(description: "ep #{i}") }
|
|
39
|
+
recent = auto.recent_episodes(3)
|
|
40
|
+
expect(recent.size).to eq(3)
|
|
41
|
+
expect(recent.last.description).to eq('ep 4')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe '#significant_episodes' do
|
|
46
|
+
it 'returns episodes above threshold' do
|
|
47
|
+
auto.record_episode(description: 'big deal', significance: 0.9)
|
|
48
|
+
auto.record_episode(description: 'small thing', significance: 0.2)
|
|
49
|
+
significant = auto.significant_episodes(min_significance: 0.5)
|
|
50
|
+
expect(significant.size).to eq(1)
|
|
51
|
+
expect(significant.first.description).to eq('big deal')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '#episodes_by_type' do
|
|
56
|
+
it 'filters by episode type' do
|
|
57
|
+
auto.record_episode(description: 'win', episode_type: :achievement)
|
|
58
|
+
auto.record_episode(description: 'loss', episode_type: :failure)
|
|
59
|
+
auto.record_episode(description: 'another win', episode_type: :achievement)
|
|
60
|
+
expect(auto.episodes_by_type(:achievement).size).to eq(2)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe '#episodes_in_domain' do
|
|
65
|
+
it 'filters by domain' do
|
|
66
|
+
auto.record_episode(description: 'code', domain: :technical)
|
|
67
|
+
auto.record_episode(description: 'meeting', domain: :social)
|
|
68
|
+
expect(auto.episodes_in_domain(:technical).size).to eq(1)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
describe '#create_thread' do
|
|
73
|
+
it 'creates a narrative thread' do
|
|
74
|
+
thread = auto.create_thread(theme: :growth, domain: :personal)
|
|
75
|
+
expect(thread.theme).to eq(:growth)
|
|
76
|
+
expect(auto.threads.size).to eq(1)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe '#strongest_threads' do
|
|
81
|
+
it 'returns threads sorted by strength' do
|
|
82
|
+
auto.create_thread(theme: :growth)
|
|
83
|
+
t2 = auto.create_thread(theme: :mastery)
|
|
84
|
+
t2.reinforce
|
|
85
|
+
strongest = auto.strongest_threads(2)
|
|
86
|
+
expect(strongest.first).to eq(t2)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe '#timeline' do
|
|
91
|
+
it 'returns recent episodes as hashes' do
|
|
92
|
+
auto.record_episode(description: 'first')
|
|
93
|
+
auto.record_episode(description: 'second')
|
|
94
|
+
tl = auto.timeline(window: 10)
|
|
95
|
+
expect(tl.size).to eq(2)
|
|
96
|
+
expect(tl.first).to be_a(Hash)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#self_summary' do
|
|
101
|
+
it 'returns a comprehensive summary' do
|
|
102
|
+
auto.record_episode(description: 'a', episode_type: :achievement, domain: :tech)
|
|
103
|
+
auto.record_episode(description: 'b', episode_type: :insight, domain: :tech)
|
|
104
|
+
summary = auto.self_summary
|
|
105
|
+
expect(summary).to have_key(:total_episodes)
|
|
106
|
+
expect(summary).to have_key(:dominant_types)
|
|
107
|
+
expect(summary).to have_key(:dominant_domains)
|
|
108
|
+
expect(summary).to have_key(:self_concept)
|
|
109
|
+
expect(summary).to have_key(:narrative_richness)
|
|
110
|
+
expect(summary[:total_episodes]).to eq(2)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
describe '#decay_all' do
|
|
115
|
+
it 'decays episodes and removes faded ones' do
|
|
116
|
+
ep = auto.record_episode(description: 'old', significance: 0.06)
|
|
117
|
+
200.times { ep.decay }
|
|
118
|
+
auto.decay_all
|
|
119
|
+
expect(auto.episodes).not_to include(ep)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'decays threads and removes weak ones' do
|
|
123
|
+
t = auto.create_thread(theme: :test)
|
|
124
|
+
100.times { t.decay }
|
|
125
|
+
auto.decay_all
|
|
126
|
+
expect(auto.threads).not_to include(t)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
describe '#to_h' do
|
|
131
|
+
it 'returns summary statistics' do
|
|
132
|
+
auto.record_episode(description: 'test', episode_type: :insight, domain: :tech)
|
|
133
|
+
h = auto.to_h
|
|
134
|
+
expect(h).to have_key(:episode_count)
|
|
135
|
+
expect(h).to have_key(:thread_count)
|
|
136
|
+
expect(h).to have_key(:self_concept)
|
|
137
|
+
expect(h).to have_key(:by_type)
|
|
138
|
+
expect(h).to have_key(:by_domain)
|
|
139
|
+
expect(h).to have_key(:avg_significance)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
describe 'auto-linking' do
|
|
144
|
+
it 'links episodes to matching threads' do
|
|
145
|
+
thread = auto.create_thread(theme: :learning, domain: :cognition)
|
|
146
|
+
episode = auto.record_episode(
|
|
147
|
+
description: 'learned something new',
|
|
148
|
+
domain: :cognition,
|
|
149
|
+
tags: %i[learning growth]
|
|
150
|
+
)
|
|
151
|
+
expect(thread.episode_ids).to include(episode.id)
|
|
152
|
+
expect(episode.thread_ids).to include(thread.id)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Constants do
|
|
4
|
+
it 'defines MAX_EPISODES' do
|
|
5
|
+
expect(described_class::MAX_EPISODES).to eq(500)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'defines MAX_THREADS' do
|
|
9
|
+
expect(described_class::MAX_THREADS).to eq(50)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'defines EPISODE_TYPES' do
|
|
13
|
+
expect(described_class::EPISODE_TYPES).to include(:achievement, :failure, :discovery, :insight)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'defines SIGNIFICANCE_LABELS covering 0.0..1.0' do
|
|
17
|
+
labels = described_class::SIGNIFICANCE_LABELS
|
|
18
|
+
[0.0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0].each do |val|
|
|
19
|
+
matched = labels.any? { |range, _| range.cover?(val) }
|
|
20
|
+
expect(matched).to be(true), "Expected #{val} to match a label range"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'has all expected SIGNIFICANCE_LABELS values' do
|
|
25
|
+
values = described_class::SIGNIFICANCE_LABELS.values
|
|
26
|
+
expect(values).to contain_exactly(:pivotal, :important, :routine, :minor)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Episode do
|
|
4
|
+
let(:episode) do
|
|
5
|
+
described_class.new(
|
|
6
|
+
description: 'learned to handle context switches',
|
|
7
|
+
episode_type: :insight,
|
|
8
|
+
domain: :cognition,
|
|
9
|
+
emotional_valence: 0.6,
|
|
10
|
+
tags: %i[learning context performance]
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe '#initialize' do
|
|
15
|
+
it 'sets description and type' do
|
|
16
|
+
expect(episode.description).to eq('learned to handle context switches')
|
|
17
|
+
expect(episode.episode_type).to eq(:insight)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'sets domain' do
|
|
21
|
+
expect(episode.domain).to eq(:cognition)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'starts with default significance' do
|
|
25
|
+
plain = described_class.new(description: 'test')
|
|
26
|
+
expect(plain.significance).to eq(Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Constants::DEFAULT_SIGNIFICANCE)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'clamps emotional valence to [-1, 1]' do
|
|
30
|
+
extreme = described_class.new(description: 'extreme', emotional_valence: 5.0)
|
|
31
|
+
expect(extreme.emotional_valence).to eq(1.0)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'has a UUID id' do
|
|
35
|
+
expect(episode.id).to match(/\A[0-9a-f-]{36}\z/)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'stores tags' do
|
|
39
|
+
expect(episode.tags).to eq(%i[learning context performance])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'starts with empty thread_ids' do
|
|
43
|
+
expect(episode.thread_ids).to be_empty
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#boost' do
|
|
48
|
+
it 'increases significance' do
|
|
49
|
+
initial = episode.significance
|
|
50
|
+
episode.boost(0.1)
|
|
51
|
+
expect(episode.significance).to be > initial
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'includes emotional factor' do
|
|
55
|
+
low_emotion = described_class.new(description: 'calm', emotional_valence: 0.0)
|
|
56
|
+
high_emotion = described_class.new(description: 'excited', emotional_valence: 0.9)
|
|
57
|
+
low_emotion.boost(0.1)
|
|
58
|
+
high_emotion.boost(0.1)
|
|
59
|
+
expect(high_emotion.significance).to be > low_emotion.significance
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'caps at 1.0' do
|
|
63
|
+
10.times { episode.boost(0.5) }
|
|
64
|
+
expect(episode.significance).to be <= 1.0
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe '#decay' do
|
|
69
|
+
it 'decreases significance' do
|
|
70
|
+
initial = episode.significance
|
|
71
|
+
episode.decay
|
|
72
|
+
expect(episode.significance).to be < initial
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'does not go below zero' do
|
|
76
|
+
200.times { episode.decay }
|
|
77
|
+
expect(episode.significance).to be >= 0.0
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe '#faded?' do
|
|
82
|
+
it 'is not faded when fresh' do
|
|
83
|
+
expect(episode.faded?).to be false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'becomes faded after heavy decay' do
|
|
87
|
+
200.times { episode.decay }
|
|
88
|
+
expect(episode.faded?).to be true
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe '#label' do
|
|
93
|
+
it 'returns a symbol' do
|
|
94
|
+
expect(episode.label).to be_a(Symbol)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'returns :minor for low significance' do
|
|
98
|
+
200.times { episode.decay }
|
|
99
|
+
expect(episode.label).to eq(:minor)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe '#link_thread' do
|
|
104
|
+
it 'adds a thread id' do
|
|
105
|
+
episode.link_thread('thread-1')
|
|
106
|
+
expect(episode.thread_ids).to include('thread-1')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'does not duplicate' do
|
|
110
|
+
episode.link_thread('thread-1')
|
|
111
|
+
episode.link_thread('thread-1')
|
|
112
|
+
expect(episode.thread_ids.count('thread-1')).to eq(1)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe '#matches_tags?' do
|
|
117
|
+
it 'returns match ratio for overlapping tags' do
|
|
118
|
+
score = episode.matches_tags?(%i[learning performance])
|
|
119
|
+
expect(score).to be_within(0.01).of(2.0 / 2.0)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it 'returns 0.0 for no overlap' do
|
|
123
|
+
expect(episode.matches_tags?(%i[sleep eat])).to eq(0.0)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'returns 0.0 for empty input' do
|
|
127
|
+
expect(episode.matches_tags?([])).to be_falsey
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe '#to_h' do
|
|
132
|
+
it 'contains all expected keys' do
|
|
133
|
+
h = episode.to_h
|
|
134
|
+
expect(h).to have_key(:id)
|
|
135
|
+
expect(h).to have_key(:description)
|
|
136
|
+
expect(h).to have_key(:episode_type)
|
|
137
|
+
expect(h).to have_key(:significance)
|
|
138
|
+
expect(h).to have_key(:emotional_valence)
|
|
139
|
+
expect(h).to have_key(:label)
|
|
140
|
+
expect(h).to have_key(:tags)
|
|
141
|
+
expect(h).to have_key(:thread_ids)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::NarrativeThread do
|
|
4
|
+
let(:thread) { described_class.new(theme: :growth, domain: :cognition) }
|
|
5
|
+
|
|
6
|
+
describe '#initialize' do
|
|
7
|
+
it 'sets theme and domain' do
|
|
8
|
+
expect(thread.theme).to eq(:growth)
|
|
9
|
+
expect(thread.domain).to eq(:cognition)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'starts with strength 0.5' do
|
|
13
|
+
expect(thread.strength).to eq(0.5)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'starts with empty episode_ids' do
|
|
17
|
+
expect(thread.episode_ids).to be_empty
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'has a UUID id' do
|
|
21
|
+
expect(thread.id).to match(/\A[0-9a-f-]{36}\z/)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe '#add_episode' do
|
|
26
|
+
it 'adds an episode id' do
|
|
27
|
+
thread.add_episode('ep-1')
|
|
28
|
+
expect(thread.episode_ids).to include('ep-1')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'does not duplicate' do
|
|
32
|
+
thread.add_episode('ep-1')
|
|
33
|
+
thread.add_episode('ep-1')
|
|
34
|
+
expect(thread.episode_ids.count('ep-1')).to eq(1)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'caps at MAX_CHAPTER_SIZE' do
|
|
38
|
+
max = Legion::Extensions::Agentic::Self::NarrativeSelf::Helpers::Constants::MAX_CHAPTER_SIZE
|
|
39
|
+
(max + 5).times { |i| thread.add_episode("ep-#{i}") }
|
|
40
|
+
expect(thread.episode_ids.size).to eq(max)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'reinforces the thread' do
|
|
44
|
+
initial = thread.strength
|
|
45
|
+
thread.add_episode('ep-1')
|
|
46
|
+
expect(thread.strength).to be > initial
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe '#decay' do
|
|
51
|
+
it 'reduces strength' do
|
|
52
|
+
initial = thread.strength
|
|
53
|
+
thread.decay
|
|
54
|
+
expect(thread.strength).to be < initial
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe '#weak?' do
|
|
59
|
+
it 'is not weak when fresh' do
|
|
60
|
+
expect(thread.weak?).to be false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'becomes weak after heavy decay' do
|
|
64
|
+
100.times { thread.decay }
|
|
65
|
+
expect(thread.weak?).to be true
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe '#size' do
|
|
70
|
+
it 'returns the episode count' do
|
|
71
|
+
thread.add_episode('ep-1')
|
|
72
|
+
thread.add_episode('ep-2')
|
|
73
|
+
expect(thread.size).to eq(2)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe '#to_h' do
|
|
78
|
+
it 'contains expected keys' do
|
|
79
|
+
h = thread.to_h
|
|
80
|
+
expect(h).to have_key(:id)
|
|
81
|
+
expect(h).to have_key(:theme)
|
|
82
|
+
expect(h).to have_key(:domain)
|
|
83
|
+
expect(h).to have_key(:strength)
|
|
84
|
+
expect(h).to have_key(:episodes)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::NarrativeSelf::Runners::NarrativeSelf do
|
|
4
|
+
let(:client) { Legion::Extensions::Agentic::Self::NarrativeSelf::Client.new }
|
|
5
|
+
|
|
6
|
+
describe '#record_episode' do
|
|
7
|
+
it 'returns success with episode data' do
|
|
8
|
+
result = client.record_episode(description: 'completed first build', episode_type: :achievement)
|
|
9
|
+
expect(result[:success]).to be true
|
|
10
|
+
expect(result[:episode][:description]).to eq('completed first build')
|
|
11
|
+
expect(result[:episode][:episode_type]).to eq(:achievement)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#recent_episodes' do
|
|
16
|
+
before do
|
|
17
|
+
3.times { |i| client.record_episode(description: "event #{i}") }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'returns recent episodes' do
|
|
21
|
+
result = client.recent_episodes(count: 2)
|
|
22
|
+
expect(result[:success]).to be true
|
|
23
|
+
expect(result[:count]).to eq(2)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe '#significant_episodes' do
|
|
28
|
+
before do
|
|
29
|
+
client.record_episode(description: 'major', significance: 0.9)
|
|
30
|
+
client.record_episode(description: 'minor', significance: 0.1)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'filters by significance' do
|
|
34
|
+
result = client.significant_episodes(min_significance: 0.5)
|
|
35
|
+
expect(result[:count]).to eq(1)
|
|
36
|
+
expect(result[:episodes].first[:description]).to eq('major')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe '#episodes_by_type' do
|
|
41
|
+
before do
|
|
42
|
+
client.record_episode(description: 'win', episode_type: :achievement)
|
|
43
|
+
client.record_episode(description: 'learn', episode_type: :insight)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'filters by type' do
|
|
47
|
+
result = client.episodes_by_type(episode_type: :achievement)
|
|
48
|
+
expect(result[:count]).to eq(1)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe '#create_thread' do
|
|
53
|
+
it 'returns success with thread data' do
|
|
54
|
+
result = client.create_thread(theme: :growth, domain: :personal)
|
|
55
|
+
expect(result[:success]).to be true
|
|
56
|
+
expect(result[:thread][:theme]).to eq(:growth)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe '#strongest_threads' do
|
|
61
|
+
before do
|
|
62
|
+
client.create_thread(theme: :growth)
|
|
63
|
+
client.create_thread(theme: :mastery)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'returns threads sorted by strength' do
|
|
67
|
+
result = client.strongest_threads(count: 2)
|
|
68
|
+
expect(result[:success]).to be true
|
|
69
|
+
expect(result[:count]).to eq(2)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe '#timeline' do
|
|
74
|
+
before do
|
|
75
|
+
3.times { |i| client.record_episode(description: "event #{i}") }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'returns timeline entries' do
|
|
79
|
+
result = client.timeline(window: 10)
|
|
80
|
+
expect(result[:success]).to be true
|
|
81
|
+
expect(result[:count]).to eq(3)
|
|
82
|
+
expect(result[:timeline].first).to be_a(Hash)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe '#self_summary' do
|
|
87
|
+
before do
|
|
88
|
+
client.record_episode(description: 'a', episode_type: :achievement, domain: :tech)
|
|
89
|
+
client.record_episode(description: 'b', episode_type: :insight, domain: :personal)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'returns comprehensive summary' do
|
|
93
|
+
result = client.self_summary
|
|
94
|
+
expect(result[:success]).to be true
|
|
95
|
+
expect(result[:summary][:total_episodes]).to eq(2)
|
|
96
|
+
expect(result[:summary]).to have_key(:narrative_richness)
|
|
97
|
+
expect(result[:summary]).to have_key(:self_concept)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe '#update_narrative_self' do
|
|
102
|
+
it 'decays and reports counts' do
|
|
103
|
+
client.record_episode(description: 'test')
|
|
104
|
+
result = client.update_narrative_self
|
|
105
|
+
expect(result[:success]).to be true
|
|
106
|
+
expect(result[:episode_count]).to eq(1)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#narrative_self_stats' do
|
|
111
|
+
it 'returns stats' do
|
|
112
|
+
result = client.narrative_self_stats
|
|
113
|
+
expect(result[:success]).to be true
|
|
114
|
+
expect(result[:stats]).to have_key(:episode_count)
|
|
115
|
+
expect(result[:stats]).to have_key(:thread_count)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::Personality::Client do
|
|
4
|
+
it 'creates default personality store' do
|
|
5
|
+
client = described_class.new
|
|
6
|
+
expect(client.personality_store).to be_a(Legion::Extensions::Agentic::Self::Personality::Helpers::PersonalityStore)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'accepts injected personality store' do
|
|
10
|
+
store = Legion::Extensions::Agentic::Self::Personality::Helpers::PersonalityStore.new
|
|
11
|
+
client = described_class.new(personality_store: store)
|
|
12
|
+
expect(client.personality_store).to equal(store)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'includes Personality runner methods' do
|
|
16
|
+
client = described_class.new
|
|
17
|
+
expect(client).to respond_to(:update_personality, :personality_profile,
|
|
18
|
+
:describe_personality, :personality_stats)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::Personality::Helpers::Constants do
|
|
4
|
+
it 'defines 5 traits (OCEAN)' do
|
|
5
|
+
expect(described_class::TRAITS.size).to eq(5)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'includes all Big Five traits' do
|
|
9
|
+
expect(described_class::TRAITS).to contain_exactly(
|
|
10
|
+
:openness, :conscientiousness, :extraversion, :agreeableness, :neuroticism
|
|
11
|
+
)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'has default trait value of 0.5' do
|
|
15
|
+
expect(described_class::DEFAULT_TRAIT_VALUE).to eq(0.5)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'has a very low trait alpha for stability' do
|
|
19
|
+
expect(described_class::TRAIT_ALPHA).to be < 0.1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'defines descriptors for every trait' do
|
|
23
|
+
described_class::TRAITS.each do |trait|
|
|
24
|
+
expect(described_class::TRAIT_DESCRIPTORS).to have_key(trait)
|
|
25
|
+
expect(described_class::TRAIT_DESCRIPTORS[trait]).to include(:high, :mid, :low)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'maps signals to traits' do
|
|
30
|
+
expect(described_class::SIGNAL_MAP).not_to be_empty
|
|
31
|
+
described_class::SIGNAL_MAP.each_value do |trait, direction, weight|
|
|
32
|
+
expect(described_class::TRAITS).to include(trait)
|
|
33
|
+
expect(%i[positive negative]).to include(direction)
|
|
34
|
+
expect(weight).to be_between(0.0, 1.0)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'has HIGH_THRESHOLD > LOW_THRESHOLD' do
|
|
39
|
+
expect(described_class::HIGH_THRESHOLD).to be > described_class::LOW_THRESHOLD
|
|
40
|
+
end
|
|
41
|
+
end
|