lex-microsoft_teams 0.6.34 → 0.6.35
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 +7 -0
- data/CLAUDE.md +2 -2
- data/README.md +33 -5
- data/lib/legion/extensions/microsoft_teams/actors/channel_poller.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/actors/direct_chat_poller.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/actors/meeting_ingest.rb +2 -2
- data/lib/legion/extensions/microsoft_teams/actors/observed_chat_poller.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/actors/presence_poller.rb +1 -1
- data/lib/legion/extensions/microsoft_teams/helpers/token_cache.rb +11 -7
- 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: a180c2f6406a210f6d7f76959fd16a2030e0c43d3269901228f7a6464425d456
|
|
4
|
+
data.tar.gz: 7ea5b4c6a093f23875cc841b18e490c5812654a2bda3faf73a36453345ff4d0f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d7cbc835079bdeed837263bfbb98269ed0685223a18c002c2b11e726c85c9f2d141b97a1cb58b1270322ef63766ec5d1ee5de415e84a272bf86e48c5347bd04
|
|
7
|
+
data.tar.gz: 9e30a76561740ce85410bbf278958a2f7bff53a3dfc9476d10db329b0ee174e0baffeac9bdaec01c0c04784f2922287756c50876555984c02d1f1bf0f25cda52
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.6.35] - 2026-04-09
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Split `cached_graph_token` into separate `cached_delegated_token` and `cached_app_token` helpers in `TokenCache` — delegated token used for user-context calls, app token for application-credential (client_credentials) calls
|
|
9
|
+
- Added `Broker` soft consumer actor to cache app tokens via client_credentials flow without blocking extension boot
|
|
10
|
+
- Updated all actors (ChannelPoller, DirectChatPoller, MeetingIngest, ObservedChatPoller, PresencePoller) to route token selection based on call context: delegated token for user-scoped Graph API paths, app token for app-scoped paths
|
|
11
|
+
|
|
5
12
|
## [0.6.34] - 2026-04-03
|
|
6
13
|
|
|
7
14
|
### Fixed
|
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.34
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
@@ -264,7 +264,7 @@ Optional framework dependencies (guarded with `defined?`, not in gemspec):
|
|
|
264
264
|
|
|
265
265
|
```bash
|
|
266
266
|
bundle install
|
|
267
|
-
bundle exec rspec #
|
|
267
|
+
bundle exec rspec # 352 specs across 44 spec files
|
|
268
268
|
bundle exec rubocop # Clean
|
|
269
269
|
```
|
|
270
270
|
|
data/README.md
CHANGED
|
@@ -88,6 +88,23 @@ gem install lex-microsoft_teams
|
|
|
88
88
|
### Cache Ingest
|
|
89
89
|
- `ingest_cache` — Ingest messages from the local Teams cache into lex-memory as episodic traces; returns `{ stored:, skipped:, latest_time: }`
|
|
90
90
|
|
|
91
|
+
### People
|
|
92
|
+
- `get_profile` — Get Graph API profile for a user (default: `/me`)
|
|
93
|
+
- `list_people` — List relevant people for a user via `/me/people`
|
|
94
|
+
|
|
95
|
+
### AI Insights
|
|
96
|
+
- `list_meeting_ai_insights` — List AI-generated insights for an online meeting
|
|
97
|
+
- `get_meeting_ai_insight` — Get a specific AI insight
|
|
98
|
+
- `list_meeting_recordings` — List recordings for an online meeting
|
|
99
|
+
- `get_meeting_recording` — Get a specific meeting recording
|
|
100
|
+
- `list_call_records` — List call records from Graph API
|
|
101
|
+
- `get_call_record` — Get a specific call record
|
|
102
|
+
|
|
103
|
+
### Ownership
|
|
104
|
+
- `sync_owners` — Sync team ownership data from Graph API (single team or all teams)
|
|
105
|
+
- `detect_orphans` — Detect teams with no current owners
|
|
106
|
+
- `get_team_owners` — Get owners for a specific team
|
|
107
|
+
|
|
91
108
|
### Adaptive Cards
|
|
92
109
|
- `build_card` — Build an Adaptive Card payload
|
|
93
110
|
- `text_block` — Create a TextBlock element
|
|
@@ -109,9 +126,20 @@ gem install lex-microsoft_teams
|
|
|
109
126
|
- `observe_message` — Conversation observer that extracts tasks, context, and relationship data from subscribed human chats (disabled by default, compliance-gated)
|
|
110
127
|
|
|
111
128
|
**Actors:**
|
|
112
|
-
- `
|
|
113
|
-
- `
|
|
114
|
-
- `
|
|
129
|
+
- `CacheBulkIngest` — Once at startup: full local LevelDB cache ingest
|
|
130
|
+
- `CacheSync` — Every 5min: incremental new-message ingest from local cache
|
|
131
|
+
- `DirectChatPoller` — Every 5s: polls bot DM chats via Graph API, publishes to AMQP
|
|
132
|
+
- `ObservedChatPoller` — Every 30s: polls subscribed conversations (compliance-gated, disabled by default)
|
|
133
|
+
- `MessageProcessor` — AMQP subscription actor, routes messages by mode
|
|
134
|
+
- `AuthValidator` — Once at boot: validates and restores delegated tokens
|
|
135
|
+
- `TokenRefresher` — Every 15min: keeps delegated tokens fresh
|
|
136
|
+
- `ProfileIngest` — Once (5s delay): four-phase cognitive data pipeline after auth
|
|
137
|
+
- `ApiIngest` — Every 30min: Graph API ingest with HWM dedup
|
|
138
|
+
- `ChannelPoller` — Every 60s: polls joined team channels for new messages
|
|
139
|
+
- `MeetingIngest` — Every 5min: polls online meetings, fetches transcripts and AI insights
|
|
140
|
+
- `PresencePoller` — Every 60s: polls Graph API presence, logs changes
|
|
141
|
+
- `AbsorbMeeting` — Subscription: absorbs Teams meeting data via absorber framework
|
|
142
|
+
- `IncrementalSync` — Every 15min: periodic re-sync with HWM dedup
|
|
115
143
|
|
|
116
144
|
**Helpers:**
|
|
117
145
|
- `SessionManager` — Multi-turn LLM session lifecycle with lex-memory persistence
|
|
@@ -143,11 +171,11 @@ auth = Legion::Extensions::MicrosoftTeams::Helpers::BrowserAuth.new(
|
|
|
143
171
|
result = auth.authenticate # returns token hash with access_token, refresh_token, expires_in
|
|
144
172
|
```
|
|
145
173
|
|
|
146
|
-
Tokens are stored in Vault (`
|
|
174
|
+
Tokens are stored in Vault at a per-user path (`{USER}/microsoft_teams/delegated_token`) and silently refreshed before expiry.
|
|
147
175
|
|
|
148
176
|
## Standalone Client
|
|
149
177
|
|
|
150
|
-
The `Client` class includes all runner modules (Auth, Teams, Chats, Messages, Channels, ChannelMessages, Subscriptions, AdaptiveCards, Bot, Presence, Meetings, Transcripts, LocalCache, CacheIngest).
|
|
178
|
+
The `Client` class includes all runner modules (Auth, Teams, Chats, Messages, Channels, ChannelMessages, Subscriptions, AdaptiveCards, Bot, Presence, Meetings, Transcripts, LocalCache, CacheIngest, People, ProfileIngest, ApiIngest, AiInsights, Ownership).
|
|
151
179
|
|
|
152
180
|
```ruby
|
|
153
181
|
client = Legion::Extensions::MicrosoftTeams::Client.new(
|
|
@@ -10,7 +10,7 @@ module Legion
|
|
|
10
10
|
DEFAULT_INGEST_INTERVAL = 300
|
|
11
11
|
|
|
12
12
|
def runner_class = Legion::Extensions::MicrosoftTeams::Helpers::TokenCache
|
|
13
|
-
def runner_function = '
|
|
13
|
+
def runner_function = 'cached_delegated_token'
|
|
14
14
|
def run_now? = false
|
|
15
15
|
def use_runner? = false
|
|
16
16
|
def check_subtask? = false
|
|
@@ -52,7 +52,7 @@ module Legion
|
|
|
52
52
|
|
|
53
53
|
def manual
|
|
54
54
|
log.info('MeetingIngest polling for meetings')
|
|
55
|
-
token = token_cache.
|
|
55
|
+
token = token_cache.cached_delegated_token
|
|
56
56
|
return if token.nil?
|
|
57
57
|
|
|
58
58
|
conn = graph_connection(token: token)
|
|
@@ -45,8 +45,15 @@ module Legion
|
|
|
45
45
|
|
|
46
46
|
# --- Application token (client_credentials) ---
|
|
47
47
|
|
|
48
|
-
def
|
|
48
|
+
def cached_app_token
|
|
49
49
|
@mutex.synchronize do
|
|
50
|
+
# Phase 8: Broker-managed Entra app token (short-circuits cache path)
|
|
51
|
+
if defined?(Legion::Identity::Broker)
|
|
52
|
+
token = Legion::Identity::Broker.token_for(:entra)
|
|
53
|
+
return token if token
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Legacy: self-managed client_credentials + cache
|
|
50
57
|
if @token_cache && !token_expired?(@token_cache)
|
|
51
58
|
log.debug('Using cached app token')
|
|
52
59
|
return @token_cache[:token]
|
|
@@ -55,19 +62,16 @@ module Legion
|
|
|
55
62
|
result = refresh_app_token
|
|
56
63
|
return result if result
|
|
57
64
|
|
|
58
|
-
if @delegated_cache && !token_expired?(@delegated_cache)
|
|
59
|
-
log.debug('No app token available, using delegated token')
|
|
60
|
-
return @delegated_cache[:token]
|
|
61
|
-
end
|
|
62
|
-
|
|
63
65
|
unless @app_token_warned
|
|
64
|
-
log.warn('No app
|
|
66
|
+
log.warn('No app token available for Graph API calls')
|
|
65
67
|
@app_token_warned = true
|
|
66
68
|
end
|
|
67
69
|
nil
|
|
68
70
|
end
|
|
69
71
|
end
|
|
70
72
|
|
|
73
|
+
alias cached_graph_token cached_app_token
|
|
74
|
+
|
|
71
75
|
def clear_token_cache!
|
|
72
76
|
@mutex.synchronize do
|
|
73
77
|
@token_cache = nil
|