lex-microsoft_teams 0.6.14 → 0.6.15

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: 7e4252f4382060712bb112a7d7beaf55b10947fe6200185a3fb6ee413e4f3927
4
- data.tar.gz: af5fb381e122efd02feab899a484242c71f5b67fb620717fad6dcb12c372e2cd
3
+ metadata.gz: 1f1d44ab9629e5fae32a00f28afb74942d9872083de6e378e6585eeb7ae091ba
4
+ data.tar.gz: 5994c5df760cbe750b1dbb53dfc7de3f04812d173efd29cad18d5d49890c85e3
5
5
  SHA512:
6
- metadata.gz: 22a8726642d3a8209c09c4fc797812825cd21ae7dcc8818438333a62291fa9a3a08356125e5003a426e8098ba56ad8033e77a1fd0bb4a162bd6c989bd20b127d
7
- data.tar.gz: 89f55fcbe2210cc4f55a77d4ee04407fe0a3ba437cb1ad14e4699468f0dfbdcf1481ae72d01f230305c0ded9c9e2b1a1558360502ae43a27428d9f5d72634377
6
+ metadata.gz: 7548451323db291361400838619ba453d2b1eac29ac5291ab3688f61b604d1600aca5841446f60816fc10639905b03a1edcde82cbff80b66848a8ed6fc90c48f
7
+ data.tar.gz: 5a0c144c9ee151dd7a68d621377ea591fbbb0e83ef03b208e877f979a69be1681e6af5bfa32533f560cdfd8626cadf4193f74fcb1af5b4771f0a11d8b298b817
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.15] - 2026-03-23
4
+
5
+ ### Added
6
+ - Apollo knowledge graph integration: ingest conversation observations and extract entities from Teams messages
7
+ - `publish_to_apollo` feeds per-person message summaries into Apollo's knowledge store as observations
8
+ - `extract_and_ingest_entities` uses Apollo EntityExtractor to identify people, services, repos, and concepts
9
+ - Soft guards: Apollo integration is a no-op when lex-apollo or legion-data are not loaded
10
+
3
11
  ## [0.6.14] - 2026-03-23
4
12
 
5
13
  ### Added
@@ -39,6 +39,7 @@ module Legion
39
39
  skipped = 0
40
40
  people_ingested = 0
41
41
  thread_groups = Hash.new { |h, k| h[k] = [] }
42
+ person_texts = Hash.new { |h, k| h[k] = [] }
42
43
 
43
44
  people.each do |person|
44
45
  chat = match_chat_to_person(chats: chats, person: person, conn: conn)
@@ -73,6 +74,7 @@ module Legion
73
74
  msg_stored += 1
74
75
  existing_hashes << content_hash
75
76
  thread_groups[chat['id']] << trace_result[:trace_id]
77
+ person_texts[person['displayName']] << text
76
78
  else
77
79
  skipped += 1
78
80
  end
@@ -88,9 +90,11 @@ module Legion
88
90
 
89
91
  coactivate_thread_traces(thread_groups)
90
92
  flush_trace_store if stored.positive?
93
+ apollo_results = publish_to_apollo(person_texts) if stored.positive?
91
94
 
92
95
  { result: { stored: stored, skipped: skipped, people_ingested: people_ingested,
93
- people_found: people.length, chats_found: chats.length } }
96
+ people_found: people.length, chats_found: chats.length,
97
+ apollo: apollo_results } }
94
98
  rescue StandardError => e
95
99
  log_msg = "ApiIngest failed: #{e.class} — #{e.message}"
96
100
  log.error(log_msg)
@@ -297,6 +301,78 @@ module Legion
297
301
  log.debug("ApiIngest: coactivation skipped: #{e.message}")
298
302
  end
299
303
 
304
+ def publish_to_apollo(person_texts)
305
+ return { skipped: true, reason: :apollo_unavailable } unless apollo_available?
306
+
307
+ ingested = 0
308
+ entities_found = 0
309
+ knowledge_runner = apollo_knowledge_runner
310
+
311
+ person_texts.each do |person_name, texts|
312
+ combined = texts.join("\n\n")
313
+ next if combined.length < 20
314
+
315
+ result = knowledge_runner.handle_ingest(
316
+ content: "Conversation observations from #{person_name}: #{combined[0, 2000]}",
317
+ content_type: :observation,
318
+ tags: ['teams', 'graph_api', "peer:#{person_name}"],
319
+ source_agent: 'teams-api-ingest',
320
+ source_provider: 'microsoft',
321
+ source_channel: 'teams_graph_api',
322
+ context: { person: person_name, message_count: texts.length }
323
+ )
324
+ ingested += 1 if result[:success]
325
+
326
+ entity_result = extract_and_ingest_entities(combined, person_name, knowledge_runner)
327
+ entities_found += entity_result[:count] if entity_result[:success]
328
+ end
329
+
330
+ { ingested: ingested, entities_found: entities_found }
331
+ rescue StandardError => e
332
+ log.warn("ApiIngest: publish_to_apollo failed: #{e.message}")
333
+ { skipped: true, reason: :error, error: e.message }
334
+ end
335
+
336
+ def extract_and_ingest_entities(text, person_name, knowledge_runner)
337
+ return { success: false, count: 0 } unless entity_extractor_available?
338
+
339
+ extractor = Object.new.extend(Legion::Extensions::Apollo::Runners::EntityExtractor)
340
+ result = extractor.extract_entities(text: text[0, 4000])
341
+ return { success: false, count: 0 } unless result[:success] && result[:entities]&.any?
342
+
343
+ result[:entities].each do |entity|
344
+ knowledge_runner.handle_ingest(
345
+ content: "#{entity[:type]}: #{entity[:name]}",
346
+ content_type: entity[:type] == 'person' ? :association : :concept,
347
+ tags: ['teams', 'entity', "entity_type:#{entity[:type]}", "peer:#{person_name}"],
348
+ source_agent: 'teams-entity-extractor',
349
+ source_provider: 'microsoft',
350
+ source_channel: 'teams_graph_api',
351
+ context: { entity_name: entity[:name], entity_type: entity[:type],
352
+ confidence: entity[:confidence], extracted_from: person_name }
353
+ )
354
+ end
355
+
356
+ { success: true, count: result[:entities].length }
357
+ rescue StandardError => e
358
+ log.debug("ApiIngest: entity extraction failed for #{person_name}: #{e.message}")
359
+ { success: false, count: 0 }
360
+ end
361
+
362
+ def apollo_available?
363
+ defined?(Legion::Extensions::Apollo::Runners::Knowledge) &&
364
+ defined?(Legion::Data::Model::ApolloEntry)
365
+ end
366
+
367
+ def entity_extractor_available?
368
+ defined?(Legion::Extensions::Apollo::Runners::EntityExtractor) &&
369
+ defined?(Legion::LLM) && Legion::LLM.respond_to?(:started?) && Legion::LLM.started?
370
+ end
371
+
372
+ def apollo_knowledge_runner
373
+ @apollo_knowledge_runner ||= Object.new.extend(Legion::Extensions::Apollo::Runners::Knowledge)
374
+ end
375
+
300
376
  def error_result(message)
301
377
  { result: { stored: 0, skipped: 0, error: message } }
302
378
  end
@@ -3,7 +3,7 @@
3
3
  module Legion
4
4
  module Extensions
5
5
  module MicrosoftTeams
6
- VERSION = '0.6.14'
6
+ VERSION = '0.6.15'
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.14
4
+ version: 0.6.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity