infinity-context 0.1.0__py3-none-any.whl

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 (1053) hide show
  1. infinity_context-0.1.0.dist-info/METADATA +239 -0
  2. infinity_context-0.1.0.dist-info/RECORD +1053 -0
  3. infinity_context-0.1.0.dist-info/WHEEL +5 -0
  4. infinity_context-0.1.0.dist-info/entry_points.txt +9 -0
  5. infinity_context-0.1.0.dist-info/licenses/LICENSE +201 -0
  6. infinity_context-0.1.0.dist-info/top_level.txt +8 -0
  7. infinity_context_adapters/__init__.py +1 -0
  8. infinity_context_adapters/cognee/__init__.py +5 -0
  9. infinity_context_adapters/cognee/adapter.py +364 -0
  10. infinity_context_adapters/embeddings/__init__.py +6 -0
  11. infinity_context_adapters/embeddings/noop_adapter.py +5 -0
  12. infinity_context_adapters/embeddings/openai_adapter.py +104 -0
  13. infinity_context_adapters/extraction/__init__.py +41 -0
  14. infinity_context_adapters/extraction/content.py +828 -0
  15. infinity_context_adapters/extraction/docling_engine.py +255 -0
  16. infinity_context_adapters/extraction/document_normalization.py +434 -0
  17. infinity_context_adapters/extraction/factory.py +69 -0
  18. infinity_context_adapters/extraction/fallback_context.py +137 -0
  19. infinity_context_adapters/extraction/file_detection.py +378 -0
  20. infinity_context_adapters/extraction/image_evidence.py +319 -0
  21. infinity_context_adapters/extraction/media_tools.py +579 -0
  22. infinity_context_adapters/extraction/openai_json.py +356 -0
  23. infinity_context_adapters/extraction/openai_vision.py +722 -0
  24. infinity_context_adapters/extraction/prompts/__init__.py +1 -0
  25. infinity_context_adapters/extraction/prompts/semantic_memory_v1.md +20 -0
  26. infinity_context_adapters/extraction/schemas/__init__.py +1 -0
  27. infinity_context_adapters/extraction/schemas/semantic_memory_v1.json +62 -0
  28. infinity_context_adapters/extraction/transcription/__init__.py +11 -0
  29. infinity_context_adapters/extraction/transcription/openai_adapter.py +400 -0
  30. infinity_context_adapters/extraction/transcription_engine.py +544 -0
  31. infinity_context_adapters/extraction/video_evidence.py +129 -0
  32. infinity_context_adapters/extraction/whisper_engine.py +386 -0
  33. infinity_context_adapters/features/__init__.py +7 -0
  34. infinity_context_adapters/features/context_building/__init__.py +53 -0
  35. infinity_context_adapters/features/context_building/candidate_provider_chain.py +68 -0
  36. infinity_context_adapters/features/context_building/graphiti_candidate_provider.py +44 -0
  37. infinity_context_adapters/features/context_building/in_memory_candidate_provider.py +62 -0
  38. infinity_context_adapters/features/context_building/postgres_candidate_provider.py +44 -0
  39. infinity_context_adapters/features/context_building/qdrant_candidate_provider.py +44 -0
  40. infinity_context_adapters/features/context_building/query_request.py +99 -0
  41. infinity_context_adapters/features/context_building/records.py +113 -0
  42. infinity_context_adapters/features/document_ingestion/__init__.py +74 -0
  43. infinity_context_adapters/features/document_ingestion/composition.py +69 -0
  44. infinity_context_adapters/features/document_ingestion/extraction_adapter.py +114 -0
  45. infinity_context_adapters/features/document_ingestion/in_memory_chunk_index.py +67 -0
  46. infinity_context_adapters/features/document_ingestion/in_memory_document_store.py +176 -0
  47. infinity_context_adapters/features/document_ingestion/postgres_document_store.py +110 -0
  48. infinity_context_adapters/features/document_ingestion/qdrant_chunk_index.py +49 -0
  49. infinity_context_adapters/features/document_ingestion/records.py +88 -0
  50. infinity_context_adapters/features/memory_facts/__init__.py +53 -0
  51. infinity_context_adapters/features/memory_facts/graphiti_fact_projection.py +111 -0
  52. infinity_context_adapters/features/memory_facts/in_memory_fact_store.py +200 -0
  53. infinity_context_adapters/features/memory_facts/postgres_fact_store.py +126 -0
  54. infinity_context_adapters/features/memory_facts/qdrant_fact_projection.py +100 -0
  55. infinity_context_adapters/features/memory_scopes/__init__.py +44 -0
  56. infinity_context_adapters/features/memory_scopes/in_memory_scope_store.py +189 -0
  57. infinity_context_adapters/features/memory_scopes/postgres_scope_store.py +121 -0
  58. infinity_context_adapters/features/memory_scopes/records.py +86 -0
  59. infinity_context_adapters/graphiti/__init__.py +5 -0
  60. infinity_context_adapters/graphiti/adapter.py +613 -0
  61. infinity_context_adapters/graphiti/identity_evidence.py +711 -0
  62. infinity_context_adapters/graphiti/scope_identity.py +31 -0
  63. infinity_context_adapters/local_blob.py +101 -0
  64. infinity_context_adapters/noop/__init__.py +16 -0
  65. infinity_context_adapters/noop/adapters.py +156 -0
  66. infinity_context_adapters/noop/runtime.py +21 -0
  67. infinity_context_adapters/postgres/__init__.py +19 -0
  68. infinity_context_adapters/postgres/asset_mappers.py +348 -0
  69. infinity_context_adapters/postgres/asset_repositories.py +865 -0
  70. infinity_context_adapters/postgres/benchmark_projection_schema.py +241 -0
  71. infinity_context_adapters/postgres/benchmark_run_completion.py +645 -0
  72. infinity_context_adapters/postgres/benchmark_run_repositories.py +908 -0
  73. infinity_context_adapters/postgres/benchmark_writer_fence.py +139 -0
  74. infinity_context_adapters/postgres/canonical_keyword_trigram.py +31 -0
  75. infinity_context_adapters/postgres/canonical_retrieval_batching.py +388 -0
  76. infinity_context_adapters/postgres/fact_repositories.py +766 -0
  77. infinity_context_adapters/postgres/mappers.py +745 -0
  78. infinity_context_adapters/postgres/migrations/0001_core_facts.sql +95 -0
  79. infinity_context_adapters/postgres/migrations/0002_threads_documents_chunks.sql +97 -0
  80. infinity_context_adapters/postgres/migrations/0003_suggestions.sql +24 -0
  81. infinity_context_adapters/postgres/migrations/0004_service_tokens.sql +16 -0
  82. infinity_context_adapters/postgres/migrations/0005_data_classification_lite.sql +8 -0
  83. infinity_context_adapters/postgres/migrations/0006_service_token_usage_metadata.sql +5 -0
  84. infinity_context_adapters/postgres/migrations/0007_service_token_permissions.sql +2 -0
  85. infinity_context_adapters/postgres/migrations/0008_service_token_memory_scope.sql +2 -0
  86. infinity_context_adapters/postgres/migrations/0009_outbox_lifecycle_hardening.sql +15 -0
  87. infinity_context_adapters/postgres/migrations/0010_fact_taxonomy.sql +14 -0
  88. infinity_context_adapters/postgres/migrations/0011_asset_extractions.sql +66 -0
  89. infinity_context_adapters/postgres/migrations/0012_asset_extraction_execution_hardening.sql +20 -0
  90. infinity_context_adapters/postgres/migrations/0012_usage_governance.sql +33 -0
  91. infinity_context_adapters/postgres/migrations/0013_context_link_suggestions.sql +44 -0
  92. infinity_context_adapters/postgres/migrations/0014_memory_anchors.sql +26 -0
  93. infinity_context_adapters/postgres/migrations/0015_users_acl.sql +36 -0
  94. infinity_context_adapters/postgres/migrations/0016_managed_benchmark_runs.sql +27 -0
  95. infinity_context_adapters/postgres/migrations/0017_managed_benchmark_writer_fence.sql +104 -0
  96. infinity_context_adapters/postgres/migrations/0018_benchmark_projection_manifest.sql +51 -0
  97. infinity_context_adapters/postgres/migrations/0019_managed_benchmark_sealed_fence.sql +131 -0
  98. infinity_context_adapters/postgres/migrations/0020_benchmark_cleanup_completion.sql +219 -0
  99. infinity_context_adapters/postgres/migrations/0021_benchmark_unsealed_abort.sql +64 -0
  100. infinity_context_adapters/postgres/migrations/0022_canonical_keyword_trigram.sql +5 -0
  101. infinity_context_adapters/postgres/models.py +878 -0
  102. infinity_context_adapters/postgres/projection_fence.py +80 -0
  103. infinity_context_adapters/postgres/repositories.py +906 -0
  104. infinity_context_adapters/postgres/repository_helpers.py +115 -0
  105. infinity_context_adapters/postgres/scope_repositories.py +540 -0
  106. infinity_context_adapters/postgres/unit_of_work.py +785 -0
  107. infinity_context_adapters/postgres/usage_repositories.py +128 -0
  108. infinity_context_adapters/postgres/user_repositories.py +164 -0
  109. infinity_context_adapters/provider_errors.py +73 -0
  110. infinity_context_adapters/qdrant/__init__.py +5 -0
  111. infinity_context_adapters/qdrant/identity_evidence.py +504 -0
  112. infinity_context_adapters/qdrant/vector_adapter.py +718 -0
  113. infinity_context_adapters/s3_blob.py +242 -0
  114. infinity_context_cli/__init__.py +5 -0
  115. infinity_context_cli/__main__.py +6 -0
  116. infinity_context_cli/cli.py +964 -0
  117. infinity_context_cli/config.py +184 -0
  118. infinity_context_cli/doctor.py +397 -0
  119. infinity_context_cli/local_experience.py +250 -0
  120. infinity_context_cli/mcp_config.py +124 -0
  121. infinity_context_cli/onboarding.py +542 -0
  122. infinity_context_cli/runtime.py +179 -0
  123. infinity_context_contracts/__init__.py +16 -0
  124. infinity_context_contracts/_json.py +32 -0
  125. infinity_context_contracts/capabilities.py +67 -0
  126. infinity_context_contracts/common.py +54 -0
  127. infinity_context_contracts/features/__init__.py +12 -0
  128. infinity_context_contracts/features/context_building.py +248 -0
  129. infinity_context_contracts/features/document_ingestion.py +277 -0
  130. infinity_context_contracts/features/memory_facts.py +236 -0
  131. infinity_context_contracts/features/memory_scopes.py +329 -0
  132. infinity_context_contracts/health.py +23 -0
  133. infinity_context_core/__init__.py +76 -0
  134. infinity_context_core/agent_behavior_contract.py +72 -0
  135. infinity_context_core/application/__init__.py +580 -0
  136. infinity_context_core/application/anchor_creative_work_filters.py +148 -0
  137. infinity_context_core/application/anchor_event_extraction.py +1571 -0
  138. infinity_context_core/application/anchor_extraction.py +1144 -0
  139. infinity_context_core/application/anchor_identity_normalization.py +90 -0
  140. infinity_context_core/application/anchor_relation_projection.py +203 -0
  141. infinity_context_core/application/anchor_temporal_window.py +172 -0
  142. infinity_context_core/application/asset_extraction_mapping.py +236 -0
  143. infinity_context_core/application/asset_upload_policy.py +952 -0
  144. infinity_context_core/application/auto_apply.py +72 -0
  145. infinity_context_core/application/auto_memory.py +527 -0
  146. infinity_context_core/application/capture_policy.py +61 -0
  147. infinity_context_core/application/chunker.py +93 -0
  148. infinity_context_core/application/context_action_role_evidence.py +890 -0
  149. infinity_context_core/application/context_action_role_labels.py +176 -0
  150. infinity_context_core/application/context_action_roles.py +2365 -0
  151. infinity_context_core/application/context_action_subject_policy.py +71 -0
  152. infinity_context_core/application/context_activity_companion.py +120 -0
  153. infinity_context_core/application/context_activity_duration_rerank.py +118 -0
  154. infinity_context_core/application/context_activity_participant_grounding.py +87 -0
  155. infinity_context_core/application/context_aggregation_answer_slots.py +586 -0
  156. infinity_context_core/application/context_aggregation_evidence_text.py +409 -0
  157. infinity_context_core/application/context_aggregation_rerank.py +145 -0
  158. infinity_context_core/application/context_aggregation_subject.py +137 -0
  159. infinity_context_core/application/context_allergy_condition_inference.py +146 -0
  160. infinity_context_core/application/context_anchor_identity.py +157 -0
  161. infinity_context_core/application/context_anchor_intent_ranking.py +84 -0
  162. infinity_context_core/application/context_anchor_relations.py +67 -0
  163. infinity_context_core/application/context_anchors.py +393 -0
  164. infinity_context_core/application/context_answer_evidence_types.py +14 -0
  165. infinity_context_core/application/context_answer_unit_shapes.py +207 -0
  166. infinity_context_core/application/context_artifact_evidence.py +893 -0
  167. infinity_context_core/application/context_attribution_lexicon.py +254 -0
  168. infinity_context_core/application/context_awareness_cause_rerank.py +109 -0
  169. infinity_context_core/application/context_baby_birth_evidence.py +91 -0
  170. infinity_context_core/application/context_birdwatching_schedule_rerank.py +130 -0
  171. infinity_context_core/application/context_bm25_ranking.py +450 -0
  172. infinity_context_core/application/context_book_author_preference_exact_turns.py +110 -0
  173. infinity_context_core/application/context_building_legacy_candidate_adapter.py +530 -0
  174. infinity_context_core/application/context_canonical_fact_retrieval.py +409 -0
  175. infinity_context_core/application/context_causal_reason_rerank.py +145 -0
  176. infinity_context_core/application/context_choice_reason_rerank.py +109 -0
  177. infinity_context_core/application/context_collectors.py +931 -0
  178. infinity_context_core/application/context_commonality_rerank.py +428 -0
  179. infinity_context_core/application/context_community_membership_inference.py +139 -0
  180. infinity_context_core/application/context_competition_count_exact_turns.py +383 -0
  181. infinity_context_core/application/context_conflicting_evidence_rerank.py +282 -0
  182. infinity_context_core/application/context_conversation_counterparty.py +260 -0
  183. infinity_context_core/application/context_count_cardinality.py +164 -0
  184. infinity_context_core/application/context_creative_work_count_exact_turns.py +517 -0
  185. infinity_context_core/application/context_diagnostics.py +55 -0
  186. infinity_context_core/application/context_diagnostics_bundle_keys.py +433 -0
  187. infinity_context_core/application/context_diagnostics_bundle_projection.py +711 -0
  188. infinity_context_core/application/context_diagnostics_item_projection.py +410 -0
  189. infinity_context_core/application/context_diagnostics_primitives.py +131 -0
  190. infinity_context_core/application/context_diagnostics_ranking.py +143 -0
  191. infinity_context_core/application/context_diagnostics_signals.py +209 -0
  192. infinity_context_core/application/context_diagnostics_sources.py +82 -0
  193. infinity_context_core/application/context_dialogue_authority.py +382 -0
  194. infinity_context_core/application/context_distinct_set_evidence.py +994 -0
  195. infinity_context_core/application/context_distinct_set_selection.py +335 -0
  196. infinity_context_core/application/context_domain_rerank_apply.py +310 -0
  197. infinity_context_core/application/context_domain_rerank_signals.py +2391 -0
  198. infinity_context_core/application/context_domain_rerank_types.py +14 -0
  199. infinity_context_core/application/context_english_activity_displacement_answer_support.py +128 -0
  200. infinity_context_core/application/context_english_lifestyle_inference.py +122 -0
  201. infinity_context_core/application/context_english_lifestyle_inference_answer_support.py +291 -0
  202. infinity_context_core/application/context_english_temporal_dates.py +53 -0
  203. infinity_context_core/application/context_evidence_priority.py +262 -0
  204. infinity_context_core/application/context_evidence_reservation_safety.py +208 -0
  205. infinity_context_core/application/context_exercise_performance_rerank.py +71 -0
  206. infinity_context_core/application/context_food_inventory_exact_turns.py +583 -0
  207. infinity_context_core/application/context_frequency_rerank.py +109 -0
  208. infinity_context_core/application/context_future_plan_timing_rerank.py +110 -0
  209. infinity_context_core/application/context_generic_behavior_inference.py +348 -0
  210. infinity_context_core/application/context_geo_residence_aliases.py +149 -0
  211. infinity_context_core/application/context_hydration.py +329 -0
  212. infinity_context_core/application/context_identity_fact_rerank.py +362 -0
  213. infinity_context_core/application/context_identity_rerank.py +76 -0
  214. infinity_context_core/application/context_identity_terms.py +15 -0
  215. infinity_context_core/application/context_inference_evidence.py +484 -0
  216. infinity_context_core/application/context_inference_evidence_terms.py +744 -0
  217. infinity_context_core/application/context_internal_diagnostics.py +61 -0
  218. infinity_context_core/application/context_item_evidence.py +108 -0
  219. infinity_context_core/application/context_item_purchase_evidence.py +49 -0
  220. infinity_context_core/application/context_keyword_aggregation_prefilter.py +63 -0
  221. infinity_context_core/application/context_keyword_ranking.py +178 -0
  222. infinity_context_core/application/context_lexical.py +750 -0
  223. infinity_context_core/application/context_lifecycle_rerank.py +502 -0
  224. infinity_context_core/application/context_link_candidate_policy.py +864 -0
  225. infinity_context_core/application/context_link_expansion.py +727 -0
  226. infinity_context_core/application/context_link_expansion_items.py +441 -0
  227. infinity_context_core/application/context_link_policy.py +451 -0
  228. infinity_context_core/application/context_link_source_enrichment.py +120 -0
  229. infinity_context_core/application/context_media_time.py +368 -0
  230. infinity_context_core/application/context_museum_visit_policy.py +66 -0
  231. infinity_context_core/application/context_named_person_preference.py +313 -0
  232. infinity_context_core/application/context_national_park_inference.py +93 -0
  233. infinity_context_core/application/context_object_attribute_rerank.py +416 -0
  234. infinity_context_core/application/context_object_mismatch.py +63 -0
  235. infinity_context_core/application/context_occupational_role_identity.py +961 -0
  236. infinity_context_core/application/context_ordinal_sequence.py +134 -0
  237. infinity_context_core/application/context_owner_grounding.py +408 -0
  238. infinity_context_core/application/context_packer.py +858 -0
  239. infinity_context_core/application/context_packer_answer_slots.py +733 -0
  240. infinity_context_core/application/context_packer_answer_support.py +3101 -0
  241. infinity_context_core/application/context_packer_answer_support_patterns.py +1267 -0
  242. infinity_context_core/application/context_packer_answer_support_slots.py +1209 -0
  243. infinity_context_core/application/context_packer_answer_support_utils.py +473 -0
  244. infinity_context_core/application/context_packer_diagnostics.py +48 -0
  245. infinity_context_core/application/context_packer_exact_literal_turns.py +697 -0
  246. infinity_context_core/application/context_packer_exact_prepasses.py +758 -0
  247. infinity_context_core/application/context_packer_exact_turn_utils.py +133 -0
  248. infinity_context_core/application/context_packer_identity_policy.py +155 -0
  249. infinity_context_core/application/context_packer_inference_reservation.py +113 -0
  250. infinity_context_core/application/context_packer_inventory_prepasses.py +359 -0
  251. infinity_context_core/application/context_packer_inventory_slots.py +771 -0
  252. infinity_context_core/application/context_packer_marker_coverage.py +409 -0
  253. infinity_context_core/application/context_packer_rendering.py +338 -0
  254. infinity_context_core/application/context_packer_selection.py +487 -0
  255. infinity_context_core/application/context_packer_source_policy.py +123 -0
  256. infinity_context_core/application/context_paired_evidence_requirements.py +78 -0
  257. infinity_context_core/application/context_paired_evidence_roles.py +64 -0
  258. infinity_context_core/application/context_person_activity_exact_turns.py +375 -0
  259. infinity_context_core/application/context_person_aliases.py +49 -0
  260. infinity_context_core/application/context_person_kinship.py +296 -0
  261. infinity_context_core/application/context_person_occupation.py +240 -0
  262. infinity_context_core/application/context_person_relation_inventory.py +755 -0
  263. infinity_context_core/application/context_person_residence.py +398 -0
  264. infinity_context_core/application/context_person_team_membership.py +305 -0
  265. infinity_context_core/application/context_pet_ownership.py +223 -0
  266. infinity_context_core/application/context_polarity_rerank.py +338 -0
  267. infinity_context_core/application/context_policy.py +107 -0
  268. infinity_context_core/application/context_political_inference.py +128 -0
  269. infinity_context_core/application/context_possession_source.py +161 -0
  270. infinity_context_core/application/context_precise_temporal_evidence.py +156 -0
  271. infinity_context_core/application/context_preference_goal_rerank.py +428 -0
  272. infinity_context_core/application/context_preference_inference.py +335 -0
  273. infinity_context_core/application/context_property_interaction_evidence.py +659 -0
  274. infinity_context_core/application/context_provider_retrieval_terms.py +95 -0
  275. infinity_context_core/application/context_quality.py +488 -0
  276. infinity_context_core/application/context_quantity_evidence_patterns.py +254 -0
  277. infinity_context_core/application/context_quantity_evidence_slots.py +750 -0
  278. infinity_context_core/application/context_quantity_pending_clothing.py +200 -0
  279. infinity_context_core/application/context_query_artifact_inventory_expansions.py +76 -0
  280. infinity_context_core/application/context_query_decomposition.py +879 -0
  281. infinity_context_core/application/context_query_decomposition_answer_policy.py +707 -0
  282. infinity_context_core/application/context_query_decomposition_contracts.py +28 -0
  283. infinity_context_core/application/context_query_decomposition_event_policy.py +535 -0
  284. infinity_context_core/application/context_query_decomposition_inventory_policy.py +767 -0
  285. infinity_context_core/application/context_query_decomposition_shared.py +300 -0
  286. infinity_context_core/application/context_query_duration.py +171 -0
  287. infinity_context_core/application/context_query_entity_relation_expansions.py +212 -0
  288. infinity_context_core/application/context_query_event_summary_expansions.py +80 -0
  289. infinity_context_core/application/context_query_expansion.py +200 -0
  290. infinity_context_core/application/context_query_expansion_rule_catalog_part1.py +1279 -0
  291. infinity_context_core/application/context_query_expansion_rule_catalog_part2.py +770 -0
  292. infinity_context_core/application/context_query_expansion_rule_catalog_part3.py +982 -0
  293. infinity_context_core/application/context_query_expansion_rule_catalog_part4.py +1334 -0
  294. infinity_context_core/application/context_query_expansion_rule_catalog_part5.py +517 -0
  295. infinity_context_core/application/context_query_expansion_rule_terms.py +269 -0
  296. infinity_context_core/application/context_query_expansion_rules.py +66 -0
  297. infinity_context_core/application/context_query_expansion_selection.py +892 -0
  298. infinity_context_core/application/context_query_financial_resources_inference.py +92 -0
  299. infinity_context_core/application/context_query_food_expansions.py +89 -0
  300. infinity_context_core/application/context_query_frequency.py +194 -0
  301. infinity_context_core/application/context_query_game_expansions.py +141 -0
  302. infinity_context_core/application/context_query_health_lifestyle_expansions.py +178 -0
  303. infinity_context_core/application/context_query_identity_terms.py +81 -0
  304. infinity_context_core/application/context_query_intent.py +33 -0
  305. infinity_context_core/application/context_query_intent_common.py +29 -0
  306. infinity_context_core/application/context_query_intent_contracts.py +92 -0
  307. infinity_context_core/application/context_query_intent_extraction.py +614 -0
  308. infinity_context_core/application/context_query_intent_keys.py +499 -0
  309. infinity_context_core/application/context_query_intent_matching.py +407 -0
  310. infinity_context_core/application/context_query_organization_summary_expansions.py +75 -0
  311. infinity_context_core/application/context_query_personal_fact_expansions.py +314 -0
  312. infinity_context_core/application/context_query_pet_activity_expansions.py +329 -0
  313. infinity_context_core/application/context_query_preference_expansions.py +97 -0
  314. infinity_context_core/application/context_query_project_summary_expansions.py +60 -0
  315. infinity_context_core/application/context_query_relevance_ranking.py +76 -0
  316. infinity_context_core/application/context_query_sports_expansions.py +48 -0
  317. infinity_context_core/application/context_query_state_transition.py +53 -0
  318. infinity_context_core/application/context_query_support_role.py +165 -0
  319. infinity_context_core/application/context_query_temporal_expansions.py +18 -0
  320. infinity_context_core/application/context_query_travel_expansions.py +134 -0
  321. infinity_context_core/application/context_query_vehicle_expansions.py +79 -0
  322. infinity_context_core/application/context_query_workflow_expansions.py +233 -0
  323. infinity_context_core/application/context_query_workflow_intent.py +65 -0
  324. infinity_context_core/application/context_quote_scanner.py +342 -0
  325. infinity_context_core/application/context_rank_dedupe.py +171 -0
  326. infinity_context_core/application/context_rank_fusion.py +191 -0
  327. infinity_context_core/application/context_ranked_activity_reservation.py +586 -0
  328. infinity_context_core/application/context_ranked_evidence_coverage_reservation.py +427 -0
  329. infinity_context_core/application/context_ranked_evidence_priority_reservation.py +37 -0
  330. infinity_context_core/application/context_ranked_evidence_selection.py +260 -0
  331. infinity_context_core/application/context_ranking.py +3681 -0
  332. infinity_context_core/application/context_ranking_reason_policy.py +31 -0
  333. infinity_context_core/application/context_ranking_reason_priorities.py +859 -0
  334. infinity_context_core/application/context_ranking_reason_scores.py +519 -0
  335. infinity_context_core/application/context_recommendation_answer_support.py +358 -0
  336. infinity_context_core/application/context_recommendation_exact_turns.py +360 -0
  337. infinity_context_core/application/context_relation_requirement.py +498 -0
  338. infinity_context_core/application/context_relationship_status_evidence.py +83 -0
  339. infinity_context_core/application/context_relative_duration_evidence.py +61 -0
  340. infinity_context_core/application/context_relevance.py +430 -0
  341. infinity_context_core/application/context_reported_obligation_attribution.py +416 -0
  342. infinity_context_core/application/context_reporting_frames.py +338 -0
  343. infinity_context_core/application/context_requirement_coverage.py +767 -0
  344. infinity_context_core/application/context_requirement_guard.py +503 -0
  345. infinity_context_core/application/context_requirement_patterns.py +943 -0
  346. infinity_context_core/application/context_requirement_ranking.py +181 -0
  347. infinity_context_core/application/context_requirement_signals.py +101 -0
  348. infinity_context_core/application/context_rerank_domain_heuristics.py +433 -0
  349. infinity_context_core/application/context_rerank_evidence_signals.py +400 -0
  350. infinity_context_core/application/context_rerank_relevance.py +131 -0
  351. infinity_context_core/application/context_retrieval_performance.py +153 -0
  352. infinity_context_core/application/context_review_items.py +338 -0
  353. infinity_context_core/application/context_score_signal_rerank.py +21 -0
  354. infinity_context_core/application/context_short_story_progress_evidence.py +119 -0
  355. infinity_context_core/application/context_snippets.py +545 -0
  356. infinity_context_core/application/context_social_education_inference.py +265 -0
  357. infinity_context_core/application/context_social_inventory_rerank.py +329 -0
  358. infinity_context_core/application/context_source_family.py +100 -0
  359. infinity_context_core/application/context_source_grounding.py +277 -0
  360. infinity_context_core/application/context_source_sibling_answer_evidence_repair.py +1983 -0
  361. infinity_context_core/application/context_source_sibling_contracts.py +35 -0
  362. infinity_context_core/application/context_source_sibling_evidence.py +405 -0
  363. infinity_context_core/application/context_source_sibling_evidence_rules.py +798 -0
  364. infinity_context_core/application/context_source_sibling_evidence_shared.py +449 -0
  365. infinity_context_core/application/context_source_sibling_identity.py +114 -0
  366. infinity_context_core/application/context_source_sibling_inventory_evidence.py +28 -0
  367. infinity_context_core/application/context_source_sibling_patterns.py +946 -0
  368. infinity_context_core/application/context_source_sibling_place_evidence.py +561 -0
  369. infinity_context_core/application/context_source_sibling_policy.py +988 -0
  370. infinity_context_core/application/context_source_sibling_scoring.py +721 -0
  371. infinity_context_core/application/context_source_siblings.py +363 -0
  372. infinity_context_core/application/context_speaker_attribution.py +574 -0
  373. infinity_context_core/application/context_speaker_disambiguation.py +108 -0
  374. infinity_context_core/application/context_stage_diagnostics.py +111 -0
  375. infinity_context_core/application/context_state_evidence.py +196 -0
  376. infinity_context_core/application/context_state_residence_inference.py +163 -0
  377. infinity_context_core/application/context_state_transition_pairing.py +401 -0
  378. infinity_context_core/application/context_temporal_answer_grounding.py +187 -0
  379. infinity_context_core/application/context_temporal_hints.py +485 -0
  380. infinity_context_core/application/context_temporal_intent_policy.py +146 -0
  381. infinity_context_core/application/context_temporal_interval_requirements.py +107 -0
  382. infinity_context_core/application/context_temporal_metadata.py +29 -0
  383. infinity_context_core/application/context_temporal_query.py +1358 -0
  384. infinity_context_core/application/context_temporal_ranges.py +471 -0
  385. infinity_context_core/application/context_temporal_session_order.py +439 -0
  386. infinity_context_core/application/context_temporal_source_identity.py +426 -0
  387. infinity_context_core/application/context_temporal_source_turn.py +1290 -0
  388. infinity_context_core/application/context_temporal_source_turn_labels.py +265 -0
  389. infinity_context_core/application/context_temporal_source_turn_patterns.py +186 -0
  390. infinity_context_core/application/context_temporal_source_turn_types.py +62 -0
  391. infinity_context_core/application/context_travel_hobby_writing_evidence.py +176 -0
  392. infinity_context_core/application/context_travel_place_evidence.py +23 -0
  393. infinity_context_core/application/document_fragments.py +206 -0
  394. infinity_context_core/application/document_text.py +203 -0
  395. infinity_context_core/application/dto.py +311 -0
  396. infinity_context_core/application/dto_anchors.py +143 -0
  397. infinity_context_core/application/dto_assets.py +234 -0
  398. infinity_context_core/application/dto_benchmark_runs.py +114 -0
  399. infinity_context_core/application/dto_context.py +176 -0
  400. infinity_context_core/application/dto_context_links.py +170 -0
  401. infinity_context_core/application/dto_facts.py +275 -0
  402. infinity_context_core/application/dto_suggestions_capture.py +199 -0
  403. infinity_context_core/application/dto_workspace.py +101 -0
  404. infinity_context_core/application/extraction_coordinates.py +56 -0
  405. infinity_context_core/application/extraction_resource_policy.py +796 -0
  406. infinity_context_core/application/extractor.py +147 -0
  407. infinity_context_core/application/memory_digest_renderer.py +215 -0
  408. infinity_context_core/application/multimodal_manifest.py +418 -0
  409. infinity_context_core/application/normalize.py +29 -0
  410. infinity_context_core/application/observed_anchor_resolution.py +243 -0
  411. infinity_context_core/application/related_facts.py +144 -0
  412. infinity_context_core/application/review_payloads.py +104 -0
  413. infinity_context_core/application/safe_payload.py +86 -0
  414. infinity_context_core/application/semantic_dedupe.py +943 -0
  415. infinity_context_core/application/sensitive_text.py +39 -0
  416. infinity_context_core/application/source_refs.py +263 -0
  417. infinity_context_core/application/storage_key_safety.py +13 -0
  418. infinity_context_core/application/temporal_validity.py +31 -0
  419. infinity_context_core/application/use_cases/__init__.py +1 -0
  420. infinity_context_core/application/use_cases/anchors.py +1165 -0
  421. infinity_context_core/application/use_cases/asset_extraction_support.py +273 -0
  422. infinity_context_core/application/use_cases/asset_extractions.py +1454 -0
  423. infinity_context_core/application/use_cases/assets.py +463 -0
  424. infinity_context_core/application/use_cases/benchmark_runs.py +877 -0
  425. infinity_context_core/application/use_cases/benchmark_unsealed_abort.py +147 -0
  426. infinity_context_core/application/use_cases/blob_storage_cleanup.py +289 -0
  427. infinity_context_core/application/use_cases/blob_storage_integrity.py +351 -0
  428. infinity_context_core/application/use_cases/build_context.py +995 -0
  429. infinity_context_core/application/use_cases/build_context_final_packing.py +59 -0
  430. infinity_context_core/application/use_cases/build_context_item_projection.py +839 -0
  431. infinity_context_core/application/use_cases/build_context_keyword_aggregation.py +908 -0
  432. infinity_context_core/application/use_cases/build_context_keyword_aggregation_seeds.py +132 -0
  433. infinity_context_core/application/use_cases/build_context_keyword_aggregation_selection.py +280 -0
  434. infinity_context_core/application/use_cases/build_context_keyword_aggregation_support.py +161 -0
  435. infinity_context_core/application/use_cases/build_context_requirement_guard.py +156 -0
  436. infinity_context_core/application/use_cases/build_context_source_selection.py +935 -0
  437. infinity_context_core/application/use_cases/build_memory_digest.py +203 -0
  438. infinity_context_core/application/use_cases/build_memory_insights.py +979 -0
  439. infinity_context_core/application/use_cases/consolidate_capture.py +806 -0
  440. infinity_context_core/application/use_cases/context_link_crud.py +196 -0
  441. infinity_context_core/application/use_cases/context_link_reviews.py +441 -0
  442. infinity_context_core/application/use_cases/context_link_suggestions.py +1060 -0
  443. infinity_context_core/application/use_cases/context_link_visibility.py +106 -0
  444. infinity_context_core/application/use_cases/context_links.py +33 -0
  445. infinity_context_core/application/use_cases/delete_document.py +71 -0
  446. infinity_context_core/application/use_cases/delete_thread_memory.py +55 -0
  447. infinity_context_core/application/use_cases/duplicate_merge_resolution.py +307 -0
  448. infinity_context_core/application/use_cases/ensure_scope.py +29 -0
  449. infinity_context_core/application/use_cases/expire_suggestions.py +36 -0
  450. infinity_context_core/application/use_cases/export_graph.py +684 -0
  451. infinity_context_core/application/use_cases/fact_relations.py +204 -0
  452. infinity_context_core/application/use_cases/forget_fact.py +43 -0
  453. infinity_context_core/application/use_cases/get_capabilities.py +213 -0
  454. infinity_context_core/application/use_cases/get_capture.py +16 -0
  455. infinity_context_core/application/use_cases/get_session_status.py +23 -0
  456. infinity_context_core/application/use_cases/ingest_document.py +376 -0
  457. infinity_context_core/application/use_cases/ingest_episode.py +263 -0
  458. infinity_context_core/application/use_cases/list_captures.py +25 -0
  459. infinity_context_core/application/use_cases/memory_browser.py +414 -0
  460. infinity_context_core/application/use_cases/operations_console.py +293 -0
  461. infinity_context_core/application/use_cases/process_document.py +83 -0
  462. infinity_context_core/application/use_cases/purge_capture.py +34 -0
  463. infinity_context_core/application/use_cases/query_documents.py +42 -0
  464. infinity_context_core/application/use_cases/query_facts.py +57 -0
  465. infinity_context_core/application/use_cases/receive_capture.py +238 -0
  466. infinity_context_core/application/use_cases/related_facts.py +47 -0
  467. infinity_context_core/application/use_cases/remember_fact.py +145 -0
  468. infinity_context_core/application/use_cases/spaces_memory_scopes.py +134 -0
  469. infinity_context_core/application/use_cases/suggestions.py +804 -0
  470. infinity_context_core/application/use_cases/update_fact.py +43 -0
  471. infinity_context_core/application/use_cases/usage.py +49 -0
  472. infinity_context_core/application/use_cases/users.py +138 -0
  473. infinity_context_core/domain/__init__.py +1 -0
  474. infinity_context_core/domain/aggregation_admission.py +200 -0
  475. infinity_context_core/domain/anchor_entities.py +316 -0
  476. infinity_context_core/domain/assets.py +654 -0
  477. infinity_context_core/domain/capture.py +321 -0
  478. infinity_context_core/domain/distinct_set_membership.py +69 -0
  479. infinity_context_core/domain/entities.py +103 -0
  480. infinity_context_core/domain/entity_policies.py +119 -0
  481. infinity_context_core/domain/entity_types.py +150 -0
  482. infinity_context_core/domain/errors.py +53 -0
  483. infinity_context_core/domain/events.py +14 -0
  484. infinity_context_core/domain/extraction.py +529 -0
  485. infinity_context_core/domain/idempotency.py +12 -0
  486. infinity_context_core/domain/memory_item_entities.py +426 -0
  487. infinity_context_core/domain/source_refs.py +91 -0
  488. infinity_context_core/domain/suggestion_entities.py +236 -0
  489. infinity_context_core/domain/taxonomy.py +121 -0
  490. infinity_context_core/domain/usage.py +221 -0
  491. infinity_context_core/domain/workspace_entities.py +269 -0
  492. infinity_context_core/features/__init__.py +7 -0
  493. infinity_context_core/features/context_building/__init__.py +3 -0
  494. infinity_context_core/features/context_building/application/__init__.py +92 -0
  495. infinity_context_core/features/context_building/application/candidate_fusion.py +136 -0
  496. infinity_context_core/features/context_building/application/coverage_reservation_selector.py +212 -0
  497. infinity_context_core/features/context_building/application/handlers.py +155 -0
  498. infinity_context_core/features/context_building/application/inference_evidence_reservation.py +592 -0
  499. infinity_context_core/features/context_building/application/provider_pipeline.py +61 -0
  500. infinity_context_core/features/context_building/application/queries.py +107 -0
  501. infinity_context_core/features/context_building/application/use_cases.py +78 -0
  502. infinity_context_core/features/context_building/domain/__init__.py +95 -0
  503. infinity_context_core/features/context_building/domain/budget.py +97 -0
  504. infinity_context_core/features/context_building/domain/context.py +157 -0
  505. infinity_context_core/features/context_building/domain/evidence_obligations.py +60 -0
  506. infinity_context_core/features/context_building/domain/feature.py +15 -0
  507. infinity_context_core/features/context_building/domain/prompt_sections.py +150 -0
  508. infinity_context_core/features/context_building/domain/query_pipeline.py +276 -0
  509. infinity_context_core/features/context_building/domain/rendering.py +102 -0
  510. infinity_context_core/features/context_building/ports/__init__.py +8 -0
  511. infinity_context_core/features/context_building/ports/candidates.py +36 -0
  512. infinity_context_core/features/context_building/public.py +165 -0
  513. infinity_context_core/features/context_building/tests/test_application_ports_public_skeleton.py +575 -0
  514. infinity_context_core/features/context_building/tests/test_domain_context_building_skeleton.py +402 -0
  515. infinity_context_core/features/document_ingestion/__init__.py +3 -0
  516. infinity_context_core/features/document_ingestion/application/__init__.py +31 -0
  517. infinity_context_core/features/document_ingestion/application/commands.py +62 -0
  518. infinity_context_core/features/document_ingestion/application/use_cases.py +273 -0
  519. infinity_context_core/features/document_ingestion/domain/__init__.py +61 -0
  520. infinity_context_core/features/document_ingestion/domain/chunking.py +297 -0
  521. infinity_context_core/features/document_ingestion/domain/errors.py +22 -0
  522. infinity_context_core/features/document_ingestion/domain/feature.py +18 -0
  523. infinity_context_core/features/document_ingestion/domain/source_document.py +228 -0
  524. infinity_context_core/features/document_ingestion/ports/__init__.py +21 -0
  525. infinity_context_core/features/document_ingestion/ports/indexing.py +51 -0
  526. infinity_context_core/features/document_ingestion/ports/repositories.py +56 -0
  527. infinity_context_core/features/document_ingestion/public.py +95 -0
  528. infinity_context_core/features/document_ingestion/tests/test_application_handlers.py +226 -0
  529. infinity_context_core/features/document_ingestion/tests/test_application_ports_public_skeleton.py +334 -0
  530. infinity_context_core/features/document_ingestion/tests/test_domain_chunking_skeleton.py +79 -0
  531. infinity_context_core/features/document_ingestion/tests/test_domain_source_document_skeleton.py +101 -0
  532. infinity_context_core/features/memory_facts/__init__.py +3 -0
  533. infinity_context_core/features/memory_facts/application/__init__.py +37 -0
  534. infinity_context_core/features/memory_facts/application/commands.py +89 -0
  535. infinity_context_core/features/memory_facts/application/handlers.py +241 -0
  536. infinity_context_core/features/memory_facts/application/use_cases.py +47 -0
  537. infinity_context_core/features/memory_facts/domain/__init__.py +35 -0
  538. infinity_context_core/features/memory_facts/domain/fact.py +98 -0
  539. infinity_context_core/features/memory_facts/domain/feature.py +15 -0
  540. infinity_context_core/features/memory_facts/ports/__init__.py +31 -0
  541. infinity_context_core/features/memory_facts/ports/clock.py +14 -0
  542. infinity_context_core/features/memory_facts/ports/ids.py +19 -0
  543. infinity_context_core/features/memory_facts/ports/outbox.py +26 -0
  544. infinity_context_core/features/memory_facts/ports/repositories.py +30 -0
  545. infinity_context_core/features/memory_facts/ports/unit_of_work.py +43 -0
  546. infinity_context_core/features/memory_facts/public.py +79 -0
  547. infinity_context_core/features/memory_facts/tests/test_application_handlers.py +332 -0
  548. infinity_context_core/features/memory_facts/tests/test_application_ports_public_skeleton.py +318 -0
  549. infinity_context_core/features/memory_facts/tests/test_domain_fact_skeleton.py +222 -0
  550. infinity_context_core/features/memory_scopes/__init__.py +3 -0
  551. infinity_context_core/features/memory_scopes/application/__init__.py +55 -0
  552. infinity_context_core/features/memory_scopes/application/commands.py +102 -0
  553. infinity_context_core/features/memory_scopes/application/errors.py +27 -0
  554. infinity_context_core/features/memory_scopes/application/handlers.py +226 -0
  555. infinity_context_core/features/memory_scopes/application/use_cases.py +68 -0
  556. infinity_context_core/features/memory_scopes/domain/__init__.py +59 -0
  557. infinity_context_core/features/memory_scopes/domain/errors.py +22 -0
  558. infinity_context_core/features/memory_scopes/domain/feature.py +18 -0
  559. infinity_context_core/features/memory_scopes/domain/policies.py +197 -0
  560. infinity_context_core/features/memory_scopes/domain/scope.py +178 -0
  561. infinity_context_core/features/memory_scopes/ports/__init__.py +25 -0
  562. infinity_context_core/features/memory_scopes/ports/clock.py +14 -0
  563. infinity_context_core/features/memory_scopes/ports/ids.py +13 -0
  564. infinity_context_core/features/memory_scopes/ports/repositories.py +40 -0
  565. infinity_context_core/features/memory_scopes/ports/unit_of_work.py +39 -0
  566. infinity_context_core/features/memory_scopes/public.py +111 -0
  567. infinity_context_core/features/memory_scopes/tests/test_application_ports_public_skeleton.py +824 -0
  568. infinity_context_core/features/memory_scopes/tests/test_domain_scope_skeleton.py +428 -0
  569. infinity_context_core/memory_scope_snapshot_preview.py +863 -0
  570. infinity_context_core/memory_scope_snapshots.py +206 -0
  571. infinity_context_core/ports/__init__.py +164 -0
  572. infinity_context_core/ports/adapters.py +217 -0
  573. infinity_context_core/ports/assets.py +270 -0
  574. infinity_context_core/ports/auth.py +68 -0
  575. infinity_context_core/ports/auto_memory.py +71 -0
  576. infinity_context_core/ports/benchmark_runs.py +205 -0
  577. infinity_context_core/ports/capabilities.py +324 -0
  578. infinity_context_core/ports/captures.py +53 -0
  579. infinity_context_core/ports/clock.py +11 -0
  580. infinity_context_core/ports/derived_projection_policy.py +72 -0
  581. infinity_context_core/ports/extraction.py +201 -0
  582. infinity_context_core/ports/graph_evidence.py +170 -0
  583. infinity_context_core/ports/ids.py +11 -0
  584. infinity_context_core/ports/projection_fence.py +27 -0
  585. infinity_context_core/ports/repositories.py +563 -0
  586. infinity_context_core/ports/transcription.py +63 -0
  587. infinity_context_core/ports/unit_of_work.py +77 -0
  588. infinity_context_core/ports/usage.py +36 -0
  589. infinity_context_core/ports/vector_projection_evidence.py +230 -0
  590. infinity_context_core/ports/vision.py +36 -0
  591. infinity_context_core/processes/__init__.py +3 -0
  592. infinity_context_core/processes/document_memory_pipeline/__init__.py +3 -0
  593. infinity_context_core/processes/document_memory_pipeline/contracts.py +44 -0
  594. infinity_context_core/processes/document_memory_pipeline/process.py +72 -0
  595. infinity_context_core/processes/document_memory_pipeline/public.py +21 -0
  596. infinity_context_core/reporting.py +105 -0
  597. infinity_context_mcp/__init__.py +5 -0
  598. infinity_context_mcp/__main__.py +6 -0
  599. infinity_context_mcp/adapters/__init__.py +1 -0
  600. infinity_context_mcp/adapters/http_gateway.py +940 -0
  601. infinity_context_mcp/agent_behavior_bench.py +1731 -0
  602. infinity_context_mcp/agent_behavior_bench_metrics.py +419 -0
  603. infinity_context_mcp/agent_behavior_bench_redaction.py +149 -0
  604. infinity_context_mcp/agent_behavior_bench_types.py +127 -0
  605. infinity_context_mcp/agent_behavior_scenarios.py +35 -0
  606. infinity_context_mcp/agent_behavior_scenarios_core.py +484 -0
  607. infinity_context_mcp/agent_behavior_scenarios_realistic.py +473 -0
  608. infinity_context_mcp/agent_behavior_scenarios_transcript.py +196 -0
  609. infinity_context_mcp/agent_behavior_transcripts.py +231 -0
  610. infinity_context_mcp/agent_behavior_types.py +66 -0
  611. infinity_context_mcp/agent_behavior_utils.py +29 -0
  612. infinity_context_mcp/application/__init__.py +1 -0
  613. infinity_context_mcp/application/context_link_review.py +109 -0
  614. infinity_context_mcp/application/local_runtime.py +473 -0
  615. infinity_context_mcp/application/normalization.py +36 -0
  616. infinity_context_mcp/application/obsidian.py +568 -0
  617. infinity_context_mcp/application/policy.py +160 -0
  618. infinity_context_mcp/application/ports.py +324 -0
  619. infinity_context_mcp/application/prepare.py +254 -0
  620. infinity_context_mcp/application/readiness.py +71 -0
  621. infinity_context_mcp/application/review_batch.py +62 -0
  622. infinity_context_mcp/application/service.py +701 -0
  623. infinity_context_mcp/application/service_base.py +29 -0
  624. infinity_context_mcp/application/service_constants.py +89 -0
  625. infinity_context_mcp/application/service_context_links.py +224 -0
  626. infinity_context_mcp/application/service_duplicates.py +62 -0
  627. infinity_context_mcp/application/service_facts.py +461 -0
  628. infinity_context_mcp/application/service_helpers.py +179 -0
  629. infinity_context_mcp/application/service_lifecycle.py +348 -0
  630. infinity_context_mcp/application/service_policy.py +74 -0
  631. infinity_context_mcp/application/service_query.py +384 -0
  632. infinity_context_mcp/application/service_resources.py +192 -0
  633. infinity_context_mcp/application/service_response.py +95 -0
  634. infinity_context_mcp/application/service_scope.py +132 -0
  635. infinity_context_mcp/application/service_suggestions.py +820 -0
  636. infinity_context_mcp/application/suggest_batch.py +71 -0
  637. infinity_context_mcp/application/usage_guide.py +74 -0
  638. infinity_context_mcp/bench.py +279 -0
  639. infinity_context_mcp/config.py +213 -0
  640. infinity_context_mcp/domain/__init__.py +1 -0
  641. infinity_context_mcp/domain/context_links.py +117 -0
  642. infinity_context_mcp/domain/local_runtime_models.py +56 -0
  643. infinity_context_mcp/domain/memory_browser.py +35 -0
  644. infinity_context_mcp/domain/models.py +1036 -0
  645. infinity_context_mcp/domain/obsidian_models.py +67 -0
  646. infinity_context_mcp/domain/policy.py +112 -0
  647. infinity_context_mcp/domain/prepare_models.py +24 -0
  648. infinity_context_mcp/plugin_hook.py +873 -0
  649. infinity_context_mcp/plugin_hook_settings.py +253 -0
  650. infinity_context_mcp/server.py +133 -0
  651. infinity_context_mcp/server_context_tools.py +404 -0
  652. infinity_context_mcp/server_fact_tools.py +928 -0
  653. infinity_context_mcp/server_hardening.py +54 -0
  654. infinity_context_mcp/server_local_runtime_tools.py +164 -0
  655. infinity_context_mcp/server_obsidian_tools.py +380 -0
  656. infinity_context_mcp/server_query_tools.py +626 -0
  657. infinity_context_mcp/server_request_mapping.py +73 -0
  658. infinity_context_mcp/server_resources.py +187 -0
  659. infinity_context_mcp/server_response.py +26 -0
  660. infinity_context_obsidian/__init__.py +5 -0
  661. infinity_context_obsidian/cli.py +594 -0
  662. infinity_context_obsidian/conflicts.py +110 -0
  663. infinity_context_obsidian/doctor.py +319 -0
  664. infinity_context_obsidian/domain.py +92 -0
  665. infinity_context_obsidian/frontmatter.py +68 -0
  666. infinity_context_obsidian/gateway.py +66 -0
  667. infinity_context_obsidian/layout.py +179 -0
  668. infinity_context_obsidian/note_format.py +159 -0
  669. infinity_context_obsidian/plugin_bundle/__init__.py +1 -0
  670. infinity_context_obsidian/plugin_bundle/main.js +5 -0
  671. infinity_context_obsidian/plugin_bundle/manifest.json +10 -0
  672. infinity_context_obsidian/plugin_bundle/styles.css +123 -0
  673. infinity_context_obsidian/plugin_install.py +139 -0
  674. infinity_context_obsidian/ports.py +72 -0
  675. infinity_context_obsidian/setup.py +202 -0
  676. infinity_context_obsidian/state.py +85 -0
  677. infinity_context_obsidian/sync.py +741 -0
  678. infinity_context_obsidian/vault.py +61 -0
  679. infinity_context_sdk/__init__.py +1049 -0
  680. infinity_context_sdk/_payloads.py +401 -0
  681. infinity_context_sdk/_redaction.py +31 -0
  682. infinity_context_sdk/anchors.py +249 -0
  683. infinity_context_sdk/assets.py +554 -0
  684. infinity_context_sdk/capabilities.py +199 -0
  685. infinity_context_sdk/context.py +540 -0
  686. infinity_context_sdk/context_bundle_diagnostics.py +905 -0
  687. infinity_context_sdk/context_payload_utils.py +219 -0
  688. infinity_context_sdk/export.py +123 -0
  689. infinity_context_sdk/scopes.py +74 -0
  690. infinity_context_sdk/thread_memory.py +55 -0
  691. infinity_context_server/__init__.py +5 -0
  692. infinity_context_server/__main__.py +19 -0
  693. infinity_context_server/admin.py +832 -0
  694. infinity_context_server/admin_invariants.py +388 -0
  695. infinity_context_server/admin_outbox.py +130 -0
  696. infinity_context_server/admin_projection_repair.py +374 -0
  697. infinity_context_server/api/__init__.py +1 -0
  698. infinity_context_server/api/auth.py +432 -0
  699. infinity_context_server/api/dependencies.py +9 -0
  700. infinity_context_server/api/errors.py +94 -0
  701. infinity_context_server/api/legacy_client.py +356 -0
  702. infinity_context_server/api/policy.py +35 -0
  703. infinity_context_server/api/public_payload.py +27 -0
  704. infinity_context_server/api/v1/__init__.py +54 -0
  705. infinity_context_server/api/v1/anchors.py +469 -0
  706. infinity_context_server/api/v1/assets.py +409 -0
  707. infinity_context_server/api/v1/capabilities.py +144 -0
  708. infinity_context_server/api/v1/captures.py +329 -0
  709. infinity_context_server/api/v1/context.py +362 -0
  710. infinity_context_server/api/v1/context_links.py +611 -0
  711. infinity_context_server/api/v1/diagnostics.py +333 -0
  712. infinity_context_server/api/v1/digest.py +107 -0
  713. infinity_context_server/api/v1/documents.py +164 -0
  714. infinity_context_server/api/v1/episodes.py +146 -0
  715. infinity_context_server/api/v1/export.py +184 -0
  716. infinity_context_server/api/v1/facts.py +265 -0
  717. infinity_context_server/api/v1/health.py +24 -0
  718. infinity_context_server/api/v1/insights.py +100 -0
  719. infinity_context_server/api/v1/internal_memory_comparison_runs.py +406 -0
  720. infinity_context_server/api/v1/memory_browser.py +183 -0
  721. infinity_context_server/api/v1/operations.py +81 -0
  722. infinity_context_server/api/v1/scope_resolution.py +389 -0
  723. infinity_context_server/api/v1/source_refs.py +111 -0
  724. infinity_context_server/api/v1/spaces_memory_scopes.py +141 -0
  725. infinity_context_server/api/v1/suggestions.py +237 -0
  726. infinity_context_server/api/v1/thread_memory.py +74 -0
  727. infinity_context_server/api/v1/usage.py +75 -0
  728. infinity_context_server/api/v1/users.py +164 -0
  729. infinity_context_server/auth_scope.py +492 -0
  730. infinity_context_server/auth_tokens.py +283 -0
  731. infinity_context_server/backpressure.py +47 -0
  732. infinity_context_server/benchmark_projection_absence.py +155 -0
  733. infinity_context_server/benchmark_projection_delete_outbox.py +162 -0
  734. infinity_context_server/composition.py +897 -0
  735. infinity_context_server/config.py +223 -0
  736. infinity_context_server/db.py +39 -0
  737. infinity_context_server/deployment_readiness.py +205 -0
  738. infinity_context_server/derived_identity_evidence.py +987 -0
  739. infinity_context_server/derived_identity_target.py +39 -0
  740. infinity_context_server/derived_projection_policy.py +85 -0
  741. infinity_context_server/diagnostics.py +536 -0
  742. infinity_context_server/doctor.py +71 -0
  743. infinity_context_server/eval.py +3066 -0
  744. infinity_context_server/eval_auto_memory.py +1735 -0
  745. infinity_context_server/eval_auto_memory_metrics.py +224 -0
  746. infinity_context_server/eval_auto_memory_types.py +75 -0
  747. infinity_context_server/eval_case_catalog.py +1590 -0
  748. infinity_context_server/eval_case_runner.py +1100 -0
  749. infinity_context_server/eval_common.py +336 -0
  750. infinity_context_server/eval_constants.py +310 -0
  751. infinity_context_server/eval_fixtures.py +150 -0
  752. infinity_context_server/eval_graph.py +92 -0
  753. infinity_context_server/eval_hybrid.py +99 -0
  754. infinity_context_server/eval_multimodal_offline.py +697 -0
  755. infinity_context_server/eval_prompt_contract.py +402 -0
  756. infinity_context_server/eval_scorecard.py +2627 -0
  757. infinity_context_server/eval_semantic_linking.py +1526 -0
  758. infinity_context_server/eval_semantic_retrieval_api_canary.py +405 -0
  759. infinity_context_server/eval_semantic_retrieval_canary.py +359 -0
  760. infinity_context_server/eval_types.py +88 -0
  761. infinity_context_server/evidence_bundle.py +523 -0
  762. infinity_context_server/extraction_capabilities.py +1234 -0
  763. infinity_context_server/features/__init__.py +3 -0
  764. infinity_context_server/features/context_building/__init__.py +5 -0
  765. infinity_context_server/features/context_building/benchmark_budget.py +29 -0
  766. infinity_context_server/features/context_building/composition.py +49 -0
  767. infinity_context_server/features/context_building/context_requests.py +151 -0
  768. infinity_context_server/features/context_building/contracts.py +96 -0
  769. infinity_context_server/features/context_building/digest_api_responses.py +225 -0
  770. infinity_context_server/features/context_building/digest_requests.py +65 -0
  771. infinity_context_server/features/context_building/insights_api_responses.py +132 -0
  772. infinity_context_server/features/context_building/legacy_api_responses.py +875 -0
  773. infinity_context_server/features/context_building/mappers.py +205 -0
  774. infinity_context_server/features/context_building/public.py +66 -0
  775. infinity_context_server/features/context_building/routes.py +44 -0
  776. infinity_context_server/features/document_ingestion/__init__.py +5 -0
  777. infinity_context_server/features/document_ingestion/asset_requests.py +45 -0
  778. infinity_context_server/features/document_ingestion/asset_responses.py +365 -0
  779. infinity_context_server/features/document_ingestion/composition.py +49 -0
  780. infinity_context_server/features/document_ingestion/contracts.py +104 -0
  781. infinity_context_server/features/document_ingestion/mappers.py +386 -0
  782. infinity_context_server/features/document_ingestion/public.py +58 -0
  783. infinity_context_server/features/document_ingestion/routes.py +44 -0
  784. infinity_context_server/features/memory_facts/__init__.py +7 -0
  785. infinity_context_server/features/memory_facts/compatibility.py +204 -0
  786. infinity_context_server/features/memory_facts/composition.py +72 -0
  787. infinity_context_server/features/memory_facts/contracts.py +187 -0
  788. infinity_context_server/features/memory_facts/mappers.py +620 -0
  789. infinity_context_server/features/memory_facts/public.py +168 -0
  790. infinity_context_server/features/memory_facts/routes.py +118 -0
  791. infinity_context_server/features/memory_facts/suggestion_requests.py +283 -0
  792. infinity_context_server/features/memory_facts/suggestion_responses.py +382 -0
  793. infinity_context_server/features/memory_scopes/__init__.py +5 -0
  794. infinity_context_server/features/memory_scopes/compatibility.py +231 -0
  795. infinity_context_server/features/memory_scopes/composition.py +49 -0
  796. infinity_context_server/features/memory_scopes/contracts.py +103 -0
  797. infinity_context_server/features/memory_scopes/graph_export_responses.py +93 -0
  798. infinity_context_server/features/memory_scopes/mappers.py +290 -0
  799. infinity_context_server/features/memory_scopes/public.py +136 -0
  800. infinity_context_server/features/memory_scopes/routes.py +185 -0
  801. infinity_context_server/features/memory_scopes/snapshot_compatibility.py +146 -0
  802. infinity_context_server/features/memory_scopes/thread_memory_requests.py +127 -0
  803. infinity_context_server/llm_provider_readiness.py +267 -0
  804. infinity_context_server/longmemeval_session_identity.py +167 -0
  805. infinity_context_server/main.py +68 -0
  806. infinity_context_server/mem0_benchmark_auth_challenge.py +160 -0
  807. infinity_context_server/memora_comparison.py +658 -0
  808. infinity_context_server/memory_comparison_answer_context.py +2442 -0
  809. infinity_context_server/memory_comparison_answer_context_backfill.py +1027 -0
  810. infinity_context_server/memory_comparison_answer_context_diagnostics.py +694 -0
  811. infinity_context_server/memory_comparison_answer_context_inspection.py +103 -0
  812. infinity_context_server/memory_comparison_answer_context_retrieval_slice.py +175 -0
  813. infinity_context_server/memory_comparison_answer_context_risks.py +223 -0
  814. infinity_context_server/memory_comparison_backend_target.py +41 -0
  815. infinity_context_server/memory_comparison_benchmark.py +651 -0
  816. infinity_context_server/memory_comparison_benchmark_compact.py +387 -0
  817. infinity_context_server/memory_comparison_benchmark_compact_fast_gate.py +387 -0
  818. infinity_context_server/memory_comparison_benchmark_compact_samples.py +931 -0
  819. infinity_context_server/memory_comparison_benchmark_config.py +105 -0
  820. infinity_context_server/memory_comparison_benchmark_control.py +215 -0
  821. infinity_context_server/memory_comparison_benchmark_execution.py +238 -0
  822. infinity_context_server/memory_comparison_benchmark_identity.py +65 -0
  823. infinity_context_server/memory_comparison_benchmark_metrics.py +686 -0
  824. infinity_context_server/memory_comparison_benchmark_replay.py +400 -0
  825. infinity_context_server/memory_comparison_benchmark_shared.py +284 -0
  826. infinity_context_server/memory_comparison_bounded_provider.py +295 -0
  827. infinity_context_server/memory_comparison_bundle_partial_support.py +107 -0
  828. infinity_context_server/memory_comparison_bundle_planner.py +3521 -0
  829. infinity_context_server/memory_comparison_bundle_source_windows.py +247 -0
  830. infinity_context_server/memory_comparison_candidate_features.py +2014 -0
  831. infinity_context_server/memory_comparison_candidate_fusion.py +893 -0
  832. infinity_context_server/memory_comparison_candidate_risks.py +124 -0
  833. infinity_context_server/memory_comparison_canonical_source_hash.py +109 -0
  834. infinity_context_server/memory_comparison_case_identity.py +100 -0
  835. infinity_context_server/memory_comparison_case_loader.py +123 -0
  836. infinity_context_server/memory_comparison_chat_completions.py +402 -0
  837. infinity_context_server/memory_comparison_clean_state.py +607 -0
  838. infinity_context_server/memory_comparison_clean_state_http.py +120 -0
  839. infinity_context_server/memory_comparison_clean_state_runner.py +103 -0
  840. infinity_context_server/memory_comparison_cli.py +295 -0
  841. infinity_context_server/memory_comparison_codex_canary.py +315 -0
  842. infinity_context_server/memory_comparison_codex_llm.py +345 -0
  843. infinity_context_server/memory_comparison_compact_gap_report.py +289 -0
  844. infinity_context_server/memory_comparison_comparative_preference.py +71 -0
  845. infinity_context_server/memory_comparison_conversation_ingestion.py +198 -0
  846. infinity_context_server/memory_comparison_evidence.py +877 -0
  847. infinity_context_server/memory_comparison_evidence_commitment.py +20 -0
  848. infinity_context_server/memory_comparison_failure_diagnostics.py +809 -0
  849. infinity_context_server/memory_comparison_full_canonical_evidence.py +746 -0
  850. infinity_context_server/memory_comparison_full_canonical_source_evidence_trust.py +450 -0
  851. infinity_context_server/memory_comparison_full_delete_evidence.py +670 -0
  852. infinity_context_server/memory_comparison_full_delete_evidence_trust.py +441 -0
  853. infinity_context_server/memory_comparison_full_delete_evidence_witnesses.py +308 -0
  854. infinity_context_server/memory_comparison_full_execution_validation.py +697 -0
  855. infinity_context_server/memory_comparison_full_execution_validation_slots.py +655 -0
  856. infinity_context_server/memory_comparison_full_methodology.py +556 -0
  857. infinity_context_server/memory_comparison_full_policy_component_validation.py +899 -0
  858. infinity_context_server/memory_comparison_full_profiles.py +398 -0
  859. infinity_context_server/memory_comparison_full_run_component_sets.py +304 -0
  860. infinity_context_server/memory_comparison_full_run_components.py +787 -0
  861. infinity_context_server/memory_comparison_full_run_evidence.py +759 -0
  862. infinity_context_server/memory_comparison_full_scope.py +244 -0
  863. infinity_context_server/memory_comparison_full_source_evidence.py +866 -0
  864. infinity_context_server/memory_comparison_full_verdict.py +252 -0
  865. infinity_context_server/memory_comparison_gold_blind.py +654 -0
  866. infinity_context_server/memory_comparison_gold_blind_answer_contract.py +492 -0
  867. infinity_context_server/memory_comparison_gold_blind_contract.py +760 -0
  868. infinity_context_server/memory_comparison_gold_blind_dispatch_models.py +34 -0
  869. infinity_context_server/memory_comparison_gold_blind_execution_validation.py +170 -0
  870. infinity_context_server/memory_comparison_gold_blind_judge_binding.py +167 -0
  871. infinity_context_server/memory_comparison_gold_blind_judge_capability.py +387 -0
  872. infinity_context_server/memory_comparison_gold_blind_retrieval_contract.py +413 -0
  873. infinity_context_server/memory_comparison_gold_blind_run_proof.py +880 -0
  874. infinity_context_server/memory_comparison_gold_blind_run_validation.py +109 -0
  875. infinity_context_server/memory_comparison_gold_blind_validation.py +319 -0
  876. infinity_context_server/memory_comparison_http.py +921 -0
  877. infinity_context_server/memory_comparison_http_ingest_observation.py +710 -0
  878. infinity_context_server/memory_comparison_http_ingest_request.py +204 -0
  879. infinity_context_server/memory_comparison_intent.py +2925 -0
  880. infinity_context_server/memory_comparison_latency.py +455 -0
  881. infinity_context_server/memory_comparison_llm.py +473 -0
  882. infinity_context_server/memory_comparison_location_roles.py +169 -0
  883. infinity_context_server/memory_comparison_locomo_cases.py +328 -0
  884. infinity_context_server/memory_comparison_locomo_expected_turn.py +297 -0
  885. infinity_context_server/memory_comparison_locomo_transport.py +873 -0
  886. infinity_context_server/memory_comparison_longmemeval_cases.py +339 -0
  887. infinity_context_server/memory_comparison_managed_attestation.py +771 -0
  888. infinity_context_server/memory_comparison_managed_benchmark_registry_abort_http.py +120 -0
  889. infinity_context_server/memory_comparison_managed_benchmark_registry_contracts.py +715 -0
  890. infinity_context_server/memory_comparison_managed_benchmark_registry_http.py +855 -0
  891. infinity_context_server/memory_comparison_managed_benchmark_registry_recovery_http.py +164 -0
  892. infinity_context_server/memory_comparison_managed_benchmark_registry_wire.py +890 -0
  893. infinity_context_server/memory_comparison_managed_composite_assembler.py +524 -0
  894. infinity_context_server/memory_comparison_managed_corpus_projection.py +653 -0
  895. infinity_context_server/memory_comparison_managed_execution_receipts.py +991 -0
  896. infinity_context_server/memory_comparison_managed_http_derived_evidence.py +724 -0
  897. infinity_context_server/memory_comparison_managed_http_exact_cleanup.py +476 -0
  898. infinity_context_server/memory_comparison_managed_http_execution.py +673 -0
  899. infinity_context_server/memory_comparison_managed_http_lifecycle.py +905 -0
  900. infinity_context_server/memory_comparison_managed_http_lifecycle_credentials.py +83 -0
  901. infinity_context_server/memory_comparison_managed_http_lifecycle_evidence.py +366 -0
  902. infinity_context_server/memory_comparison_managed_http_lifecycle_registration.py +106 -0
  903. infinity_context_server/memory_comparison_managed_http_policy_lifecycle.py +894 -0
  904. infinity_context_server/memory_comparison_managed_http_policy_material_projection.py +315 -0
  905. infinity_context_server/memory_comparison_managed_http_policy_receipts.py +219 -0
  906. infinity_context_server/memory_comparison_managed_http_policy_registry_evidence.py +177 -0
  907. infinity_context_server/memory_comparison_managed_http_policy_requirements.py +824 -0
  908. infinity_context_server/memory_comparison_managed_http_policy_support.py +108 -0
  909. infinity_context_server/memory_comparison_managed_http_policy_validation.py +762 -0
  910. infinity_context_server/memory_comparison_managed_ingest_manifest.py +449 -0
  911. infinity_context_server/memory_comparison_managed_live_admission.py +886 -0
  912. infinity_context_server/memory_comparison_managed_live_cli.py +536 -0
  913. infinity_context_server/memory_comparison_managed_live_composition.py +636 -0
  914. infinity_context_server/memory_comparison_managed_llm_execution.py +850 -0
  915. infinity_context_server/memory_comparison_managed_llm_execution_dispatch.py +269 -0
  916. infinity_context_server/memory_comparison_managed_llm_execution_ports.py +225 -0
  917. infinity_context_server/memory_comparison_managed_mem0_auth.py +65 -0
  918. infinity_context_server/memory_comparison_managed_mem0_runtime_authority.py +241 -0
  919. infinity_context_server/memory_comparison_managed_mem0_runtime_http.py +541 -0
  920. infinity_context_server/memory_comparison_managed_plan_builder.py +685 -0
  921. infinity_context_server/memory_comparison_managed_preflight.py +907 -0
  922. infinity_context_server/memory_comparison_managed_preflight_cli.py +431 -0
  923. infinity_context_server/memory_comparison_managed_production_cli.py +325 -0
  924. infinity_context_server/memory_comparison_managed_production_composition.py +140 -0
  925. infinity_context_server/memory_comparison_managed_production_ports.py +194 -0
  926. infinity_context_server/memory_comparison_managed_production_runner.py +450 -0
  927. infinity_context_server/memory_comparison_managed_projection_manifest.py +438 -0
  928. infinity_context_server/memory_comparison_managed_provider_calls.py +450 -0
  929. infinity_context_server/memory_comparison_managed_quality_projection.py +347 -0
  930. infinity_context_server/memory_comparison_managed_registry_policy_lifecycle.py +677 -0
  931. infinity_context_server/memory_comparison_managed_run.py +892 -0
  932. infinity_context_server/memory_comparison_managed_run_contract.py +454 -0
  933. infinity_context_server/memory_comparison_managed_run_ports.py +79 -0
  934. infinity_context_server/memory_comparison_managed_runtime_credentials.py +916 -0
  935. infinity_context_server/memory_comparison_managed_runtime_credentials_capability.py +361 -0
  936. infinity_context_server/memory_comparison_managed_runtime_credentials_context.py +132 -0
  937. infinity_context_server/memory_comparison_managed_runtime_credentials_integrity.py +213 -0
  938. infinity_context_server/memory_comparison_managed_runtime_credentials_models.py +81 -0
  939. infinity_context_server/memory_comparison_managed_runtime_credentials_targets.py +28 -0
  940. infinity_context_server/memory_comparison_mem0_contract.py +491 -0
  941. infinity_context_server/memory_comparison_mem0_http_observation.py +296 -0
  942. infinity_context_server/memory_comparison_mem0_locomo_prompts.py +328 -0
  943. infinity_context_server/memory_comparison_mem0_longmemeval_prompts.py +365 -0
  944. infinity_context_server/memory_comparison_mem0_official_chat.py +504 -0
  945. infinity_context_server/memory_comparison_mem0_official_prompt_renderer.py +307 -0
  946. infinity_context_server/memory_comparison_mem0_oss_contract.py +456 -0
  947. infinity_context_server/memory_comparison_mem0_oss_manifest.py +563 -0
  948. infinity_context_server/memory_comparison_mem0_platform_contract.py +467 -0
  949. infinity_context_server/memory_comparison_mem0_runtime_attestation.py +861 -0
  950. infinity_context_server/memory_comparison_models.py +398 -0
  951. infinity_context_server/memory_comparison_openai_official_transport.py +525 -0
  952. infinity_context_server/memory_comparison_preflight.py +1147 -0
  953. infinity_context_server/memory_comparison_probe_transport.py +154 -0
  954. infinity_context_server/memory_comparison_prompt_policy.py +603 -0
  955. infinity_context_server/memory_comparison_provider_provenance.py +392 -0
  956. infinity_context_server/memory_comparison_quality_accessors.py +339 -0
  957. infinity_context_server/memory_comparison_quality_actionable_gaps.py +2038 -0
  958. infinity_context_server/memory_comparison_quality_answer_context_gaps.py +450 -0
  959. infinity_context_server/memory_comparison_quality_answer_context_risks.py +75 -0
  960. infinity_context_server/memory_comparison_quality_bundle_gaps.py +860 -0
  961. infinity_context_server/memory_comparison_quality_bundle_table.py +805 -0
  962. infinity_context_server/memory_comparison_quality_diagnostics.py +2798 -0
  963. infinity_context_server/memory_comparison_quality_fusion.py +241 -0
  964. infinity_context_server/memory_comparison_quality_query_plan_gaps.py +533 -0
  965. infinity_context_server/memory_comparison_quality_query_role_gaps.py +845 -0
  966. infinity_context_server/memory_comparison_quality_query_roles.py +815 -0
  967. infinity_context_server/memory_comparison_quality_rerank_gaps.py +492 -0
  968. infinity_context_server/memory_comparison_quality_selected_weakness.py +544 -0
  969. infinity_context_server/memory_comparison_quality_support.py +921 -0
  970. infinity_context_server/memory_comparison_query_integrity.py +301 -0
  971. infinity_context_server/memory_comparison_query_plan.py +524 -0
  972. infinity_context_server/memory_comparison_query_terms.py +2055 -0
  973. infinity_context_server/memory_comparison_relation_support.py +2100 -0
  974. infinity_context_server/memory_comparison_rerank.py +3209 -0
  975. infinity_context_server/memory_comparison_rerank_intents.py +405 -0
  976. infinity_context_server/memory_comparison_rerank_policies.py +1726 -0
  977. infinity_context_server/memory_comparison_rerank_policy.py +675 -0
  978. infinity_context_server/memory_comparison_rerank_shapes.py +152 -0
  979. infinity_context_server/memory_comparison_rerank_terms.py +973 -0
  980. infinity_context_server/memory_comparison_rerank_text.py +722 -0
  981. infinity_context_server/memory_comparison_retrieval_policy.py +108 -0
  982. infinity_context_server/memory_comparison_retrieval_width.py +383 -0
  983. infinity_context_server/memory_comparison_service_probe.py +278 -0
  984. infinity_context_server/memory_comparison_service_probes.py +547 -0
  985. infinity_context_server/memory_comparison_session_identity_contract.py +328 -0
  986. infinity_context_server/memory_comparison_source_identity.py +1655 -0
  987. infinity_context_server/memory_comparison_subscription_chat.py +717 -0
  988. infinity_context_server/memory_comparison_subscription_live_probe.py +323 -0
  989. infinity_context_server/memory_comparison_subscription_probe.py +368 -0
  990. infinity_context_server/memory_comparison_target_identity.py +42 -0
  991. infinity_context_server/memory_comparison_temporal_grounding.py +771 -0
  992. infinity_context_server/memory_comparison_token_budget_contract.py +665 -0
  993. infinity_context_server/memory_comparison_token_latency.py +136 -0
  994. infinity_context_server/memory_scope_transfer.py +933 -0
  995. infinity_context_server/memory_scope_transfer_assets.py +181 -0
  996. infinity_context_server/memory_scope_transfer_conflicts.py +565 -0
  997. infinity_context_server/memory_scope_transfer_context.py +295 -0
  998. infinity_context_server/memory_scope_transfer_extractions.py +390 -0
  999. infinity_context_server/memory_scope_transfer_facts.py +65 -0
  1000. infinity_context_server/memory_scope_transfer_records.py +630 -0
  1001. infinity_context_server/memory_scope_transfer_relations.py +84 -0
  1002. infinity_context_server/memory_scope_transfer_remap.py +710 -0
  1003. infinity_context_server/memory_scope_transfer_scope.py +267 -0
  1004. infinity_context_server/memory_scope_transfer_support.py +108 -0
  1005. infinity_context_server/memory_scope_transfer_temporal.py +24 -0
  1006. infinity_context_server/metrics.py +264 -0
  1007. infinity_context_server/official_public_benchmark.py +979 -0
  1008. infinity_context_server/pagination.py +60 -0
  1009. infinity_context_server/processes/__init__.py +38 -0
  1010. infinity_context_server/processes/extractions.py +40 -0
  1011. infinity_context_server/processes/outbox.py +47 -0
  1012. infinity_context_server/processes/projections.py +372 -0
  1013. infinity_context_server/provider_budget.py +59 -0
  1014. infinity_context_server/provider_circuit.py +333 -0
  1015. infinity_context_server/public_benchmark.py +2532 -0
  1016. infinity_context_server/public_benchmark_artifacts.py +91 -0
  1017. infinity_context_server/public_benchmark_case_diagnostics.py +231 -0
  1018. infinity_context_server/public_benchmark_checkpoint.py +751 -0
  1019. infinity_context_server/public_benchmark_environment.py +102 -0
  1020. infinity_context_server/public_benchmark_execution.py +445 -0
  1021. infinity_context_server/public_benchmark_http.py +39 -0
  1022. infinity_context_server/public_benchmark_manifest.py +129 -0
  1023. infinity_context_server/public_benchmark_metrics.py +645 -0
  1024. infinity_context_server/public_benchmark_metrics_policy.py +117 -0
  1025. infinity_context_server/public_benchmark_models.py +112 -0
  1026. infinity_context_server/public_benchmark_progress.py +224 -0
  1027. infinity_context_server/public_benchmark_results.py +76 -0
  1028. infinity_context_server/public_benchmark_run_diagnostics.py +163 -0
  1029. infinity_context_server/public_benchmark_selection.py +379 -0
  1030. infinity_context_server/public_benchmark_transport.py +62 -0
  1031. infinity_context_server/public_benchmark_unsupported.py +228 -0
  1032. infinity_context_server/ranked_evidence_answer_support.py +665 -0
  1033. infinity_context_server/ranked_evidence_document_seed_contract.py +30 -0
  1034. infinity_context_server/ranked_evidence_evaluator_helpers.py +135 -0
  1035. infinity_context_server/ranked_evidence_retrieval_request.py +36 -0
  1036. infinity_context_server/ranked_evidence_seed_case.py +109 -0
  1037. infinity_context_server/ranked_evidence_semantic_gate.py +980 -0
  1038. infinity_context_server/ranked_evidence_semantic_gate_cli.py +137 -0
  1039. infinity_context_server/ranked_evidence_semantic_gate_decision.py +163 -0
  1040. infinity_context_server/ranked_evidence_semantic_metrics.py +375 -0
  1041. infinity_context_server/ranked_evidence_session_identity.py +100 -0
  1042. infinity_context_server/storage_maintenance.py +187 -0
  1043. infinity_context_server/top_evidence_dataset_profile.py +442 -0
  1044. infinity_context_server/top_evidence_policy.py +274 -0
  1045. infinity_context_server/top_evidence_preflight.py +693 -0
  1046. infinity_context_server/web/assets/memory-browser-capture.js +252 -0
  1047. infinity_context_server/web/assets/memory-browser-operations.js +143 -0
  1048. infinity_context_server/web/assets/memory-browser-review.js +687 -0
  1049. infinity_context_server/web/assets/memory-browser.css +854 -0
  1050. infinity_context_server/web/assets/memory-browser.js +3299 -0
  1051. infinity_context_server/web/index.html +261 -0
  1052. infinity_context_server/web_ui.py +29 -0
  1053. infinity_context_server/worker.py +380 -0
@@ -0,0 +1,2391 @@
1
+ """Domain-specific deterministic rerank signals for memory context items."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from dataclasses import dataclass
7
+
8
+ from infinity_context_core.application.context_aggregation_answer_slots import (
9
+ aggregation_answer_slot_count,
10
+ aggregation_answer_slots,
11
+ )
12
+ from infinity_context_core.application.context_aggregation_subject import (
13
+ aggregation_subject_grounding,
14
+ )
15
+ from infinity_context_core.application.context_internal_diagnostics import (
16
+ diagnostic_mapping,
17
+ diagnostic_text,
18
+ )
19
+ from infinity_context_core.application.context_item_purchase_evidence import (
20
+ has_item_purchase_object_evidence,
21
+ has_item_purchase_object_marker,
22
+ has_item_purchase_temporal_or_media_marker,
23
+ has_item_purchase_verb_marker,
24
+ )
25
+ from infinity_context_core.application.context_relative_duration_evidence import (
26
+ has_relative_duration_event_evidence,
27
+ )
28
+ from infinity_context_core.application.context_relevance import QueryRelevance
29
+ from infinity_context_core.application.context_score_signal_rerank import (
30
+ score_signal_reason as _score_signal_reason,
31
+ )
32
+ from infinity_context_core.application.context_travel_place_evidence import (
33
+ has_travel_place_inventory_evidence,
34
+ )
35
+ from infinity_context_core.application.dto import ContextItem
36
+
37
+ _SUPPORT_NETWORK_PEOPLE_RE = re.compile(
38
+ r"\b(?:friends?|family|mentors?|people\s+around|parents?|mother|mom|"
39
+ r"father|dad|sisters?|brothers?|siblings?|partner|spouse|husband|wife|"
40
+ r"coach|teacher|counselor)\b|"
41
+ r"\b(?:друзья|друзей|семья|семьи|родители|мама|мать|отец|папа|"
42
+ r"сестра|сестры|брат|братья|партнер|партн[её]р|супруг|супруга|"
43
+ r"наставники|наставник|тренер|учитель|люди\s+рядом)\b",
44
+ re.IGNORECASE,
45
+ )
46
+ _SUPPORT_NETWORK_SIGNAL_RE = re.compile(
47
+ r"\b(?:rocks?|there\s+for|support\s+system|support\s+network|strength|"
48
+ r"motivat(?:e|es|ed|ing)|cheer(?:s|ed)?\s+(?:me|her|him|them)\s+on|"
49
+ r"trusted|reliable|comfort(?:s|ed)?)\b|"
50
+ r"\b(?:опор\w*|рядом|поддерж\w*|помог\w*|сил\w*|мотивир\w*)\b",
51
+ re.IGNORECASE,
52
+ )
53
+ _SUPPORT_NETWORK_TECHNICAL_RE = re.compile(
54
+ r"\b(?:api|backend|cloud|customer|database|frontend|infra|integration|"
55
+ r"library|model|platform|provider|runtime|sdk|service|software|technical|"
56
+ r"tool|web)\b",
57
+ re.IGNORECASE,
58
+ )
59
+ _SUPPORT_NETWORK_RERANK_REASONS = frozenset(
60
+ (
61
+ "negative_experience_support_bridge",
62
+ "support_network_bridge",
63
+ )
64
+ )
65
+ _INVENTORY_LIST_RERANK_REASONS = frozenset(
66
+ (
67
+ "decomposition_inventory_list",
68
+ "friend_place_inventory_bridge",
69
+ "friend_place_shelter_inventory_bridge",
70
+ "friend_place_gym_inventory_bridge",
71
+ "friend_place_church_inventory_bridge",
72
+ "pottery_type_bridge",
73
+ "travel_country_inventory_bridge",
74
+ "cause_education_infrastructure_inventory_bridge",
75
+ "cause_veterans_inventory_bridge",
76
+ "book_reading_list_bridge",
77
+ "church_friend_activity_inventory_bridge",
78
+ )
79
+ )
80
+ _CURRENT_GOAL_RERANK_REASONS = frozenset(
81
+ (
82
+ "adoption_current_goal_bridge",
83
+ "adoption_current_milestone_bridge",
84
+ "decomposition_current_preference_or_goal",
85
+ )
86
+ )
87
+ _POSITIVE_PREFERENCE_RERANK_REASONS = frozenset(
88
+ (
89
+ "children_preference_bridge",
90
+ "classical_music_preference_bridge",
91
+ "decomposition_current_preference_or_goal",
92
+ "food_preference_bridge",
93
+ "outdoor_nature_memory_bridge",
94
+ "outdoor_preference_bridge",
95
+ )
96
+ )
97
+ _OUTDOOR_PREFERENCE_RERANK_REASONS = frozenset(
98
+ (
99
+ "outdoor_nature_memory_bridge",
100
+ "outdoor_preference_bridge",
101
+ )
102
+ )
103
+ _COMMONALITY_RERANK_REASONS = frozenset(
104
+ (
105
+ "business_commonality_bridge",
106
+ "commonality_interest_bridge",
107
+ "decomposition_commonality",
108
+ )
109
+ )
110
+ _FAMILY_HIKE_DETAIL_RERANK_REASONS = frozenset(
111
+ (
112
+ "family_hike_activity_bridge",
113
+ "family_hike_detail_bridge",
114
+ )
115
+ )
116
+ _TEMPORAL_CAMPING_DETAIL_RERANK_REASONS = frozenset(
117
+ (
118
+ "camping_detail_bridge",
119
+ "temporal_event_detail_bridge",
120
+ )
121
+ )
122
+ _IDENTITY_RERANK_REASONS = frozenset(
123
+ (
124
+ "decomposition_identity_attribute",
125
+ "identity_bridge",
126
+ )
127
+ )
128
+ _IDENTITY_QUERY_RE = re.compile(
129
+ r"\b(?:identity|gender\s+identity|identify|identifies|true\s+self)\b|"
130
+ r"\b(?:transgender|trans|queer|nonbinary)\b(?=.{0,80}\b(?:identity|person|"
131
+ r"woman|man|self)\b)",
132
+ re.IGNORECASE | re.DOTALL,
133
+ )
134
+ _IDENTITY_EXACT_RE = re.compile(
135
+ r"\b(?:identif(?:y|ies|ied)\s+as|"
136
+ r"(?:is|am|are|was|were)\s+(?:a\s+)?(?:transgender|trans|queer|nonbinary|"
137
+ r"gay|lesbian|bisexual)\b|"
138
+ r"transgender\s+woman|trans\s+woman|transgender\s+man|trans\s+man|"
139
+ r"gender\s+identity|true\s+self|my\s+identity|her\s+identity|"
140
+ r"his\s+identity|their\s+identity)\b",
141
+ re.IGNORECASE,
142
+ )
143
+ _IDENTITY_TOPIC_WEAK_RE = re.compile(
144
+ r"\b(?:support\s+group|pride\s+(?:flag|mural|event|parade)|"
145
+ r"transgender\s+stories|lgbtq?\s+(?:event|community|group)|"
146
+ r"support(?:s|ed|ive|ing)?\s+(?:the\s+)?(?:transgender|lgbtq?|queer)\s+"
147
+ r"(?:community|events?|rights?))\b",
148
+ re.IGNORECASE,
149
+ )
150
+ _RELATIONSHIP_STATUS_RERANK_REASONS = frozenset(
151
+ (
152
+ "relationship_status_bridge",
153
+ "decomposition_relationship_status",
154
+ )
155
+ )
156
+ _RELATIONSHIP_STATUS_QUERY_RE = re.compile(
157
+ r"\brelationship\s+status\b|"
158
+ r"\b(?:single|dating|married|partner|spouse|husband|wife)\b"
159
+ r"(?=.{0,80}\b(?:status|relationship)\b)|"
160
+ r"\b(?:отношения|статус|пара|партн[её]р|супруг|супруга)\b",
161
+ re.IGNORECASE | re.DOTALL,
162
+ )
163
+ _RELATIONSHIP_DURATION_RERANK_REASONS = frozenset(
164
+ (
165
+ "relationship_duration_bridge",
166
+ "decomposition_relationship_duration",
167
+ )
168
+ )
169
+ _RELATIONSHIP_ORIGIN_RERANK_REASONS = frozenset(("relationship_origin_bridge",))
170
+ _RECOMMENDATION_FOLLOWUP_RERANK_REASONS = frozenset(
171
+ (
172
+ "book_suggestion_bridge",
173
+ "decomposition_recommendation_source",
174
+ "food_recipe_recommendation_bridge",
175
+ "recommendation_source_bridge",
176
+ "wellness_activity_effect_bridge",
177
+ )
178
+ )
179
+ _STATE_TRANSITION_RERANK_REASONS = frozenset(
180
+ (
181
+ "change_over_time_bridge",
182
+ "decomposition_state_transition",
183
+ "decomposition_temporal_change",
184
+ "state_transition_bridge",
185
+ )
186
+ )
187
+ _CURRENT_STATE_RERANK_REASONS = frozenset(
188
+ (
189
+ "current_recommendation_bridge",
190
+ "current_state_temporal_bridge",
191
+ "decomposition_knowledge_update_current",
192
+ )
193
+ )
194
+ _STALE_STATE_RERANK_REASONS = frozenset(("stale_state_temporal_bridge",))
195
+ _AGE_BIRTHDAY_RERANK_REASONS = frozenset(("age_birthday_bridge",))
196
+ _BIRTHPLACE_RERANK_REASONS = frozenset(("birthplace_origin_bridge",))
197
+ _BEACH_OR_MOUNTAINS_RERANK_REASONS = frozenset(("beach_or_mountains_inference_bridge",))
198
+ _ITEM_PURCHASE_RERANK_REASONS = frozenset(("item_purchase_bridge",))
199
+ _SYMBOL_IMPORTANCE_RERANK_REASONS = frozenset(("symbol_importance_bridge",))
200
+ _POST_EVENT_EMOTION_RERANK_REASONS = frozenset(("post_event_emotion_bridge",))
201
+ _INVENTORY_POTTERY_QUERY_RE = re.compile(
202
+ r"\b(?:pottery|ceramic|clay|pots?|bowls?|cups?|mugs?|plates?)\b",
203
+ re.IGNORECASE,
204
+ )
205
+ _INVENTORY_POTTERY_EVIDENCE_RE = re.compile(
206
+ r"\b(?:pottery|ceramic|clay|pots?|bowls?|cups?|mugs?|plates?)\b",
207
+ re.IGNORECASE,
208
+ )
209
+ _INVENTORY_POTTERY_OWNER_EVIDENCE_RE = re.compile(
210
+ r"\bD\d+:\d+\s+(?P<speaker>[A-Z][A-Za-z'_-]{1,40}):"
211
+ r"(?=.{0,260}\b(?:pottery|ceramic|clay|pots?|bowls?|cups?|mugs?|plates?|dog\s+face)\b)"
212
+ r"(?=.{0,260}\b(?:made|make|making|class|workshop|kids?|children|finished|project|"
213
+ r"hands\s+dirty|creativity|imagination|proud)\b)",
214
+ re.IGNORECASE | re.DOTALL,
215
+ )
216
+ _QUERY_PERSON_STOPWORDS = frozenset(
217
+ {
218
+ "what",
219
+ "which",
220
+ "where",
221
+ "when",
222
+ "who",
223
+ "whom",
224
+ "whose",
225
+ "why",
226
+ "how",
227
+ }
228
+ )
229
+ _INVENTORY_COUNTRY_QUERY_RE = re.compile(
230
+ r"\b(?:cities|city|countries|country|abroad|europe(?:an)?|places?)\b",
231
+ re.IGNORECASE,
232
+ )
233
+ _INVENTORY_COUNTRY_EVIDENCE_RE = re.compile(
234
+ r"\b(?:england|spain|france|italy|germany|portugal|ireland|sweden|"
235
+ r"rome|paris|london|madrid|berlin|lisbon|dublin|stockholm)\b",
236
+ re.IGNORECASE,
237
+ )
238
+ _INVENTORY_CAUSE_QUERY_RE = re.compile(
239
+ r"\b(?:causes?|support(?:ing)?|passionate)\b",
240
+ re.IGNORECASE,
241
+ )
242
+ _INVENTORY_CAUSE_EVIDENCE_RE = re.compile(
243
+ r"\b(?:veterans?\s+rights?|military|education\s+reform|"
244
+ r"infrastructure\s+development|education|infrastructure)\b",
245
+ re.IGNORECASE,
246
+ )
247
+ _INVENTORY_DESSERT_QUERY_RE = re.compile(
248
+ r"\b(?:desserts?|sweets?|baked\s+goods?)\b",
249
+ re.IGNORECASE,
250
+ )
251
+ _INVENTORY_DESSERT_EVIDENCE_RE = re.compile(
252
+ r"\b(?:desserts?|cobblers?|peach\s+cobbler|sundae|banana\s+split|"
253
+ r"ice\s+cream|pies?|cakes?|cookies?|brownies?|puddings?|pastr(?:y|ies)|"
254
+ r"baked\s+goods?)\b",
255
+ re.IGNORECASE,
256
+ )
257
+ _INVENTORY_FRIEND_PLACE_QUERY_RE = re.compile(
258
+ r"\bwhere\b(?=.{0,100}\b(?:friend|friends|made|met|joined|meet)\b)",
259
+ re.IGNORECASE | re.DOTALL,
260
+ )
261
+ _INVENTORY_FRIEND_PLACE_EVIDENCE_RE = re.compile(
262
+ r"\b(?:made\s+friends|became\s+friends|friends\s+with|fellow\s+volunteers?|"
263
+ r"joined\s+(?:a\s+|the\s+|nearby\s+|local\s+)?(?:gym|church)|"
264
+ r"homeless\s+shelter|dog\s+shelter|animal\s+shelter|"
265
+ r"(?:gym|church).{0,100}\b(?:supportive|welcoming|community|people))\b",
266
+ re.IGNORECASE | re.DOTALL,
267
+ )
268
+ _INVENTORY_FRIEND_PLACE_SHELTER_ANCHOR_RE = re.compile(
269
+ r"\b(?:homeless\s+shelter|shelter)\b(?=.{0,80}\b"
270
+ r"(?:i\s+volunteer\s+at|where\s+(?:she\s+)?volunteers?|"
271
+ r"donated\s+(?:my\s+|her\s+)?old\s+car))|"
272
+ r"\b(?:i\s+volunteer\s+at|where\s+(?:she\s+)?volunteers?|"
273
+ r"donated\s+(?:my\s+|her\s+)?old\s+car)\b(?=.{0,80}\b"
274
+ r"(?:homeless\s+shelter|shelter))",
275
+ re.IGNORECASE | re.DOTALL,
276
+ )
277
+ _INVENTORY_FRIEND_PLACE_SHELTER_ACTIVITY_REPEAT_RE = re.compile(
278
+ r"\b(?:gave\s+a\s+few\s+talks|received\s+lots\s+of\s+compliments|"
279
+ r"fundraiser|tournament|baked\s+goods?|dropped\s+off|"
280
+ r"received\s+a\s+medal|front\s+desk|kids?\s+event)\b",
281
+ re.IGNORECASE,
282
+ )
283
+ _INVENTORY_SHELTER_QUERY_RE = re.compile(
284
+ r"\bshelters?\b",
285
+ re.IGNORECASE,
286
+ )
287
+ _INVENTORY_SHELTER_EVIDENCE_RE = re.compile(
288
+ r"\b(?:homeless\s+shelter|dog\s+shelter|animal\s+shelter|shelter)\b",
289
+ re.IGNORECASE,
290
+ )
291
+ _INVENTORY_BOOK_READING_QUERY_RE = re.compile(
292
+ r"\b(?:books?|novels?|stories?)\b(?=.{0,80}\bread\b)|"
293
+ r"\bread\b(?=.{0,80}\b(?:books?|novels?|stories?)\b)",
294
+ re.IGNORECASE | re.DOTALL,
295
+ )
296
+ _INVENTORY_BOOK_READING_EVIDENCE_RE = re.compile(
297
+ r"\b(?:loved\s+reading\s+\"?[A-Z][^\"\n]{1,80}\"?|"
298
+ r"love\s+reading\s+\"?[A-Z][^\"\n]{1,80}\"?|"
299
+ r"read(?:ing)?\s+\"?[A-Z][^\"\n]{1,80}\"?|"
300
+ r"book\s+i\s+read\s+last\s+year|favorite\s+book|favourite\s+book|"
301
+ r"book\s+you\s+remember\s+from\s+your\s+childhood|childhood\s+book|"
302
+ r"read\s+as\s+a\s+kid)\b",
303
+ re.IGNORECASE | re.DOTALL,
304
+ )
305
+ _INVENTORY_CHURCH_FRIEND_ACTIVITY_QUERY_RE = re.compile(
306
+ r"\b(?:activities?|do|done|did|went|visit(?:ed)?|hikes?|hiking|picnic)\b"
307
+ r"(?=.{0,120}\bchurch\s+friends?\b)|"
308
+ r"\bchurch\s+friends?\b(?=.{0,120}\b"
309
+ r"(?:activities?|do|done|did|went|visit(?:ed)?|hikes?|hiking|picnic)\b)",
310
+ re.IGNORECASE | re.DOTALL,
311
+ )
312
+ _INVENTORY_CHURCH_FRIEND_ACTIVITY_EVIDENCE_RE = re.compile(
313
+ r"\bchurch\s+friends?\b(?=.{0,180}\b"
314
+ r"(?:hikes?|hiking|picnic|visited?|park|activities?|outing|trip|"
315
+ r"chilled|played\s+games|games|charades|scavenger\s+hunt|nature|refreshed)\b)|"
316
+ r"\b(?:hikes?|hiking|picnic|visited?|park|activities?|outing|trip|"
317
+ r"chilled|played\s+games|games|charades|scavenger\s+hunt|nature|refreshed)\b"
318
+ r"(?=.{0,180}\bchurch\s+friends?\b)",
319
+ re.IGNORECASE | re.DOTALL,
320
+ )
321
+ _INVENTORY_GENERIC_WEAK_RE = re.compile(
322
+ r"\b(?:inventory\s+list|answer\s+options|evidence\s+observed|"
323
+ r"observed\s+mentioned|generic\s+inventory|virtual\s+support\s+group|"
324
+ r"asked\s+family\s+and\s+friends\s+to\s+join|visited\s+countries\s+abroad)\b",
325
+ re.IGNORECASE,
326
+ )
327
+ _EVENT_SEQUENCE_MARKER_RE = re.compile(
328
+ r"\b(?:after|since|following|later|next|then|subsequently|before|earlier|prior)\b|"
329
+ r"\b(?:после|с\s+тех\s+пор|затем|потом|до|перед|раньше)\b",
330
+ re.IGNORECASE,
331
+ )
332
+ _EVENT_SEQUENCE_OUTCOME_RE = re.compile(
333
+ r"\b(?:decid(?:e|ed|es|ing)|chang(?:e|ed|es|ing)|agreed?|promis(?:e|ed|es|ing)|"
334
+ r"selected?|chos(?:e|en)|picked?|planned?|wait(?:ed|ing)?|follow(?:ed)?\s+up|"
335
+ r"outcome|result|happened|response|next\s+step)\b|"
336
+ r"\b(?:решил\w*|изменил\w*|согласил\w*|пообещал\w*|выбрал\w*|"
337
+ r"запланировал\w*|договорил\w*|результат|следующ\w+\s+шаг)\b",
338
+ re.IGNORECASE,
339
+ )
340
+ _EVENT_SEQUENCE_QUERY_RE = re.compile(
341
+ r"\b(?:what|which|who|when|where|how)\b(?=.{0,120}\b(?:after|since|following|"
342
+ r"before|prior)\b)(?=.{0,160}\b(?:talk(?:ed|ing)?|spoke|conversation|call|"
343
+ r"meeting|chat|message|event|decid(?:e|ed)|chang(?:e|ed)|happened)\b)|"
344
+ r"\b(?:что|кто|когда|где|как)\b(?=.{0,120}\b(?:после|до|перед|с\s+тех\s+пор)\b)",
345
+ re.IGNORECASE | re.DOTALL,
346
+ )
347
+ _RECOMMENDATION_FOLLOWUP_BOOK_RE = re.compile(
348
+ r"\b(?:book|novel|memoir|story|read(?:ing)?|чит(?:аю|ал\w*|ает\w*)|книг\w*)\b",
349
+ re.IGNORECASE,
350
+ )
351
+ _RECOMMENDATION_FOLLOWUP_SIGNAL_RE = re.compile(
352
+ r"\b(?:recommend(?:ed|ation)?|suggest(?:ed|ion)?|told\s+me\s+about|"
353
+ r"посоветовал\w*|порекомендовал\w*)\b",
354
+ re.IGNORECASE,
355
+ )
356
+ _FOOD_RECIPE_RECOMMENDATION_EVIDENCE_RE = re.compile(
357
+ r"\b(?:recipes?|meals?|foods?|dishes?|roasted\s+veg(?:etables?)?|"
358
+ r"grilled\s+chicken|veggie\s+stir-fry|vegetable\s+stir-fry|"
359
+ r"local\s+dishes|poutine|french\s+fries|chopsticks|sauce|"
360
+ r"healthy\s+grilled|tasty\s+and\s+easy)\b",
361
+ re.IGNORECASE,
362
+ )
363
+ _FOOD_RECIPE_RECOMMENDATION_SIGNAL_RE = re.compile(
364
+ r"\b(?:recommend(?:ed|s|ation)?|suggest(?:ed|s|ion)?|share|shared|"
365
+ r"try|trying|give\s+it\s+a\s+go|wanna\s+give|image\s+caption|"
366
+ r"visual\s+query)\b",
367
+ re.IGNORECASE,
368
+ )
369
+ _FOOD_RECIPE_RECOMMENDATION_WEAK_RE = re.compile(
370
+ r"\b(?:diet|healthy|honeymoon|skiing|food|meal|recipe|restaurant|"
371
+ r"container|photo|image)\b",
372
+ re.IGNORECASE,
373
+ )
374
+ _WELLNESS_ACTIVITY_EFFECT_EVIDENCE_RE = re.compile(
375
+ r"\b(?:yoga|stretch(?:ing)?|pilates|exercise|activity)\b"
376
+ r"(?=.{0,140}\b(?:stress|staying\s+flexible|flexibility|flexible|diet|"
377
+ r"help(?:ed|s|ing)?|alongside)\b)|"
378
+ r"\b(?:stress|staying\s+flexible|flexibility|flexible|diet)\b"
379
+ r"(?=.{0,140}\b(?:yoga|stretch(?:ing)?|pilates|exercise|activity)\b)",
380
+ re.IGNORECASE | re.DOTALL,
381
+ )
382
+ _WELLNESS_ACTIVITY_EFFECT_WEAK_RE = re.compile(
383
+ r"\b(?:stress|flexibility|flexible|diet|healthy|activity|exercise|"
384
+ r"workout|movie|watch)\b",
385
+ re.IGNORECASE,
386
+ )
387
+ _EVENT_SEQUENCE_NAMED_ANCHOR_RE = re.compile(
388
+ r"\b[A-ZА-ЯЁ][A-Za-zА-Яа-яЁё0-9._-]{1,}\b"
389
+ )
390
+ _EVENT_SEQUENCE_IGNORED_ANCHORS = frozenset(
391
+ {
392
+ "After",
393
+ "Before",
394
+ "Following",
395
+ "How",
396
+ "Since",
397
+ "The",
398
+ "What",
399
+ "When",
400
+ "Where",
401
+ "Which",
402
+ "Who",
403
+ "Why",
404
+ "Где",
405
+ "До",
406
+ "Зачем",
407
+ "Как",
408
+ "Какая",
409
+ "Какие",
410
+ "Какой",
411
+ "Когда",
412
+ "Кто",
413
+ "Перед",
414
+ "После",
415
+ "Почему",
416
+ "Что",
417
+ }
418
+ )
419
+ _EVENT_SEQUENCE_MIN_QUERY_DISTINCTIVE_TERMS = 3
420
+ _EVENT_SEQUENCE_MIN_EXACT_DISTINCTIVE_HITS = 3
421
+ _CURRENT_GOAL_EVIDENCE_RE = re.compile(
422
+ r"\b(?:goal|hope(?:s|d|ful)?|plan(?:s|ned|ning)?|intend(?:s|ed|ing)?|"
423
+ r"want(?:s|ed)?\s+to|decid(?:e|ed|es|ing)\s+to|pursu(?:e|ed|ing)|"
424
+ r"career\s+path|next\s+steps?|adoption|adopting|adopt(?:ed|s)?|"
425
+ r"build\s+my\s+own\s+family|having\s+a\s+family|"
426
+ r"committ(?:ed|ing)?\s+to\s+stay|plans?\s+to\s+stay|staying\s+through)\b|"
427
+ r"\b(?:signed|renewed|accepted|started|enrolled|booked|scheduled|committed)\b"
428
+ r"(?=.{0,80}\b(?:lease|contract|job|role|program|semester|project|deadline|"
429
+ r"appointment|school|stay|local)\b)|"
430
+ r"\b(?:lease|contract|job|role|program|semester|project|deadline|appointment|"
431
+ r"school|local)\b(?=.{0,80}\b(?:signed|renewed|accepted|started|enrolled|"
432
+ r"booked|scheduled|committed)\b)|"
433
+ r"\b(?:цель|намерен\w*|планир\w*|решил\w*|хочет\s+.+\bсделать|"
434
+ r"усынов\w*|удочер\w*|семь[яю]|подписал\w*|продлил\w*|записал\w*|"
435
+ r"забронировал\w*|остаться)\b",
436
+ re.IGNORECASE | re.DOTALL,
437
+ )
438
+ _CURRENT_GOAL_WEAK_RE = re.compile(
439
+ r"\b(?:miss(?:es|ed|ing)?\s+(?:home|her\s+home|his\s+home|their\s+home|"
440
+ r"home\s+country)|moving?\s+back\s+someday|move\s+back\s+someday|"
441
+ r"general\s+planning\s+advice|thought\s+about|considered\s+maybe)\b|"
442
+ r"\b(?:скуча\w*|когда-нибудь\s+верн\w*|общие\s+планы)\b",
443
+ re.IGNORECASE,
444
+ )
445
+ _ANIMAL_CAREER_QUERY_RE = re.compile(
446
+ r"\b(?:alternative\s+career|career)\b(?=.{0,80}\bgaming\b)|"
447
+ r"\bgaming\b(?=.{0,80}\bcareer\b)",
448
+ re.IGNORECASE | re.DOTALL,
449
+ )
450
+ _ANIMAL_CAREER_EVIDENCE_RE = re.compile(
451
+ r"\b(?:animals?|pets?|reptiles?|turtles?|zoo|zookeeper|keeper|habitat|"
452
+ r"tank|feed|feeding|eat|eating|diet|vegetables|fruits|insects|clean|"
453
+ r"light|care|caring|joy|peace|companions?|pet\s+store)\b",
454
+ re.IGNORECASE,
455
+ )
456
+ _ANIMAL_CAREER_GAMING_ONLY_RE = re.compile(
457
+ r"\b(?:gaming|games?|gamer|tournament|tournaments|console|streamer|"
458
+ r"streaming|esports?|champion|championship)\b",
459
+ re.IGNORECASE,
460
+ )
461
+ _POSITIVE_PREFERENCE_QUERY_RE = re.compile(
462
+ r"\b(?:what|which)\b(?=.{0,120}\b(?:like|likes|liked|love|loves|"
463
+ r"enjoy|enjoys|prefer|prefers|favorite|favourite|food|meal|music|song|"
464
+ r"artist|book|activity|hobby)\b)|"
465
+ r"\b(?:would\b(?=.{0,80}\benjoy\b)|prefer(?:s|red)?|favorite|favourite|"
466
+ r"likes?|loves?|fan\s+of)\b|"
467
+ r"\b(?:что|какой|какие)\b(?=.{0,120}\b(?:нравит|любит|предпочит|"
468
+ r"любим))",
469
+ re.IGNORECASE | re.DOTALL,
470
+ )
471
+ _POSITIVE_PREFERENCE_NEGATIVE_QUERY_RE = re.compile(
472
+ r"\b(?:not\s+(?:like|likes|liked|enjoy|enjoys|prefer|want)|"
473
+ r"doesn'?t\s+(?:like|enjoy|prefer|want)|does\s+not\s+"
474
+ r"(?:like|enjoy|prefer|want)|dislikes?|hates?|avoid|avoids|allergic)\b|"
475
+ r"\b(?:не\s+нравит|не\s+любит|избега|аллерг)\w*\b",
476
+ re.IGNORECASE,
477
+ )
478
+ _POSITIVE_PREFERENCE_MARKER_RE = re.compile(
479
+ r"\b(?:likes?|liked|loves?|loved|enjoys?|enjoyed|prefers?|preferred|"
480
+ r"favorites?|favourites?|favorite\s+(?:food|meal|dish|song|book|activity)|"
481
+ r"one\s+of\s+(?:my|her|his|their)\s+favorites?|fan\s+of|"
482
+ r"interested\s+in|stoked\s+about|excited\s+about)\b|"
483
+ r"\b(?:нравит\w*|любит|любил\w*|предпочит\w*|любим\w*|"
484
+ r"фанат\w*|интересу\w*)\b",
485
+ re.IGNORECASE,
486
+ )
487
+ _POSITIVE_PREFERENCE_WEAK_TOPIC_RE = re.compile(
488
+ r"\b(?:discuss(?:ed|es|ing)?|talk(?:ed|s|ing)?\s+about|mentioned|"
489
+ r"shared|sent|saw|watched|listened\s+to|usually\s+listen(?:s|ed)?\s+to|"
490
+ r"recipe\s+includes?|cooked|served|brought)\b|"
491
+ r"\b(?:обсуждал\w*|упомянул\w*|слушал\w*|смотрел\w*|готовил\w*)\b",
492
+ re.IGNORECASE,
493
+ )
494
+ _BOOK_AUTHOR_PREFERENCE_QUERY_RE = re.compile(
495
+ r"\b(?:books?\s+by|author|authors?|c\.?\s*s\.?\s*lewis|lewis|"
496
+ r"john\s+green(?:e)?|would\b(?=.{0,80}\benjoy\b).{0,120}\bread(?:ing)?)\b",
497
+ re.IGNORECASE | re.DOTALL,
498
+ )
499
+ _BOOK_AUTHOR_WORLD_EXACT_RE = re.compile(
500
+ r"\b(?:harry\s+potter|potter|j\.?\s*k\.?\s*rowling|fantasy)\b"
501
+ r"(?=.{0,180}\b(?:magical\s+world|wizarding\s+world|universe|characters?|"
502
+ r"spells?|magical\s+creatures?|london|movie|tour|real\s+potter\s+places?|"
503
+ r"getting?\s+lost|lost\s+in|transport|alternate\s+realities|escape|"
504
+ r"different\s+worlds?|other\s+places?)\b)|"
505
+ r"\b(?:magical\s+world|wizarding\s+world|universe|characters?|spells?|"
506
+ r"magical\s+creatures?|london|movie|tour|real\s+potter\s+places?|"
507
+ r"getting?\s+lost|lost\s+in|transport|alternate\s+realities|escape|"
508
+ r"different\s+worlds?|other\s+places?)\b"
509
+ r"(?=.{0,180}\b(?:harry\s+potter|potter|j\.?\s*k\.?\s*rowling|fantasy)\b)",
510
+ re.IGNORECASE | re.DOTALL,
511
+ )
512
+ _BOOK_AUTHOR_POTTER_WORLD_RE = re.compile(
513
+ r"\b(?:harry\s+potter|potter)\b(?=.{0,180}\b(?:magical\s+world|"
514
+ r"wizarding\s+world|universe|characters?|spells?|magical\s+creatures?|"
515
+ r"london|movie|tour|real\s+potter\s+places?|getting?\s+lost|lost\s+in)\b)|"
516
+ r"\b(?:magical\s+world|wizarding\s+world|universe|characters?|spells?|"
517
+ r"magical\s+creatures?|london|movie|tour|real\s+potter\s+places?|"
518
+ r"getting?\s+lost|lost\s+in)\b(?=.{0,180}\b(?:harry\s+potter|potter)\b)",
519
+ re.IGNORECASE | re.DOTALL,
520
+ )
521
+ _BOOK_AUTHOR_GENERIC_COLLECTION_RE = re.compile(
522
+ r"\b(?:bookshelf|book\s+shelf|book\s+collection|favorites?\s+on\s+there|"
523
+ r"photo\s+of\s+a\s+book|bunch\s+of\s+books)\b",
524
+ re.IGNORECASE,
525
+ )
526
+ _OUTDOOR_NATURE_EVIDENCE_RE = re.compile(
527
+ r"\b(?:camp(?:ing|fire)|hikes?|hiking|trail|forest|mountains?|nature|"
528
+ r"outdoors?|national\s+park|meteor\s+shower|perseid|sky|universe)\b",
529
+ re.IGNORECASE,
530
+ )
531
+ _OUTDOOR_STRONG_NATURE_EVIDENCE_RE = re.compile(
532
+ r"\b(?:camp(?:ing|fire)|hikes?|hiking|trail|forest|mountains?|nature|"
533
+ r"outdoors?|meteor\s+shower|perseid|sky|universe)\b",
534
+ re.IGNORECASE,
535
+ )
536
+ _COMMONALITY_QUERY_RE = re.compile(
537
+ r"\b(?:common|shared|both|mutual|same|similar|overlap|who\s+else)\b|"
538
+ r"\b(?:обе|оба|общ\w*|похож\w*|тоже)\b",
539
+ re.IGNORECASE,
540
+ )
541
+ _COMMONALITY_WHO_ELSE_QUERY_RE = re.compile(
542
+ r"\bwho\s+else\b|"
543
+ r"\b(?:кто\s+ещ[её]|еще\s+кто|ещ[её]\s+кто)\b",
544
+ re.IGNORECASE,
545
+ )
546
+ _COMMONALITY_EVIDENCE_RE = re.compile(
547
+ r"\b(?:both|share(?:s|d)?|shared|common|mutual|same|similar|also|"
548
+ r"each|together|overlap)\b|"
549
+ r"\b(?:обе|оба|общ\w*|похож\w*|тоже|вместе)\b",
550
+ re.IGNORECASE,
551
+ )
552
+ _COMMONALITY_WHO_ELSE_EVIDENCE_RE = re.compile(
553
+ r"\b(?:also|too|as\s+well|like|likes|liked|enjoys?|enjoyed|interested\s+in|"
554
+ r"fan\s+of)\b|"
555
+ r"\b(?:тоже|также|любит|нравит\w*|интересу\w*)\b",
556
+ re.IGNORECASE,
557
+ )
558
+ _COMMONALITY_SHARED_ARTIFACT_RE = re.compile(
559
+ r"\bshared?\s+(?:a\s+|an\s+|the\s+)?"
560
+ r"(?:photo|picture|image|screenshot|file|document|attachment|link|post)\b",
561
+ re.IGNORECASE,
562
+ )
563
+ _BUSINESS_COMMONALITY_ORIGIN_RE = re.compile(
564
+ r"\b(?:"
565
+ r"lost\s+my\s+job\s+(?:as|at)|"
566
+ r"also\s+lost\s+my\s+job|"
567
+ r"lost\s+(?:her|his)\s+job|"
568
+ r"after\s+losing\s+(?:her|his)\s+job|"
569
+ r"take\s+a\s+shot\s+at\s+starting\s+my\s+own\s+business|"
570
+ r"starting\s+my\s+own\s+store|"
571
+ r"started\s+(?:her|his)\s+own\s+(?:online\s+)?clothing\s+store|"
572
+ r"launched\s+an\s+ad\s+campaign|"
573
+ r"taking\s+risks\s+is\s+both\s+scary\s+and\s+rewarding|"
574
+ r"i['']?m\s+starting\s+a\s+dance\s+studio"
575
+ r")\b",
576
+ re.IGNORECASE,
577
+ )
578
+ _BUSINESS_COMMONALITY_LATE_UPDATE_RE = re.compile(
579
+ r"\b(?:"
580
+ r"congrats?\s+on\s+the\s+clothing\s+store|"
581
+ r"hard\s+work\s+paying\s+off|"
582
+ r"got\s+a\s+temp\s+job|"
583
+ r"built\s+a\s+new\s+website|"
584
+ r"acquired\s+some\s+new\s+unique\s+pieces|"
585
+ r"working\s+on\s+(?:my\s+)?online\s+store|"
586
+ r"promoting\s+(?:my\s+)?business|"
587
+ r"business\s+project\s+and\s+seeks\s+advice"
588
+ r")\b",
589
+ re.IGNORECASE,
590
+ )
591
+ _SHARED_PAINTED_SUBJECT_EXACT_RE = re.compile(
592
+ r"\b(?:sunsets?|sunrises?|landscapes?|flowers?|nature(?:-inspired)?|"
593
+ r"lake|mountains?|abstract|portraits?|scen(?:e|ery))\b"
594
+ r"(?=.{0,80}\b(?:paint(?:ed|ing)?|artwork|work|image|visual|caption)\b)|"
595
+ r"\b(?:paint(?:ed|ing)?|artwork|work|image|visual|caption)\b"
596
+ r"(?=.{0,80}\b(?:sunsets?|sunrises?|landscapes?|flowers?|"
597
+ r"nature(?:-inspired)?|lake|mountains?|abstract|portraits?|scen(?:e|ery))\b)",
598
+ re.IGNORECASE | re.DOTALL,
599
+ )
600
+ _SHARED_PAINTED_SUBJECT_TOPIC_RE = re.compile(
601
+ r"\b(?:paint(?:ed|ing)?|artwork)\b",
602
+ re.IGNORECASE,
603
+ )
604
+ _FAMILY_HIKE_DETAIL_EXACT_RE = re.compile(
605
+ r"\b(?:roast(?:ed|ing)?\s+marshmallows?|marshmallows?|"
606
+ r"tell(?:ing)?\s+stories|shared\s+stories)\b",
607
+ re.IGNORECASE,
608
+ )
609
+ _FAMILY_HIKE_DETAIL_TOPIC_RE = re.compile(
610
+ r"\b(?:family|kids?|children|hikes?|hiking|camp(?:ing|fire)?|nature|"
611
+ r"trail|waterfall|photos?|pictures?)\b",
612
+ re.IGNORECASE,
613
+ )
614
+ _FAMILY_HIKE_DETAIL_QUERY_RE = re.compile(
615
+ r"\bwhat\b(?=.{0,80}\b(?:family|kids?|children)\b)"
616
+ r"(?=.{0,80}\b(?:hikes?|hiking)\b)|"
617
+ r"\b(?:hikes?|hiking)\b(?=.{0,80}\b(?:family|kids?|children)\b)",
618
+ re.IGNORECASE | re.DOTALL,
619
+ )
620
+ _TEMPORAL_CAMPING_DETAIL_QUERY_RE = re.compile(
621
+ r"\bwhen\b(?=.{0,120}\bcamp(?:ing|ed)?\b)|"
622
+ r"\bcamp(?:ing|ed)?\b(?=.{0,120}\bwhen\b)",
623
+ re.IGNORECASE | re.DOTALL,
624
+ )
625
+ _TEMPORAL_CAMPING_CORE_DETAIL_RE = re.compile(
626
+ r"\b(?:roast(?:ed|ing)?\s+marshmallows?|marshmallows?|campfire)\b",
627
+ re.IGNORECASE,
628
+ )
629
+ _TEMPORAL_CAMPING_DETAIL_TERM_RE = re.compile(
630
+ r"\b(?:campfire|marshmallows?|roast(?:ed|ing)?|hikes?|hiking|trail|"
631
+ r"mountains?|nature|view|family|kids?|children|moments?)\b",
632
+ re.IGNORECASE,
633
+ )
634
+ _COMMONALITY_NAMED_ANCHOR_RE = re.compile(r"\b[A-Z][A-Za-z0-9._-]{1,}\b")
635
+ _COMMONALITY_IGNORED_ANCHORS = frozenset(
636
+ {
637
+ "How",
638
+ "What",
639
+ "When",
640
+ "Where",
641
+ "Which",
642
+ "Who",
643
+ "Why",
644
+ }
645
+ )
646
+ _AGGREGATION_RETRIEVAL_SOURCE = "keyword_aggregation_chunks"
647
+ _AGGREGATION_COUNT_QUERY_RE = re.compile(
648
+ r"\b(?:how\s+many|number\s+of|count|total|times?)\b|"
649
+ r"\b(?:сколько|количество|число|раз)\b",
650
+ re.IGNORECASE,
651
+ )
652
+ _AGGREGATION_LIST_QUERY_RE = re.compile(
653
+ r"\b(?:what|which|where)\b(?=.{0,80}\b(?:items?|things?|countries|places|"
654
+ r"types?|kinds?|events?|activities|bands?|artists?|shelters?|causes?|people|"
655
+ r"foods?|recipes?|meals?|dishes?|desserts?|baked\s+goods?)\b)|"
656
+ r"\b(?:list|name|show)\b(?=.{0,100}\b(?:all|both|items?|things?|countries|places|"
657
+ r"types?|kinds?|events?|activities|bands?|artists?|shelters?|causes?|people|"
658
+ r"foods?|recipes?|meals?|dishes?|desserts?|baked\s+goods?)\b)|"
659
+ r"\b(?:all|both)\b(?=.{0,100}\b(?:items?|things?|countries|places|types?|"
660
+ r"kinds?|events?|activities|bands?|artists?|shelters?|causes?|people|"
661
+ r"foods?|recipes?|meals?|dishes?|desserts?|baked\s+goods?)\b)|"
662
+ r"\bwho\b(?=.{0,120}\b(?:friends?|people|person|volunteer(?:s|ed|ing)?|"
663
+ r"met|helped|worked\s+with|customers?|clients?|colleagues?|teammates?)\b)|"
664
+ r"\b(?:какие|какой|где|кого|кому)\b",
665
+ re.IGNORECASE | re.DOTALL,
666
+ )
667
+ _AGGREGATION_NUMERIC_ANSWER_RE = re.compile(
668
+ r"\b(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|once|twice|"
669
+ r"couple|several|multiple|another|again)\b|"
670
+ r"\b(?:один|одна|два|две|три|четыре|пять|шесть|семь|восемь|девять|"
671
+ r"десять|раз|дважды|несколько|много|ещ[её])\b",
672
+ re.IGNORECASE,
673
+ )
674
+ _AGGREGATION_MARKER_RE = re.compile(r"\bD\d+:\d+\b")
675
+ _RELATIONSHIP_STATUS_EXACT_RE = re.compile(
676
+ r"\b(?:relationship\s+status|single\s+parent|single\b|not\s+dating|"
677
+ r"dating|boyfriend|girlfriend|fianc[eé]e?|romantic\s+partner|"
678
+ r"life\s+partner|spouse|husband|wife|married|divorced|separated|"
679
+ r"widow(?:ed|er)?|breakup|broke\s+up|split\s+up|"
680
+ r"in\s+a\s+relationship)\b|"
681
+ r"\b(?:статус\s+отношений|одинок\w*|холост\w*|не\s+замужем|"
682
+ r"не\s+женат|в\s+отношениях|парень|девушка|партн[её]р|муж|жена|"
683
+ r"супруг|супруга|развод\w*|расстал\w*)\b",
684
+ re.IGNORECASE,
685
+ )
686
+ _RELATIONSHIP_STATUS_WORK_PARTNER_RE = re.compile(
687
+ r"\b(?:accountability|business|class|cofounder|co-founder|conversation|"
688
+ r"dance|founder|gym|lab|project|research|running|school|sparring|startup|"
689
+ r"study|team|training|volunteer|work)\s+"
690
+ r"partners?\b|\bpartners?\s+(?:on|for|in)\s+"
691
+ r"(?:atlas|business|class|gym|lab|project|research|running|school|startup|"
692
+ r"study|team|training|volunteer|work)\b|"
693
+ r"\b(?:рабоч\w*|бизнес|проектн\w*|учебн\w*|тренировочн\w*)\s+"
694
+ r"партн[её]р\w*\b",
695
+ re.IGNORECASE,
696
+ )
697
+ _RELATIONSHIP_STATUS_SOCIAL_WEAK_RE = re.compile(
698
+ r"\b(?:friend|friends|old\s+friend|classmate|school|colleague|coworker|"
699
+ r"mentor|coach|teacher|family|support\s+system|met\s+at|went\s+to\s+"
700
+ r"school\s+with|knows?\s+from)\b|"
701
+ r"\b(?:друг|друзья|подруга|одноклассник|школ\w*|коллег\w*|"
702
+ r"наставник|учитель|семь[яи]|знаком\w*)\b",
703
+ re.IGNORECASE,
704
+ )
705
+ _RELATIONSHIP_DURATION_EXACT_RE = re.compile(
706
+ r"\b(?:for\s+(?:about\s+|roughly\s+|nearly\s+|almost\s+)?"
707
+ r"(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|"
708
+ r"eleven|twelve|several|many|a\s+couple\s+of)\s+"
709
+ r"(?:years?|months?|weeks?|days?)|since\s+(?:\d{4}|"
710
+ r"[A-Z][a-z]+\s+\d{4}|childhood|college|school)|anniversary|"
711
+ r"known\s+each\s+other\s+for|have\s+been\s+(?:married|together)|"
712
+ r"been\s+friends\s+for)\b|"
713
+ r"\b(?:уже\s+)?(?:\d+|один|одна|два|две|три|четыре|пять|шесть|"
714
+ r"семь|восемь|девять|десять|несколько)\s+"
715
+ r"(?:лет|года|год|месяц(?:ев|а)?|недель|недели|дней)|"
716
+ r"\bс\s+\d{4}\b|годовщин\w*|знаком\w+\s+.*\b(?:лет|года|год)\b",
717
+ re.IGNORECASE,
718
+ )
719
+ _RELATIONSHIP_DURATION_WEAK_RE = re.compile(
720
+ r"\b(?:married|husband|wife|spouse|partner|friend|friends|old\s+friend|"
721
+ r"relationship|wedding|met|known|school|college)\b|"
722
+ r"\b(?:женат|замужем|муж|жена|супруг|супруга|партн[её]р|друг|"
723
+ r"друзья|отношен\w*|свадьб\w*|знаком\w*)\b",
724
+ re.IGNORECASE,
725
+ )
726
+ _RELATIONSHIP_ORIGIN_EXACT_RE = re.compile(
727
+ r"\b(?:first\s+met|met\s+(?:at|in|on|during|through|via)|"
728
+ r"met\s+(?!(?:the\s+)?(?:deadline|deadlines|goal|goals|requirement|"
729
+ r"requirements|target|targets)\b).{1,80}\s+"
730
+ r"(?:at|in|on|during|through|via|while|when|after|before)\b|"
731
+ r"met\s+(?:while|when|after|before)\b|"
732
+ r"introduced\s+(?:at|in|during|through|via|by)|"
733
+ r"introduced\s+.{1,80}\s+(?:at|in|during|through|via|by)\b|"
734
+ r"became\s+friends\s+(?:at|in|during|through|via|while|when|after)|"
735
+ r"got\s+to\s+know\s+.{1,80}\s+"
736
+ r"(?:at|in|on|during|through|via|while|when|after|before)|"
737
+ r"got\s+to\s+know\s+(?:each\s+other\s+)?(?:at|in|on|during|through|via|while|when)|"
738
+ r"know(?:n)?\s+each\s+other\s+(?:from|through|via|since)|"
739
+ r"first\s+encounter\s+(?:was\s+)?(?:at|in|on|during|through|via|while|when)|"
740
+ r"known\s+(?:each\s+other\s+)?since|go\s+back\s+to|"
741
+ r"have\s+known\s+each\s+other\s+since)\b|"
742
+ r"\b(?:впервые\s+)?(?:познакомил(?:ись|ся|ась)|встретил(?:ись|ся|ась))\s+"
743
+ r"(?:в|на|через|во\s+время|благодаря)\b|"
744
+ r"\bзнаком\w+\s+с\s+(?:\d{4}|детства|школ\w*|университет\w*|колледж\w*)\b",
745
+ re.IGNORECASE,
746
+ )
747
+ _RELATIONSHIP_ORIGIN_WEAK_RE = re.compile(
748
+ r"\b(?:friend|friends|old\s+friend|classmate|colleague|coworker|school|"
749
+ r"college|university|work|event|party|conference|knows?|met)\b|"
750
+ r"\b(?:друг|друзья|подруга|одноклассник|коллег\w*|школ\w*|"
751
+ r"университет\w*|колледж\w*|работ\w*|событи\w*|знаком\w*)\b",
752
+ re.IGNORECASE,
753
+ )
754
+ _STATE_TRANSITION_PAIR_RE = re.compile(
755
+ r"\b(?:changed|updated|switched|migrated|transitioned|replaced)\b"
756
+ r"(?=.{0,120}\bfrom\b)(?=.{0,160}\bto\b)|"
757
+ r"\b(?:current|active|latest|selected|chosen|provider|tool|model|plan|"
758
+ r"policy|source|decision)\b(?=.{0,160}\bnot\b.{0,80}\bbut\b)|"
759
+ r"\bnot\b(?=.{0,80}\bbut\b)(?=.{0,160}\b(?:current|active|latest|"
760
+ r"selected|chosen|provider|tool|model|plan|policy|source|decision)\b)|"
761
+ r"\b(?:cancell?ed|rescheduled|postponed|moved|delayed)\b"
762
+ r"(?=.{0,140}\b(?:to|for|until|from|after|instead|new|now|current|"
763
+ r"latest|date|time|day|week|month|meeting|call|demo|event|plan)\b)|"
764
+ r"\bfrom\b(?=.{0,120}\bto\b)(?=.{0,180}\b(?:current|new|active|final|"
765
+ r"replacement|provider|tool|model|plan|policy|source)\b)|"
766
+ r"\b(?:replaced|superseded|took\s+over)\b(?=.{0,120}\b(?:by|with|current|"
767
+ r"new|active|final)\b)|"
768
+ r"\b(?:old|previous|stale|superseded|deprecated|no\s+longer\s+valid|"
769
+ r"no\s+longer\s+current)\b"
770
+ r"(?=.{0,180}\b(?:current|new|active|final|replacement|replaced\s+by|"
771
+ r"switched\s+to|migrated\s+to|now)\b)|"
772
+ r"\b(?:изменил\w*|обновил\w*|смени\w*|переш[её]л\w*|мигрировал\w*)\b"
773
+ r"(?=.{0,120}\b(?:с|со)\b)(?=.{0,160}\b(?:на|в)\b)|"
774
+ r"\b(?:заменил\w*|заменен\w*|заменён\w*)\b(?=.{0,120}\b(?:на|нов\w*|"
775
+ r"текущ\w*|актуальн\w*)\b)|"
776
+ r"\b(?:стар\w*|предыдущ\w*|устаревш\w*|больше\s+не\s+актуальн\w*)\b"
777
+ r"(?=.{0,180}\b(?:нов\w*|текущ\w*|актуальн\w*|сейчас|теперь|замен\w*)\b)",
778
+ re.IGNORECASE | re.DOTALL,
779
+ )
780
+ _STATE_TRANSITION_MARKER_RE = re.compile(
781
+ r"\b(?:changed|updated|switched|migrated|transitioned|replaced|superseded|"
782
+ r"current|active|new|old|previous|stale|deprecated|no\s+longer|now|"
783
+ r"cancell?ed|rescheduled|postponed|moved|delayed)\b|"
784
+ r"\b(?:изменил\w*|изменилось|обновил\w*|смени\w*|переш[её]л\w*|"
785
+ r"мигрировал\w*|заменил\w*|заменен\w*|заменён\w*|текущ\w*|"
786
+ r"актуальн\w*|нов\w*|стар\w*|предыдущ\w*|устаревш\w*|теперь|сейчас)\b",
787
+ re.IGNORECASE,
788
+ )
789
+ _CURRENT_STATE_EXACT_RE = re.compile(
790
+ r"\b(?:current|active|latest|final|selected|chosen|recommended|"
791
+ r"canonical|source\s+of\s+truth|decided\s+to\s+use|should\s+use|"
792
+ r"using\s+now|right\s+now|remains?\s+valid|still\s+valid|"
793
+ r"valid\s+and\s+active)\b|"
794
+ r"\b(?:актуальн\w*|текущ\w*|финальн\w*|окончательн\w*|"
795
+ r"выбранн\w*|рекомендованн\w*|сейчас|действу\w*)\b",
796
+ re.IGNORECASE,
797
+ )
798
+ _STALE_STATE_EXACT_RE = re.compile(
799
+ r"\b(?:no\s+longer\s+(?:valid|current|active|used?|using)|"
800
+ r"not\s+current|not\s+valid|stale|outdated|deprecated|superseded|"
801
+ r"replaced\s+by|switched\s+away|previous(?:ly)?\s+valid|former|"
802
+ r"old\s+(?:provider|tool|model|plan|policy|decision|source))\b|"
803
+ r"\b(?:устаревш\w*|больше\s+не\s+(?:актуальн\w*|использ\w*)|"
804
+ r"не\s+актуальн\w*|предыдущ\w*|замен[её]н\w*)\b",
805
+ re.IGNORECASE,
806
+ )
807
+ _CURRENT_STATE_QUERY_RE = re.compile(
808
+ r"\b(?:current|currently|latest|active|final|selected|chosen|recommended|"
809
+ r"canonical|source\s+of\s+truth|still\s+valid|should\s+(?:i\s+)?use|"
810
+ r"what\s+did\s+i\s+decide\s+to\s+use)\b|"
811
+ r"\b(?:актуальн\w*|текущ\w*|финальн\w*|окончательн\w*|"
812
+ r"выбранн\w*|рекомендованн\w*)\b",
813
+ re.IGNORECASE,
814
+ )
815
+ _CONTRASTIVE_CORRECTION_RE = re.compile(
816
+ r"\b(?:provider|tool|model|plan|policy|decision|source|option|choice|"
817
+ r"date|time|meeting|call|demo|event)\b(?=.{0,160}\bnot\b.{0,80}\bbut\b)|"
818
+ r"\bnot\b(?=.{0,80}\bbut\b)(?=.{0,160}\b(?:provider|tool|model|plan|"
819
+ r"policy|decision|source|option|choice|date|time|meeting|call|demo|event)\b)|"
820
+ r"\b(?:provider|tool|model|plan|policy|decision|source|option|choice|"
821
+ r"date|time|meeting|call|demo|event)\b(?=.{0,160}\b(?:instead\s+of|"
822
+ r"rather\s+than)\b)|"
823
+ r"\b(?:instead\s+of|rather\s+than)\b(?=.{0,160}\b(?:provider|tool|model|"
824
+ r"plan|policy|decision|source|option|choice|date|time|meeting|call|demo|"
825
+ r"event)\b)",
826
+ re.IGNORECASE | re.DOTALL,
827
+ )
828
+ _STALE_STATE_QUERY_RE = re.compile(
829
+ r"\b(?:no\s+longer\s+(?:valid|current|active|used?|using)|not\s+current|"
830
+ r"not\s+valid|stale|outdated|deprecated|"
831
+ r"(?:previous|former|old)\s+"
832
+ r"(?:provider|tool|model|plan|policy|decision|source|state|option)|"
833
+ r"should\s+(?:i\s+)?no\s+longer\s+use)\b|"
834
+ r"\b(?:устаревш\w*|больше\s+не\s+(?:актуальн\w*|использ\w*)|"
835
+ r"не\s+актуальн\w*|предыдущ\w*)\b",
836
+ re.IGNORECASE,
837
+ )
838
+ _AGE_BIRTHDAY_EXACT_RE = re.compile(
839
+ r"\b(?:born\s+in\s+\d{4}|born\s+on\b|date\s+of\s+birth|birthdate|"
840
+ r"birthday|age\s+(?:is\s+)?\d{1,3}|\d{1,3}\s+years?\s+old)\b|"
841
+ r"\b(?:родил(?:ся|ась|ись)\s+в\s+\d{4}|дата\s+рождения|"
842
+ r"день\s+рождения|возраст\s+\d{1,3}|\d{1,3}\s+лет)\b",
843
+ re.IGNORECASE,
844
+ )
845
+ _AGE_BIRTHDAY_WEAK_OLD_RE = re.compile(
846
+ r"\bold\s+(?:friend|plan|state|policy|note|home|school|job)\b|"
847
+ r"\b(?:стар(?:ый|ая|ое|ые)\s+(?:друг|план|политик\w*|заметк\w*))\b",
848
+ re.IGNORECASE,
849
+ )
850
+ _BIRTHPLACE_QUERY_RE = re.compile(
851
+ r"\bwhere\b(?=.{0,80}\bborn\b)|\bborn\b(?=.{0,80}\bwhere\b)|"
852
+ r"\b(?:где|откуда)\b(?=.{0,80}\bродил)",
853
+ re.IGNORECASE | re.DOTALL,
854
+ )
855
+ _BIRTHPLACE_EXACT_RE = re.compile(
856
+ r"\b(?:birthplace|born\s+in\s+(?!\d{4}\b)[A-Z][A-Za-z]+(?:\s+[A-Z][A-Za-z]+)?|"
857
+ r"born\s+near\s+[A-Z][A-Za-z]+|home\s+country\s+is\s+[A-Z][A-Za-z]+)\b|"
858
+ r"\b(?:место\s+рождения|родил(?:ся|ась|ись)\s+в\s+(?!\d{4}\b)[А-ЯЁA-Z]"
859
+ r"[\wА-Яа-яЁё-]+)\b",
860
+ re.IGNORECASE,
861
+ )
862
+ _BIRTHPLACE_BIRTHDATE_NOISE_RE = re.compile(
863
+ r"\bborn\s+in\s+\d{4}\b|\b(?:birthday|date\s+of\s+birth|birthdate)\b|"
864
+ r"\bродил(?:ся|ась|ись)\s+в\s+\d{4}\b|\b(?:дата\s+рождения|день\s+рождения)\b",
865
+ re.IGNORECASE,
866
+ )
867
+ _BEACH_OR_MOUNTAINS_QUERY_RE = re.compile(
868
+ r"\b(?:beach|beaches|ocean|shore|coast|mountain|mountains)\b"
869
+ r"(?=.{0,120}\b(?:close|near|nearby|live|lives|living|by|next\s+to)\b)|"
870
+ r"\b(?:close|near|nearby|live|lives|living|by|next\s+to)\b"
871
+ r"(?=.{0,120}\b(?:beach|beaches|ocean|shore|coast|mountain|mountains)\b)",
872
+ re.IGNORECASE | re.DOTALL,
873
+ )
874
+ _BEACH_OR_MOUNTAINS_DOMAIN_RE = re.compile(
875
+ r"\b(?:beach|beaches|ocean|shore|coast|coastal|sailboat|sand|sunset|"
876
+ r"mountain|mountains|trail|hiking|hike)\b",
877
+ re.IGNORECASE,
878
+ )
879
+ _BEACH_OR_MOUNTAINS_PROXIMITY_RE = re.compile(
880
+ r"\b(?:close|near|nearby|by|next\s+to|weekly\s+walks?|walks?|goes?\s+on\s+"
881
+ r"walks?|lives?\s+close|lives?\s+near|from\s+home|local)\b",
882
+ re.IGNORECASE,
883
+ )
884
+ _BEACH_OR_MOUNTAINS_TOPIC_ONLY_RE = re.compile(
885
+ r"\b(?:whether|sounded\s+nice|someday|maybe|vacation|wallpaper|poster|"
886
+ r"preference|would\s+like|dream(?:ed)?\s+of)\b"
887
+ r"(?=.{0,120}\b(?:beach|beaches|ocean|mountains?)\b)|"
888
+ r"\b(?:beach|beaches|ocean|mountains?)\b"
889
+ r"(?=.{0,120}\b(?:whether|sounded\s+nice|someday|maybe|vacation|"
890
+ r"wallpaper|poster|preference|would\s+like|dream(?:ed)?\s+of)\b)",
891
+ re.IGNORECASE | re.DOTALL,
892
+ )
893
+ _SYMBOL_IMPORTANCE_EXACT_RE = re.compile(
894
+ r"\b(?:symboli[sz](?:e|es|ed|ing)|represents?|meaning|means|stands?\s+for|"
895
+ r"important|reminds?\s+(?:me|her|him|them)\s+of|pride|freedom|courage|"
896
+ r"resilience|identity|acceptance)\b|"
897
+ r"\b(?:символизир\w*|значит|значение|важн\w*|напомина\w*|гордост\w*|"
898
+ r"свобод\w*|смелост\w*|идентичност\w*|приняти\w*)\b",
899
+ re.IGNORECASE,
900
+ )
901
+ _SYMBOL_IMPORTANCE_MEANING_RE = re.compile(
902
+ r"\b(?:symboli[sz](?:e|es|ed|ing)|represents?|meaning|means|stands?\s+for|"
903
+ r"reminds?\s+(?:me|her|him|them)\s+of|pride|freedom|courage|resilience|"
904
+ r"identity|acceptance)\b|"
905
+ r"\b(?:символизир\w*|значит|значение|напомина\w*|гордост\w*|свобод\w*|"
906
+ r"смелост\w*|идентичност\w*|приняти\w*)\b",
907
+ re.IGNORECASE,
908
+ )
909
+ _SYMBOL_IMPORTANCE_OBJECT_RE = re.compile(
910
+ r"\b(?:rainbow\s+flag|flag|mural|eagle|pendant|necklace|"
911
+ r"transgender\s+symbol|cross|heart|symbol|symbols)\b|"
912
+ r"\b(?:радужн\w+\s+флаг|флаг|орел|орёл|кулон|ожерелье|крест|"
913
+ r"сердце|символ\w*)\b",
914
+ re.IGNORECASE,
915
+ )
916
+ _SYMBOL_IMPORTANCE_PERSONAL_OBJECT_RE = re.compile(
917
+ r"\b(?:pendant|necklace)\b(?=.{0,100}\b(?:symbol|cross|heart|transgender)\b)|"
918
+ r"\b(?:symbol|cross|heart|transgender)\b(?=.{0,100}\b(?:pendant|necklace)\b)",
919
+ re.IGNORECASE | re.DOTALL,
920
+ )
921
+ _SYMBOL_IMPORTANCE_VISUAL_OBJECT_RE = re.compile(
922
+ r"\b(?:visual\s+query|image\s+caption|caption)\b"
923
+ r"(?=.{0,140}\b(?:pendant|necklace)\b)"
924
+ r"(?=.{0,140}\b(?:transgender\s+symbol|cross|heart|symbol)\b)",
925
+ re.IGNORECASE | re.DOTALL,
926
+ )
927
+ _SYMBOL_IMPORTANCE_TECHNICAL_NOISE_RE = re.compile(
928
+ r"\b(?:unicode|currency|math(?:ematical)?|keyboard|font|icon|icons|"
929
+ r"svg|css|ui|interface|variable|operator|code|programming)\b",
930
+ re.IGNORECASE,
931
+ )
932
+ _POST_EVENT_EMOTION_EXACT_RE = re.compile(
933
+ r"\b(?:felt|feel|feeling|realiz(?:e|ed)|learned|grateful|thankful|relieved|lucky|scared|"
934
+ r"freaked|inspired|proud|happy|sad|upset|awe|means?\s+the\s+world|"
935
+ r"meaningful)\b",
936
+ re.IGNORECASE,
937
+ )
938
+ _POST_EVENT_FAMILY_APPRECIATION_RE = re.compile(
939
+ r"\b(?:i|i'm|i've|me|my|we|our)\b"
940
+ r"(?=.{0,220}\b(?:family|fam|loved\s+ones|them|they)\b)"
941
+ r"(?=.{0,180}\b(?:super\s+important|important\s+to\s+me|"
942
+ r"mean\s+the\s+world|means\s+the\s+world|need\s+them|"
943
+ r"thankful\s+to\s+have|grateful\s+to\s+have|cherish|"
944
+ r"biggest\s+motivation|support|rock)\b)|"
945
+ r"\b(?:super\s+important|important\s+to\s+me|mean\s+the\s+world|"
946
+ r"means\s+the\s+world|need\s+them|thankful\s+to\s+have|"
947
+ r"grateful\s+to\s+have|cherish|biggest\s+motivation|support|rock)\b"
948
+ r"(?=.{0,180}\b(?:family|fam|loved\s+ones|them|they)\b)"
949
+ r"(?=.{0,220}\b(?:i|i'm|i've|me|my|we|our)\b)",
950
+ re.IGNORECASE | re.DOTALL,
951
+ )
952
+ _POST_EVENT_EMOTION_EVENT_ONLY_RE = re.compile(
953
+ r"\b(?:accident|roadtrip|trip|event|happened|mentioned|talked|family)\b",
954
+ re.IGNORECASE,
955
+ )
956
+
957
+
958
+ @dataclass(frozen=True)
959
+ class DomainRerankSignal:
960
+ boost: float = 0.0
961
+ penalty: float = 0.0
962
+ reason: str = ""
963
+ rank_signal_key: str = ""
964
+ rank_signal: float = 0.0
965
+
966
+
967
+ def support_network_rerank_signal(
968
+ *,
969
+ query_reason: str,
970
+ item: ContextItem,
971
+ relevance: QueryRelevance,
972
+ ) -> DomainRerankSignal:
973
+ if _support_network_exact_evidence(query_reason=query_reason, item=item):
974
+ return DomainRerankSignal(boost=0.028, reason="support_network_exact_evidence")
975
+ if _support_network_weak_evidence(
976
+ query_reason=query_reason,
977
+ item=item,
978
+ relevance=relevance,
979
+ ):
980
+ return DomainRerankSignal(penalty=0.07, reason="support_network_weak_evidence")
981
+ return DomainRerankSignal()
982
+
983
+
984
+ def inventory_list_rerank_signal(
985
+ *,
986
+ query: str,
987
+ query_reason: str,
988
+ item: ContextItem,
989
+ relevance: QueryRelevance,
990
+ ) -> DomainRerankSignal:
991
+ if _inventory_friend_place_shelter_anchor_evidence(
992
+ query=query,
993
+ query_reason=query_reason,
994
+ item=item,
995
+ ):
996
+ return DomainRerankSignal(
997
+ boost=0.09,
998
+ reason="friend_place_shelter_anchor_evidence",
999
+ rank_signal_key="friend_place_shelter_anchor_evidence",
1000
+ rank_signal=3.0,
1001
+ )
1002
+ if _inventory_list_exact_evidence(query=query, query_reason=query_reason, item=item):
1003
+ if _inventory_book_reading_exact_match(query=query, item=item):
1004
+ return DomainRerankSignal(
1005
+ boost=0.09,
1006
+ reason="book_reading_inventory_evidence",
1007
+ rank_signal_key="book_reading_inventory_evidence",
1008
+ rank_signal=3.0,
1009
+ )
1010
+ if _inventory_church_friend_activity_exact_match(query=query, item=item):
1011
+ return DomainRerankSignal(
1012
+ boost=0.09,
1013
+ reason="church_friend_activity_inventory_evidence",
1014
+ rank_signal_key="church_friend_activity_inventory_evidence",
1015
+ rank_signal=3.0,
1016
+ )
1017
+ return DomainRerankSignal(boost=0.058, reason="inventory_list_exact_evidence")
1018
+ if _inventory_list_wrong_owner_evidence(query=query, query_reason=query_reason, item=item):
1019
+ return DomainRerankSignal(penalty=0.16, reason="inventory_list_wrong_owner_evidence")
1020
+ if _inventory_list_weak_evidence(
1021
+ query=query,
1022
+ query_reason=query_reason,
1023
+ item=item,
1024
+ relevance=relevance,
1025
+ ):
1026
+ return DomainRerankSignal(penalty=0.055, reason="inventory_list_weak_evidence")
1027
+ return DomainRerankSignal()
1028
+
1029
+
1030
+ def aggregation_evidence_rerank_signal(
1031
+ *,
1032
+ query: str,
1033
+ item: ContextItem,
1034
+ has_multi_evidence_competitor: bool = False,
1035
+ ) -> DomainRerankSignal:
1036
+ if not _is_aggregation_query(query):
1037
+ return DomainRerankSignal()
1038
+ is_list_query = _is_aggregation_list_query(query)
1039
+ answer_slot_count = len(aggregation_answer_slots(query=query, text=item.text))
1040
+ if _has_aggregation_subject_mismatch(
1041
+ query=query,
1042
+ item=item,
1043
+ answer_slot_count=answer_slot_count,
1044
+ ):
1045
+ return DomainRerankSignal(penalty=0.072, reason="aggregation_subject_mismatch")
1046
+ if answer_slot_count >= 2:
1047
+ if is_list_query:
1048
+ return DomainRerankSignal(
1049
+ boost=0.058,
1050
+ reason="aggregation_list_slot_diverse_evidence",
1051
+ rank_signal_key="aggregation_list_distinct_answer_slot_count",
1052
+ rank_signal=float(answer_slot_count),
1053
+ )
1054
+ return DomainRerankSignal(
1055
+ boost=0.044,
1056
+ reason="aggregation_slot_diverse_evidence",
1057
+ )
1058
+ if _is_aggregation_context_item(item):
1059
+ if _aggregation_evidence_count(item) >= 2:
1060
+ if is_list_query and answer_slot_count == 1:
1061
+ return DomainRerankSignal(
1062
+ penalty=0.024,
1063
+ reason="aggregation_list_duplicate_answer_slot_evidence",
1064
+ rank_signal_key="aggregation_list_distinct_answer_slot_count",
1065
+ rank_signal=1.0,
1066
+ )
1067
+ if is_list_query:
1068
+ return DomainRerankSignal(
1069
+ boost=0.046,
1070
+ reason="aggregation_list_multi_evidence",
1071
+ )
1072
+ return DomainRerankSignal(boost=0.034, reason="aggregation_multi_evidence")
1073
+ if is_list_query:
1074
+ return DomainRerankSignal(boost=0.018, reason="aggregation_list_evidence")
1075
+ return DomainRerankSignal(boost=0.018, reason="aggregation_evidence")
1076
+ if _AGGREGATION_COUNT_QUERY_RE.search(query) and _is_single_weak_count_evidence(item):
1077
+ return DomainRerankSignal(penalty=0.055, reason="aggregation_single_evidence_noise")
1078
+ if (
1079
+ is_list_query
1080
+ and has_multi_evidence_competitor
1081
+ and _is_single_list_evidence(query=query, item=item)
1082
+ ):
1083
+ return DomainRerankSignal(
1084
+ penalty=0.052,
1085
+ reason="aggregation_list_single_evidence_incomplete",
1086
+ )
1087
+ return DomainRerankSignal()
1088
+
1089
+
1090
+ def has_multi_evidence_aggregation_candidate(
1091
+ *,
1092
+ query: str,
1093
+ items: tuple[ContextItem, ...],
1094
+ ) -> bool:
1095
+ if not _is_aggregation_query(query):
1096
+ return False
1097
+ return any(
1098
+ (
1099
+ _is_aggregation_context_item(item)
1100
+ and _aggregation_evidence_count(item) >= 2
1101
+ )
1102
+ or aggregation_answer_slot_count(query=query, text=item.text) >= 2
1103
+ for item in items
1104
+ )
1105
+
1106
+
1107
+ def event_sequence_rerank_signal(
1108
+ *,
1109
+ query: str,
1110
+ query_reason: str,
1111
+ item: ContextItem,
1112
+ relevance: QueryRelevance,
1113
+ ) -> DomainRerankSignal:
1114
+ if not _is_event_sequence_candidate(
1115
+ query=query,
1116
+ query_reason=query_reason,
1117
+ item=item,
1118
+ ):
1119
+ return DomainRerankSignal()
1120
+ if relevance.distinctive_term_count < _EVENT_SEQUENCE_MIN_QUERY_DISTINCTIVE_TERMS:
1121
+ return DomainRerankSignal()
1122
+ has_sequence_shape = (
1123
+ _EVENT_SEQUENCE_MARKER_RE.search(item.text) is not None
1124
+ and (
1125
+ _EVENT_SEQUENCE_OUTCOME_RE.search(item.text) is not None
1126
+ or _STATE_TRANSITION_PAIR_RE.search(item.text) is not None
1127
+ )
1128
+ )
1129
+ anchor_terms = _event_sequence_anchor_terms(query)
1130
+ anchor_hits = _event_sequence_anchor_hits(anchor_terms=anchor_terms, text=item.text)
1131
+ required_anchor_hits = min(3, len(anchor_terms))
1132
+ has_required_anchors = required_anchor_hits <= 0 or anchor_hits >= required_anchor_hits
1133
+ if (
1134
+ has_sequence_shape
1135
+ and relevance.distinctive_term_hits >= _EVENT_SEQUENCE_MIN_EXACT_DISTINCTIVE_HITS
1136
+ and has_required_anchors
1137
+ ):
1138
+ return DomainRerankSignal(boost=0.034, reason="event_sequence_exact_evidence")
1139
+ if required_anchor_hits > 0 and anchor_hits < required_anchor_hits:
1140
+ return DomainRerankSignal(penalty=0.06, reason="event_sequence_anchor_mismatch")
1141
+ if relevance.distinctive_term_hits < _EVENT_SEQUENCE_MIN_EXACT_DISTINCTIVE_HITS:
1142
+ return DomainRerankSignal(penalty=0.06, reason="event_sequence_weak_evidence")
1143
+ if not has_sequence_shape:
1144
+ return DomainRerankSignal(penalty=0.075, reason="event_sequence_shape_missing")
1145
+ return DomainRerankSignal()
1146
+
1147
+
1148
+ def current_goal_rerank_signal(
1149
+ *,
1150
+ query: str = "",
1151
+ query_reason: str,
1152
+ item: ContextItem,
1153
+ relevance: QueryRelevance,
1154
+ ) -> DomainRerankSignal:
1155
+ if not _is_current_goal_candidate(query_reason=query_reason, item=item):
1156
+ return DomainRerankSignal()
1157
+ if (
1158
+ _ANIMAL_CAREER_QUERY_RE.search(query) is not None
1159
+ and _ANIMAL_CAREER_EVIDENCE_RE.search(item.text) is None
1160
+ and _ANIMAL_CAREER_GAMING_ONLY_RE.search(item.text) is not None
1161
+ ):
1162
+ return DomainRerankSignal(
1163
+ penalty=0.05,
1164
+ reason="current_goal_animal_career_mismatch",
1165
+ )
1166
+ if _CURRENT_GOAL_EVIDENCE_RE.search(item.text) is not None:
1167
+ return DomainRerankSignal(boost=0.03, reason="current_goal_exact_evidence")
1168
+ if (
1169
+ _CURRENT_GOAL_WEAK_RE.search(item.text) is not None
1170
+ or relevance.distinctive_term_hits < 4
1171
+ ):
1172
+ return DomainRerankSignal(penalty=0.046, reason="current_goal_weak_evidence")
1173
+ return DomainRerankSignal()
1174
+
1175
+
1176
+ def positive_preference_rerank_signal(
1177
+ *,
1178
+ query: str,
1179
+ query_reason: str,
1180
+ item: ContextItem,
1181
+ relevance: QueryRelevance,
1182
+ ) -> DomainRerankSignal:
1183
+ if not _is_positive_preference_candidate(
1184
+ query=query,
1185
+ query_reason=query_reason,
1186
+ item=item,
1187
+ ):
1188
+ return DomainRerankSignal()
1189
+ if (
1190
+ _BOOK_AUTHOR_PREFERENCE_QUERY_RE.search(query) is not None
1191
+ and query_reason in {"book_suggestion_bridge", "book_reading_list_bridge"}
1192
+ and _BOOK_AUTHOR_WORLD_EXACT_RE.search(item.text) is not None
1193
+ and relevance.distinctive_term_hits >= 3
1194
+ ):
1195
+ rank_signal = 3.0 if _BOOK_AUTHOR_POTTER_WORLD_RE.search(item.text) else 2.0
1196
+ return DomainRerankSignal(
1197
+ boost=0.03,
1198
+ reason="book_author_preference_world_evidence",
1199
+ rank_signal_key="book_author_preference_world_evidence",
1200
+ rank_signal=rank_signal,
1201
+ )
1202
+ if (
1203
+ _BOOK_AUTHOR_PREFERENCE_QUERY_RE.search(query) is not None
1204
+ and query_reason in {"book_suggestion_bridge", "book_reading_list_bridge"}
1205
+ and _BOOK_AUTHOR_GENERIC_COLLECTION_RE.search(item.text) is not None
1206
+ and _BOOK_AUTHOR_WORLD_EXACT_RE.search(item.text) is None
1207
+ ):
1208
+ return DomainRerankSignal(
1209
+ penalty=0.04,
1210
+ reason="book_author_preference_generic_collection",
1211
+ )
1212
+ if (
1213
+ _is_recommendation_followup_candidate(query_reason=query_reason, item=item)
1214
+ and _RECOMMENDATION_FOLLOWUP_BOOK_RE.search(item.text) is not None
1215
+ and _RECOMMENDATION_FOLLOWUP_SIGNAL_RE.search(item.text) is not None
1216
+ ):
1217
+ return DomainRerankSignal()
1218
+ if (
1219
+ _is_outdoor_preference_candidate(query_reason=query_reason, item=item)
1220
+ and _OUTDOOR_NATURE_EVIDENCE_RE.search(item.text) is not None
1221
+ and (
1222
+ _OUTDOOR_STRONG_NATURE_EVIDENCE_RE.search(item.text) is not None
1223
+ or _POSITIVE_PREFERENCE_MARKER_RE.search(item.text) is not None
1224
+ )
1225
+ and relevance.distinctive_term_hits >= 3
1226
+ ):
1227
+ return DomainRerankSignal(boost=0.026, reason="outdoor_preference_exact_evidence")
1228
+ if (
1229
+ _POSITIVE_PREFERENCE_WEAK_TOPIC_RE.search(item.text) is not None
1230
+ and _POSITIVE_PREFERENCE_MARKER_RE.search(item.text) is None
1231
+ ):
1232
+ return DomainRerankSignal(penalty=0.046, reason="preference_weak_evidence")
1233
+ if (
1234
+ _POSITIVE_PREFERENCE_MARKER_RE.search(item.text) is not None
1235
+ and relevance.distinctive_term_hits >= 3
1236
+ ):
1237
+ return DomainRerankSignal(boost=0.024, reason="preference_exact_evidence")
1238
+ if (
1239
+ _POSITIVE_PREFERENCE_WEAK_TOPIC_RE.search(item.text) is not None
1240
+ or relevance.distinctive_term_hits >= 4
1241
+ ):
1242
+ return DomainRerankSignal(penalty=0.034, reason="preference_weak_evidence")
1243
+ return DomainRerankSignal()
1244
+
1245
+
1246
+ def commonality_rerank_signal(
1247
+ *,
1248
+ query: str,
1249
+ query_reason: str,
1250
+ item: ContextItem,
1251
+ relevance: QueryRelevance,
1252
+ ) -> DomainRerankSignal:
1253
+ if not _is_commonality_candidate(
1254
+ query=query,
1255
+ query_reason=query_reason,
1256
+ item=item,
1257
+ ):
1258
+ return DomainRerankSignal()
1259
+ business_signal = _business_commonality_signal(
1260
+ query_reason=query_reason,
1261
+ item=item,
1262
+ relevance=relevance,
1263
+ )
1264
+ if business_signal.reason:
1265
+ return business_signal
1266
+ who_else_signal = _commonality_who_else_signal(query=query, item=item)
1267
+ if who_else_signal.reason:
1268
+ return who_else_signal
1269
+ shared_painted_subject_signal = _shared_painted_subject_signal(
1270
+ query_reason=query_reason,
1271
+ item=item,
1272
+ relevance=relevance,
1273
+ )
1274
+ if shared_painted_subject_signal.reason:
1275
+ return shared_painted_subject_signal
1276
+ if (
1277
+ query_reason in _INVENTORY_LIST_RERANK_REASONS
1278
+ and _inventory_list_exact_evidence(
1279
+ query=query,
1280
+ query_reason=query_reason,
1281
+ item=item,
1282
+ )
1283
+ ):
1284
+ return DomainRerankSignal()
1285
+ anchor_terms = _commonality_anchor_terms(query)
1286
+ if len(anchor_terms) < 2:
1287
+ return DomainRerankSignal()
1288
+ anchor_hits = _commonality_anchor_hits(anchor_terms=anchor_terms, text=item.text)
1289
+ has_commonality_shape = _COMMONALITY_EVIDENCE_RE.search(item.text) is not None
1290
+ if anchor_hits >= 2 and _COMMONALITY_SHARED_ARTIFACT_RE.search(item.text):
1291
+ return DomainRerankSignal(penalty=0.032, reason="commonality_weak_evidence")
1292
+ if anchor_hits >= 2 and has_commonality_shape:
1293
+ return DomainRerankSignal(boost=0.028, reason="commonality_exact_evidence")
1294
+ if anchor_hits < 2:
1295
+ return DomainRerankSignal(penalty=0.048, reason="commonality_anchor_mismatch")
1296
+ if not has_commonality_shape or relevance.distinctive_term_hits < 5:
1297
+ return DomainRerankSignal(penalty=0.032, reason="commonality_weak_evidence")
1298
+ return DomainRerankSignal()
1299
+
1300
+
1301
+ def _business_commonality_signal(
1302
+ *,
1303
+ query_reason: str,
1304
+ item: ContextItem,
1305
+ relevance: QueryRelevance,
1306
+ ) -> DomainRerankSignal:
1307
+ if not _matches_query_or_score_signal_reason(
1308
+ query_reason=query_reason,
1309
+ item=item,
1310
+ target_reason="business_commonality_bridge",
1311
+ ):
1312
+ return DomainRerankSignal()
1313
+ if _BUSINESS_COMMONALITY_ORIGIN_RE.search(item.text) is not None:
1314
+ return DomainRerankSignal(
1315
+ boost=0.044,
1316
+ reason="business_commonality_origin_evidence",
1317
+ )
1318
+ if (
1319
+ _BUSINESS_COMMONALITY_LATE_UPDATE_RE.search(item.text) is not None
1320
+ or relevance.distinctive_term_hits < 7
1321
+ ):
1322
+ return DomainRerankSignal(
1323
+ penalty=0.052,
1324
+ reason="business_commonality_weak_update",
1325
+ )
1326
+ return DomainRerankSignal()
1327
+
1328
+
1329
+ def _shared_painted_subject_signal(
1330
+ *,
1331
+ query_reason: str,
1332
+ item: ContextItem,
1333
+ relevance: QueryRelevance,
1334
+ ) -> DomainRerankSignal:
1335
+ if not _matches_query_or_score_signal_reason(
1336
+ query_reason=query_reason,
1337
+ item=item,
1338
+ target_reason="shared_painted_subject_bridge",
1339
+ ):
1340
+ return DomainRerankSignal()
1341
+ if (
1342
+ _SHARED_PAINTED_SUBJECT_EXACT_RE.search(item.text) is not None
1343
+ and relevance.distinctive_term_hits >= 4
1344
+ ):
1345
+ return DomainRerankSignal(
1346
+ boost=0.034,
1347
+ reason="shared_painted_subject_exact_evidence",
1348
+ )
1349
+ if _SHARED_PAINTED_SUBJECT_TOPIC_RE.search(item.text) is not None:
1350
+ return DomainRerankSignal(
1351
+ penalty=0.052,
1352
+ reason="shared_painted_subject_topic_only_noise",
1353
+ )
1354
+ return DomainRerankSignal()
1355
+
1356
+
1357
+ def family_hike_detail_rerank_signal(
1358
+ *,
1359
+ query: str = "",
1360
+ query_reason: str,
1361
+ item: ContextItem,
1362
+ relevance: QueryRelevance,
1363
+ ) -> DomainRerankSignal:
1364
+ if not _is_family_hike_detail_candidate(
1365
+ query=query,
1366
+ query_reason=query_reason,
1367
+ item=item,
1368
+ ):
1369
+ return DomainRerankSignal()
1370
+ if (
1371
+ _FAMILY_HIKE_DETAIL_EXACT_RE.search(item.text) is not None
1372
+ and relevance.distinctive_term_hits >= 4
1373
+ ):
1374
+ return DomainRerankSignal(
1375
+ boost=0.034,
1376
+ reason="family_hike_detail_exact_evidence",
1377
+ )
1378
+ if _FAMILY_HIKE_DETAIL_TOPIC_RE.search(item.text) is not None:
1379
+ return DomainRerankSignal(
1380
+ penalty=0.062,
1381
+ reason="family_hike_detail_topic_only_noise",
1382
+ )
1383
+ return DomainRerankSignal()
1384
+
1385
+
1386
+ def temporal_camping_detail_rerank_signal(
1387
+ *,
1388
+ query: str,
1389
+ query_reason: str,
1390
+ item: ContextItem,
1391
+ relevance: QueryRelevance,
1392
+ ) -> DomainRerankSignal:
1393
+ if not _is_temporal_camping_detail_candidate(
1394
+ query=query,
1395
+ query_reason=query_reason,
1396
+ item=item,
1397
+ ):
1398
+ return DomainRerankSignal()
1399
+ if relevance.distinctive_term_hits < 6:
1400
+ return DomainRerankSignal()
1401
+ if _TEMPORAL_CAMPING_CORE_DETAIL_RE.search(item.text) is None:
1402
+ return DomainRerankSignal()
1403
+ detail_terms = {
1404
+ match.group(0).casefold()
1405
+ for match in _TEMPORAL_CAMPING_DETAIL_TERM_RE.finditer(item.text)
1406
+ }
1407
+ if len(detail_terms) < 4:
1408
+ return DomainRerankSignal()
1409
+ return DomainRerankSignal(
1410
+ boost=0.058,
1411
+ reason="temporal_camping_detail_evidence",
1412
+ )
1413
+
1414
+
1415
+ def commonality_who_else_anchor_override(
1416
+ *,
1417
+ query: str,
1418
+ query_reason: str,
1419
+ item: ContextItem,
1420
+ ) -> bool:
1421
+ if not _is_commonality_candidate(query=query, query_reason=query_reason, item=item):
1422
+ return False
1423
+ if _COMMONALITY_WHO_ELSE_QUERY_RE.search(query) is None:
1424
+ return False
1425
+ anchor_terms = _commonality_anchor_terms(query)
1426
+ if len(anchor_terms) != 1:
1427
+ return False
1428
+ return (
1429
+ not _text_has_any_anchor(anchor_terms=anchor_terms, text=item.text)
1430
+ and _COMMONALITY_WHO_ELSE_EVIDENCE_RE.search(item.text) is not None
1431
+ )
1432
+
1433
+
1434
+ def identity_rerank_signal(
1435
+ *,
1436
+ query: str = "",
1437
+ query_reason: str,
1438
+ item: ContextItem,
1439
+ relevance: QueryRelevance,
1440
+ ) -> DomainRerankSignal:
1441
+ if not _is_identity_candidate(query=query, query_reason=query_reason, item=item):
1442
+ return DomainRerankSignal()
1443
+ if _IDENTITY_EXACT_RE.search(item.text) is not None:
1444
+ return DomainRerankSignal(
1445
+ boost=0.042,
1446
+ reason="identity_exact_evidence",
1447
+ )
1448
+ if _IDENTITY_TOPIC_WEAK_RE.search(item.text) is not None or (
1449
+ relevance.distinctive_term_hits < 4
1450
+ ):
1451
+ return DomainRerankSignal(
1452
+ penalty=0.04,
1453
+ reason="identity_topic_only_evidence",
1454
+ )
1455
+ return DomainRerankSignal()
1456
+
1457
+
1458
+ def relationship_status_rerank_signal(
1459
+ *,
1460
+ query: str = "",
1461
+ query_reason: str,
1462
+ item: ContextItem,
1463
+ relevance: QueryRelevance,
1464
+ ) -> DomainRerankSignal:
1465
+ if not _is_relationship_status_candidate(
1466
+ query=query,
1467
+ query_reason=query_reason,
1468
+ item=item,
1469
+ ):
1470
+ return DomainRerankSignal()
1471
+ if _RELATIONSHIP_STATUS_WORK_PARTNER_RE.search(item.text) is not None:
1472
+ return DomainRerankSignal(
1473
+ penalty=0.055,
1474
+ reason="relationship_status_weak_evidence",
1475
+ )
1476
+ if _RELATIONSHIP_STATUS_EXACT_RE.search(item.text) is not None:
1477
+ return DomainRerankSignal(
1478
+ boost=0.028,
1479
+ reason="relationship_status_exact_evidence",
1480
+ )
1481
+ if (
1482
+ _RELATIONSHIP_STATUS_SOCIAL_WEAK_RE.search(item.text) is not None
1483
+ or relevance.distinctive_term_hits < 4
1484
+ ):
1485
+ return DomainRerankSignal(
1486
+ penalty=0.052,
1487
+ reason="relationship_status_weak_evidence",
1488
+ )
1489
+ return DomainRerankSignal()
1490
+
1491
+
1492
+ def relationship_duration_rerank_signal(
1493
+ *,
1494
+ query_reason: str,
1495
+ item: ContextItem,
1496
+ relevance: QueryRelevance,
1497
+ ) -> DomainRerankSignal:
1498
+ if not _is_relationship_duration_candidate(query_reason=query_reason, item=item):
1499
+ return DomainRerankSignal()
1500
+ if _RELATIONSHIP_DURATION_EXACT_RE.search(item.text) is not None:
1501
+ return DomainRerankSignal(
1502
+ boost=0.028,
1503
+ reason="relationship_duration_exact_evidence",
1504
+ )
1505
+ if (
1506
+ _RELATIONSHIP_DURATION_WEAK_RE.search(item.text) is not None
1507
+ or relevance.distinctive_term_hits < 4
1508
+ ):
1509
+ return DomainRerankSignal(
1510
+ penalty=0.05,
1511
+ reason="relationship_duration_weak_evidence",
1512
+ )
1513
+ return DomainRerankSignal()
1514
+
1515
+
1516
+ def relationship_origin_rerank_signal(
1517
+ *,
1518
+ query_reason: str,
1519
+ item: ContextItem,
1520
+ relevance: QueryRelevance,
1521
+ ) -> DomainRerankSignal:
1522
+ if not _is_relationship_origin_candidate(query_reason=query_reason, item=item):
1523
+ return DomainRerankSignal()
1524
+ if _RELATIONSHIP_ORIGIN_EXACT_RE.search(item.text) is not None:
1525
+ return DomainRerankSignal(
1526
+ boost=0.028,
1527
+ reason="relationship_origin_exact_evidence",
1528
+ )
1529
+ if (
1530
+ _RELATIONSHIP_ORIGIN_WEAK_RE.search(item.text) is not None
1531
+ or relevance.distinctive_term_hits < 4
1532
+ ):
1533
+ return DomainRerankSignal(
1534
+ penalty=0.05,
1535
+ reason="relationship_origin_weak_evidence",
1536
+ )
1537
+ return DomainRerankSignal()
1538
+
1539
+
1540
+ def recommendation_followup_rerank_signal(
1541
+ *,
1542
+ query_reason: str,
1543
+ item: ContextItem,
1544
+ ) -> DomainRerankSignal:
1545
+ if not _is_recommendation_followup_candidate(query_reason=query_reason, item=item):
1546
+ return DomainRerankSignal()
1547
+ if (
1548
+ _RECOMMENDATION_FOLLOWUP_BOOK_RE.search(item.text) is None
1549
+ or _RECOMMENDATION_FOLLOWUP_SIGNAL_RE.search(item.text) is None
1550
+ ):
1551
+ return DomainRerankSignal()
1552
+ return DomainRerankSignal(
1553
+ boost=0.018,
1554
+ reason="recommendation_followup_evidence",
1555
+ )
1556
+
1557
+
1558
+ def lifestyle_recommendation_rerank_signal(
1559
+ *,
1560
+ query_reason: str,
1561
+ item: ContextItem,
1562
+ relevance: QueryRelevance,
1563
+ ) -> DomainRerankSignal:
1564
+ if not _is_lifestyle_recommendation_candidate(
1565
+ query_reason=query_reason,
1566
+ item=item,
1567
+ ):
1568
+ return DomainRerankSignal()
1569
+ if (
1570
+ query_reason == "food_recipe_recommendation_bridge"
1571
+ or _score_signal_reason(item) == "food_recipe_recommendation_bridge"
1572
+ ):
1573
+ if _FOOD_RECIPE_RECOMMENDATION_EVIDENCE_RE.search(item.text) is None:
1574
+ if (
1575
+ relevance.distinctive_term_hits < 3
1576
+ and _FOOD_RECIPE_RECOMMENDATION_WEAK_RE.search(item.text) is not None
1577
+ ):
1578
+ return DomainRerankSignal(
1579
+ penalty=0.036,
1580
+ reason="food_recipe_recommendation_weak_evidence",
1581
+ )
1582
+ return DomainRerankSignal()
1583
+ rank_signal = (
1584
+ 3.0
1585
+ if _FOOD_RECIPE_RECOMMENDATION_SIGNAL_RE.search(item.text) is not None
1586
+ else 2.0
1587
+ )
1588
+ return DomainRerankSignal(
1589
+ boost=0.046,
1590
+ reason="food_recipe_recommendation_evidence",
1591
+ rank_signal_key="food_recipe_recommendation_evidence",
1592
+ rank_signal=rank_signal,
1593
+ )
1594
+ if _WELLNESS_ACTIVITY_EFFECT_EVIDENCE_RE.search(item.text) is not None:
1595
+ return DomainRerankSignal(
1596
+ boost=0.052,
1597
+ reason="wellness_activity_effect_evidence",
1598
+ rank_signal_key="wellness_activity_effect_evidence",
1599
+ rank_signal=3.0,
1600
+ )
1601
+ if (
1602
+ relevance.distinctive_term_hits < 3
1603
+ and _WELLNESS_ACTIVITY_EFFECT_WEAK_RE.search(item.text) is not None
1604
+ ):
1605
+ return DomainRerankSignal(
1606
+ penalty=0.034,
1607
+ reason="wellness_activity_effect_weak_evidence",
1608
+ )
1609
+ return DomainRerankSignal()
1610
+
1611
+
1612
+ def state_transition_rerank_signal(
1613
+ *,
1614
+ query_reason: str,
1615
+ item: ContextItem,
1616
+ relevance: QueryRelevance,
1617
+ ) -> DomainRerankSignal:
1618
+ if not _is_state_transition_candidate(query_reason=query_reason, item=item):
1619
+ return DomainRerankSignal()
1620
+ if _STATE_TRANSITION_PAIR_RE.search(item.text) is not None:
1621
+ return DomainRerankSignal(
1622
+ boost=0.03,
1623
+ reason="state_transition_exact_evidence",
1624
+ )
1625
+ if _STATE_TRANSITION_MARKER_RE.search(item.text) is not None:
1626
+ return DomainRerankSignal()
1627
+ if relevance.distinctive_term_hits < 4:
1628
+ return DomainRerankSignal(
1629
+ penalty=0.055,
1630
+ reason="state_transition_weak_evidence",
1631
+ )
1632
+ return DomainRerankSignal(
1633
+ penalty=0.035,
1634
+ reason="state_transition_weak_evidence",
1635
+ )
1636
+
1637
+
1638
+ def current_state_rerank_signal(
1639
+ *,
1640
+ query: str,
1641
+ query_reason: str,
1642
+ item: ContextItem,
1643
+ relevance: QueryRelevance,
1644
+ ) -> DomainRerankSignal:
1645
+ if _is_stale_state_candidate(query=query, query_reason=query_reason, item=item):
1646
+ if _STALE_STATE_EXACT_RE.search(item.text) is not None:
1647
+ return DomainRerankSignal(boost=0.032, reason="stale_state_exact_evidence")
1648
+ if _CURRENT_STATE_EXACT_RE.search(item.text) is not None:
1649
+ return DomainRerankSignal(
1650
+ penalty=0.045,
1651
+ reason="stale_state_current_conflict",
1652
+ )
1653
+ if relevance.distinctive_term_hits < 4:
1654
+ return DomainRerankSignal(penalty=0.035, reason="stale_state_weak_evidence")
1655
+ return DomainRerankSignal()
1656
+ if not _is_current_state_candidate(query=query, query_reason=query_reason, item=item):
1657
+ return DomainRerankSignal()
1658
+ if has_current_state_correction_evidence(item.text):
1659
+ return DomainRerankSignal(
1660
+ boost=0.045,
1661
+ reason="current_state_correction_evidence",
1662
+ )
1663
+ if _STATE_TRANSITION_PAIR_RE.search(item.text) is not None:
1664
+ return DomainRerankSignal(
1665
+ boost=0.038,
1666
+ reason="current_state_transition_evidence",
1667
+ )
1668
+ if _STALE_STATE_EXACT_RE.search(item.text) is not None:
1669
+ return DomainRerankSignal(
1670
+ penalty=0.055,
1671
+ reason="current_state_stale_conflict",
1672
+ )
1673
+ if _CURRENT_STATE_EXACT_RE.search(item.text) is not None:
1674
+ return DomainRerankSignal(boost=0.028, reason="current_state_exact_evidence")
1675
+ if relevance.distinctive_term_hits < 3:
1676
+ return DomainRerankSignal(penalty=0.026, reason="current_state_weak_evidence")
1677
+ return DomainRerankSignal()
1678
+
1679
+
1680
+ def age_birthday_rerank_signal(
1681
+ *,
1682
+ query: str = "",
1683
+ query_reason: str,
1684
+ item: ContextItem,
1685
+ relevance: QueryRelevance,
1686
+ ) -> DomainRerankSignal:
1687
+ if not _is_age_birthday_candidate(query_reason=query_reason, item=item):
1688
+ return DomainRerankSignal()
1689
+ if (
1690
+ _BIRTHPLACE_QUERY_RE.search(query) is not None
1691
+ and _AGE_BIRTHDAY_EXACT_RE.search(item.text) is not None
1692
+ ):
1693
+ return DomainRerankSignal(
1694
+ penalty=0.052,
1695
+ reason="age_birthday_birthplace_query_noise",
1696
+ )
1697
+ if has_relative_duration_event_evidence(
1698
+ query=query,
1699
+ query_reason=query_reason,
1700
+ text=item.text,
1701
+ ):
1702
+ return DomainRerankSignal(
1703
+ boost=0.034,
1704
+ reason="age_birthday_relative_duration_evidence",
1705
+ )
1706
+ if _AGE_BIRTHDAY_EXACT_RE.search(item.text) is not None:
1707
+ return DomainRerankSignal(boost=0.026, reason="age_birthday_exact_evidence")
1708
+ if (
1709
+ _AGE_BIRTHDAY_WEAK_OLD_RE.search(item.text) is not None
1710
+ or relevance.distinctive_term_hits < 4
1711
+ ):
1712
+ return DomainRerankSignal(penalty=0.05, reason="age_birthday_weak_evidence")
1713
+ return DomainRerankSignal()
1714
+
1715
+
1716
+ def birthplace_rerank_signal(
1717
+ *,
1718
+ query_reason: str,
1719
+ item: ContextItem,
1720
+ relevance: QueryRelevance,
1721
+ ) -> DomainRerankSignal:
1722
+ if not _is_birthplace_candidate(query_reason=query_reason, item=item):
1723
+ return DomainRerankSignal()
1724
+ if _BIRTHPLACE_EXACT_RE.search(item.text) is not None:
1725
+ return DomainRerankSignal(boost=0.026, reason="birthplace_exact_evidence")
1726
+ if (
1727
+ _BIRTHPLACE_BIRTHDATE_NOISE_RE.search(item.text) is not None
1728
+ or relevance.distinctive_term_hits < 4
1729
+ ):
1730
+ return DomainRerankSignal(penalty=0.052, reason="birthplace_birthdate_noise")
1731
+ return DomainRerankSignal()
1732
+
1733
+
1734
+ def beach_or_mountains_rerank_signal(
1735
+ *,
1736
+ query: str,
1737
+ query_reason: str,
1738
+ item: ContextItem,
1739
+ relevance: QueryRelevance,
1740
+ ) -> DomainRerankSignal:
1741
+ if not _is_beach_or_mountains_candidate(
1742
+ query=query,
1743
+ query_reason=query_reason,
1744
+ item=item,
1745
+ ):
1746
+ return DomainRerankSignal()
1747
+ has_domain = _BEACH_OR_MOUNTAINS_DOMAIN_RE.search(item.text) is not None
1748
+ has_proximity = _BEACH_OR_MOUNTAINS_PROXIMITY_RE.search(item.text) is not None
1749
+ if has_domain and has_proximity:
1750
+ return DomainRerankSignal(
1751
+ boost=0.026,
1752
+ reason="beach_mountains_proximity_evidence",
1753
+ )
1754
+ if (
1755
+ _BEACH_OR_MOUNTAINS_TOPIC_ONLY_RE.search(item.text) is not None
1756
+ or not has_domain
1757
+ or relevance.distinctive_term_hits < 3
1758
+ ):
1759
+ return DomainRerankSignal(
1760
+ penalty=0.038,
1761
+ reason="beach_mountains_topic_only_noise",
1762
+ )
1763
+ return DomainRerankSignal()
1764
+
1765
+
1766
+ def item_purchase_rerank_signal(
1767
+ *,
1768
+ query_reason: str,
1769
+ item: ContextItem,
1770
+ relevance: QueryRelevance,
1771
+ ) -> DomainRerankSignal:
1772
+ if not _is_item_purchase_candidate(query_reason=query_reason, item=item):
1773
+ return DomainRerankSignal()
1774
+ if has_item_purchase_object_evidence(item.text):
1775
+ return DomainRerankSignal(
1776
+ boost=0.055,
1777
+ reason="item_purchase_object_evidence",
1778
+ rank_signal_key="item_purchase_object_evidence",
1779
+ rank_signal=3.0,
1780
+ )
1781
+ if (
1782
+ has_item_purchase_temporal_or_media_marker(item.text)
1783
+ or not has_item_purchase_object_marker(item.text)
1784
+ or not has_item_purchase_verb_marker(item.text)
1785
+ or relevance.distinctive_term_hits < 4
1786
+ ):
1787
+ return DomainRerankSignal(
1788
+ penalty=0.11,
1789
+ reason="item_purchase_temporal_weak_evidence",
1790
+ )
1791
+ return DomainRerankSignal()
1792
+
1793
+
1794
+ def symbol_importance_rerank_signal(
1795
+ *,
1796
+ query_reason: str,
1797
+ item: ContextItem,
1798
+ relevance: QueryRelevance,
1799
+ ) -> DomainRerankSignal:
1800
+ if not _is_symbol_importance_candidate(query_reason=query_reason, item=item):
1801
+ return DomainRerankSignal()
1802
+ has_symbol_object = _SYMBOL_IMPORTANCE_OBJECT_RE.search(item.text) is not None
1803
+ has_personal_object = _SYMBOL_IMPORTANCE_PERSONAL_OBJECT_RE.search(item.text) is not None
1804
+ if _SYMBOL_IMPORTANCE_TECHNICAL_NOISE_RE.search(item.text) is not None:
1805
+ return DomainRerankSignal(penalty=0.042, reason="symbol_importance_weak_evidence")
1806
+ if has_personal_object and _SYMBOL_IMPORTANCE_VISUAL_OBJECT_RE.search(item.text):
1807
+ return DomainRerankSignal(
1808
+ boost=0.036,
1809
+ reason="symbol_importance_visual_object",
1810
+ rank_signal_key="symbol_importance_visual_evidence",
1811
+ rank_signal=3.0,
1812
+ )
1813
+ if has_symbol_object and _SYMBOL_IMPORTANCE_EXACT_RE.search(item.text) is not None:
1814
+ return DomainRerankSignal(
1815
+ boost=0.028,
1816
+ reason="symbol_importance_exact_evidence",
1817
+ rank_signal_key="symbol_importance_visual_evidence",
1818
+ rank_signal=1.0 if has_personal_object else 0.0,
1819
+ )
1820
+ if has_personal_object:
1821
+ return DomainRerankSignal(boost=0.02, reason="symbol_importance_personal_object")
1822
+ if (
1823
+ _SYMBOL_IMPORTANCE_TECHNICAL_NOISE_RE.search(item.text) is not None
1824
+ or not has_symbol_object
1825
+ or relevance.distinctive_term_hits < 3
1826
+ ):
1827
+ return DomainRerankSignal(penalty=0.042, reason="symbol_importance_weak_evidence")
1828
+ return DomainRerankSignal()
1829
+
1830
+
1831
+ def post_event_emotion_rerank_signal(
1832
+ *,
1833
+ query_reason: str,
1834
+ item: ContextItem,
1835
+ relevance: QueryRelevance,
1836
+ ) -> DomainRerankSignal:
1837
+ if not _is_post_event_emotion_candidate(query_reason=query_reason, item=item):
1838
+ return DomainRerankSignal()
1839
+ if _POST_EVENT_FAMILY_APPRECIATION_RE.search(item.text) is not None:
1840
+ return DomainRerankSignal(
1841
+ boost=0.052,
1842
+ reason="post_event_family_appreciation_evidence",
1843
+ )
1844
+ if _POST_EVENT_EMOTION_EXACT_RE.search(item.text) is not None:
1845
+ return DomainRerankSignal(boost=0.026, reason="post_event_emotion_exact_evidence")
1846
+ if (
1847
+ _POST_EVENT_EMOTION_EVENT_ONLY_RE.search(item.text) is not None
1848
+ or relevance.distinctive_term_hits < 4
1849
+ ):
1850
+ return DomainRerankSignal(penalty=0.038, reason="post_event_emotion_weak_evidence")
1851
+ return DomainRerankSignal()
1852
+
1853
+
1854
+ def _support_network_exact_evidence(*, query_reason: str, item: ContextItem) -> bool:
1855
+ if not _is_support_network_candidate(query_reason=query_reason, item=item):
1856
+ return False
1857
+ return (
1858
+ _SUPPORT_NETWORK_PEOPLE_RE.search(item.text) is not None
1859
+ and _SUPPORT_NETWORK_SIGNAL_RE.search(item.text) is not None
1860
+ )
1861
+
1862
+
1863
+ def _support_network_weak_evidence(
1864
+ *,
1865
+ query_reason: str,
1866
+ item: ContextItem,
1867
+ relevance: QueryRelevance,
1868
+ ) -> bool:
1869
+ if not _is_support_network_candidate(query_reason=query_reason, item=item):
1870
+ return False
1871
+ if _SUPPORT_NETWORK_TECHNICAL_RE.search(item.text) is not None:
1872
+ return True
1873
+ if _support_network_exact_evidence(query_reason=query_reason, item=item):
1874
+ return False
1875
+ return relevance.distinctive_term_hits < 4
1876
+
1877
+
1878
+ def _inventory_list_exact_evidence(
1879
+ *,
1880
+ query: str,
1881
+ query_reason: str,
1882
+ item: ContextItem,
1883
+ ) -> bool:
1884
+ if not _is_inventory_list_candidate(query_reason=query_reason, item=item):
1885
+ return False
1886
+ text = item.text
1887
+ if _INVENTORY_POTTERY_QUERY_RE.search(query):
1888
+ return _pottery_inventory_owner_evidence_matches_query(query=query, text=text)
1889
+ if _INVENTORY_COUNTRY_QUERY_RE.search(query):
1890
+ return (
1891
+ _INVENTORY_COUNTRY_EVIDENCE_RE.search(text) is not None
1892
+ or has_travel_place_inventory_evidence(text)
1893
+ )
1894
+ if _INVENTORY_CAUSE_QUERY_RE.search(query):
1895
+ return _INVENTORY_CAUSE_EVIDENCE_RE.search(text) is not None
1896
+ if _INVENTORY_DESSERT_QUERY_RE.search(query):
1897
+ return _INVENTORY_DESSERT_EVIDENCE_RE.search(text) is not None
1898
+ if _INVENTORY_FRIEND_PLACE_QUERY_RE.search(query):
1899
+ return _INVENTORY_FRIEND_PLACE_EVIDENCE_RE.search(text) is not None
1900
+ if _INVENTORY_SHELTER_QUERY_RE.search(query):
1901
+ return _INVENTORY_SHELTER_EVIDENCE_RE.search(text) is not None
1902
+ if _INVENTORY_BOOK_READING_QUERY_RE.search(query):
1903
+ return _INVENTORY_BOOK_READING_EVIDENCE_RE.search(text) is not None
1904
+ if _INVENTORY_CHURCH_FRIEND_ACTIVITY_QUERY_RE.search(query):
1905
+ return _INVENTORY_CHURCH_FRIEND_ACTIVITY_EVIDENCE_RE.search(text) is not None
1906
+ return False
1907
+
1908
+
1909
+ def _pottery_inventory_owner_evidence_matches_query(*, query: str, text: str) -> bool:
1910
+ matches = tuple(_INVENTORY_POTTERY_OWNER_EVIDENCE_RE.finditer(text))
1911
+ if not matches:
1912
+ return False
1913
+ query_people = _query_person_terms(query)
1914
+ if not query_people:
1915
+ return True
1916
+ return any(
1917
+ match.group("speaker").casefold() in query_people
1918
+ for match in matches
1919
+ if match.group("speaker")
1920
+ )
1921
+
1922
+
1923
+ def _query_person_terms(query: str) -> frozenset[str]:
1924
+ return frozenset(
1925
+ match.group(0).casefold()
1926
+ for match in re.finditer(r"\b[A-Z][A-Za-z'_-]{1,40}\b", query)
1927
+ if match.group(0).casefold() not in _QUERY_PERSON_STOPWORDS
1928
+ )
1929
+
1930
+
1931
+ def _inventory_book_reading_exact_match(*, query: str, item: ContextItem) -> bool:
1932
+ return (
1933
+ _INVENTORY_BOOK_READING_QUERY_RE.search(query) is not None
1934
+ and _INVENTORY_BOOK_READING_EVIDENCE_RE.search(item.text) is not None
1935
+ )
1936
+
1937
+
1938
+ def _inventory_church_friend_activity_exact_match(*, query: str, item: ContextItem) -> bool:
1939
+ return (
1940
+ _INVENTORY_CHURCH_FRIEND_ACTIVITY_QUERY_RE.search(query) is not None
1941
+ and _INVENTORY_CHURCH_FRIEND_ACTIVITY_EVIDENCE_RE.search(item.text) is not None
1942
+ )
1943
+
1944
+
1945
+ def _inventory_friend_place_shelter_anchor_evidence(
1946
+ *,
1947
+ query: str,
1948
+ query_reason: str,
1949
+ item: ContextItem,
1950
+ ) -> bool:
1951
+ if not _is_inventory_list_candidate(query_reason=query_reason, item=item):
1952
+ return False
1953
+ if not _INVENTORY_FRIEND_PLACE_QUERY_RE.search(query):
1954
+ return False
1955
+ text = item.text
1956
+ if _INVENTORY_FRIEND_PLACE_SHELTER_ACTIVITY_REPEAT_RE.search(text):
1957
+ return False
1958
+ return _INVENTORY_FRIEND_PLACE_SHELTER_ANCHOR_RE.search(text) is not None
1959
+
1960
+
1961
+ def _inventory_list_weak_evidence(
1962
+ *,
1963
+ query: str,
1964
+ query_reason: str,
1965
+ item: ContextItem,
1966
+ relevance: QueryRelevance,
1967
+ ) -> bool:
1968
+ if not _is_inventory_list_candidate(query_reason=query_reason, item=item):
1969
+ return False
1970
+ if _inventory_list_exact_evidence(query=query, query_reason=query_reason, item=item):
1971
+ return False
1972
+ if _INVENTORY_POTTERY_QUERY_RE.search(query) and _INVENTORY_POTTERY_EVIDENCE_RE.search(
1973
+ item.text
1974
+ ):
1975
+ return True
1976
+ if _INVENTORY_GENERIC_WEAK_RE.search(item.text):
1977
+ return True
1978
+ if _inventory_query_has_specific_expected_slot(query):
1979
+ return relevance.distinctive_term_hits < 4 or relevance.unique_term_hits < 4
1980
+ return False
1981
+
1982
+
1983
+ def _inventory_list_wrong_owner_evidence(
1984
+ *,
1985
+ query: str,
1986
+ query_reason: str,
1987
+ item: ContextItem,
1988
+ ) -> bool:
1989
+ if not _is_inventory_list_candidate(query_reason=query_reason, item=item):
1990
+ return False
1991
+ if not _INVENTORY_POTTERY_QUERY_RE.search(query):
1992
+ return False
1993
+ return _INVENTORY_POTTERY_EVIDENCE_RE.search(item.text) is not None
1994
+
1995
+
1996
+ def _inventory_query_has_specific_expected_slot(query: str) -> bool:
1997
+ return any(
1998
+ pattern.search(query)
1999
+ for pattern in (
2000
+ _INVENTORY_POTTERY_QUERY_RE,
2001
+ _INVENTORY_COUNTRY_QUERY_RE,
2002
+ _INVENTORY_CAUSE_QUERY_RE,
2003
+ _INVENTORY_DESSERT_QUERY_RE,
2004
+ _INVENTORY_FRIEND_PLACE_QUERY_RE,
2005
+ _INVENTORY_SHELTER_QUERY_RE,
2006
+ _INVENTORY_BOOK_READING_QUERY_RE,
2007
+ _INVENTORY_CHURCH_FRIEND_ACTIVITY_QUERY_RE,
2008
+ )
2009
+ )
2010
+
2011
+
2012
+ def _is_inventory_list_candidate(*, query_reason: str, item: ContextItem) -> bool:
2013
+ if query_reason in _INVENTORY_LIST_RERANK_REASONS:
2014
+ return True
2015
+ reason = _score_signal_reason(item)
2016
+ return reason in _INVENTORY_LIST_RERANK_REASONS
2017
+
2018
+
2019
+ def _is_support_network_candidate(*, query_reason: str, item: ContextItem) -> bool:
2020
+ if query_reason in _SUPPORT_NETWORK_RERANK_REASONS:
2021
+ return True
2022
+ return _score_signal_reason(item) in _SUPPORT_NETWORK_RERANK_REASONS
2023
+
2024
+
2025
+ def _is_recommendation_followup_candidate(*, query_reason: str, item: ContextItem) -> bool:
2026
+ if query_reason in _RECOMMENDATION_FOLLOWUP_RERANK_REASONS:
2027
+ return True
2028
+ return _score_signal_reason(item) in _RECOMMENDATION_FOLLOWUP_RERANK_REASONS
2029
+
2030
+
2031
+ def _is_lifestyle_recommendation_candidate(
2032
+ *,
2033
+ query_reason: str,
2034
+ item: ContextItem,
2035
+ ) -> bool:
2036
+ return query_reason in {
2037
+ "food_recipe_recommendation_bridge",
2038
+ "wellness_activity_effect_bridge",
2039
+ } or _score_signal_reason(item) in {
2040
+ "food_recipe_recommendation_bridge",
2041
+ "wellness_activity_effect_bridge",
2042
+ }
2043
+
2044
+
2045
+ def _is_event_sequence_candidate(
2046
+ *,
2047
+ query: str,
2048
+ query_reason: str,
2049
+ item: ContextItem,
2050
+ ) -> bool:
2051
+ return _matches_query_or_score_signal_reason(
2052
+ query_reason=query_reason,
2053
+ item=item,
2054
+ target_reason="decomposition_event_sequence",
2055
+ ) or _EVENT_SEQUENCE_QUERY_RE.search(query) is not None
2056
+
2057
+
2058
+ def _is_current_goal_candidate(*, query_reason: str, item: ContextItem) -> bool:
2059
+ if query_reason in _CURRENT_GOAL_RERANK_REASONS:
2060
+ return True
2061
+ return _score_signal_reason(item) in _CURRENT_GOAL_RERANK_REASONS
2062
+
2063
+
2064
+ def _is_positive_preference_candidate(
2065
+ *,
2066
+ query: str,
2067
+ query_reason: str,
2068
+ item: ContextItem,
2069
+ ) -> bool:
2070
+ if _POSITIVE_PREFERENCE_NEGATIVE_QUERY_RE.search(query) is not None:
2071
+ return False
2072
+ if query_reason in _POSITIVE_PREFERENCE_RERANK_REASONS:
2073
+ return True
2074
+ if _score_signal_reason(item) in _POSITIVE_PREFERENCE_RERANK_REASONS:
2075
+ return True
2076
+ return _POSITIVE_PREFERENCE_QUERY_RE.search(query) is not None
2077
+
2078
+
2079
+ def _is_outdoor_preference_candidate(*, query_reason: str, item: ContextItem) -> bool:
2080
+ return (
2081
+ query_reason in _OUTDOOR_PREFERENCE_RERANK_REASONS
2082
+ or _score_signal_reason(item) in _OUTDOOR_PREFERENCE_RERANK_REASONS
2083
+ )
2084
+
2085
+
2086
+ def _is_commonality_candidate(
2087
+ *,
2088
+ query: str,
2089
+ query_reason: str,
2090
+ item: ContextItem,
2091
+ ) -> bool:
2092
+ if query_reason in _COMMONALITY_RERANK_REASONS:
2093
+ return True
2094
+ if _score_signal_reason(item) in _COMMONALITY_RERANK_REASONS:
2095
+ return True
2096
+ return _COMMONALITY_QUERY_RE.search(query) is not None
2097
+
2098
+
2099
+ def _is_family_hike_detail_candidate(
2100
+ *,
2101
+ query: str,
2102
+ query_reason: str,
2103
+ item: ContextItem,
2104
+ ) -> bool:
2105
+ return (
2106
+ query_reason in _FAMILY_HIKE_DETAIL_RERANK_REASONS
2107
+ or _score_signal_reason(item) in _FAMILY_HIKE_DETAIL_RERANK_REASONS
2108
+ or _FAMILY_HIKE_DETAIL_QUERY_RE.search(query) is not None
2109
+ )
2110
+
2111
+
2112
+ def _is_temporal_camping_detail_candidate(
2113
+ *,
2114
+ query: str,
2115
+ query_reason: str,
2116
+ item: ContextItem,
2117
+ ) -> bool:
2118
+ if _TEMPORAL_CAMPING_DETAIL_QUERY_RE.search(query) is None:
2119
+ return False
2120
+ return (
2121
+ query_reason in _TEMPORAL_CAMPING_DETAIL_RERANK_REASONS
2122
+ or _score_signal_reason(item) in _TEMPORAL_CAMPING_DETAIL_RERANK_REASONS
2123
+ )
2124
+
2125
+
2126
+ def _is_relationship_status_candidate(
2127
+ *,
2128
+ query: str = "",
2129
+ query_reason: str,
2130
+ item: ContextItem,
2131
+ ) -> bool:
2132
+ if query_reason in _RELATIONSHIP_STATUS_RERANK_REASONS:
2133
+ return True
2134
+ if query and _RELATIONSHIP_STATUS_QUERY_RE.search(query) is not None:
2135
+ return True
2136
+ return _score_signal_reason(item) in _RELATIONSHIP_STATUS_RERANK_REASONS
2137
+
2138
+
2139
+ def _is_identity_candidate(
2140
+ *,
2141
+ query: str = "",
2142
+ query_reason: str,
2143
+ item: ContextItem,
2144
+ ) -> bool:
2145
+ if query_reason in _IDENTITY_RERANK_REASONS:
2146
+ return True
2147
+ if query and _IDENTITY_QUERY_RE.search(query) is not None:
2148
+ return True
2149
+ return _score_signal_reason(item) in _IDENTITY_RERANK_REASONS
2150
+
2151
+
2152
+ def _is_relationship_duration_candidate(*, query_reason: str, item: ContextItem) -> bool:
2153
+ if query_reason in _RELATIONSHIP_DURATION_RERANK_REASONS:
2154
+ return True
2155
+ return _score_signal_reason(item) in _RELATIONSHIP_DURATION_RERANK_REASONS
2156
+
2157
+
2158
+ def _is_relationship_origin_candidate(*, query_reason: str, item: ContextItem) -> bool:
2159
+ if query_reason in _RELATIONSHIP_ORIGIN_RERANK_REASONS:
2160
+ return True
2161
+ return _score_signal_reason(item) in _RELATIONSHIP_ORIGIN_RERANK_REASONS
2162
+
2163
+
2164
+ def _is_state_transition_candidate(*, query_reason: str, item: ContextItem) -> bool:
2165
+ if query_reason in _STATE_TRANSITION_RERANK_REASONS:
2166
+ return True
2167
+ return _score_signal_reason(item) in _STATE_TRANSITION_RERANK_REASONS
2168
+
2169
+
2170
+ def _is_current_state_candidate(*, query: str, query_reason: str, item: ContextItem) -> bool:
2171
+ if _CURRENT_STATE_QUERY_RE.search(query) is not None:
2172
+ return True
2173
+ if query_reason in _CURRENT_STATE_RERANK_REASONS:
2174
+ return True
2175
+ return _score_signal_reason(item) in _CURRENT_STATE_RERANK_REASONS
2176
+
2177
+
2178
+ def _is_stale_state_candidate(*, query: str, query_reason: str, item: ContextItem) -> bool:
2179
+ if _STALE_STATE_QUERY_RE.search(query) is not None:
2180
+ return True
2181
+ if query_reason in _STALE_STATE_RERANK_REASONS:
2182
+ return True
2183
+ return _score_signal_reason(item) in _STALE_STATE_RERANK_REASONS
2184
+
2185
+
2186
+ def has_current_state_correction_evidence(text: str) -> bool:
2187
+ has_current_state = _CURRENT_STATE_EXACT_RE.search(text) is not None
2188
+ has_stale_context = _STALE_STATE_EXACT_RE.search(text) is not None
2189
+ has_transition = _STATE_TRANSITION_PAIR_RE.search(text) is not None
2190
+ has_contrastive_correction = _CONTRASTIVE_CORRECTION_RE.search(text) is not None
2191
+ return (has_current_state and (has_stale_context or has_transition)) or (
2192
+ has_contrastive_correction and (has_stale_context or has_transition)
2193
+ )
2194
+
2195
+
2196
+ def _is_age_birthday_candidate(*, query_reason: str, item: ContextItem) -> bool:
2197
+ if query_reason in _AGE_BIRTHDAY_RERANK_REASONS:
2198
+ return True
2199
+ return _score_signal_reason(item) in _AGE_BIRTHDAY_RERANK_REASONS
2200
+
2201
+
2202
+ def _is_birthplace_candidate(*, query_reason: str, item: ContextItem) -> bool:
2203
+ if query_reason in _BIRTHPLACE_RERANK_REASONS:
2204
+ return True
2205
+ return _score_signal_reason(item) in _BIRTHPLACE_RERANK_REASONS
2206
+
2207
+
2208
+ def _is_beach_or_mountains_candidate(
2209
+ *,
2210
+ query: str,
2211
+ query_reason: str,
2212
+ item: ContextItem,
2213
+ ) -> bool:
2214
+ if _BEACH_OR_MOUNTAINS_QUERY_RE.search(query) is not None:
2215
+ return True
2216
+ if query_reason in _BEACH_OR_MOUNTAINS_RERANK_REASONS:
2217
+ return True
2218
+ return _score_signal_reason(item) in _BEACH_OR_MOUNTAINS_RERANK_REASONS
2219
+
2220
+
2221
+ def _is_symbol_importance_candidate(*, query_reason: str, item: ContextItem) -> bool:
2222
+ if query_reason in _SYMBOL_IMPORTANCE_RERANK_REASONS:
2223
+ return True
2224
+ return _score_signal_reason(item) in _SYMBOL_IMPORTANCE_RERANK_REASONS
2225
+
2226
+
2227
+ def _is_item_purchase_candidate(*, query_reason: str, item: ContextItem) -> bool:
2228
+ if query_reason in _ITEM_PURCHASE_RERANK_REASONS:
2229
+ return True
2230
+ return _score_signal_reason(item) in _ITEM_PURCHASE_RERANK_REASONS
2231
+
2232
+
2233
+ def _is_post_event_emotion_candidate(*, query_reason: str, item: ContextItem) -> bool:
2234
+ if query_reason in _POST_EVENT_EMOTION_RERANK_REASONS:
2235
+ return True
2236
+ return _score_signal_reason(item) in _POST_EVENT_EMOTION_RERANK_REASONS
2237
+
2238
+
2239
+ def _event_sequence_anchor_terms(query: str) -> tuple[str, ...]:
2240
+ terms = []
2241
+ seen = set()
2242
+ for match in _EVENT_SEQUENCE_NAMED_ANCHOR_RE.finditer(query):
2243
+ term = match.group(0)
2244
+ if term in _EVENT_SEQUENCE_IGNORED_ANCHORS:
2245
+ continue
2246
+ normalized = term.casefold()
2247
+ if normalized in seen:
2248
+ continue
2249
+ seen.add(normalized)
2250
+ terms.append(normalized)
2251
+ return tuple(terms)
2252
+
2253
+
2254
+ def _event_sequence_anchor_hits(*, anchor_terms: tuple[str, ...], text: str) -> int:
2255
+ text_lower = text.casefold()
2256
+ return sum(
2257
+ 1
2258
+ for term in anchor_terms
2259
+ if re.search(rf"\b{re.escape(term)}\b", text_lower)
2260
+ )
2261
+
2262
+
2263
+ def _commonality_anchor_terms(query: str) -> tuple[str, ...]:
2264
+ terms = []
2265
+ seen = set()
2266
+ for match in _COMMONALITY_NAMED_ANCHOR_RE.finditer(query):
2267
+ term = match.group(0)
2268
+ if term in _COMMONALITY_IGNORED_ANCHORS:
2269
+ continue
2270
+ normalized = term.casefold()
2271
+ if normalized in seen:
2272
+ continue
2273
+ seen.add(normalized)
2274
+ terms.append(normalized)
2275
+ return tuple(terms)
2276
+
2277
+
2278
+ def _commonality_anchor_hits(*, anchor_terms: tuple[str, ...], text: str) -> int:
2279
+ text_lower = text.casefold()
2280
+ return sum(
2281
+ 1
2282
+ for term in anchor_terms
2283
+ if re.search(rf"\b{re.escape(term)}\b", text_lower)
2284
+ )
2285
+
2286
+
2287
+ def _commonality_who_else_signal(*, query: str, item: ContextItem) -> DomainRerankSignal:
2288
+ if _COMMONALITY_WHO_ELSE_QUERY_RE.search(query) is None:
2289
+ return DomainRerankSignal()
2290
+ anchor_terms = _commonality_anchor_terms(query)
2291
+ if len(anchor_terms) != 1:
2292
+ return DomainRerankSignal()
2293
+ if _text_has_any_anchor(anchor_terms=anchor_terms, text=item.text):
2294
+ return DomainRerankSignal(
2295
+ penalty=0.052,
2296
+ reason="commonality_original_person_noise",
2297
+ )
2298
+ if _COMMONALITY_WHO_ELSE_EVIDENCE_RE.search(item.text) is not None:
2299
+ return DomainRerankSignal(boost=0.034, reason="commonality_who_else_evidence")
2300
+ return DomainRerankSignal()
2301
+
2302
+
2303
+ def _text_has_any_anchor(*, anchor_terms: tuple[str, ...], text: str) -> bool:
2304
+ text_lower = text.casefold()
2305
+ return any(re.search(rf"\b{re.escape(term)}\b", text_lower) for term in anchor_terms)
2306
+
2307
+
2308
+ def _matches_query_or_score_signal_reason(
2309
+ *,
2310
+ query_reason: str,
2311
+ item: ContextItem,
2312
+ target_reason: str,
2313
+ ) -> bool:
2314
+ return query_reason == target_reason or _score_signal_reason(item) == target_reason
2315
+
2316
+
2317
+ def _is_aggregation_query(query: str) -> bool:
2318
+ return bool(
2319
+ _AGGREGATION_COUNT_QUERY_RE.search(query)
2320
+ or _AGGREGATION_LIST_QUERY_RE.search(query)
2321
+ )
2322
+
2323
+
2324
+ def _is_aggregation_list_query(query: str) -> bool:
2325
+ return _AGGREGATION_LIST_QUERY_RE.search(query) is not None
2326
+
2327
+
2328
+ def _has_aggregation_subject_mismatch(
2329
+ *,
2330
+ query: str,
2331
+ item: ContextItem,
2332
+ answer_slot_count: int,
2333
+ ) -> bool:
2334
+ if not (
2335
+ _is_aggregation_context_item(item)
2336
+ or _AGGREGATION_NUMERIC_ANSWER_RE.search(item.text) is not None
2337
+ or _list_evidence_looks_multi_value(item.text)
2338
+ or answer_slot_count > 0
2339
+ ):
2340
+ return False
2341
+ grounding = aggregation_subject_grounding(query=query, text=item.text)
2342
+ if (
2343
+ grounding.query_person_count
2344
+ and not grounding.matched_person_count
2345
+ and grounding.text_person_count
2346
+ ):
2347
+ return True
2348
+ if answer_slot_count > 0:
2349
+ return False
2350
+ return (
2351
+ grounding.query_subject_term_count > 0
2352
+ and grounding.matched_subject_term_count == 0
2353
+ )
2354
+
2355
+
2356
+ def _is_aggregation_context_item(item: ContextItem) -> bool:
2357
+ diagnostics = diagnostic_mapping(item.diagnostics)
2358
+ retrieval_source = diagnostic_text(diagnostics, "retrieval_source")
2359
+ if retrieval_source == _AGGREGATION_RETRIEVAL_SOURCE:
2360
+ return True
2361
+ sources = diagnostics.get("retrieval_sources")
2362
+ if isinstance(sources, list | tuple | set):
2363
+ return _AGGREGATION_RETRIEVAL_SOURCE in {str(source) for source in sources}
2364
+ return False
2365
+
2366
+
2367
+ def _aggregation_evidence_count(item: ContextItem) -> int:
2368
+ marker_count = len(set(_AGGREGATION_MARKER_RE.findall(item.text)))
2369
+ return max(marker_count, len(item.source_refs))
2370
+
2371
+
2372
+ def _is_single_weak_count_evidence(item: ContextItem) -> bool:
2373
+ if _aggregation_evidence_count(item) >= 2:
2374
+ return False
2375
+ return _AGGREGATION_NUMERIC_ANSWER_RE.search(item.text) is None
2376
+
2377
+
2378
+ def _is_single_list_evidence(*, query: str, item: ContextItem) -> bool:
2379
+ if _is_aggregation_context_item(item) or _aggregation_evidence_count(item) >= 2:
2380
+ return False
2381
+ if aggregation_answer_slot_count(query=query, text=item.text) == 1:
2382
+ return True
2383
+ return not _list_evidence_looks_multi_value(item.text)
2384
+
2385
+
2386
+ def _list_evidence_looks_multi_value(text: str) -> bool:
2387
+ if len(set(_AGGREGATION_MARKER_RE.findall(text))) >= 2:
2388
+ return True
2389
+ if len(re.findall(r"\b(?:also|another|as\s+well|and)\b", text, re.IGNORECASE)) >= 1:
2390
+ return True
2391
+ return ";" in text or len(re.findall(r",", text)) >= 2