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,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module Personality
|
|
8
|
+
module Runners
|
|
9
|
+
module Personality
|
|
10
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers::Lex)
|
|
11
|
+
|
|
12
|
+
def update_personality(tick_results: {}, **)
|
|
13
|
+
personality_store.update(tick_results)
|
|
14
|
+
model = personality_store.model
|
|
15
|
+
|
|
16
|
+
{
|
|
17
|
+
updated: true,
|
|
18
|
+
observation_count: model.observation_count,
|
|
19
|
+
formed: model.formed?,
|
|
20
|
+
profile: model.profile,
|
|
21
|
+
dominant_trait: model.dominant_trait
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def personality_profile(**)
|
|
26
|
+
model = personality_store.model
|
|
27
|
+
{
|
|
28
|
+
traits: model.profile,
|
|
29
|
+
formed: model.formed?,
|
|
30
|
+
stability: model.stability,
|
|
31
|
+
dominant: model.dominant_trait,
|
|
32
|
+
observations: model.observation_count,
|
|
33
|
+
history_size: model.history.size
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def describe_personality(**)
|
|
38
|
+
{
|
|
39
|
+
description: personality_store.full_description,
|
|
40
|
+
formed: personality_store.model.formed?
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def trait_detail(trait:, **)
|
|
45
|
+
model = personality_store.model
|
|
46
|
+
value = model.trait(trait)
|
|
47
|
+
return { trait: trait.to_sym, error: :unknown_trait } unless value
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
trait: trait.to_sym,
|
|
51
|
+
value: value.round(3),
|
|
52
|
+
level: model.trait_level(trait),
|
|
53
|
+
description: model.describe(trait),
|
|
54
|
+
trend: model.trend(trait)
|
|
55
|
+
}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def personality_compatibility(other_profile:, **)
|
|
59
|
+
score = personality_store.compatibility_score(other_profile)
|
|
60
|
+
{
|
|
61
|
+
compatibility: score,
|
|
62
|
+
interpretation: interpret_compatibility(score)
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def personality_stats(**)
|
|
67
|
+
model = personality_store.model
|
|
68
|
+
{
|
|
69
|
+
observation_count: model.observation_count,
|
|
70
|
+
formed: model.formed?,
|
|
71
|
+
stability: model.stability,
|
|
72
|
+
dominant_trait: model.dominant_trait,
|
|
73
|
+
profile: model.profile,
|
|
74
|
+
history_size: model.history.size,
|
|
75
|
+
trait_trends: Helpers::Constants::TRAITS.to_h { |t| [t, model.trend(t)] }
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def interpret_compatibility(score)
|
|
82
|
+
return :unknown unless score.is_a?(Numeric)
|
|
83
|
+
|
|
84
|
+
if score >= 0.85
|
|
85
|
+
:highly_compatible
|
|
86
|
+
elsif score >= 0.7
|
|
87
|
+
:compatible
|
|
88
|
+
elsif score >= 0.5
|
|
89
|
+
:neutral
|
|
90
|
+
elsif score >= 0.3
|
|
91
|
+
:divergent
|
|
92
|
+
else
|
|
93
|
+
:incompatible
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'personality/version'
|
|
4
|
+
require_relative 'personality/helpers/constants'
|
|
5
|
+
require_relative 'personality/helpers/trait_model'
|
|
6
|
+
require_relative 'personality/helpers/personality_store'
|
|
7
|
+
require_relative 'personality/runners/personality'
|
|
8
|
+
require_relative 'personality/client'
|
|
9
|
+
|
|
10
|
+
module Legion
|
|
11
|
+
module Extensions
|
|
12
|
+
module Agentic
|
|
13
|
+
module Self
|
|
14
|
+
module Personality
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/agentic/self/reflection/helpers/constants'
|
|
4
|
+
require 'legion/extensions/agentic/self/reflection/helpers/reflection'
|
|
5
|
+
require 'legion/extensions/agentic/self/reflection/helpers/reflection_store'
|
|
6
|
+
require 'legion/extensions/agentic/self/reflection/helpers/monitors'
|
|
7
|
+
require 'legion/extensions/agentic/self/reflection/runners/reflection'
|
|
8
|
+
|
|
9
|
+
module Legion
|
|
10
|
+
module Extensions
|
|
11
|
+
module Agentic
|
|
12
|
+
module Self
|
|
13
|
+
module Reflection
|
|
14
|
+
class Client
|
|
15
|
+
include Runners::Reflection
|
|
16
|
+
|
|
17
|
+
attr_reader :reflection_store
|
|
18
|
+
|
|
19
|
+
def initialize(store: nil, **)
|
|
20
|
+
@reflection_store = store || Helpers::ReflectionStore.new
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module Reflection
|
|
8
|
+
module Helpers
|
|
9
|
+
module Constants
|
|
10
|
+
CATEGORIES = %i[
|
|
11
|
+
prediction_calibration
|
|
12
|
+
curiosity_effectiveness
|
|
13
|
+
emotional_stability
|
|
14
|
+
trust_drift
|
|
15
|
+
memory_health
|
|
16
|
+
cognitive_load
|
|
17
|
+
mode_patterns
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
SEVERITIES = %i[trivial notable significant critical].freeze
|
|
21
|
+
|
|
22
|
+
RECOMMENDATIONS = %i[
|
|
23
|
+
increase_curiosity
|
|
24
|
+
decrease_curiosity
|
|
25
|
+
stabilize_emotion
|
|
26
|
+
rebuild_trust
|
|
27
|
+
consolidate_memory
|
|
28
|
+
reduce_load
|
|
29
|
+
celebrate_success
|
|
30
|
+
investigate
|
|
31
|
+
no_action
|
|
32
|
+
].freeze
|
|
33
|
+
|
|
34
|
+
# Thresholds for monitor triggers
|
|
35
|
+
PREDICTION_ACCURACY_LOW = 0.4
|
|
36
|
+
PREDICTION_ACCURACY_DROP = 0.2
|
|
37
|
+
CURIOSITY_RESOLUTION_LOW = 0.2
|
|
38
|
+
CURIOSITY_RESOLUTION_HIGH = 0.8
|
|
39
|
+
EMOTION_INSTABILITY_THRESHOLD = 0.3
|
|
40
|
+
EMOTION_FLATNESS_THRESHOLD = 0.05
|
|
41
|
+
TRUST_DROP_THRESHOLD = 0.15
|
|
42
|
+
MEMORY_DECAY_RATIO_HIGH = 0.8
|
|
43
|
+
BUDGET_OVER_THRESHOLD = 0.9
|
|
44
|
+
MODE_OSCILLATION_THRESHOLD = 5
|
|
45
|
+
|
|
46
|
+
# Rolling window for metrics
|
|
47
|
+
METRIC_WINDOW_SIZE = 20
|
|
48
|
+
|
|
49
|
+
# Health score weights
|
|
50
|
+
HEALTH_WEIGHTS = {
|
|
51
|
+
prediction_calibration: 0.25,
|
|
52
|
+
curiosity_effectiveness: 0.15,
|
|
53
|
+
emotional_stability: 0.15,
|
|
54
|
+
trust_drift: 0.15,
|
|
55
|
+
memory_health: 0.15,
|
|
56
|
+
cognitive_load: 0.15
|
|
57
|
+
}.freeze
|
|
58
|
+
|
|
59
|
+
MAX_REFLECTIONS = 100
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module Reflection
|
|
8
|
+
module Helpers
|
|
9
|
+
module LlmEnhancer
|
|
10
|
+
SYSTEM_PROMPT = <<~PROMPT
|
|
11
|
+
You are the metacognitive reflection engine for an autonomous AI agent built on LegionIO.
|
|
12
|
+
You analyze post-tick cognitive metrics and produce insightful observations.
|
|
13
|
+
Be analytical and specific. Reference the actual numbers. Identify correlations between metrics.
|
|
14
|
+
Write as internal reflection, not a report. Present tense, first person.
|
|
15
|
+
PROMPT
|
|
16
|
+
|
|
17
|
+
# Maps prompt label -> actual category symbol from Constants::CATEGORIES
|
|
18
|
+
CATEGORY_LABEL_MAP = {
|
|
19
|
+
'EMOTION' => :emotional_stability,
|
|
20
|
+
'PREDICTION' => :prediction_calibration,
|
|
21
|
+
'MEMORY' => :memory_health,
|
|
22
|
+
'TRUST' => :trust_drift,
|
|
23
|
+
'CURIOSITY' => :curiosity_effectiveness,
|
|
24
|
+
'IDENTITY' => :mode_patterns
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
REFLECTION_CATEGORIES = CATEGORY_LABEL_MAP.keys.freeze
|
|
28
|
+
|
|
29
|
+
module_function
|
|
30
|
+
|
|
31
|
+
def available?
|
|
32
|
+
defined?(Legion::LLM) && Legion::LLM.respond_to?(:started?) && Legion::LLM.started?
|
|
33
|
+
rescue StandardError
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def enhance_reflection(monitors_data:, health_scores:)
|
|
38
|
+
prompt = build_enhance_reflection_prompt(monitors_data: monitors_data, health_scores: health_scores)
|
|
39
|
+
response = llm_ask(prompt)
|
|
40
|
+
parse_enhance_reflection_response(response)
|
|
41
|
+
rescue StandardError => e
|
|
42
|
+
Legion::Logging.warn "[reflection:llm] enhance_reflection failed: #{e.message}"
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def reflect_on_dream(dream_results:)
|
|
47
|
+
prompt = build_reflect_on_dream_prompt(dream_results: dream_results)
|
|
48
|
+
response = llm_ask(prompt)
|
|
49
|
+
parse_reflect_on_dream_response(response)
|
|
50
|
+
rescue StandardError => e
|
|
51
|
+
Legion::Logging.warn "[reflection:llm] reflect_on_dream failed: #{e.message}"
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# --- Private helpers ---
|
|
56
|
+
|
|
57
|
+
def llm_ask(prompt)
|
|
58
|
+
chat = Legion::LLM.chat
|
|
59
|
+
chat.with_instructions(SYSTEM_PROMPT)
|
|
60
|
+
chat.ask(prompt)
|
|
61
|
+
end
|
|
62
|
+
private_class_method :llm_ask
|
|
63
|
+
|
|
64
|
+
def build_enhance_reflection_prompt(monitors_data:, health_scores:)
|
|
65
|
+
metrics_lines = format_monitors_data(monitors_data)
|
|
66
|
+
health_lines = health_scores.map { |cat, score| "#{cat}: #{score.round(3)}" }.join("\n")
|
|
67
|
+
|
|
68
|
+
<<~PROMPT
|
|
69
|
+
Analyze these post-tick cognitive metrics and generate insightful observations.
|
|
70
|
+
|
|
71
|
+
METRICS:
|
|
72
|
+
#{metrics_lines}
|
|
73
|
+
|
|
74
|
+
HEALTH SCORES:
|
|
75
|
+
#{health_lines}
|
|
76
|
+
|
|
77
|
+
For each category, write 1-2 sentences of genuine analytical observation.
|
|
78
|
+
Look for correlations between categories. Note concerning or interesting patterns.
|
|
79
|
+
|
|
80
|
+
Format EXACTLY as (one line per category):
|
|
81
|
+
EMOTION: <observation>
|
|
82
|
+
PREDICTION: <observation>
|
|
83
|
+
MEMORY: <observation>
|
|
84
|
+
TRUST: <observation>
|
|
85
|
+
CURIOSITY: <observation>
|
|
86
|
+
IDENTITY: <observation>
|
|
87
|
+
PROMPT
|
|
88
|
+
end
|
|
89
|
+
private_class_method :build_enhance_reflection_prompt
|
|
90
|
+
|
|
91
|
+
def format_monitors_data(monitors_data)
|
|
92
|
+
return '' unless monitors_data.is_a?(Array)
|
|
93
|
+
|
|
94
|
+
monitors_data.filter_map do |entry|
|
|
95
|
+
next unless entry.is_a?(Hash) && entry[:category]
|
|
96
|
+
|
|
97
|
+
metrics = entry[:metrics]
|
|
98
|
+
if metrics.is_a?(Hash) && metrics.any?
|
|
99
|
+
metric_str = metrics.map { |k, v| "#{k}=#{v.is_a?(Float) ? v.round(3) : v}" }.join(', ')
|
|
100
|
+
"#{entry[:category].to_s.upcase}: #{metric_str}"
|
|
101
|
+
else
|
|
102
|
+
entry[:category].to_s.upcase
|
|
103
|
+
end
|
|
104
|
+
end.join("\n")
|
|
105
|
+
end
|
|
106
|
+
private_class_method :format_monitors_data
|
|
107
|
+
|
|
108
|
+
def parse_enhance_reflection_response(response)
|
|
109
|
+
return nil unless response&.content
|
|
110
|
+
|
|
111
|
+
observations = {}
|
|
112
|
+
CATEGORY_LABEL_MAP.each do |label, category_sym|
|
|
113
|
+
match = response.content.match(/^#{label}:\s*(.+)$/i)
|
|
114
|
+
observations[category_sym] = match.captures.first.strip if match
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
observations.empty? ? nil : { observations: observations }
|
|
118
|
+
end
|
|
119
|
+
private_class_method :parse_enhance_reflection_response
|
|
120
|
+
|
|
121
|
+
def build_reflect_on_dream_prompt(dream_results:)
|
|
122
|
+
summary = format_dream_results(dream_results)
|
|
123
|
+
|
|
124
|
+
<<~PROMPT
|
|
125
|
+
Reflect on the completed dream cycle and its cognitive significance.
|
|
126
|
+
|
|
127
|
+
DREAM CYCLE RESULTS:
|
|
128
|
+
#{summary}
|
|
129
|
+
|
|
130
|
+
Generate a first-person, present-tense reflection on what emerged from this dream cycle.
|
|
131
|
+
Be specific about patterns, consolidations, and what needs attention.
|
|
132
|
+
|
|
133
|
+
Format EXACTLY as:
|
|
134
|
+
REFLECTION: <2-4 sentences of internal reflection>
|
|
135
|
+
PROMPT
|
|
136
|
+
end
|
|
137
|
+
private_class_method :build_reflect_on_dream_prompt
|
|
138
|
+
|
|
139
|
+
def format_dream_results(dream_results)
|
|
140
|
+
return 'no results' unless dream_results.is_a?(Hash) && dream_results.any?
|
|
141
|
+
|
|
142
|
+
dream_results.map do |phase, result|
|
|
143
|
+
next unless result.is_a?(Hash)
|
|
144
|
+
|
|
145
|
+
summary = result.except(:error).map { |k, v| "#{k}=#{v}" }.first(4).join(', ')
|
|
146
|
+
"#{phase}: #{summary}"
|
|
147
|
+
end.compact.join("\n")
|
|
148
|
+
end
|
|
149
|
+
private_class_method :format_dream_results
|
|
150
|
+
|
|
151
|
+
def parse_reflect_on_dream_response(response)
|
|
152
|
+
return nil unless response&.content
|
|
153
|
+
|
|
154
|
+
match = response.content.match(/REFLECTION:\s*(.+)/im)
|
|
155
|
+
return nil unless match
|
|
156
|
+
|
|
157
|
+
{ reflection: match.captures.first.strip }
|
|
158
|
+
end
|
|
159
|
+
private_class_method :parse_reflect_on_dream_response
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module Reflection
|
|
8
|
+
module Helpers
|
|
9
|
+
module Monitors
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def run_all(tick_results, metric_history)
|
|
13
|
+
reflections = []
|
|
14
|
+
reflections.concat(monitor_predictions(tick_results, metric_history))
|
|
15
|
+
reflections.concat(monitor_curiosity(tick_results))
|
|
16
|
+
reflections.concat(monitor_emotions(tick_results))
|
|
17
|
+
reflections.concat(monitor_trust(tick_results, metric_history))
|
|
18
|
+
reflections.concat(monitor_memory(tick_results))
|
|
19
|
+
reflections.concat(monitor_cognitive_load(tick_results))
|
|
20
|
+
reflections
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def monitor_predictions(tick_results, history)
|
|
24
|
+
prediction = tick_results[:prediction_engine]
|
|
25
|
+
return [] unless prediction.is_a?(Hash)
|
|
26
|
+
|
|
27
|
+
reflections = []
|
|
28
|
+
confidence = prediction[:confidence]
|
|
29
|
+
|
|
30
|
+
if confidence.is_a?(Numeric) && confidence < Constants::PREDICTION_ACCURACY_LOW
|
|
31
|
+
reflections << ReflectionFactory.new_reflection(
|
|
32
|
+
category: :prediction_calibration,
|
|
33
|
+
observation: "Prediction confidence is low at #{(confidence * 100).round}%",
|
|
34
|
+
severity: ReflectionFactory.severity_for_drop(1.0 - confidence),
|
|
35
|
+
metrics: { confidence: confidence },
|
|
36
|
+
recommendation: :increase_curiosity
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
reflections.concat(detect_accuracy_trend(history))
|
|
41
|
+
reflections
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def monitor_curiosity(tick_results)
|
|
45
|
+
curiosity = tick_results[:working_memory_integration]
|
|
46
|
+
return [] unless curiosity.is_a?(Hash)
|
|
47
|
+
|
|
48
|
+
reflections = []
|
|
49
|
+
|
|
50
|
+
resolution_rate = curiosity[:resolution_rate] if curiosity.key?(:resolution_rate)
|
|
51
|
+
if resolution_rate.is_a?(Numeric)
|
|
52
|
+
if resolution_rate < Constants::CURIOSITY_RESOLUTION_LOW
|
|
53
|
+
reflections << ReflectionFactory.new_reflection(
|
|
54
|
+
category: :curiosity_effectiveness,
|
|
55
|
+
observation: "Curiosity resolution rate is low at #{(resolution_rate * 100).round}%",
|
|
56
|
+
severity: :notable,
|
|
57
|
+
metrics: { resolution_rate: resolution_rate },
|
|
58
|
+
recommendation: :decrease_curiosity
|
|
59
|
+
)
|
|
60
|
+
elsif resolution_rate > Constants::CURIOSITY_RESOLUTION_HIGH
|
|
61
|
+
reflections << ReflectionFactory.new_reflection(
|
|
62
|
+
category: :curiosity_effectiveness,
|
|
63
|
+
observation: "Curiosity resolution rate is excellent at #{(resolution_rate * 100).round}%",
|
|
64
|
+
severity: :trivial,
|
|
65
|
+
metrics: { resolution_rate: resolution_rate },
|
|
66
|
+
recommendation: :celebrate_success
|
|
67
|
+
)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
reflections
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def monitor_emotions(tick_results)
|
|
75
|
+
emotion = tick_results[:emotional_evaluation]
|
|
76
|
+
return [] unless emotion.is_a?(Hash)
|
|
77
|
+
|
|
78
|
+
reflections = []
|
|
79
|
+
stability = emotion[:stability] || emotion.dig(:momentum, :stability)
|
|
80
|
+
|
|
81
|
+
if stability.is_a?(Numeric)
|
|
82
|
+
if stability < Constants::EMOTION_INSTABILITY_THRESHOLD
|
|
83
|
+
reflections << ReflectionFactory.new_reflection(
|
|
84
|
+
category: :emotional_stability,
|
|
85
|
+
observation: "Emotional state is unstable (stability: #{stability.round(2)})",
|
|
86
|
+
severity: :significant,
|
|
87
|
+
metrics: { stability: stability },
|
|
88
|
+
recommendation: :stabilize_emotion
|
|
89
|
+
)
|
|
90
|
+
elsif stability > (1.0 - Constants::EMOTION_FLATNESS_THRESHOLD)
|
|
91
|
+
reflections << ReflectionFactory.new_reflection(
|
|
92
|
+
category: :emotional_stability,
|
|
93
|
+
observation: 'Emotional state is unusually flat — possible disengagement',
|
|
94
|
+
severity: :notable,
|
|
95
|
+
metrics: { stability: stability },
|
|
96
|
+
recommendation: :investigate
|
|
97
|
+
)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
reflections
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def monitor_trust(tick_results, history)
|
|
105
|
+
trust = tick_results[:action_selection]
|
|
106
|
+
return [] unless trust.is_a?(Hash) && trust[:trust_score].is_a?(Numeric)
|
|
107
|
+
|
|
108
|
+
trust_scores = history.filter_map { |h| h.dig(:action_selection, :trust_score) }
|
|
109
|
+
return [] if trust_scores.size < 3
|
|
110
|
+
|
|
111
|
+
recent_avg = trust_scores.last(5).sum / trust_scores.last(5).size.to_f
|
|
112
|
+
older_avg = trust_scores.first(5).sum / trust_scores.first(5).size.to_f
|
|
113
|
+
drop = older_avg - recent_avg
|
|
114
|
+
|
|
115
|
+
return [] unless drop > Constants::TRUST_DROP_THRESHOLD
|
|
116
|
+
|
|
117
|
+
[ReflectionFactory.new_reflection(
|
|
118
|
+
category: :trust_drift,
|
|
119
|
+
observation: "Trust scores have dropped by #{(drop * 100).round}% recently",
|
|
120
|
+
severity: ReflectionFactory.severity_for_drop(drop),
|
|
121
|
+
metrics: { drop: drop, recent_avg: recent_avg, older_avg: older_avg },
|
|
122
|
+
recommendation: :rebuild_trust
|
|
123
|
+
)]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def monitor_memory(tick_results)
|
|
127
|
+
memory = tick_results[:memory_consolidation]
|
|
128
|
+
return [] unless memory.is_a?(Hash)
|
|
129
|
+
|
|
130
|
+
pruned = memory[:pruned] || 0
|
|
131
|
+
total = memory[:total] || 1
|
|
132
|
+
ratio = pruned.to_f / [total, 1].max
|
|
133
|
+
|
|
134
|
+
return [] unless ratio > Constants::MEMORY_DECAY_RATIO_HIGH
|
|
135
|
+
|
|
136
|
+
[ReflectionFactory.new_reflection(
|
|
137
|
+
category: :memory_health,
|
|
138
|
+
observation: "High memory decay ratio: #{(ratio * 100).round}% of traces pruned",
|
|
139
|
+
severity: :significant,
|
|
140
|
+
metrics: { pruned: pruned, total: total, ratio: ratio },
|
|
141
|
+
recommendation: :consolidate_memory
|
|
142
|
+
)]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def monitor_cognitive_load(tick_results)
|
|
146
|
+
elapsed = tick_results[:elapsed]
|
|
147
|
+
budget = tick_results[:budget]
|
|
148
|
+
return [] unless elapsed.is_a?(Numeric) && budget.is_a?(Numeric) && budget.positive?
|
|
149
|
+
|
|
150
|
+
utilization = elapsed / budget
|
|
151
|
+
return [] unless utilization > Constants::BUDGET_OVER_THRESHOLD
|
|
152
|
+
|
|
153
|
+
[ReflectionFactory.new_reflection(
|
|
154
|
+
category: :cognitive_load,
|
|
155
|
+
observation: "Tick budget utilization at #{(utilization * 100).round}%",
|
|
156
|
+
severity: utilization > 1.0 ? :significant : :notable,
|
|
157
|
+
metrics: { utilization: utilization, elapsed: elapsed, budget: budget },
|
|
158
|
+
recommendation: :reduce_load
|
|
159
|
+
)]
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def detect_accuracy_trend(history)
|
|
163
|
+
accuracies = history.filter_map { |h| h.dig(:prediction_engine, :confidence) }
|
|
164
|
+
return [] if accuracies.size < 5
|
|
165
|
+
|
|
166
|
+
recent = accuracies.last(5).sum / 5.0
|
|
167
|
+
older = accuracies.first(5).sum / 5.0
|
|
168
|
+
drop = older - recent
|
|
169
|
+
|
|
170
|
+
return [] unless drop > Constants::PREDICTION_ACCURACY_DROP
|
|
171
|
+
|
|
172
|
+
[ReflectionFactory.new_reflection(
|
|
173
|
+
category: :prediction_calibration,
|
|
174
|
+
observation: "Prediction accuracy trending down: #{(older * 100).round}% -> #{(recent * 100).round}%",
|
|
175
|
+
severity: ReflectionFactory.severity_for_drop(drop),
|
|
176
|
+
metrics: { trend_drop: drop, recent_avg: recent, older_avg: older },
|
|
177
|
+
recommendation: :increase_curiosity
|
|
178
|
+
)]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Agentic
|
|
8
|
+
module Self
|
|
9
|
+
module Reflection
|
|
10
|
+
module Helpers
|
|
11
|
+
module ReflectionFactory
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def new_reflection(category:, observation:, severity: :notable,
|
|
15
|
+
metrics: {}, recommendation: :no_action)
|
|
16
|
+
raise ArgumentError, "invalid category: #{category}" unless Constants::CATEGORIES.include?(category)
|
|
17
|
+
raise ArgumentError, "invalid severity: #{severity}" unless Constants::SEVERITIES.include?(severity)
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
reflection_id: SecureRandom.uuid,
|
|
21
|
+
category: category,
|
|
22
|
+
observation: observation,
|
|
23
|
+
severity: severity,
|
|
24
|
+
metrics: metrics,
|
|
25
|
+
recommendation: recommendation,
|
|
26
|
+
created_at: Time.now.utc,
|
|
27
|
+
acted_on: false
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def severity_weight(severity)
|
|
32
|
+
case severity
|
|
33
|
+
when :critical then 1.0
|
|
34
|
+
when :significant then 0.7
|
|
35
|
+
when :notable then 0.4
|
|
36
|
+
when :trivial then 0.1
|
|
37
|
+
else 0.0
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def severity_for_drop(drop)
|
|
42
|
+
if drop >= 0.4 then :critical
|
|
43
|
+
elsif drop >= 0.25 then :significant
|
|
44
|
+
elsif drop >= 0.1 then :notable
|
|
45
|
+
else :trivial
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|