Class: Legion::Extensions::Agentic::Self::NarrativeIdentity::Helpers::NarrativeEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeNarrativeEngine

Returns a new instance of NarrativeEngine.



12
13
14
15
16
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 12

def initialize
  @episodes = {}
  @themes   = {}
  @chapters = {}
end

Instance Attribute Details

#chaptersObject (readonly)

Returns the value of attribute chapters.



10
11
12
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 10

def chapters
  @chapters
end

#episodesObject (readonly)

Returns the value of attribute episodes.



10
11
12
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 10

def episodes
  @episodes
end

#themesObject (readonly)

Returns the value of attribute themes.



10
11
12
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 10

def themes
  @themes
end

Instance Method Details

#add_episode(content:, episode_type:, emotional_valence:, significance:, domain:) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 18

def add_episode(content:, episode_type:, emotional_valence:, significance:, domain:)
  return nil unless Constants::EPISODE_TYPES.include?(episode_type)

  prune_episodes! if @episodes.size >= Constants::MAX_EPISODES
  episode = Episode.new(
    content:           content,
    episode_type:      episode_type,
    emotional_valence: emotional_valence,
    significance:      significance,
    domain:            domain
  )
  @episodes[episode.id] = episode
  episode
end

#add_theme(name:, theme_type:) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 58

def add_theme(name:, theme_type:)
  return nil unless Constants::THEME_TYPES.include?(theme_type)

  prune_themes! if @themes.size >= Constants::MAX_THEMES
  theme = Theme.new(name: name, theme_type: theme_type)
  @themes[theme.id] = theme
  theme
end

#assign_to_chapter(episode_id:, chapter_id:) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 33

def assign_to_chapter(episode_id:, chapter_id:)
  episode = @episodes.fetch(episode_id, nil)
  chapter = @chapters.fetch(chapter_id, nil)
  return false unless episode && chapter

  episode.chapter_id = chapter_id
  chapter.episode_ids << episode_id unless chapter.episode_ids.include?(episode_id)
  true
end

#close_chapter(chapter_id:) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 50

def close_chapter(chapter_id:)
  chapter = @chapters.fetch(chapter_id, nil)
  return false unless chapter

  chapter.end_time = Time.now.utc
  true
end

#create_chapter(title:, label:) ⇒ Object



43
44
45
46
47
48
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 43

def create_chapter(title:, label:)
  prune_chapters! if @chapters.size >= Constants::MAX_CHAPTERS
  chapter = Chapter.new(title: title, label: label)
  @chapters[chapter.id] = chapter
  chapter
end

#current_chapterObject



125
126
127
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 125

def current_chapter
  @chapters.values.find(&:current?)
end

#decay_all_themes!Object



129
130
131
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 129

def decay_all_themes!
  @themes.each_value(&:decay!)
end

#identity_summaryObject



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 94

def identity_summary
  {
    top_themes:        prominent_themes.first(5).map(&:to_h),
    defining_episodes: most_defining_episodes(limit: 5).map(&:to_h),
    current_chapter:   current_chapter&.to_h,
    coherence:         narrative_coherence,
    coherence_label:   coherence_label,
    episode_count:     @episodes.size,
    theme_count:       @themes.size,
    chapter_count:     @chapters.size
  }
end

#life_storyObject



107
108
109
110
111
112
113
114
115
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 107

def life_story
  @chapters.values.sort_by(&:start_time).map do |chapter|
    eps = chapter.episode_ids.filter_map { |id| @episodes[id] }.sort_by(&:created_at)
    {
      chapter:  chapter.to_h,
      episodes: eps.map { |ep| ep.to_h.merge(theme_names: theme_names_for(ep)) }
    }
  end
end


67
68
69
70
71
72
73
74
75
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 67

def link_theme(episode_id:, theme_id:)
  episode = @episodes.fetch(episode_id, nil)
  theme   = @themes.fetch(theme_id, nil)
  return false unless episode && theme

  episode.themes << theme_id unless episode.themes.include?(theme_id)
  theme.episode_ids << episode_id unless theme.episode_ids.include?(episode_id)
  true
end

#most_defining_episodes(limit: 5) ⇒ Object



117
118
119
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 117

def most_defining_episodes(limit: 5)
  @episodes.values.sort_by { |ep| -ep.significance }.first(limit)
end

#narrative_coherenceObject



85
86
87
88
89
90
91
92
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 85

def narrative_coherence
  return 0.0 if @episodes.empty? || @themes.empty?

  linked       = @episodes.values.count { |ep| ep.themes.any? }
  base         = (linked.to_f / @episodes.size).round(10)
  theme_factor = prominent_themes.size.to_f / [@themes.size, 1].max
  ((base * 0.7) + (theme_factor * 0.3)).round(10).clamp(0.0, 1.0)
end

#narrative_reportObject



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 133

def narrative_report
  {
    identity_summary: identity_summary,
    life_story:       life_story,
    narrative_state:  {
      coherence:         narrative_coherence,
      coherence_label:   coherence_label,
      prominent_themes:  prominent_themes.map(&:to_h),
      defining_episodes: most_defining_episodes(limit: 3).map(&:to_h),
      current_chapter:   current_chapter&.to_h
    }
  }
end

#prominent_themesObject



121
122
123
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 121

def prominent_themes
  @themes.values.select(&:prominent?).sort_by { |t| -t.strength }
end

#reinforce_theme(theme_id:, amount:) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 77

def reinforce_theme(theme_id:, amount:)
  theme = @themes.fetch(theme_id, nil)
  return false unless theme

  theme.reinforce!(amount)
  true
end

#to_hObject



147
148
149
150
151
152
153
# File 'lib/legion/extensions/agentic/self/narrative_identity/helpers/narrative_engine.rb', line 147

def to_h
  {
    episodes: @episodes.transform_values(&:to_h),
    themes:   @themes.transform_values(&:to_h),
    chapters: @chapters.transform_values(&:to_h)
  }
end