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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1f1d44ab9629e5fae32a00f28afb74942d9872083de6e378e6585eeb7ae091ba
|
|
4
|
+
data.tar.gz: 5994c5df760cbe750b1dbb53dfc7de3f04812d173efd29cad18d5d49890c85e3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|