Module: Legion::Gaia

Extended by:
Logging, TeamsAuth
Defined in:
lib/legion/gaia.rb,
lib/legion/gaia/router.rb,
lib/legion/gaia/logging.rb,
lib/legion/gaia/version.rb,
lib/legion/gaia/advisory.rb,
lib/legion/gaia/registry.rb,
lib/legion/gaia/settings.rb,
lib/legion/gaia/proactive.rb,
lib/legion/gaia/teams_auth.rb,
lib/legion/gaia/input_frame.rb,
lib/legion/gaia/runner_host.rb,
lib/legion/gaia/output_frame.rb,
lib/legion/gaia/phase_wiring.rb,
lib/legion/gaia/output_router.rb,
lib/legion/gaia/session_store.rb,
lib/legion/gaia/audit_observer.rb,
lib/legion/gaia/sensory_buffer.rb,
lib/legion/gaia/channel_adapter.rb,
lib/legion/gaia/offline_handler.rb,
lib/legion/gaia/actors/heartbeat.rb,
lib/legion/gaia/channel_registry.rb,
lib/legion/gaia/notification_gate.rb,
lib/legion/gaia/router/agent_bridge.rb,
lib/legion/gaia/channels/cli_adapter.rb,
lib/legion/gaia/router/router_bridge.rb,
lib/legion/gaia/router/worker_routing.rb,
lib/legion/gaia/channel_aware_renderer.rb,
lib/legion/gaia/channels/slack_adapter.rb,
lib/legion/gaia/channels/teams_adapter.rb,
lib/legion/gaia/notification_gate/delay_queue.rb,
lib/legion/gaia/channels/teams/webhook_handler.rb,
lib/legion/gaia/channels/slack/signing_verifier.rb,
lib/legion/gaia/router/transport/exchanges/gaia.rb,
lib/legion/gaia/router/transport/queues/inbound.rb,
lib/legion/gaia/router/transport/queues/outbound.rb,
lib/legion/gaia/channels/teams/bot_framework_auth.rb,
lib/legion/gaia/channels/teams/conversation_store.rb,
lib/legion/gaia/notification_gate/presence_evaluator.rb,
lib/legion/gaia/notification_gate/schedule_evaluator.rb,
lib/legion/gaia/notification_gate/behavioral_evaluator.rb,
lib/legion/gaia/router/transport/messages/input_frame_message.rb,
lib/legion/gaia/router/transport/messages/output_frame_message.rb

Defined Under Namespace

Modules: Actors, Advisory, Channels, Logging, OfflineHandler, PhaseWiring, Proactive, Router, Settings, TeamsAuth Classes: AuditObserver, ChannelAdapter, ChannelAwareRenderer, ChannelRegistry, InputFrame, NotificationGate, OutputFrame, OutputRouter, Registry, RunnerHost, SensoryBuffer, SessionStore

Constant Summary collapse

VERSION =
'0.9.18'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.agent_bridgeObject (readonly)

Returns the value of attribute agent_bridge.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def agent_bridge
  @agent_bridge
end

.channel_registryObject (readonly)

Returns the value of attribute channel_registry.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def channel_registry
  @channel_registry
end

.last_valencesObject (readonly)

Returns the value of attribute last_valences.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def last_valences
  @last_valences
end

.output_routerObject (readonly)

Returns the value of attribute output_router.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def output_router
  @output_router
end

.registryObject (readonly)

Returns the value of attribute registry.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def registry
  @registry
end

.router_bridgeObject (readonly)

Returns the value of attribute router_bridge.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def router_bridge
  @router_bridge
end

.sensory_bufferObject (readonly)

Returns the value of attribute sensory_buffer.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def sensory_buffer
  @sensory_buffer
end

.session_storeObject (readonly)

Returns the value of attribute session_store.



35
36
37
# File 'lib/legion/gaia.rb', line 35

def session_store
  @session_store
end

Class Method Details

.advise(conversation_id:, messages:, caller:) ⇒ Object



38
39
40
# File 'lib/legion/gaia.rb', line 38

def advise(conversation_id:, messages:, caller:)
  Advisory.advise(conversation_id: conversation_id, messages: messages, caller: caller)
end

.boot(mode: nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/legion/gaia.rb', line 42

def boot(mode: nil)
  @mode = mode || (settings&.dig(:router, :mode) ? :router : :agent)
  log_info "Legion::Gaia booting (mode: #{@mode})"

  if router_mode?
    boot_router
  else
    boot_agent
  end

  @started = true
  settings_hash = settings
  settings_hash[:connected] = true if settings_hash

  check_teams_auth

  log_info "Legion::Gaia booted (#{@mode}): #{boot_summary}"
end

.heartbeatObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/legion/gaia.rb', line 98

def heartbeat(**)
  return { error: :not_started } unless started?

  signals = @sensory_buffer.drain
  @registry.ensure_wired

  tick_host = @registry.tick_host
  unless tick_host
    log_warn '[gaia] lex-tick not available, will retry next heartbeat'
    return { error: :no_tick_extension }
  end

  phase_handlers = @registry.phase_handlers

  log_debug "[gaia] heartbeat: signals=#{signals.size} wired_phases=#{phase_handlers.size}"

  result = tick_host.execute_tick(signals: signals, phase_handlers: phase_handlers)

  if result.is_a?(Hash) && result[:results]
    valence_result = result[:results][:emotional_evaluation]
    @last_valences = [valence_result[:valence]] if valence_result.is_a?(Hash) && valence_result[:valence]
    tick_host.last_tick_result = result
  end

  result
end

.ingest(input_frame) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/legion/gaia.rb', line 125

def ingest(input_frame)
  return { ingested: false, reason: :not_started } unless started?

  signal = input_frame.to_signal
  @sensory_buffer.push(signal)

  session = @session_store&.find_or_create(identity: input_frame.auth_context[:identity] || :anonymous)
  @session_store&.touch(session.id, channel_id: input_frame.channel_id) if session

  { ingested: true, buffer_depth: @sensory_buffer.size, session_id: session&.id }
end

.respond(content:, channel_id:, in_reply_to: nil, session_continuity_id: nil, metadata: {}) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/legion/gaia.rb', line 137

def respond(content:, channel_id:, in_reply_to: nil, session_continuity_id: nil, metadata: {})
  frame = OutputFrame.new(
    content: content,
    channel_id: channel_id,
    in_reply_to: in_reply_to,
    session_continuity_id: session_continuity_id,
    metadata: 
  )

  if @agent_bridge&.started?
    @agent_bridge.publish_output(frame)
  else
    @output_router&.route(frame) || { delivered: false, reason: :no_router }
  end
end

.router_mode?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/legion/gaia.rb', line 61

def router_mode?
  @mode == :router
end

.settingsObject



90
91
92
93
94
95
96
# File 'lib/legion/gaia.rb', line 90

def settings
  if Legion.const_defined?('Settings', false)
    Legion::Settings[:gaia]
  else
    Legion::Gaia::Settings.default
  end
end

.shutdownObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/legion/gaia.rb', line 65

def shutdown
  log_info 'Legion::Gaia shutting down'

  @started = false
  settings_hash = settings
  settings_hash[:connected] = false if settings_hash

  @router_bridge&.stop
  @agent_bridge&.stop
  @channel_registry&.stop_all
  @sensory_buffer = nil
  @registry = nil
  @channel_registry = nil
  @output_router = nil
  @session_store = nil
  @router_bridge = nil
  @agent_bridge = nil

  log_info 'Legion::Gaia shut down'
end

.started?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/legion/gaia.rb', line 86

def started?
  @started == true
end

.statusObject



153
154
155
156
157
# File 'lib/legion/gaia.rb', line 153

def status
  return { started: false } unless started?

  base_status.merge(router_status)
end