lex-agentic-self 0.1.8 → 0.1.10
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 +17 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/constants.rb +14 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/personality_store.rb +38 -0
- data/lib/legion/extensions/agentic/self/personality/helpers/trait_model.rb +23 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/client.rb +20 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine.rb +122 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/helpers/constants.rb +39 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/helpers/milestone.rb +42 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/runners/relationship_arc.rb +80 -0
- data/lib/legion/extensions/agentic/self/relationship_arc/version.rb +13 -0
- data/lib/legion/extensions/agentic/self/relationship_arc.rb +19 -0
- data/lib/legion/extensions/agentic/self/version.rb +1 -1
- data/lib/legion/extensions/agentic/self.rb +1 -0
- data/spec/legion/extensions/agentic/self/personality/helpers/partner_signals_spec.rb +106 -0
- data/spec/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine_spec.rb +124 -0
- data/spec/legion/extensions/agentic/self/relationship_arc/helpers/constants_spec.rb +31 -0
- data/spec/legion/extensions/agentic/self/relationship_arc/helpers/milestone_spec.rb +46 -0
- data/spec/legion/extensions/agentic/self/relationship_arc/runners/relationship_arc_spec.rb +64 -0
- metadata +13 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '081b534c7eaf4efbc0265eada2d3b8f11b37b93a3fb34be77068d0ce4f0e842d'
|
|
4
|
+
data.tar.gz: ce8a3839f617dc41d904ccf54a98a208037178cd89eefb39cd031fce8a89e315
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 49409e3e358267476770c66db88a4eff2f7968857c130e547cc3170a3c3e891b27358d7b28ac77e81e5733d480ab65480b38c10c908ef9323738b4159bab527e
|
|
7
|
+
data.tar.gz: fd913ef78cfa8b14ccb5bdadbd95e3133e5bcf67d21a40332ba360ba6393ebd1b34e7db0ccebe3a4bf177aea506d1fc666dcb0efc89820e26853e0574888998d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.10] - 2026-03-31
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- RelationshipArc sub-module for Phase C relational intelligence
|
|
7
|
+
- Constants: chapters, milestone types, health weights, chapter thresholds
|
|
8
|
+
- Milestone: typed data class with UUID, significance clamping, serialization
|
|
9
|
+
- ArcEngine: chapter progression, milestone tracking, relationship health, Apollo Local persistence
|
|
10
|
+
- RelationshipArc runner: record_milestone, update_arc, arc_stats with NarrativeIdentity episode stamping
|
|
11
|
+
|
|
12
|
+
## [0.1.9] - 2026-03-31
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- add `PARTNER_SIGNAL_MAP` and `PARTNER_SIGNAL_THRESHOLD` constants to Personality::Helpers::Constants for partner-specific OCEAN nudges (weight 0.2 per signal)
|
|
16
|
+
- add `TraitModel#apply_partner_signals` to nudge extraversion, agreeableness, openness, and conscientiousness from partner engagement patterns; signals below threshold (0.3) are ignored
|
|
17
|
+
- wire partner signal extraction into `PersonalityStore#update` via `tick_results[:social]` reputation data (engagement frequency, direct address ratio, content diversity, consistency)
|
|
18
|
+
- add 16 specs covering PARTNER_SIGNAL_MAP entries, threshold gating, multi-signal application, and no observation_count side-effect
|
|
19
|
+
|
|
3
20
|
## [0.1.8] - 2026-03-30
|
|
4
21
|
|
|
5
22
|
### Fixed
|
|
@@ -70,6 +70,20 @@ module Legion
|
|
|
70
70
|
mood_stability: [:neuroticism, :negative, 0.3]
|
|
71
71
|
}.freeze
|
|
72
72
|
|
|
73
|
+
# Partner-specific signal map: partner interaction patterns that slowly nudge OCEAN traits.
|
|
74
|
+
# Lower weight (0.2) than general signals — personality should drift very slowly from
|
|
75
|
+
# partner engagement alone.
|
|
76
|
+
# Each entry: [trait, direction, weight]
|
|
77
|
+
PARTNER_SIGNAL_MAP = {
|
|
78
|
+
partner_engagement_frequency: [:extraversion, :positive, 0.2],
|
|
79
|
+
partner_direct_address_ratio: [:agreeableness, :positive, 0.2],
|
|
80
|
+
partner_content_diversity: [:openness, :positive, 0.2],
|
|
81
|
+
partner_consistency: [:conscientiousness, :positive, 0.2]
|
|
82
|
+
}.freeze
|
|
83
|
+
|
|
84
|
+
# Minimum signal value required to apply a partner nudge (0.0–1.0)
|
|
85
|
+
PARTNER_SIGNAL_THRESHOLD = 0.3
|
|
86
|
+
|
|
73
87
|
# Threshold for "high" trait descriptor
|
|
74
88
|
HIGH_THRESHOLD = 0.65
|
|
75
89
|
|
|
@@ -16,6 +16,8 @@ module Legion
|
|
|
16
16
|
def update(tick_results)
|
|
17
17
|
signals = extract_signals(tick_results)
|
|
18
18
|
@model.update(signals)
|
|
19
|
+
partner_signals = extract_partner_signals(tick_results)
|
|
20
|
+
@model.apply_partner_signals(partner_signals) unless partner_signals.empty?
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def full_description
|
|
@@ -41,6 +43,42 @@ module Legion
|
|
|
41
43
|
|
|
42
44
|
private
|
|
43
45
|
|
|
46
|
+
def extract_partner_signals(tick_results)
|
|
47
|
+
counts = partner_records(tick_results)
|
|
48
|
+
return {} if counts.empty?
|
|
49
|
+
|
|
50
|
+
{
|
|
51
|
+
partner_engagement_frequency: partner_engagement_frequency(counts),
|
|
52
|
+
partner_direct_address_ratio: avg_partner_field(counts, :direct_address_ratio),
|
|
53
|
+
partner_content_diversity: avg_partner_diversity(counts),
|
|
54
|
+
partner_consistency: avg_partner_field(counts, :consistency)
|
|
55
|
+
}.compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def partner_records(tick_results)
|
|
59
|
+
social = tick_results[:social] || tick_results[:social_cognition] || {}
|
|
60
|
+
return [] unless social.is_a?(Hash)
|
|
61
|
+
|
|
62
|
+
reputation = social[:reputation_updates] || social[:partners] || {}
|
|
63
|
+
return [] unless reputation.is_a?(Hash) && reputation.any?
|
|
64
|
+
|
|
65
|
+
reputation.values.grep(Hash)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def partner_engagement_frequency(counts)
|
|
69
|
+
(counts.count { |p| p[:message_count].to_i.positive? } / counts.size.to_f).clamp(0.0, 1.0)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def avg_partner_field(counts, key)
|
|
73
|
+
vals = counts.filter_map { |p| p[key] }.grep(Numeric)
|
|
74
|
+
vals.any? ? (vals.sum / vals.size.to_f).clamp(0.0, 1.0) : nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def avg_partner_diversity(counts)
|
|
78
|
+
vals = counts.filter_map { |p| p[:topic_diversity] || p[:content_diversity] }.grep(Numeric)
|
|
79
|
+
vals.any? ? (vals.sum / vals.size.to_f).clamp(0.0, 1.0) : nil
|
|
80
|
+
end
|
|
81
|
+
|
|
44
82
|
def extract_signals(tick_results)
|
|
45
83
|
signals = {}
|
|
46
84
|
|
|
@@ -30,6 +30,14 @@ module Legion
|
|
|
30
30
|
@traits[name.to_sym]
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def apply_partner_signals(signals)
|
|
34
|
+
observations = extract_partner_observations(signals)
|
|
35
|
+
return if observations.empty?
|
|
36
|
+
|
|
37
|
+
apply_observations(observations)
|
|
38
|
+
record_snapshot
|
|
39
|
+
end
|
|
40
|
+
|
|
33
41
|
def formed?
|
|
34
42
|
@observation_count >= Constants::FORMATION_THRESHOLD
|
|
35
43
|
end
|
|
@@ -105,6 +113,21 @@ module Legion
|
|
|
105
113
|
|
|
106
114
|
private
|
|
107
115
|
|
|
116
|
+
def extract_partner_observations(signals)
|
|
117
|
+
observations = Hash.new { |h, k| h[k] = [] }
|
|
118
|
+
|
|
119
|
+
Constants::PARTNER_SIGNAL_MAP.each do |signal_key, (trait, direction, weight)|
|
|
120
|
+
value = signals[signal_key]
|
|
121
|
+
next unless value.is_a?(Numeric)
|
|
122
|
+
next if value <= Constants::PARTNER_SIGNAL_THRESHOLD
|
|
123
|
+
|
|
124
|
+
effective = direction == :positive ? value : 1.0 - value
|
|
125
|
+
observations[trait] << { value: effective, weight: weight }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
observations
|
|
129
|
+
end
|
|
130
|
+
|
|
108
131
|
def extract_observations(signals)
|
|
109
132
|
observations = Hash.new { |h, k| h[k] = [] }
|
|
110
133
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/constants'
|
|
4
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/milestone'
|
|
5
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/arc_engine'
|
|
6
|
+
require 'legion/extensions/agentic/self/relationship_arc/runners/relationship_arc'
|
|
7
|
+
|
|
8
|
+
module Legion
|
|
9
|
+
module Extensions
|
|
10
|
+
module Agentic
|
|
11
|
+
module Self
|
|
12
|
+
module RelationshipArc
|
|
13
|
+
class Client
|
|
14
|
+
include Runners::RelationshipArc
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module RelationshipArc
|
|
8
|
+
module Helpers
|
|
9
|
+
class ArcEngine
|
|
10
|
+
attr_reader :agent_id, :current_chapter, :milestones
|
|
11
|
+
|
|
12
|
+
BOND_STAGE_ORDER = %i[initial forming established deep].freeze
|
|
13
|
+
private_constant :BOND_STAGE_ORDER
|
|
14
|
+
|
|
15
|
+
def initialize(agent_id:)
|
|
16
|
+
@agent_id = agent_id
|
|
17
|
+
@current_chapter = :formative
|
|
18
|
+
@milestones = []
|
|
19
|
+
@dirty = false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_milestone(type:, description:, significance:, **)
|
|
23
|
+
ms = Milestone.new(type: type, description: description, significance: significance)
|
|
24
|
+
@milestones << ms
|
|
25
|
+
@milestones.shift while @milestones.size > Constants::MAX_MILESTONES
|
|
26
|
+
@dirty = true
|
|
27
|
+
ms
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def update_chapter!(bond_stage: :initial, **)
|
|
31
|
+
new_chapter = derive_chapter(bond_stage)
|
|
32
|
+
return if Constants::CHAPTERS.index(new_chapter) <= Constants::CHAPTERS.index(@current_chapter)
|
|
33
|
+
|
|
34
|
+
@current_chapter = new_chapter
|
|
35
|
+
@dirty = true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def relationship_health(attachment_strength: 0.0, reciprocity_balance: 0.5,
|
|
39
|
+
communication_consistency: 0.5, **)
|
|
40
|
+
w = Constants::HEALTH_WEIGHTS
|
|
41
|
+
score = (attachment_strength.to_f * w[:attachment_strength]) +
|
|
42
|
+
(reciprocity_balance.to_f * w[:reciprocity_balance]) +
|
|
43
|
+
(communication_consistency.to_f * w[:communication_consistency])
|
|
44
|
+
score.clamp(0.0, 1.0)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def dirty?
|
|
48
|
+
@dirty
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def mark_clean!
|
|
52
|
+
@dirty = false
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def to_apollo_entries
|
|
57
|
+
tags = Constants::TAG_PREFIX.dup + [@agent_id]
|
|
58
|
+
tags << 'partner' if partner?(@agent_id)
|
|
59
|
+
[{ content: serialize(arc_state_hash), tags: tags }]
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def from_apollo(store:)
|
|
63
|
+
result = store.query(text: 'relationship_arc', tags: Constants::TAG_PREFIX + [@agent_id])
|
|
64
|
+
return false unless result[:success] && result[:results]&.any?
|
|
65
|
+
|
|
66
|
+
parsed = deserialize(result[:results].first[:content])
|
|
67
|
+
return false unless parsed
|
|
68
|
+
|
|
69
|
+
@current_chapter = parsed[:current_chapter]&.to_sym || :formative
|
|
70
|
+
@milestones = (parsed[:milestones] || []).map { |mh| Milestone.from_h(mh.transform_keys(&:to_sym)) }
|
|
71
|
+
true
|
|
72
|
+
rescue StandardError => e
|
|
73
|
+
warn "[arc_engine] from_apollo error: #{e.message}"
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def to_h
|
|
78
|
+
{ agent_id: @agent_id, current_chapter: @current_chapter,
|
|
79
|
+
milestones: @milestones.map(&:to_h),
|
|
80
|
+
relationship_health: nil, milestone_count: @milestones.size }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
def arc_state_hash
|
|
86
|
+
{ agent_id: @agent_id, current_chapter: @current_chapter,
|
|
87
|
+
milestones: @milestones.map(&:to_h) }
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def derive_chapter(bond_stage)
|
|
91
|
+
Constants::CHAPTER_THRESHOLDS.each_key.reverse_each do |chapter|
|
|
92
|
+
threshold = Constants::CHAPTER_THRESHOLDS[chapter]
|
|
93
|
+
stage_idx = BOND_STAGE_ORDER.index(threshold[:stage]) || 0
|
|
94
|
+
current_stage_idx = BOND_STAGE_ORDER.index(bond_stage) || 0
|
|
95
|
+
|
|
96
|
+
return chapter if @milestones.size >= threshold[:milestones] &&
|
|
97
|
+
current_stage_idx >= stage_idx
|
|
98
|
+
end
|
|
99
|
+
:formative
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def partner?(agent_id)
|
|
103
|
+
defined?(Legion::Gaia::BondRegistry) && Legion::Gaia::BondRegistry.partner?(agent_id)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def serialize(hash)
|
|
107
|
+
defined?(Legion::JSON) ? Legion::JSON.dump(hash) : ::JSON.dump(hash)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def deserialize(content)
|
|
111
|
+
parsed = defined?(Legion::JSON) ? Legion::JSON.parse(content) : ::JSON.parse(content, symbolize_names: true)
|
|
112
|
+
parsed.is_a?(Hash) ? parsed.transform_keys(&:to_sym) : nil
|
|
113
|
+
rescue StandardError => _e
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module RelationshipArc
|
|
8
|
+
module Helpers
|
|
9
|
+
module Constants
|
|
10
|
+
CHAPTERS = %i[formative developing established deepening].freeze
|
|
11
|
+
|
|
12
|
+
MILESTONE_TYPES = %i[
|
|
13
|
+
first_interaction first_direct_address stage_transition
|
|
14
|
+
prediction_accuracy communication_shift absence_return
|
|
15
|
+
].freeze
|
|
16
|
+
|
|
17
|
+
HEALTH_WEIGHTS = {
|
|
18
|
+
attachment_strength: 0.4,
|
|
19
|
+
reciprocity_balance: 0.3,
|
|
20
|
+
communication_consistency: 0.3
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
MAX_MILESTONES = 200
|
|
24
|
+
|
|
25
|
+
CHAPTER_THRESHOLDS = {
|
|
26
|
+
developing: { milestones: 3, stage: :forming },
|
|
27
|
+
established: { milestones: 10, stage: :established },
|
|
28
|
+
deepening: { milestones: 25, stage: :deep }
|
|
29
|
+
}.freeze
|
|
30
|
+
|
|
31
|
+
TAG_PREFIX = %w[bond relationship_arc].freeze
|
|
32
|
+
MILESTONE_TAG_PREFIX = %w[bond milestone].freeze
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Legion
|
|
6
|
+
module Extensions
|
|
7
|
+
module Agentic
|
|
8
|
+
module Self
|
|
9
|
+
module RelationshipArc
|
|
10
|
+
module Helpers
|
|
11
|
+
class Milestone
|
|
12
|
+
attr_reader :id, :type, :description, :significance, :created_at
|
|
13
|
+
|
|
14
|
+
def initialize(type:, description:, significance:, id: nil, created_at: nil)
|
|
15
|
+
@id = id || SecureRandom.uuid
|
|
16
|
+
@type = type.to_sym
|
|
17
|
+
@description = description
|
|
18
|
+
@significance = significance.to_f.clamp(0.0, 1.0)
|
|
19
|
+
@created_at = created_at || Time.now.utc
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_h
|
|
23
|
+
{ id: @id, type: @type, description: @description,
|
|
24
|
+
significance: @significance, created_at: @created_at.iso8601 }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.from_h(hash)
|
|
28
|
+
new(
|
|
29
|
+
id: hash[:id],
|
|
30
|
+
type: hash[:type],
|
|
31
|
+
description: hash[:description],
|
|
32
|
+
significance: hash[:significance],
|
|
33
|
+
created_at: hash[:created_at] ? Time.parse(hash[:created_at].to_s) : nil
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Legion
|
|
4
|
+
module Extensions
|
|
5
|
+
module Agentic
|
|
6
|
+
module Self
|
|
7
|
+
module RelationshipArc
|
|
8
|
+
module Runners
|
|
9
|
+
module RelationshipArc
|
|
10
|
+
include Legion::Extensions::Helpers::Lex if defined?(Legion::Extensions::Helpers) &&
|
|
11
|
+
Legion::Extensions::Helpers.const_defined?(:Lex, false)
|
|
12
|
+
|
|
13
|
+
def record_milestone(agent_id:, type:, description:, significance:, **)
|
|
14
|
+
unless Helpers::Constants::MILESTONE_TYPES.include?(type.to_sym)
|
|
15
|
+
return { success: false,
|
|
16
|
+
error: "unknown type: #{type}" }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
engine = arc_engine_for(agent_id)
|
|
20
|
+
ms = engine.add_milestone(type: type, description: description, significance: significance)
|
|
21
|
+
|
|
22
|
+
stamp_narrative_episode(ms)
|
|
23
|
+
|
|
24
|
+
{ success: true, milestone: ms.to_h }
|
|
25
|
+
rescue StandardError => e
|
|
26
|
+
{ success: false, error: e.message }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def update_arc(agent_id:, attachment_state: {}, **)
|
|
30
|
+
engine = arc_engine_for(agent_id)
|
|
31
|
+
engine.update_chapter!(bond_stage: attachment_state[:bond_stage] || :initial)
|
|
32
|
+
|
|
33
|
+
{ success: true, current_chapter: engine.current_chapter,
|
|
34
|
+
milestone_count: engine.milestones.size }
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
{ success: false, error: e.message }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def arc_stats(agent_id:, **)
|
|
40
|
+
engine = arc_engine_for(agent_id)
|
|
41
|
+
engine.to_h
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def arc_engine_for(agent_id)
|
|
47
|
+
@arc_engines ||= {}
|
|
48
|
+
@arc_engines[agent_id.to_s] ||= Helpers::ArcEngine.new(agent_id: agent_id.to_s)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def stamp_narrative_episode(milestone)
|
|
52
|
+
narrator = resolve_narrative_identity
|
|
53
|
+
return unless narrator
|
|
54
|
+
|
|
55
|
+
narrator.record_episode(
|
|
56
|
+
content: milestone.description,
|
|
57
|
+
episode_type: :relationship,
|
|
58
|
+
emotional_valence: 0.3,
|
|
59
|
+
significance: milestone.significance,
|
|
60
|
+
domain: :relationship,
|
|
61
|
+
tags: ['partner', 'milestone', milestone.type.to_s]
|
|
62
|
+
)
|
|
63
|
+
rescue StandardError => e
|
|
64
|
+
warn "[relationship_arc] narrative stamp failed: #{e.message}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def resolve_narrative_identity
|
|
68
|
+
return nil unless defined?(Legion::Extensions::Agentic::Self::NarrativeIdentity::Client)
|
|
69
|
+
|
|
70
|
+
@narrative_client ||= Legion::Extensions::Agentic::Self::NarrativeIdentity::Client.new
|
|
71
|
+
rescue StandardError => _e
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'relationship_arc/version'
|
|
4
|
+
require_relative 'relationship_arc/helpers/constants'
|
|
5
|
+
require_relative 'relationship_arc/helpers/milestone'
|
|
6
|
+
require_relative 'relationship_arc/helpers/arc_engine'
|
|
7
|
+
require_relative 'relationship_arc/runners/relationship_arc'
|
|
8
|
+
require_relative 'relationship_arc/client'
|
|
9
|
+
|
|
10
|
+
module Legion
|
|
11
|
+
module Extensions
|
|
12
|
+
module Agentic
|
|
13
|
+
module Self
|
|
14
|
+
module RelationshipArc
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe Legion::Extensions::Agentic::Self::Personality::Helpers::TraitModel do
|
|
4
|
+
subject(:model) { described_class.new }
|
|
5
|
+
|
|
6
|
+
let(:constants) { Legion::Extensions::Agentic::Self::Personality::Helpers::Constants }
|
|
7
|
+
|
|
8
|
+
describe 'PARTNER_SIGNAL_MAP constant' do
|
|
9
|
+
it 'defines partner_engagement_frequency nudging extraversion positively' do
|
|
10
|
+
entry = constants::PARTNER_SIGNAL_MAP[:partner_engagement_frequency]
|
|
11
|
+
expect(entry).to eq([:extraversion, :positive, 0.2])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'defines partner_direct_address_ratio nudging agreeableness positively' do
|
|
15
|
+
entry = constants::PARTNER_SIGNAL_MAP[:partner_direct_address_ratio]
|
|
16
|
+
expect(entry).to eq([:agreeableness, :positive, 0.2])
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'defines partner_content_diversity nudging openness positively' do
|
|
20
|
+
entry = constants::PARTNER_SIGNAL_MAP[:partner_content_diversity]
|
|
21
|
+
expect(entry).to eq([:openness, :positive, 0.2])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'defines partner_consistency nudging conscientiousness positively' do
|
|
25
|
+
entry = constants::PARTNER_SIGNAL_MAP[:partner_consistency]
|
|
26
|
+
expect(entry).to eq([:conscientiousness, :positive, 0.2])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'has all entries with weights of 0.2' do
|
|
30
|
+
constants::PARTNER_SIGNAL_MAP.each_value do |_trait, _direction, weight|
|
|
31
|
+
expect(weight).to eq(0.2)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'references only valid OCEAN traits' do
|
|
36
|
+
constants::PARTNER_SIGNAL_MAP.each_value do |trait, _direction, _weight|
|
|
37
|
+
expect(constants::TRAITS).to include(trait)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#apply_partner_signals' do
|
|
43
|
+
it 'nudges extraversion upward when partner_engagement_frequency is high' do
|
|
44
|
+
baseline = model.trait(:extraversion)
|
|
45
|
+
model.apply_partner_signals(partner_engagement_frequency: 0.9)
|
|
46
|
+
expect(model.trait(:extraversion)).to be > baseline
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'nudges agreeableness upward when partner_direct_address_ratio is high' do
|
|
50
|
+
baseline = model.trait(:agreeableness)
|
|
51
|
+
model.apply_partner_signals(partner_direct_address_ratio: 0.8)
|
|
52
|
+
expect(model.trait(:agreeableness)).to be > baseline
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'nudges openness upward when partner_content_diversity is high' do
|
|
56
|
+
baseline = model.trait(:openness)
|
|
57
|
+
model.apply_partner_signals(partner_content_diversity: 0.8)
|
|
58
|
+
expect(model.trait(:openness)).to be > baseline
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'nudges conscientiousness upward when partner_consistency is high' do
|
|
62
|
+
baseline = model.trait(:conscientiousness)
|
|
63
|
+
model.apply_partner_signals(partner_consistency: 0.8)
|
|
64
|
+
expect(model.trait(:conscientiousness)).to be > baseline
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'ignores signals below the minimum threshold' do
|
|
68
|
+
baseline = model.trait(:extraversion)
|
|
69
|
+
model.apply_partner_signals(partner_engagement_frequency: 0.1)
|
|
70
|
+
expect(model.trait(:extraversion)).to eq(baseline)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'ignores signals exactly at the threshold boundary' do
|
|
74
|
+
baseline = model.trait(:extraversion)
|
|
75
|
+
model.apply_partner_signals(partner_engagement_frequency: 0.3)
|
|
76
|
+
expect(model.trait(:extraversion)).to eq(baseline)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'applies multiple signals in a single call' do
|
|
80
|
+
extraversion_before = model.trait(:extraversion)
|
|
81
|
+
agreeableness_before = model.trait(:agreeableness)
|
|
82
|
+
|
|
83
|
+
model.apply_partner_signals(
|
|
84
|
+
partner_engagement_frequency: 0.9,
|
|
85
|
+
partner_direct_address_ratio: 0.8
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
expect(model.trait(:extraversion)).to be > extraversion_before
|
|
89
|
+
expect(model.trait(:agreeableness)).to be > agreeableness_before
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'ignores unrecognized signal keys' do
|
|
93
|
+
expect { model.apply_partner_signals(unknown_signal: 0.9) }.not_to raise_error
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'does not change observation_count' do
|
|
97
|
+
model.apply_partner_signals(partner_engagement_frequency: 0.9)
|
|
98
|
+
expect(model.observation_count).to eq(0)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it 'records a history snapshot after applying signals' do
|
|
102
|
+
model.apply_partner_signals(partner_engagement_frequency: 0.9)
|
|
103
|
+
expect(model.history.size).to eq(1)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/constants'
|
|
5
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/milestone'
|
|
6
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/arc_engine'
|
|
7
|
+
|
|
8
|
+
RSpec.describe Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::ArcEngine do
|
|
9
|
+
subject(:engine) { described_class.new(agent_id: 'partner-1') }
|
|
10
|
+
|
|
11
|
+
describe '#initialize' do
|
|
12
|
+
it 'starts in formative chapter' do
|
|
13
|
+
expect(engine.current_chapter).to eq(:formative)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'starts with empty milestones' do
|
|
17
|
+
expect(engine.milestones).to be_empty
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe '#add_milestone' do
|
|
22
|
+
it 'adds a milestone' do
|
|
23
|
+
engine.add_milestone(type: :first_interaction, description: 'Hello', significance: 0.8)
|
|
24
|
+
expect(engine.milestones.size).to eq(1)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'returns the milestone' do
|
|
28
|
+
ms = engine.add_milestone(type: :first_interaction, description: 'Hello', significance: 0.8)
|
|
29
|
+
expect(ms).to be_a(Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::Milestone)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'marks dirty' do
|
|
33
|
+
engine.add_milestone(type: :first_interaction, description: 'Hello', significance: 0.8)
|
|
34
|
+
expect(engine).to be_dirty
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'caps at MAX_MILESTONES' do
|
|
38
|
+
201.times { |i| engine.add_milestone(type: :first_interaction, description: "ms #{i}", significance: 0.1) }
|
|
39
|
+
expect(engine.milestones.size).to eq(200)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe '#update_chapter!' do
|
|
44
|
+
it 'transitions to developing after enough milestones' do
|
|
45
|
+
4.times { engine.add_milestone(type: :first_interaction, description: 'x', significance: 0.5) }
|
|
46
|
+
engine.update_chapter!(bond_stage: :forming)
|
|
47
|
+
expect(engine.current_chapter).to eq(:developing)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'never regresses' do
|
|
51
|
+
engine.instance_variable_set(:@current_chapter, :established)
|
|
52
|
+
engine.update_chapter!(bond_stage: :initial)
|
|
53
|
+
expect(engine.current_chapter).to eq(:established)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe '#relationship_health' do
|
|
58
|
+
it 'computes weighted health score' do
|
|
59
|
+
health = engine.relationship_health(
|
|
60
|
+
attachment_strength: 0.8,
|
|
61
|
+
reciprocity_balance: 0.6,
|
|
62
|
+
communication_consistency: 0.7
|
|
63
|
+
)
|
|
64
|
+
expected = (0.8 * 0.4) + (0.6 * 0.3) + (0.7 * 0.3)
|
|
65
|
+
expect(health).to be_within(0.01).of(expected)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'clamps to 0.0..1.0' do
|
|
69
|
+
health = engine.relationship_health(
|
|
70
|
+
attachment_strength: 1.5,
|
|
71
|
+
reciprocity_balance: 1.5,
|
|
72
|
+
communication_consistency: 1.5
|
|
73
|
+
)
|
|
74
|
+
expect(health).to eq(1.0)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe '#dirty? and #mark_clean!' do
|
|
79
|
+
it 'starts clean' do
|
|
80
|
+
expect(engine).not_to be_dirty
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'cleans up' do
|
|
84
|
+
engine.add_milestone(type: :first_interaction, description: 'x', significance: 0.5)
|
|
85
|
+
engine.mark_clean!
|
|
86
|
+
expect(engine).not_to be_dirty
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe '#to_apollo_entries' do
|
|
91
|
+
before { engine.add_milestone(type: :first_interaction, description: 'Hello', significance: 0.8) }
|
|
92
|
+
|
|
93
|
+
it 'returns entries with arc state' do
|
|
94
|
+
entries = engine.to_apollo_entries
|
|
95
|
+
expect(entries).to be_an(Array)
|
|
96
|
+
expect(entries.first[:tags]).to include('bond', 'relationship_arc', 'partner-1')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#from_apollo' do
|
|
101
|
+
let(:mock_store) { double('apollo_local') }
|
|
102
|
+
|
|
103
|
+
it 'restores state from Apollo' do
|
|
104
|
+
engine.add_milestone(type: :first_interaction, description: 'Hello', significance: 0.8)
|
|
105
|
+
engine.instance_variable_set(:@current_chapter, :developing)
|
|
106
|
+
content = engine.send(:serialize, engine.send(:arc_state_hash))
|
|
107
|
+
|
|
108
|
+
new_engine = described_class.new(agent_id: 'partner-1')
|
|
109
|
+
allow(mock_store).to receive(:query)
|
|
110
|
+
.and_return({ success: true, results: [{ content: content, tags: %w[bond relationship_arc partner-1] }] })
|
|
111
|
+
|
|
112
|
+
expect(new_engine.from_apollo(store: mock_store)).to be true
|
|
113
|
+
expect(new_engine.current_chapter).to eq(:developing)
|
|
114
|
+
expect(new_engine.milestones.size).to eq(1)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
describe '#to_h' do
|
|
119
|
+
it 'includes all fields' do
|
|
120
|
+
h = engine.to_h
|
|
121
|
+
expect(h).to include(:agent_id, :current_chapter, :milestones, :relationship_health)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/constants'
|
|
5
|
+
|
|
6
|
+
RSpec.describe Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::Constants do
|
|
7
|
+
describe 'CHAPTERS' do
|
|
8
|
+
it 'defines 4 chapters in order' do
|
|
9
|
+
expect(described_class::CHAPTERS).to eq(%i[formative developing established deepening])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe 'MILESTONE_TYPES' do
|
|
14
|
+
it 'includes expected types' do
|
|
15
|
+
expect(described_class::MILESTONE_TYPES).to include(:first_interaction, :stage_transition,
|
|
16
|
+
:prediction_accuracy, :absence_return)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe 'HEALTH_WEIGHTS' do
|
|
21
|
+
it 'sums to 1.0' do
|
|
22
|
+
expect(described_class::HEALTH_WEIGHTS.values.sum).to eq(1.0)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'MAX_MILESTONES' do
|
|
27
|
+
it 'caps at 200' do
|
|
28
|
+
expect(described_class::MAX_MILESTONES).to eq(200)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/constants'
|
|
5
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/milestone'
|
|
6
|
+
|
|
7
|
+
RSpec.describe Legion::Extensions::Agentic::Self::RelationshipArc::Helpers::Milestone do
|
|
8
|
+
subject(:milestone) do
|
|
9
|
+
described_class.new(type: :first_interaction, description: 'First hello', significance: 0.8)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe '#initialize' do
|
|
13
|
+
it 'sets type' do
|
|
14
|
+
expect(milestone.type).to eq(:first_interaction)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'generates a UUID' do
|
|
18
|
+
expect(milestone.id).to match(/\A[0-9a-f-]{36}\z/)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'clamps significance to 0.0..1.0' do
|
|
22
|
+
ms = described_class.new(type: :first_interaction, description: 'test', significance: 1.5)
|
|
23
|
+
expect(ms.significance).to eq(1.0)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'records timestamp' do
|
|
27
|
+
expect(milestone.created_at).to be_a(Time)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#to_h' do
|
|
32
|
+
it 'returns complete hash' do
|
|
33
|
+
h = milestone.to_h
|
|
34
|
+
expect(h).to include(:id, :type, :description, :significance, :created_at)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '.from_h' do
|
|
39
|
+
it 'round-trips' do
|
|
40
|
+
restored = described_class.from_h(milestone.to_h)
|
|
41
|
+
expect(restored.type).to eq(milestone.type)
|
|
42
|
+
expect(restored.description).to eq(milestone.description)
|
|
43
|
+
expect(restored.significance).to eq(milestone.significance)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/constants'
|
|
5
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/milestone'
|
|
6
|
+
require 'legion/extensions/agentic/self/relationship_arc/helpers/arc_engine'
|
|
7
|
+
require 'legion/extensions/agentic/self/relationship_arc/runners/relationship_arc'
|
|
8
|
+
|
|
9
|
+
RSpec.describe Legion::Extensions::Agentic::Self::RelationshipArc::Runners::RelationshipArc do
|
|
10
|
+
let(:described_module) { described_class }
|
|
11
|
+
let(:host) { Object.new.extend(described_module) }
|
|
12
|
+
|
|
13
|
+
before { host.instance_variable_set(:@arc_engines, nil) }
|
|
14
|
+
|
|
15
|
+
describe '#record_milestone' do
|
|
16
|
+
it 'records a milestone for an agent' do
|
|
17
|
+
result = host.record_milestone(agent_id: 'p1', type: :first_interaction,
|
|
18
|
+
description: 'Hello', significance: 0.8)
|
|
19
|
+
expect(result[:success]).to be true
|
|
20
|
+
expect(result[:milestone][:type]).to eq(:first_interaction)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'returns error for unknown type' do
|
|
24
|
+
result = host.record_milestone(agent_id: 'p1', type: :bogus,
|
|
25
|
+
description: 'x', significance: 0.5)
|
|
26
|
+
expect(result[:success]).to be false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'calls NarrativeIdentity record_episode when available' do
|
|
30
|
+
narrator = double('narrator')
|
|
31
|
+
allow(host).to receive(:resolve_narrative_identity).and_return(narrator)
|
|
32
|
+
allow(narrator).to receive(:record_episode).and_return({ success: true })
|
|
33
|
+
|
|
34
|
+
host.record_milestone(agent_id: 'p1', type: :first_interaction,
|
|
35
|
+
description: 'Hello', significance: 0.8)
|
|
36
|
+
expect(narrator).to have_received(:record_episode)
|
|
37
|
+
.with(hash_including(episode_type: :relationship, significance: 0.8))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe '#update_arc' do
|
|
42
|
+
it 'updates chapter based on attachment state' do
|
|
43
|
+
3.times do
|
|
44
|
+
host.record_milestone(agent_id: 'p1', type: :first_interaction,
|
|
45
|
+
description: 'x', significance: 0.5)
|
|
46
|
+
end
|
|
47
|
+
result = host.update_arc(agent_id: 'p1', attachment_state: { bond_stage: :forming })
|
|
48
|
+
expect(result[:success]).to be true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'returns arc summary' do
|
|
52
|
+
result = host.update_arc(agent_id: 'p1', attachment_state: {})
|
|
53
|
+
expect(result).to have_key(:current_chapter)
|
|
54
|
+
expect(result).to have_key(:milestone_count)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe '#arc_stats' do
|
|
59
|
+
it 'returns stats' do
|
|
60
|
+
result = host.arc_stats(agent_id: 'p1')
|
|
61
|
+
expect(result).to have_key(:current_chapter)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lex-agentic-self
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Esity
|
|
@@ -309,6 +309,13 @@ files:
|
|
|
309
309
|
- lib/legion/extensions/agentic/self/reflection/helpers/reflection_store.rb
|
|
310
310
|
- lib/legion/extensions/agentic/self/reflection/runners/reflection.rb
|
|
311
311
|
- lib/legion/extensions/agentic/self/reflection/version.rb
|
|
312
|
+
- lib/legion/extensions/agentic/self/relationship_arc.rb
|
|
313
|
+
- lib/legion/extensions/agentic/self/relationship_arc/client.rb
|
|
314
|
+
- lib/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine.rb
|
|
315
|
+
- lib/legion/extensions/agentic/self/relationship_arc/helpers/constants.rb
|
|
316
|
+
- lib/legion/extensions/agentic/self/relationship_arc/helpers/milestone.rb
|
|
317
|
+
- lib/legion/extensions/agentic/self/relationship_arc/runners/relationship_arc.rb
|
|
318
|
+
- lib/legion/extensions/agentic/self/relationship_arc/version.rb
|
|
312
319
|
- lib/legion/extensions/agentic/self/self_model.rb
|
|
313
320
|
- lib/legion/extensions/agentic/self/self_model/client.rb
|
|
314
321
|
- lib/legion/extensions/agentic/self/self_model/helpers/capability.rb
|
|
@@ -406,6 +413,7 @@ files:
|
|
|
406
413
|
- spec/legion/extensions/agentic/self/narrative_self/runners/narrative_self_spec.rb
|
|
407
414
|
- spec/legion/extensions/agentic/self/personality/client_spec.rb
|
|
408
415
|
- spec/legion/extensions/agentic/self/personality/helpers/constants_spec.rb
|
|
416
|
+
- spec/legion/extensions/agentic/self/personality/helpers/partner_signals_spec.rb
|
|
409
417
|
- spec/legion/extensions/agentic/self/personality/helpers/personality_store_spec.rb
|
|
410
418
|
- spec/legion/extensions/agentic/self/personality/helpers/trait_model_spec.rb
|
|
411
419
|
- spec/legion/extensions/agentic/self/personality/runners/personality_spec.rb
|
|
@@ -415,6 +423,10 @@ files:
|
|
|
415
423
|
- spec/legion/extensions/agentic/self/reflection/helpers/reflection_spec.rb
|
|
416
424
|
- spec/legion/extensions/agentic/self/reflection/helpers/reflection_store_spec.rb
|
|
417
425
|
- spec/legion/extensions/agentic/self/reflection/runners/reflection_spec.rb
|
|
426
|
+
- spec/legion/extensions/agentic/self/relationship_arc/helpers/arc_engine_spec.rb
|
|
427
|
+
- spec/legion/extensions/agentic/self/relationship_arc/helpers/constants_spec.rb
|
|
428
|
+
- spec/legion/extensions/agentic/self/relationship_arc/helpers/milestone_spec.rb
|
|
429
|
+
- spec/legion/extensions/agentic/self/relationship_arc/runners/relationship_arc_spec.rb
|
|
418
430
|
- spec/legion/extensions/agentic/self/self_model/client_spec.rb
|
|
419
431
|
- spec/legion/extensions/agentic/self/self_model/helpers/capability_spec.rb
|
|
420
432
|
- spec/legion/extensions/agentic/self/self_model/helpers/knowledge_domain_spec.rb
|