lex-microsoft_teams 0.6.27 → 0.6.28
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 +13 -0
- data/CLAUDE.md +15 -6
- data/lib/legion/extensions/microsoft_teams/actors/api_ingest.rb +7 -1
- data/lib/legion/extensions/microsoft_teams/actors/auth_validator.rb +5 -2
- data/lib/legion/extensions/microsoft_teams/actors/profile_ingest.rb +7 -1
- data/lib/legion/extensions/microsoft_teams/actors/token_refresher.rb +8 -1
- data/lib/legion/extensions/microsoft_teams/helpers/subscription_registry.rb +2 -1
- data/lib/legion/extensions/microsoft_teams/helpers/token_cache.rb +8 -1
- data/lib/legion/extensions/microsoft_teams/helpers/trace_retriever.rb +4 -2
- data/lib/legion/extensions/microsoft_teams/runners/profile_ingest.rb +2 -1
- data/lib/legion/extensions/microsoft_teams/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2635c7d3e8d564623f365709464ce8b8e20bb84e535c20d6a268d2419cf816cc
|
|
4
|
+
data.tar.gz: e3886e4a92ab9e885d48308d2657fea15d9a853d6be25ca56a4083033a50cba6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 159525c1fbf00aa64cdd5ce9b992b2210dbd1077382c8a51ba188be8670139c7b393612f10401ab88f457d24ab3b998890f9ca4c972a104873c78ce428d0d010
|
|
7
|
+
data.tar.gz: 6d1110df11e58b20a3f518f0df2bbd6788cc351408b247010a7039666fde2ed46754153e4ffc20381c426417b291d42381b13157589bcdaf0ea931ab3b5fd353
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.6.28] - 2026-03-30
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- `teams_auth_settings` in AuthValidator, TokenRefresher, and TokenCache now falls back to parent `[:microsoft_teams][:tenant_id]`/`[:client_id]` when not found under `[:auth]`, fixing browser auth never triggering when config uses top-level keys
|
|
9
|
+
- `TokenCache#teams_auth_settings` now includes ENV fallback for `AZURE_TENANT_ID`/`AZURE_CLIENT_ID` (previously missing, inconsistent with actor implementations) and parent-level `client_secret` fallback
|
|
10
|
+
- Silent rescue blocks in TraceRetriever (`format_single_trace`, `trace_age_label`), SubscriptionRegistry (`parse_stored`), and ProfileIngest runner (`ingest_self` presence fetch) now log errors instead of swallowing them
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- AuthValidator actor delay increased from 2s to 90s to allow Vault, transport, cache, and delegated auth to fully initialize before validation runs
|
|
14
|
+
- ProfileIngest actor delay increased from 5s to 95s to fire after AuthValidator completes (Once actor — no retry if token missing)
|
|
15
|
+
- ApiIngest actor delay increased from 10s to 95s to fire after AuthValidator completes delegated auth
|
|
16
|
+
- CLAUDE.md updated: added 5 undocumented actors (AbsorbMeeting, ApiIngest, ChannelPoller, MeetingIngest, PresencePoller), 3 runners (AiInsights, ApiIngest, Ownership), 1 helper (GraphClient), corrected spec counts
|
|
17
|
+
|
|
5
18
|
## [0.6.27] - 2026-03-29
|
|
6
19
|
|
|
7
20
|
### Changed
|
data/CLAUDE.md
CHANGED
|
@@ -10,7 +10,7 @@ Legion Extension that connects LegionIO to Microsoft Teams via Graph API and Bot
|
|
|
10
10
|
|
|
11
11
|
**GitHub**: https://github.com/LegionIO/lex-microsoft_teams
|
|
12
12
|
**License**: MIT
|
|
13
|
-
**Version**: 0.6.
|
|
13
|
+
**Version**: 0.6.28
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
@@ -32,16 +32,24 @@ Legion::Extensions::MicrosoftTeams
|
|
|
32
32
|
│ ├── LocalCache # Offline message extraction from local LevelDB cache
|
|
33
33
|
│ ├── CacheIngest # Ingest cached messages into lex-memory as episodic traces
|
|
34
34
|
│ ├── People # Graph API /me and /me/people (profile + relevant contacts)
|
|
35
|
-
│
|
|
35
|
+
│ ├── ProfileIngest # Four-phase cognitive pipeline (self, people, conversations, teams/meetings)
|
|
36
|
+
│ ├── ApiIngest # Graph API ingest (top contacts, 1:1 chat messages, HWM dedup)
|
|
37
|
+
│ ├── AiInsights # Graph API meeting AI insights, recordings, call records
|
|
38
|
+
│ └── Ownership # Graph API ownership sync
|
|
36
39
|
├── Actors/
|
|
37
40
|
│ ├── CacheBulkIngest # Once: full cache ingest at startup (imprint window support)
|
|
38
41
|
│ ├── CacheSync # Every 5min: incremental ingest of new messages
|
|
39
42
|
│ ├── DirectChatPoller # Every 5s: polls bot DM chats via Graph API
|
|
40
43
|
│ ├── ObservedChatPoller # Every 30s: polls subscribed human conversations (compliance-gated)
|
|
41
44
|
│ ├── MessageProcessor # Subscription: consumes AMQP queue, routes by mode
|
|
42
|
-
│ ├── AuthValidator # Once: validates/restores delegated tokens on boot
|
|
45
|
+
│ ├── AuthValidator # Once (90s delay): validates/restores delegated tokens on boot
|
|
43
46
|
│ ├── TokenRefresher # Every 15min (configurable): keeps delegated tokens fresh
|
|
44
|
-
│ ├── ProfileIngest # Once (
|
|
47
|
+
│ ├── ProfileIngest # Once (95s delay): four-phase data pipeline after auth
|
|
48
|
+
│ ├── ApiIngest # Every 30min (95s delay): Graph API ingest with HWM dedup
|
|
49
|
+
│ ├── ChannelPoller # Every 60s: polls joined team channels for new messages
|
|
50
|
+
│ ├── MeetingIngest # Every 5min: polls online meetings, fetches transcripts and AI insights
|
|
51
|
+
│ ├── PresencePoller # Every 60s: polls Graph API presence, logs changes
|
|
52
|
+
│ ├── AbsorbMeeting # Subscription: absorbs Teams meeting data via absorber framework
|
|
45
53
|
│ └── IncrementalSync # Every 15min: periodic re-sync with HWM dedup
|
|
46
54
|
├── Transport/
|
|
47
55
|
│ ├── Exchanges/Messages # teams.messages topic exchange
|
|
@@ -62,7 +70,8 @@ Legion::Extensions::MicrosoftTeams
|
|
|
62
70
|
│ ├── CallbackServer # Ephemeral TCP server for OAuth redirect callback
|
|
63
71
|
│ ├── PermissionGuard # Circuit breaker for 403 errors with exponential backoff
|
|
64
72
|
│ ├── TraceRetriever # Retrieves memory traces from the shared store for bot context (2000-token budget, strength-ranked dedup)
|
|
65
|
-
│
|
|
73
|
+
│ ├── TransformDefinitions # lex-transformer definitions for conversation extraction and person summary
|
|
74
|
+
│ └── GraphClient # Graph API wrapper mixin (graph_get, graph_post, graph_paginate, GraphError)
|
|
66
75
|
├── Hooks/
|
|
67
76
|
│ └── Auth # OAuth callback hook (mount '/callback') → /api/extensions/microsoft_teams/hooks/auth/handle
|
|
68
77
|
├── CLI/
|
|
@@ -255,7 +264,7 @@ Optional framework dependencies (guarded with `defined?`, not in gemspec):
|
|
|
255
264
|
|
|
256
265
|
```bash
|
|
257
266
|
bundle install
|
|
258
|
-
bundle exec rspec # ~
|
|
267
|
+
bundle exec rspec # ~342 specs across 43 spec files (as of v0.6.28)
|
|
259
268
|
bundle exec rubocop # Clean
|
|
260
269
|
```
|
|
261
270
|
|
|
@@ -18,7 +18,13 @@ module Legion
|
|
|
18
18
|
def run_now? = true
|
|
19
19
|
|
|
20
20
|
def delay
|
|
21
|
-
|
|
21
|
+
if defined?(Legion::Extensions::MicrosoftTeams::Actor::AuthValidator)
|
|
22
|
+
auth_validator = Legion::Extensions::MicrosoftTeams::Actor::AuthValidator.allocate
|
|
23
|
+
base_delay = auth_validator.respond_to?(:delay) ? auth_validator.delay.to_f : 90.0
|
|
24
|
+
base_delay + 5.0 # must fire shortly after AuthValidator completes delegated auth
|
|
25
|
+
else
|
|
26
|
+
95.0 # conservative boot-ordering fallback if AuthValidator is unavailable
|
|
27
|
+
end
|
|
22
28
|
end
|
|
23
29
|
|
|
24
30
|
def time
|
|
@@ -10,7 +10,7 @@ module Legion
|
|
|
10
10
|
def generate_task? = false
|
|
11
11
|
|
|
12
12
|
def delay
|
|
13
|
-
|
|
13
|
+
90.0
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def enabled?
|
|
@@ -105,7 +105,10 @@ module Legion
|
|
|
105
105
|
def teams_auth_settings
|
|
106
106
|
settings = if defined?(Legion::Settings)
|
|
107
107
|
ms = Legion::Settings[:microsoft_teams]
|
|
108
|
-
|
|
108
|
+
auth = ms && ms[:auth].is_a?(Hash) ? ms[:auth].dup : {}
|
|
109
|
+
auth[:tenant_id] ||= ms[:tenant_id] if ms
|
|
110
|
+
auth[:client_id] ||= ms[:client_id] if ms
|
|
111
|
+
auth
|
|
109
112
|
else
|
|
110
113
|
{}
|
|
111
114
|
end
|
|
@@ -12,7 +12,13 @@ module Legion
|
|
|
12
12
|
def generate_task? = false
|
|
13
13
|
|
|
14
14
|
def delay
|
|
15
|
-
|
|
15
|
+
if defined?(Legion::Extensions::MicrosoftTeams::Actor::AuthValidator)
|
|
16
|
+
auth_validator = Legion::Extensions::MicrosoftTeams::Actor::AuthValidator.allocate
|
|
17
|
+
base_delay = auth_validator.respond_to?(:delay) ? auth_validator.delay.to_f : 90.0
|
|
18
|
+
base_delay + 5.0
|
|
19
|
+
else
|
|
20
|
+
95.0
|
|
21
|
+
end
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
def enabled?
|
|
@@ -100,7 +100,14 @@ module Legion
|
|
|
100
100
|
def teams_auth_settings
|
|
101
101
|
settings = if defined?(Legion::Settings)
|
|
102
102
|
ms = Legion::Settings[:microsoft_teams]
|
|
103
|
-
|
|
103
|
+
auth = if ms && ms[:auth].is_a?(Hash)
|
|
104
|
+
ms[:auth].dup
|
|
105
|
+
else
|
|
106
|
+
{}
|
|
107
|
+
end
|
|
108
|
+
auth[:tenant_id] ||= ms[:tenant_id] if ms
|
|
109
|
+
auth[:client_id] ||= ms[:client_id] if ms
|
|
110
|
+
auth
|
|
104
111
|
else
|
|
105
112
|
{}
|
|
106
113
|
end
|
|
@@ -123,7 +123,8 @@ module Legion
|
|
|
123
123
|
v[:created_at] = Time.parse(v[:created_at]) if v[:created_at].is_a?(String)
|
|
124
124
|
v
|
|
125
125
|
end
|
|
126
|
-
rescue ::JSON::ParserError =>
|
|
126
|
+
rescue ::JSON::ParserError => e
|
|
127
|
+
log.warn("SubscriptionRegistry: corrupted subscription data, resetting: #{e.message}")
|
|
127
128
|
{}
|
|
128
129
|
end
|
|
129
130
|
|
|
@@ -386,7 +386,14 @@ module Legion
|
|
|
386
386
|
return {} unless defined?(Legion::Settings)
|
|
387
387
|
|
|
388
388
|
ms = Legion::Settings[:microsoft_teams]
|
|
389
|
-
|
|
389
|
+
auth = ms && ms[:auth].is_a?(Hash) ? ms[:auth].dup : {}
|
|
390
|
+
auth[:tenant_id] ||= ms[:tenant_id] if ms
|
|
391
|
+
auth[:client_id] ||= ms[:client_id] if ms
|
|
392
|
+
auth[:client_secret] ||= ms[:client_secret] if ms
|
|
393
|
+
auth[:tenant_id] ||= ENV.fetch('AZURE_TENANT_ID', nil)
|
|
394
|
+
auth[:client_id] ||= ENV.fetch('AZURE_CLIENT_ID', nil)
|
|
395
|
+
auth[:client_secret] ||= ENV.fetch('AZURE_CLIENT_SECRET', nil)
|
|
396
|
+
auth
|
|
390
397
|
end
|
|
391
398
|
end
|
|
392
399
|
end
|
|
@@ -95,7 +95,8 @@ module Legion
|
|
|
95
95
|
age = trace_age_label(trace[:created_at] || trace[:last_reinforced])
|
|
96
96
|
|
|
97
97
|
"- [#{type}] #{content} (#{age}, tags: #{tags})"
|
|
98
|
-
rescue StandardError =>
|
|
98
|
+
rescue StandardError => e
|
|
99
|
+
log_trace_error('format_single_trace', e)
|
|
99
100
|
nil
|
|
100
101
|
end
|
|
101
102
|
|
|
@@ -109,7 +110,8 @@ module Legion
|
|
|
109
110
|
when 86_400..604_800 then "#{(seconds / 86_400).to_i}d ago"
|
|
110
111
|
else "#{(seconds / 604_800).to_i}w ago"
|
|
111
112
|
end
|
|
112
|
-
rescue StandardError =>
|
|
113
|
+
rescue StandardError => e
|
|
114
|
+
log_trace_error('trace_age_label', e)
|
|
113
115
|
'unknown age'
|
|
114
116
|
end
|
|
115
117
|
|