lex-microsoft_teams 0.6.51 → 0.6.53

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +10 -1
  4. data/lib/legion/extensions/microsoft_teams/absorbers/channel.rb +3 -3
  5. data/lib/legion/extensions/microsoft_teams/absorbers/chat.rb +3 -3
  6. data/lib/legion/extensions/microsoft_teams/absorbers/meeting.rb +2 -2
  7. data/lib/legion/extensions/microsoft_teams/actors/absorb_channel.rb +2 -2
  8. data/lib/legion/extensions/microsoft_teams/actors/absorb_chat.rb +2 -2
  9. data/lib/legion/extensions/microsoft_teams/actors/absorb_meeting.rb +2 -2
  10. data/lib/legion/extensions/microsoft_teams/actors/api_ingest.rb +16 -6
  11. data/lib/legion/extensions/microsoft_teams/actors/cache_bulk_ingest.rb +1 -1
  12. data/lib/legion/extensions/microsoft_teams/actors/channel_poller.rb +1 -1
  13. data/lib/legion/extensions/microsoft_teams/actors/direct_chat_poller.rb +1 -1
  14. data/lib/legion/extensions/microsoft_teams/actors/incremental_sync.rb +1 -1
  15. data/lib/legion/extensions/microsoft_teams/actors/meeting_ingest.rb +14 -6
  16. data/lib/legion/extensions/microsoft_teams/actors/observed_chat_poller.rb +1 -1
  17. data/lib/legion/extensions/microsoft_teams/actors/presence_poller.rb +14 -5
  18. data/lib/legion/extensions/microsoft_teams/actors/profile_ingest.rb +2 -2
  19. data/lib/legion/extensions/microsoft_teams/faraday/retry_after.rb +1 -1
  20. data/lib/legion/extensions/microsoft_teams/helpers/client.rb +4 -4
  21. data/lib/legion/extensions/microsoft_teams/helpers/graph_cache.rb +3 -3
  22. data/lib/legion/extensions/microsoft_teams/helpers/graph_client.rb +1 -1
  23. data/lib/legion/extensions/microsoft_teams/helpers/high_water_mark.rb +1 -1
  24. data/lib/legion/extensions/microsoft_teams/helpers/prompt_resolver.rb +1 -1
  25. data/lib/legion/extensions/microsoft_teams/helpers/session_manager.rb +1 -1
  26. data/lib/legion/extensions/microsoft_teams/helpers/throttle_aware.rb +185 -0
  27. data/lib/legion/extensions/microsoft_teams/helpers/trace_retriever.rb +1 -1
  28. data/lib/legion/extensions/microsoft_teams/local_cache/sstable_reader.rb +1 -1
  29. data/lib/legion/extensions/microsoft_teams/runners/api_ingest.rb +91 -19
  30. data/lib/legion/extensions/microsoft_teams/runners/bot.rb +2 -2
  31. data/lib/legion/extensions/microsoft_teams/runners/cache_ingest.rb +2 -2
  32. data/lib/legion/extensions/microsoft_teams/runners/profile_ingest.rb +89 -35
  33. data/lib/legion/extensions/microsoft_teams/version.rb +1 -1
  34. data/lib/legion/extensions/microsoft_teams.rb +3 -1
  35. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76994e2ead987d49e26c776ff30d9e6a2b78789a12654d38e80e36e81814d703
4
- data.tar.gz: ebf842a7daf81e017078e894d111d38f9474ecc1b3ced0f4105cea29dfb1b7fb
3
+ metadata.gz: 1c452da3646f36302d562fefd816a7b00621e95d819017c6125cc7c0fcb1ea74
4
+ data.tar.gz: c11fa2558cb00fa66d884360242f98a574b68d4ecda61451ba7e1a5de3b8067c
5
5
  SHA512:
6
- metadata.gz: ac9c034b99ef410ab0c1727f83409cd8d8d063b20082ace208be85e0a1bbd4c8314b983caf4c2a80af82d9ca6245e3616d67dae3f60cdff4a204bea087b2d777
7
- data.tar.gz: 1b13b4c36751a4dd02888c3867acafd0594d6a1a83e00668481a07533997de3bfce5abd68b66fc56adbb5bce6006601d1994daa16ebdb3738bd9309f0ff244a1
6
+ metadata.gz: db1531411cd4b67f36b644652e3549aae7b9f3360a987187f04a8bc39c9d436bb8dea21873f61edcbf85964b6bcf5889e68bd64bd786f1967f0426f5aede2d51
7
+ data.tar.gz: 6798cc2a718ac3ba43db14b3476abaeab0279d9747c90c8d47f6dfd185f86271787f48042ab22d0dcdfce48af5d7cdf505bb4bf0766601d0d2bfdd8f37bfeb7a
data/.rubocop.yml CHANGED
@@ -16,6 +16,10 @@ Legion/Extension/EveryActorRequiresTime:
16
16
  # RunnerReturnHash fires on private helper methods inside runner modules (false positives)
17
17
  Legion/Extension/RunnerReturnHash:
18
18
  Enabled: false
19
+
20
+ # This extension uses trace types (episodic, semantic, procedural) not LLM taxonomy types
21
+ Legion/Llm/TaxonomyEnum:
22
+ Enabled: false
19
23
 
20
24
  Metrics/CyclomaticComplexity:
21
25
  Max: 25
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.53] - 2026-07-15
4
+ ### Fixed
5
+ - Fix throttle propagation, invalid OData filter, member index priority, stop trace spam from API fetches
6
+
7
+ ## [0.6.52] - 2026-05-29
8
+ ### Fixed
9
+ - **Actors now defer their next scheduled run on a Graph throttle** instead of re-firing on their fixed timer interval — resolves the 0.6.51 "Known follow-up". New `Helpers::ThrottleAware` mixin records a "suppress until" instant of `now + retry_after` when a Graph call raises `Errors::Throttled`; subsequent ticks short-circuit until that window elapses. Wired into `PresencePoller`, `MeetingIngest`, and `ApiIngest`. Falls back to a bounded 60s deferral when the server gave no usable `Retry-After`, and clamps any single deferral to 600s. Previously a poller on a 30–300s interval would walk straight back into the still-open shared circuit every interval, emitting a `[throttle_circuit] hard circuit` ERROR (and a duplicate `Errors::Throttled` WARN/ERROR) each tick while ingesting nothing.
10
+ - **`ProfileIngest#full_ingest` and `ApiIngest#ingest_api` now propagate `Errors::Throttled`** rather than folding it into a per-stage error hash. `full_ingest` catches it once and aborts the remaining fan-out stages — once the shared circuit is open every later stage would only raise `Throttled(attempts: 0)` instantly, so continuing produced a burst of identical errors. The actor that drives `ingest_api` uses the propagated throttle to open its deferral window. Non-throttle errors keep their existing error-result behavior.
11
+
3
12
  ## [0.6.51] - 2026-05-27
4
13
  ### Added
5
14
  - `Faraday::RetryAfter` middleware honoring `Retry-After` per RFC 9110 §10.2.3 (originally RFC 7231 §7.1.3) in both delta-seconds and HTTP-date forms. Retries HTTP 429 by default; 503/504 opt-in. Bounded by `max_retries` and cumulative `max_wait`; ±jitter on advertised wait to avoid thundering-herd. Configurable via `microsoft_teams.client.retry.{max_retries,max_wait,jitter,fallback_wait,retry_statuses}`; `fetch` semantics preserve explicit falsey values.
@@ -18,7 +27,7 @@
18
27
  - Actors that were accidentally re-enabled by `952607c` (rubocop removed `return false` guards) are now properly gated by `settings[:actor_name][:enabled]` — `presence_poller`, `channel_poller`, `direct_chat_poller`, and `observed_chat_poller` all default to `false`.
19
28
 
20
29
  ### Known follow-up
21
- - Actors (`*_poller.rb`, `meeting_ingest`, `profile_ingest`) still catch `Errors::Throttled` via the generic `rescue StandardError` block but do not yet *defer their next scheduled run* using the carried `retry_after`. To be addressed in a follow-up issue.
30
+ - Actors (`*_poller.rb`, `meeting_ingest`, `profile_ingest`) still catch `Errors::Throttled` via the generic `rescue StandardError` block but do not yet *defer their next scheduled run* using the carried `retry_after`. To be addressed in a follow-up issue. *(Resolved in [Unreleased] — see `Helpers::ThrottleAware`.)*
22
31
 
23
32
  ## [0.6.50] - 2026-05-27
24
33
  ### Added
@@ -57,7 +57,7 @@ module Legion
57
57
  def graph_token
58
58
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
59
59
  rescue StandardError => e
60
- handle_exception(e, level: :debug, operation: 'Channel#graph_token')
60
+ handle_exception(e, level: :warn, operation: 'Channel#graph_token')
61
61
  nil
62
62
  end
63
63
 
@@ -85,7 +85,7 @@ module Legion
85
85
 
86
86
  { team_id: team_id, channel_id: channel_id, message_id: message_id }
87
87
  rescue StandardError => e
88
- handle_exception(e, level: :debug, operation: 'Channel#extract_ids', url: url)
88
+ handle_exception(e, level: :warn, operation: 'Channel#extract_ids', url: url)
89
89
  nil
90
90
  end
91
91
 
@@ -202,7 +202,7 @@ module Legion
202
202
  " ↳ [#{timestamp}] #{sender}: #{text}"
203
203
  end
204
204
  rescue StandardError => e
205
- handle_exception(e, level: :debug, operation: 'Channel#fetch_reply_lines',
205
+ handle_exception(e, level: :warn, operation: 'Channel#fetch_reply_lines',
206
206
  team_id: team_id, channel_id: channel_id, message_id: message_id)
207
207
  []
208
208
  end
@@ -46,7 +46,7 @@ module Legion
46
46
  def graph_token
47
47
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
48
48
  rescue StandardError => e
49
- handle_exception(e, level: :debug, operation: 'Chat#graph_token')
49
+ handle_exception(e, level: :warn, operation: 'Chat#graph_token')
50
50
  nil
51
51
  end
52
52
 
@@ -60,7 +60,7 @@ module Legion
60
60
 
61
61
  URI.decode_uri_component(match[1])
62
62
  rescue StandardError => e
63
- handle_exception(e, level: :debug, operation: 'Chat#extract_chat_id', url: url)
63
+ handle_exception(e, level: :warn, operation: 'Chat#extract_chat_id', url: url)
64
64
  nil
65
65
  end
66
66
 
@@ -150,7 +150,7 @@ module Legion
150
150
  " ↳ [#{timestamp}] #{sender}: #{text}"
151
151
  end
152
152
  rescue StandardError => e
153
- handle_exception(e, level: :debug, operation: 'Chat#fetch_reply_lines',
153
+ handle_exception(e, level: :warn, operation: 'Chat#fetch_reply_lines',
154
154
  chat_id: chat_id, message_id: message_id)
155
155
  []
156
156
  end
@@ -51,7 +51,7 @@ module Legion
51
51
  def graph_token
52
52
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
53
53
  rescue StandardError => e
54
- handle_exception(e, level: :debug, operation: 'Meeting#graph_token')
54
+ handle_exception(e, level: :warn, operation: 'Meeting#graph_token')
55
55
  nil
56
56
  end
57
57
 
@@ -75,7 +75,7 @@ module Legion
75
75
  match = uri.path.match(%r{/l/chat/(19:meeting_[^/]+)})
76
76
  match&.[](1)
77
77
  rescue URI::InvalidURIError => e
78
- handle_exception(e, level: :debug, operation: 'Meeting#extract_meeting_thread_id', url: url)
78
+ handle_exception(e, level: :warn, operation: 'Meeting#extract_meeting_thread_id', url: url)
79
79
  nil
80
80
  end
81
81
 
@@ -14,7 +14,7 @@ module Legion
14
14
  defined?(Legion::Extensions::Absorbers::Base) &&
15
15
  defined?(Legion::Extensions::MicrosoftTeams::Absorbers::Channel)
16
16
  rescue StandardError => e
17
- handle_exception(e, level: :debug, operation: 'AbsorbChannel#enabled?')
17
+ handle_exception(e, level: :warn, operation: 'AbsorbChannel#enabled?')
18
18
  false
19
19
  end
20
20
 
@@ -53,7 +53,7 @@ module Legion
53
53
 
54
54
  data.transform_keys(&:to_sym)
55
55
  rescue StandardError => e
56
- handle_exception(e, level: :debug, operation: 'AbsorbChannel#parse_payload')
56
+ handle_exception(e, level: :warn, operation: 'AbsorbChannel#parse_payload')
57
57
  {}
58
58
  end
59
59
  end
@@ -14,7 +14,7 @@ module Legion
14
14
  defined?(Legion::Extensions::Absorbers::Base) &&
15
15
  defined?(Legion::Extensions::MicrosoftTeams::Absorbers::Chat)
16
16
  rescue StandardError => e
17
- handle_exception(e, level: :debug, operation: 'AbsorbChat#enabled?')
17
+ handle_exception(e, level: :warn, operation: 'AbsorbChat#enabled?')
18
18
  false
19
19
  end
20
20
 
@@ -53,7 +53,7 @@ module Legion
53
53
 
54
54
  data.transform_keys(&:to_sym)
55
55
  rescue StandardError => e
56
- handle_exception(e, level: :debug, operation: 'AbsorbChat#parse_payload')
56
+ handle_exception(e, level: :warn, operation: 'AbsorbChat#parse_payload')
57
57
  {}
58
58
  end
59
59
  end
@@ -14,7 +14,7 @@ module Legion
14
14
  defined?(Legion::Extensions::Absorbers::Base) &&
15
15
  defined?(Legion::Extensions::MicrosoftTeams::Absorbers::Meeting)
16
16
  rescue StandardError => e
17
- handle_exception(e, level: :debug, operation: 'AbsorbMeeting#enabled?')
17
+ handle_exception(e, level: :warn, operation: 'AbsorbMeeting#enabled?')
18
18
  false
19
19
  end
20
20
 
@@ -53,7 +53,7 @@ module Legion
53
53
 
54
54
  data.transform_keys(&:to_sym)
55
55
  rescue StandardError => e
56
- handle_exception(e, level: :debug, operation: 'AbsorbMeeting#parse_payload')
56
+ handle_exception(e, level: :warn, operation: 'AbsorbMeeting#parse_payload')
57
57
  {}
58
58
  end
59
59
  end
@@ -5,6 +5,8 @@ module Legion
5
5
  module MicrosoftTeams
6
6
  module Actor
7
7
  class ApiIngest < Legion::Extensions::Actors::Every
8
+ include Legion::Extensions::MicrosoftTeams::Helpers::ThrottleAware
9
+
8
10
  def runner_class = Legion::Extensions::MicrosoftTeams::Runners::ApiIngest
9
11
 
10
12
  def runner_function = 'ingest_api'
@@ -22,7 +24,7 @@ module Legion
22
24
  base_delay = auth_validator.respond_to?(:delay) ? auth_validator.delay.to_f : 9.0
23
25
  [base_delay + 5.0, 14].max
24
26
  rescue StandardError => e
25
- handle_exception(e, level: :debug, operation: 'ApiIngest#delay')
27
+ handle_exception(e, level: :warn, operation: 'ApiIngest#delay')
26
28
  14
27
29
  end
28
30
 
@@ -40,6 +42,18 @@ module Legion
40
42
 
41
43
  def manual
42
44
  log.debug('ApiIngest#manual starting')
45
+ # The runner re-raises Errors::Throttled (rather than folding it
46
+ # into an error result) precisely so this actor can defer its
47
+ # next run by the advertised retry_after instead of charging the
48
+ # shared Graph circuit again on the next interval.
49
+ with_throttle_deferral { run_ingest }
50
+ rescue StandardError => e
51
+ handle_exception(e, level: :error, operation: 'ApiIngest#manual')
52
+ end
53
+
54
+ private
55
+
56
+ def run_ingest
43
57
  token = resolve_token
44
58
  unless token
45
59
  log.warn('ApiIngest: no delegated token, skipping')
@@ -57,12 +71,8 @@ module Legion
57
71
  )
58
72
  log.info("ApiIngest: #{result.inspect[0, 200]}")
59
73
  result
60
- rescue StandardError => e
61
- handle_exception(e, level: :error, operation: 'ApiIngest#manual')
62
74
  end
63
75
 
64
- private
65
-
66
76
  def token_available?
67
77
  resolve_token != nil
68
78
  end
@@ -83,7 +93,7 @@ module Legion
83
93
 
84
94
  Legion::Extensions::Coldstart::Helpers::Bootstrap.new.imprint_active?
85
95
  rescue StandardError => e
86
- handle_exception(e, level: :debug, operation: 'ApiIngest#imprint_active?')
96
+ handle_exception(e, level: :warn, operation: 'ApiIngest#imprint_active?')
87
97
  false
88
98
  end
89
99
  end
@@ -41,7 +41,7 @@ module Legion
41
41
 
42
42
  Legion::Extensions::Coldstart::Helpers::Bootstrap.new.imprint_active?
43
43
  rescue StandardError => e
44
- handle_exception(e, level: :debug, operation: 'CacheBulkIngest#imprint_active?')
44
+ handle_exception(e, level: :warn, operation: 'CacheBulkIngest#imprint_active?')
45
45
  false
46
46
  end
47
47
  end
@@ -34,7 +34,7 @@ module Legion
34
34
  def enabled?
35
35
  settings.dig(:channel_poller, :enabled)
36
36
  rescue StandardError => e
37
- handle_exception(e, level: :debug, operation: 'ChannelPoller#enabled?')
37
+ handle_exception(e, level: :warn, operation: 'ChannelPoller#enabled?')
38
38
  false
39
39
  end
40
40
 
@@ -29,7 +29,7 @@ module Legion
29
29
  defined?(Legion::Extensions::MicrosoftTeams::Runners::Bot) &&
30
30
  Legion.const_defined?(:Transport, false)
31
31
  rescue StandardError => e
32
- handle_exception(e, level: :debug, operation: 'DirectChatPoller#enabled?')
32
+ handle_exception(e, level: :warn, operation: 'DirectChatPoller#enabled?')
33
33
  false
34
34
  end
35
35
 
@@ -22,7 +22,7 @@ module Legion
22
22
  defined?(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces) &&
23
23
  token_available?
24
24
  rescue StandardError => e
25
- handle_exception(e, level: :debug, operation: 'IncrementalSync#enabled?')
25
+ handle_exception(e, level: :warn, operation: 'IncrementalSync#enabled?')
26
26
  false
27
27
  end
28
28
 
@@ -6,6 +6,7 @@ module Legion
6
6
  module Actor
7
7
  class MeetingIngest < Legion::Extensions::Actors::Every
8
8
  include Legion::Extensions::MicrosoftTeams::Helpers::Client
9
+ include Legion::Extensions::MicrosoftTeams::Helpers::ThrottleAware
9
10
 
10
11
  def runner_class = self.class
11
12
  def runner_function = 'manual'
@@ -27,7 +28,7 @@ module Legion
27
28
  settings.dig(:meeting_ingest, :enabled) &&
28
29
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.respond_to?(:load_token)
29
30
  rescue StandardError => e
30
- handle_exception(e, level: :debug, operation: 'MeetingIngest#enabled?')
31
+ handle_exception(e, level: :warn, operation: 'MeetingIngest#enabled?')
31
32
  false
32
33
  end
33
34
 
@@ -41,6 +42,17 @@ module Legion
41
42
 
42
43
  def manual
43
44
  log.info('MeetingIngest polling for meetings')
45
+ # Defer the next run when Graph throttles the meetings listing
46
+ # (the first, fixed call every tick makes); per-meeting throttles
47
+ # are handled by the inner rescue below and don't change cadence.
48
+ with_throttle_deferral { ingest_meetings }
49
+ rescue StandardError => e
50
+ handle_exception(e, level: :error, operation: 'MeetingIngest#manual')
51
+ end
52
+
53
+ private
54
+
55
+ def ingest_meetings
44
56
  token = Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
45
57
  return if token.nil?
46
58
 
@@ -57,16 +69,12 @@ module Legion
57
69
  process_meeting(meeting_id: meeting_id, subject: meeting['subject'], token: token)
58
70
  @processed_meetings.add(meeting_id)
59
71
  rescue StandardError => e
60
- handle_exception(e, level: :error, operation: 'MeetingIngest#manual',
72
+ handle_exception(e, level: :error, operation: 'MeetingIngest#ingest_meetings',
61
73
  meeting_id: meeting_id)
62
74
  end
63
75
  end
64
- rescue StandardError => e
65
- handle_exception(e, level: :error, operation: 'MeetingIngest#manual')
66
76
  end
67
77
 
68
- private
69
-
70
78
  def process_meeting(meeting_id:, subject:, token:)
71
79
  log.debug("MeetingIngest#process_meeting meeting_id=#{meeting_id} subject=#{subject}")
72
80
  conn = graph_connection(token: token)
@@ -28,7 +28,7 @@ module Legion
28
28
  defined?(Legion::Extensions::MicrosoftTeams::Runners::Bot) &&
29
29
  Legion.const_defined?(:Transport, false)
30
30
  rescue StandardError => e
31
- handle_exception(e, level: :debug, operation: 'ObservedChatPoller#enabled?')
31
+ handle_exception(e, level: :warn, operation: 'ObservedChatPoller#enabled?')
32
32
  false
33
33
  end
34
34
 
@@ -6,6 +6,7 @@ module Legion
6
6
  module Actor
7
7
  class PresencePoller < Legion::Extensions::Actors::Every
8
8
  include Legion::Extensions::MicrosoftTeams::Helpers::Client
9
+ include Legion::Extensions::MicrosoftTeams::Helpers::ThrottleAware
9
10
 
10
11
  def runner_class = self.class
11
12
  def runner_function = 'manual'
@@ -22,12 +23,24 @@ module Legion
22
23
  settings.dig(:presence_poller, :enabled) &&
23
24
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.respond_to?(:load_token)
24
25
  rescue StandardError => e
25
- handle_exception(e, level: :debug, operation: 'PresencePoller#enabled?')
26
+ handle_exception(e, level: :warn, operation: 'PresencePoller#enabled?')
26
27
  false
27
28
  end
28
29
 
29
30
  def manual
30
31
  log.debug('PresencePoller#manual starting')
32
+ # Honour a recent Graph throttle by deferring this run; on a
33
+ # 429 the block raises Errors::Throttled, which the mixin
34
+ # converts into a deferral window so the next tick stands down
35
+ # for retry_after seconds instead of re-firing on the interval.
36
+ with_throttle_deferral { poll_presence }
37
+ rescue StandardError => e
38
+ handle_exception(e, level: :error, operation: 'PresencePoller#manual')
39
+ end
40
+
41
+ private
42
+
43
+ def poll_presence
31
44
  token = delegated_token
32
45
  unless token
33
46
  log.debug('No token available, skipping presence poll')
@@ -49,12 +62,8 @@ module Legion
49
62
  log.info("Presence changed: availability=#{availability}, activity=#{activity}")
50
63
  @last_presence = current
51
64
  end
52
- rescue StandardError => e
53
- handle_exception(e, level: :error, operation: 'PresencePoller#manual')
54
65
  end
55
66
 
56
- private
57
-
58
67
  def delegated_token
59
68
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
60
69
  rescue StandardError => e
@@ -16,7 +16,7 @@ module Legion
16
16
  base_delay = auth_validator.respond_to?(:delay) ? auth_validator.delay.to_f : 9.0
17
17
  base_delay + 5.0
18
18
  rescue StandardError => e
19
- handle_exception(e, level: :debug, operation: 'ProfileIngest#delay')
19
+ handle_exception(e, level: :warn, operation: 'ProfileIngest#delay')
20
20
  14.0
21
21
  end
22
22
 
@@ -25,7 +25,7 @@ module Legion
25
25
  defined?(Legion::Extensions::Agentic::Memory::Trace::Runners::Traces) &&
26
26
  token_available?
27
27
  rescue StandardError => e
28
- handle_exception(e, level: :debug, operation: 'ProfileIngest#enabled?')
28
+ handle_exception(e, level: :warn, operation: 'ProfileIngest#enabled?')
29
29
  false
30
30
  end
31
31
 
@@ -92,7 +92,7 @@ module Legion
92
92
  total_wait = 0.0
93
93
  last_advertised = nil
94
94
 
95
- loop do
95
+ (@max_retries + 1).times do
96
96
  response = @app.call(env.dup)
97
97
  return response unless retryable?(response.status)
98
98
 
@@ -12,7 +12,7 @@ module Legion
12
12
  include Legion::Extensions::Helpers::Lex if Legion::Extensions.const_defined?(:Helpers, false) &&
13
13
  Legion::Extensions::Helpers.const_defined?(:Lex, false)
14
14
 
15
- def graph_connection(token: nil, api_url: 'https://graph.microsoft.com/v1.0', **_opts)
15
+ def graph_connection(token: nil, api_url: 'https://graph.microsoft.com/v1.0', **)
16
16
  token ||= entra_delegated_token
17
17
  ::Faraday.new(url: api_url) do |conn|
18
18
  conn.request :json
@@ -24,7 +24,7 @@ module Legion
24
24
  end
25
25
  end
26
26
 
27
- def bot_connection(token: nil, service_url: 'https://smba.trafficmanager.net/teams/', **_opts)
27
+ def bot_connection(token: nil, service_url: 'https://smba.trafficmanager.net/teams/', **)
28
28
  ::Faraday.new(url: service_url) do |conn|
29
29
  conn.request :json
30
30
  conn.use Legion::Extensions::MicrosoftTeams::Faraday::ThrottleCircuit, **throttle_circuit_options
@@ -39,7 +39,7 @@ module Legion
39
39
  user_id == 'me' ? 'me' : "users/#{user_id}"
40
40
  end
41
41
 
42
- def oauth_connection(tenant_id: 'common', **_opts)
42
+ def oauth_connection(tenant_id: 'common', **)
43
43
  ::Faraday.new(url: "https://login.microsoftonline.com/#{tenant_id}") do |conn|
44
44
  conn.request :url_encoded
45
45
  conn.response :json, content_type: /\bjson$/
@@ -51,7 +51,7 @@ module Legion
51
51
  def entra_delegated_token
52
52
  Legion::Extensions::Identity::Entra::Helpers::TokenManager.load_token(:delegated)
53
53
  rescue StandardError => e
54
- handle_exception(e, level: :debug, operation: 'Client#entra_delegated_token')
54
+ handle_exception(e, level: :warn, operation: 'Client#entra_delegated_token')
55
55
  nil
56
56
  end
57
57
 
@@ -21,7 +21,7 @@ module Legion
21
21
  resp.body
22
22
  end
23
23
  rescue StandardError => e
24
- handle_exception(e, level: :debug, operation: 'GraphCache#cached_graph_get', path: path)
24
+ handle_exception(e, level: :warn, operation: 'GraphCache#cached_graph_get', path: path)
25
25
  conn.get(path, params).body
26
26
  end
27
27
 
@@ -35,7 +35,7 @@ module Legion
35
35
  key = graph_cache_key(path: path, params: params, shared: shared)
36
36
  cache_delete(key)
37
37
  rescue StandardError => e
38
- handle_exception(e, level: :debug, operation: 'GraphCache#invalidate_graph_cache')
38
+ handle_exception(e, level: :warn, operation: 'GraphCache#invalidate_graph_cache')
39
39
  end
40
40
 
41
41
  private
@@ -55,7 +55,7 @@ module Legion
55
55
 
56
56
  Legion::Settings[:microsoft_teams] || {}
57
57
  rescue StandardError => e
58
- handle_exception(e, level: :debug, operation: 'GraphCache#teams_extension_settings')
58
+ handle_exception(e, level: :warn, operation: 'GraphCache#teams_extension_settings')
59
59
  {}
60
60
  end
61
61
  end
@@ -21,7 +21,7 @@ module Legion
21
21
  next_link = nil
22
22
  page = 0
23
23
 
24
- loop do
24
+ max_pages.times do
25
25
  current_path = next_link || path
26
26
  data = graph_get(current_path, token: token, params: page.zero? ? params : {})
27
27
  break if data.nil?
@@ -59,7 +59,7 @@ module Legion
59
59
 
60
60
  raw.is_a?(Hash) ? raw : ::JSON.parse(raw, symbolize_names: true)
61
61
  rescue StandardError => e
62
- handle_exception(e, level: :debug, operation: 'HighWaterMark#get_extended_hwm',
62
+ handle_exception(e, level: :warn, operation: 'HighWaterMark#get_extended_hwm',
63
63
  chat_id: chat_id)
64
64
  nil
65
65
  end
@@ -55,7 +55,7 @@ module Legion
55
55
  Legion::Extensions::Mesh::Helpers::PreferenceProfile.preference_instructions(profile: profile)
56
56
  rescue StandardError => e
57
57
  if defined?(handle_exception)
58
- handle_exception(e, level: :debug, operation: 'PromptResolver#preference_instructions_for',
58
+ handle_exception(e, level: :warn, operation: 'PromptResolver#preference_instructions_for',
59
59
  owner_id: owner_id)
60
60
  end
61
61
  nil
@@ -153,7 +153,7 @@ module Legion
153
153
  profile_traces.map { |t| { type: t[:trace_type], content: t[:content_payload].to_s[0, 200] } }
154
154
  rescue StandardError => e
155
155
  if defined?(handle_exception)
156
- handle_exception(e, level: :debug, operation: 'SessionManager#trace_seed_for',
156
+ handle_exception(e, level: :warn, operation: 'SessionManager#trace_seed_for',
157
157
  owner_id: owner_id)
158
158
  end
159
159
  nil