lex-microsoft_teams 0.6.5 → 0.6.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1eae25ec2551dc1467fb72e447817bad5cebf0df377cb8bd432fc11fdd13472f
4
- data.tar.gz: b8a562b68c05bad57ff0660756a4883d87cf01da93c6f3665bd5575c94765946
3
+ metadata.gz: f2b4cefc6a1bd6c568b74afb644092dbff531b11e2eb40fd5ad62835caccba13
4
+ data.tar.gz: 6077b95ded27b3160e4d31d3bd003ca6b4fa17c35e0defdd91e5fb66d72245f0
5
5
  SHA512:
6
- metadata.gz: 88f9605803f81b12cbb7065d9d607a9f5106dfaa7b8ab4802ecbdda3ba3d5d5de2d670ca1015620defeb6573893dc5b10e669d470b9f9f06677e271b2c96d1b3
7
- data.tar.gz: 1683ec4477164cbe81ded4d0827f8e2912ec2ed386decd58ce4e914fda8d20779a4b8cfb263c338fe78f5b655b363fb186b3651f932cafa5f069810eaece382f
6
+ metadata.gz: 0cf55cc7c012c40fc2299e2697384efea18f2e9d220f7dfcc97470eae276ebe76524251e79d57681edf408aa660c38ae00880dc45861be0cbdc8303c7147910e
7
+ data.tar.gz: 7891774a5a9a02d9ac2c71d0f55d44ff9be5e11949b7a36f8b6bcdbe9d94bd7f5503f984afa7e42ddac77132fa155af35c57b35e7c8b070de3d333356183327a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.7] - 2026-03-22
4
+
5
+ ### Fixed
6
+ - ProfileIngest actor uses `TokenCache.instance` singleton instead of `TokenCache.new` (empty cache returned nil token, preventing boot-time profile ingest)
7
+
8
+ ## [0.6.6] - 2026-03-22
9
+
10
+ ### Added
11
+ - `Bot.dispatch_message` routes AMQP messages by mode (direct -> handle_message, observe -> observe_message)
12
+ - MeetingIngest stores transcripts as episodic traces and AI insights as semantic traces in lex-agentic-memory
13
+ - ChannelPoller stores new channel messages as episodic traces in lex-agentic-memory
14
+ - INFO-level poll logging in MeetingIngest and ChannelPoller for visibility
15
+
16
+ ### Changed
17
+ - MessageProcessor actor now calls `dispatch_message` instead of `handle_message` directly
18
+
3
19
  ## [0.6.5] - 2026-03-22
4
20
 
5
21
  ### Added
@@ -26,6 +26,14 @@ module Legion
26
26
  def check_subtask? = false
27
27
  def generate_task? = false
28
28
 
29
+ def memory_available?
30
+ defined?(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces)
31
+ end
32
+
33
+ def memory_runner
34
+ @memory_runner ||= Object.new.extend(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces)
35
+ end
36
+
29
37
  def enabled?
30
38
  return false unless defined?(Legion::Extensions::MicrosoftTeams::Helpers::TokenCache)
31
39
 
@@ -39,6 +47,7 @@ module Legion
39
47
  end
40
48
 
41
49
  def manual
50
+ log_info('ChannelPoller polling team channels')
42
51
  token = token_cache.cached_graph_token
43
52
  unless token
44
53
  log_debug('No token available, skipping poll')
@@ -113,7 +122,10 @@ module Legion
113
122
  return if new_msgs.empty?
114
123
 
115
124
  log_info("#{team_name} / #{channel_name}: #{new_msgs.length} new message(s)")
116
- new_msgs.each { |msg| log_message(team_name: team_name, channel_name: channel_name, msg: msg) }
125
+ new_msgs.each do |msg|
126
+ log_message(team_name: team_name, channel_name: channel_name, msg: msg)
127
+ store_channel_message_trace(team_name: team_name, channel_name: channel_name, msg: msg) if memory_available?
128
+ end
117
129
 
118
130
  latest = new_msgs.map { |m| m['createdDateTime'] }.compact.max
119
131
  @channel_hwm[channel_id] = latest if latest
@@ -149,6 +161,20 @@ module Legion
149
161
  default
150
162
  end
151
163
 
164
+ def store_channel_message_trace(team_name:, channel_name:, msg:)
165
+ sender = msg.dig('from', 'user', 'displayName') || 'Unknown'
166
+ content = (msg.dig('body', 'content') || '').gsub(/<[^>]+>/, '').strip
167
+ memory_runner.store_trace(
168
+ type: :episodic,
169
+ content_payload: "#{sender} in #{team_name}/##{channel_name}: #{content}"[0, 5000],
170
+ domain_tags: ['teams', 'channel', "team:#{team_name}", "channel:#{channel_name}", "sender:#{sender}"],
171
+ origin: :direct_experience,
172
+ confidence: 0.7
173
+ )
174
+ rescue StandardError => e
175
+ log_error("Failed to store channel message trace: #{e.message}")
176
+ end
177
+
152
178
  def log_debug(msg)
153
179
  Legion::Logging.debug("[Teams::ChannelPoller] #{msg}") if defined?(Legion::Logging)
154
180
  end
@@ -36,11 +36,20 @@ module Legion
36
36
  false
37
37
  end
38
38
 
39
+ def memory_available?
40
+ defined?(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces)
41
+ end
42
+
43
+ def memory_runner
44
+ @memory_runner ||= Object.new.extend(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces)
45
+ end
46
+
39
47
  def token_cache
40
48
  Legion::Extensions::MicrosoftTeams::Helpers::TokenCache.instance
41
49
  end
42
50
 
43
51
  def manual
52
+ log_info('MeetingIngest polling for meetings')
44
53
  token = token_cache.cached_graph_token
45
54
  return if token.nil?
46
55
 
@@ -104,6 +113,7 @@ module Legion
104
113
  content = content_response.body.to_s
105
114
  preview = content[0, 200]
106
115
  log_debug("Meeting '#{subject}' transcript #{tid}: #{preview}")
116
+ store_transcript_trace(meeting_id: meeting_id, subject: subject, transcript_id: tid, content: content) if memory_available?
107
117
  rescue StandardError => e
108
118
  log_warn("Could not fetch transcript content #{tid} for meeting #{meeting_id}: #{e.message}")
109
119
  end
@@ -121,11 +131,37 @@ module Legion
121
131
  action_items.each do |item|
122
132
  log_info(" - #{item['text'] || item.inspect}")
123
133
  end
134
+
135
+ store_insight_trace(meeting_id: meeting_id, subject: subject, insight: insight) if memory_available?
124
136
  end
125
137
  rescue StandardError => e
126
138
  log_warn("Could not fetch AI insights for meeting #{meeting_id}: #{e.message}")
127
139
  end
128
140
 
141
+ def store_transcript_trace(meeting_id:, subject:, transcript_id:, content:) # rubocop:disable Lint/UnusedMethodArgument
142
+ memory_runner.store_trace(
143
+ type: :episodic,
144
+ content_payload: content[0, 10_000],
145
+ domain_tags: ['teams', 'transcript', "meeting:#{meeting_id}", "transcript:#{transcript_id}"],
146
+ origin: :direct_experience,
147
+ confidence: 0.9
148
+ )
149
+ rescue StandardError => e
150
+ log_warn("Could not store transcript trace for meeting #{meeting_id}: #{e.message}")
151
+ end
152
+
153
+ def store_insight_trace(meeting_id:, subject:, insight:) # rubocop:disable Lint/UnusedMethodArgument
154
+ memory_runner.store_trace(
155
+ type: :semantic,
156
+ content_payload: insight.to_s,
157
+ domain_tags: ['teams', 'ai-insight', "meeting:#{meeting_id}"],
158
+ origin: :inferred,
159
+ confidence: 0.8
160
+ )
161
+ rescue StandardError => e
162
+ log_warn("Could not store insight trace for meeting #{meeting_id}: #{e.message}")
163
+ end
164
+
129
165
  def log_debug(msg)
130
166
  Legion::Logging.debug("[Teams::MeetingIngest] #{msg}") if defined?(Legion::Logging)
131
167
  end
@@ -6,7 +6,7 @@ module Legion
6
6
  module Actor
7
7
  class MessageProcessor < Legion::Extensions::Actors::Subscription
8
8
  def runner_class = 'Legion::Extensions::MicrosoftTeams::Runners::Bot'
9
- def runner_function = 'handle_message'
9
+ def runner_function = 'dispatch_message'
10
10
  def check_subtask? = false
11
11
  def generate_task? = false
12
12
 
@@ -49,8 +49,7 @@ module Legion
49
49
 
50
50
  def resolve_token
51
51
  if defined?(Legion::Extensions::MicrosoftTeams::Helpers::TokenCache)
52
- cache = Legion::Extensions::MicrosoftTeams::Helpers::TokenCache.new
53
- cache.cached_delegated_token
52
+ Legion::Extensions::MicrosoftTeams::Helpers::TokenCache.instance.cached_delegated_token
54
53
  end
55
54
  rescue StandardError
56
55
  nil
@@ -71,6 +71,15 @@ module Legion
71
71
  { result: response.body }
72
72
  end
73
73
 
74
+ def dispatch_message(mode: :direct, **payload)
75
+ case mode.to_s
76
+ when 'observe'
77
+ observe_message(**payload)
78
+ else
79
+ handle_message(**payload)
80
+ end
81
+ end
82
+
74
83
  def handle_message(chat_id:, conversation_id:, text:, owner_id:, mode: :direct, **opts)
75
84
  command_result = handle_command(text: text, owner_id: owner_id, chat_id: chat_id, **opts)
76
85
  if command_result
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module MicrosoftTeams
6
- VERSION = '0.6.5'
6
+ VERSION = '0.6.7'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lex-microsoft_teams
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.5
4
+ version: 0.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity