topos-node 1.3.36__tar.gz → 1.3.37__tar.gz

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 (758) hide show
  1. {topos_node-1.3.36/topos_node.egg-info → topos_node-1.3.37}/PKG-INFO +1 -1
  2. {topos_node-1.3.36 → topos_node-1.3.37}/pyproject.toml +1 -1
  3. {topos_node-1.3.36 → topos_node-1.3.37}/topos/__version__.py +2 -2
  4. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/ingestion_sources.py +18 -6
  5. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/sources.py +12 -5
  6. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/ollama.py +9 -0
  7. topos_node-1.3.37/topos/engine/ollama_runtime.py +142 -0
  8. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/local_sync.py +66 -23
  9. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/imessage_reader.py +96 -10
  10. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/llm/openai.py +13 -0
  11. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/source_settings.py +56 -22
  12. {topos_node-1.3.36 → topos_node-1.3.37}/topos/upgrades/manifests.json +9 -0
  13. {topos_node-1.3.36 → topos_node-1.3.37/topos_node.egg-info}/PKG-INFO +1 -1
  14. {topos_node-1.3.36 → topos_node-1.3.37}/topos_node.egg-info/SOURCES.txt +1 -0
  15. {topos_node-1.3.36 → topos_node-1.3.37}/LICENSE +0 -0
  16. {topos_node-1.3.36 → topos_node-1.3.37}/MANIFEST.in +0 -0
  17. {topos_node-1.3.36 → topos_node-1.3.37}/README.md +0 -0
  18. {topos_node-1.3.36 → topos_node-1.3.37}/setup.cfg +0 -0
  19. {topos_node-1.3.36 → topos_node-1.3.37}/shared/__init__.py +0 -0
  20. {topos_node-1.3.36 → topos_node-1.3.37}/shared/filtering.py +0 -0
  21. {topos_node-1.3.36 → topos_node-1.3.37}/shared/schema_registry.py +0 -0
  22. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_active_database_binding.py +0 -0
  23. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_active_ingestion_binding.py +0 -0
  24. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_extensions.py +0 -0
  25. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_gate_leg_hermeticity.py +0 -0
  26. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_llm_integrations_storage.py +0 -0
  27. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_local_gate_composition.py +0 -0
  28. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_owner_database_hermeticity.py +0 -0
  29. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_prewarm_first_run.py +0 -0
  30. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_profile_hygiene.py +0 -0
  31. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_profiles.py +0 -0
  32. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_protocol_handled_types.py +0 -0
  33. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_query_field_contract.py +0 -0
  34. {topos_node-1.3.36 → topos_node-1.3.37}/tests/test_system_computer_name.py +0 -0
  35. {topos_node-1.3.36 → topos_node-1.3.37}/topos/__init__.py +0 -0
  36. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/__init__.py +0 -0
  37. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/dataset_resolution.py +0 -0
  38. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/duckdb_adapter.py +0 -0
  39. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/luck_surface.py +0 -0
  40. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/messenger_communities.py +0 -0
  41. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/messenger_directed.py +0 -0
  42. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/messenger_graph.py +0 -0
  43. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/messenger_labels.py +0 -0
  44. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/person_graph.py +0 -0
  45. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/person_overlay.py +0 -0
  46. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/profiles.py +0 -0
  47. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/query_engine.py +0 -0
  48. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/raw_queries.py +0 -0
  49. {topos_node-1.3.36 → topos_node-1.3.37}/topos/analytics/relationship_reads.py +0 -0
  50. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/__init__.py +0 -0
  51. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/analytics.py +0 -0
  52. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/app_registry.py +0 -0
  53. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/backup.py +0 -0
  54. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/community_naming_config.py +0 -0
  55. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/compute_remote.py +0 -0
  56. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/connected_apps.py +0 -0
  57. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/conversation_context.py +0 -0
  58. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/data_commit.py +0 -0
  59. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/data_explorer_table_prefs.py +0 -0
  60. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/database_explorer.py +0 -0
  61. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/db.py +0 -0
  62. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/device.py +0 -0
  63. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/disk_space_config.py +0 -0
  64. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/engine_run.py +0 -0
  65. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/enrichment.py +0 -0
  66. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/enrichment_lab.py +0 -0
  67. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/facts_llm_config.py +0 -0
  68. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/filter_lab.py +0 -0
  69. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/health.py +0 -0
  70. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/home_chat.py +0 -0
  71. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/ingestion_api.py +0 -0
  72. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/ingestion_compat.py +0 -0
  73. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/intelligence_lifecycle.py +0 -0
  74. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/llm.py +0 -0
  75. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/local_mcp.py +0 -0
  76. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/messenger_analytics.py +0 -0
  77. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/privacy_disclose.py +0 -0
  78. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/query_api.py +0 -0
  79. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/runtime_bootstrap.py +0 -0
  80. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/sanitization_ollama_config.py +0 -0
  81. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/shell.py +0 -0
  82. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/signal.py +0 -0
  83. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/signal_extraction_config.py +0 -0
  84. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/source_install.py +0 -0
  85. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/source_scrub.py +0 -0
  86. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/sources.py +0 -0
  87. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/sources_overview.py +0 -0
  88. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/sync.py +0 -0
  89. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/tool_index.py +0 -0
  90. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/ui_config.py +0 -0
  91. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/uma_data.py +0 -0
  92. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/upgrades.py +0 -0
  93. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/usage.py +0 -0
  94. {topos_node-1.3.36 → topos_node-1.3.37}/topos/api/user_identity.py +0 -0
  95. {topos_node-1.3.36 → topos_node-1.3.37}/topos/app.py +0 -0
  96. {topos_node-1.3.36 → topos_node-1.3.37}/topos/auth.py +0 -0
  97. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/__init__.py +0 -0
  98. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/declared_field_map.py +0 -0
  99. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/__init__.py +0 -0
  100. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/base.py +0 -0
  101. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  102. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  103. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  104. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  105. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  106. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  107. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  108. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  109. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/models.py +0 -0
  110. {topos_node-1.3.36 → topos_node-1.3.37}/topos/canonicalization/resolver.py +0 -0
  111. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/__init__.py +0 -0
  112. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/__main__.py +0 -0
  113. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/assets/topos_blk_rounded.png +0 -0
  114. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/assets/topos_white.png +0 -0
  115. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/commands.py +0 -0
  116. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/profile_cmd.py +0 -0
  117. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/reprocess_cmd.py +0 -0
  118. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/setup_models_cmd.py +0 -0
  119. {topos_node-1.3.36 → topos_node-1.3.37}/topos/cli/tray.py +0 -0
  120. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/__init__.py +0 -0
  121. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/conversation_context_llm.py +0 -0
  122. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/facts_llm.py +0 -0
  123. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/local_model_builds.py +0 -0
  124. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/model_packs.py +0 -0
  125. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/node_function_providers.py +0 -0
  126. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/sanitization_ollama.py +0 -0
  127. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/settings.py +0 -0
  128. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/signal_extraction.py +0 -0
  129. {topos_node-1.3.36 → topos_node-1.3.37}/topos/config/uvicorn_logging.json +0 -0
  130. {topos_node-1.3.36 → topos_node-1.3.37}/topos/contacts/__init__.py +0 -0
  131. {topos_node-1.3.36 → topos_node-1.3.37}/topos/contacts/identity.py +0 -0
  132. {topos_node-1.3.36 → topos_node-1.3.37}/topos/control_plane_client.py +0 -0
  133. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/__init__.py +0 -0
  134. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/api_models.py +0 -0
  135. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/connection_resilience.py +0 -0
  136. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/db_health.py +0 -0
  137. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/device_helpers.py +0 -0
  138. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/errors.py +0 -0
  139. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/events.py +0 -0
  140. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/__init__.py +0 -0
  141. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/common.py +0 -0
  142. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/complexity.py +0 -0
  143. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/config.py +0 -0
  144. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/contacts_import.py +0 -0
  145. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/database_explorer.py +0 -0
  146. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/derivation.py +0 -0
  147. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/device.py +0 -0
  148. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/enrichment.py +0 -0
  149. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/enrichment_lab.py +0 -0
  150. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/filter_lab.py +0 -0
  151. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/graph_query.py +0 -0
  152. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/home_chat.py +0 -0
  153. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/ingest.py +0 -0
  154. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/mcp_client_elevations.py +0 -0
  155. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/mcp_clients.py +0 -0
  156. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/messages.py +0 -0
  157. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/messenger_analytics.py +0 -0
  158. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/query.py +0 -0
  159. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/registry.py +0 -0
  160. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/routines.py +0 -0
  161. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/signal_features.py +0 -0
  162. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/timeline_daily.py +0 -0
  163. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/tool_index.py +0 -0
  164. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/handlers/uma.py +0 -0
  165. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/logging.py +0 -0
  166. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/metrics.py +0 -0
  167. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/routine_access.py +0 -0
  168. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/startup_banner.py +0 -0
  169. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/state.py +0 -0
  170. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/table_layers.py +0 -0
  171. {topos_node-1.3.36 → topos_node-1.3.37}/topos/core/types.py +0 -0
  172. {topos_node-1.3.36 → topos_node-1.3.37}/topos/data_explorer_row_delete.py +0 -0
  173. {topos_node-1.3.36 → topos_node-1.3.37}/topos/data_explorer_table_prefs.py +0 -0
  174. {topos_node-1.3.36 → topos_node-1.3.37}/topos/data_explorer_tables.py +0 -0
  175. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/__init__.py +0 -0
  176. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/canonical_writer.py +0 -0
  177. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/content_policy.py +0 -0
  178. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/field_registry.py +0 -0
  179. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/privacy_layer.py +0 -0
  180. {topos_node-1.3.36 → topos_node-1.3.37}/topos/disclosure/tier.py +0 -0
  181. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/__init__.py +0 -0
  182. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/__init__.py +0 -0
  183. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/base.py +0 -0
  184. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/generative_prompts.py +0 -0
  185. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/generative_response.py +0 -0
  186. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/huggingface.py +0 -0
  187. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/openai.py +0 -0
  188. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/openai_compatible.py +0 -0
  189. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/redpill.py +0 -0
  190. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/backends/stub.py +0 -0
  191. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/client.py +0 -0
  192. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/disk_space.py +0 -0
  193. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/engine.py +0 -0
  194. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/hosted_llm_wallet.py +0 -0
  195. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/intake.py +0 -0
  196. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/memory_utils.py +0 -0
  197. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/model_cache.py +0 -0
  198. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/model_manager.py +0 -0
  199. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/ollama_install.py +0 -0
  200. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/ollama_pull.py +0 -0
  201. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/ollama_setup_guidance.py +0 -0
  202. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/pipeline_memory.py +0 -0
  203. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/queue_manager.py +0 -0
  204. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/registration.py +0 -0
  205. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/result_formatter.py +0 -0
  206. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/router.py +0 -0
  207. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/scoped_token.py +0 -0
  208. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/tasks.py +0 -0
  209. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/torch_runtime.py +0 -0
  210. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/transport.py +0 -0
  211. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/usage_guard.py +0 -0
  212. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/usage_observation.py +0 -0
  213. {topos_node-1.3.36 → topos_node-1.3.37}/topos/engine/validator.py +0 -0
  214. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/__init__.py +0 -0
  215. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/catalog.py +0 -0
  216. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/derivation_recovery.py +0 -0
  217. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/derived_tables.py +0 -0
  218. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/job_readiness.py +0 -0
  219. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/job_writer.py +0 -0
  220. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/__init__.py +0 -0
  221. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/base.py +0 -0
  222. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  223. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  224. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  225. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  226. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  227. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  228. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  229. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  230. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
  231. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  232. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  233. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  234. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  235. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  236. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  237. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  238. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  239. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  240. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  241. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  242. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  243. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  244. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/raw/__init__.py +0 -0
  245. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  246. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/raw/language_job.py +0 -0
  247. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  248. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  249. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/model_overrides.py +0 -0
  250. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/models/__init__.py +0 -0
  251. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/models/manager.py +0 -0
  252. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/models/mvp_defaults.py +0 -0
  253. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/models/registry.py +0 -0
  254. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/models/versioning.py +0 -0
  255. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/orchestrator.py +0 -0
  256. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/pipeline_activity.py +0 -0
  257. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/processor.py +0 -0
  258. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/progress_bar.py +0 -0
  259. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/record_progress.py +0 -0
  260. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/registry_contract.py +0 -0
  261. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/signal_derivation_config.json +0 -0
  262. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment/source_overrides.py +0 -0
  263. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/__init__.py +0 -0
  264. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/bundles.py +0 -0
  265. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/model_resolve.py +0 -0
  266. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/schema.py +0 -0
  267. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/service.py +0 -0
  268. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/store.py +0 -0
  269. {topos_node-1.3.36 → topos_node-1.3.37}/topos/enrichment_lab/worker.py +0 -0
  270. {topos_node-1.3.36 → topos_node-1.3.37}/topos/evals/__init__.py +0 -0
  271. {topos_node-1.3.36 → topos_node-1.3.37}/topos/evals/enrichment_eval.py +0 -0
  272. {topos_node-1.3.36 → topos_node-1.3.37}/topos/extensions.py +0 -0
  273. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/__init__.py +0 -0
  274. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/canonical.py +0 -0
  275. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/engine.py +0 -0
  276. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/entropy.py +0 -0
  277. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/focus.py +0 -0
  278. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/graph_metrics.py +0 -0
  279. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/influence.py +0 -0
  280. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/projection.py +0 -0
  281. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/snapshots.py +0 -0
  282. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/store.py +0 -0
  283. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/topic_merge.py +0 -0
  284. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/topics.py +0 -0
  285. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/topics_daily.py +0 -0
  286. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/complexity/volatility.py +0 -0
  287. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/__init__.py +0 -0
  288. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  289. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  290. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
  291. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  292. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  293. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  294. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  295. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  296. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  297. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  298. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  299. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  300. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  301. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
  302. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  303. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  304. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  305. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  306. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  307. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  308. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
  309. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
  310. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  311. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
  312. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  313. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  314. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  315. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  316. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  317. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  318. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  319. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  320. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  321. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  322. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  323. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
  324. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/candidates.py +0 -0
  325. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/guard.py +0 -0
  326. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/kernels.py +0 -0
  327. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/net_subject_policy.py +0 -0
  328. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/packs.py +0 -0
  329. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/person_bridge.py +0 -0
  330. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/prefilter.py +0 -0
  331. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/registry.py +0 -0
  332. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/report_card.py +0 -0
  333. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/router.py +0 -0
  334. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/social_bench.py +0 -0
  335. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/social_kernels.py +0 -0
  336. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/surfaces.py +0 -0
  337. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/synthesize.py +0 -0
  338. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/template.py +0 -0
  339. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/verify.py +0 -0
  340. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/derivation/writer.py +0 -0
  341. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/__init__.py +0 -0
  342. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/affinity.py +0 -0
  343. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/affinity_owner.py +0 -0
  344. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/affinity_quality.py +0 -0
  345. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/community_names.py +0 -0
  346. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/community_naming.py +0 -0
  347. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/consolidation.py +0 -0
  348. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/context_vectors.py +0 -0
  349. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/cypher.py +0 -0
  350. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/declared_mappings.py +0 -0
  351. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/dossier.py +0 -0
  352. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/edges.py +0 -0
  353. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/fact_materializer.py +0 -0
  354. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/graph_enrichers.py +0 -0
  355. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/graph_refresh.py +0 -0
  356. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/graph_search.py +0 -0
  357. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/linking.py +0 -0
  358. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/maintenance.py +0 -0
  359. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/owner.py +0 -0
  360. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/reads.py +0 -0
  361. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/rebuild_subprocess.py +0 -0
  362. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/resolver.py +0 -0
  363. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/entities/structured_fields.py +0 -0
  364. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/__init__.py +0 -0
  365. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/extract.py +0 -0
  366. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/llm_extract.py +0 -0
  367. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/reads.py +0 -0
  368. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/store.py +0 -0
  369. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/facts/verdicts.py +0 -0
  370. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/fit/evaluator.py +0 -0
  371. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/fit/opportunity_types.json +0 -0
  372. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/__init__.py +0 -0
  373. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/blackhole.py +0 -0
  374. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/blackhole_guard.py +0 -0
  375. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/blackhole_llm.py +0 -0
  376. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  377. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/derived_scrub.py +0 -0
  378. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/exclusions.py +0 -0
  379. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/lifecycle/gc.py +0 -0
  380. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/provenance/__init__.py +0 -0
  381. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/provenance/posture.py +0 -0
  382. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/provenance/roles.py +0 -0
  383. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/__init__.py +0 -0
  384. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/brief_canonical_loader.py +0 -0
  385. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/brief_ontology.py +0 -0
  386. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/brief_renderer.py +0 -0
  387. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/brief_schemas.py +0 -0
  388. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/chunking.py +0 -0
  389. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/cluster_labels.py +0 -0
  390. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/conversation_context.py +0 -0
  391. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/data_health.py +0 -0
  392. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  393. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/intentions.json +0 -0
  394. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/interests.json +0 -0
  395. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/memory.json +0 -0
  396. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/places.json +0 -0
  397. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/profile.json +0 -0
  398. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/relationships.json +0 -0
  399. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/resources.json +0 -0
  400. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  401. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/time.json +0 -0
  402. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/wellbeing.json +0 -0
  403. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/definitions/work.json +0 -0
  404. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/derived_index.py +0 -0
  405. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/derived_spec.py +0 -0
  406. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/dimension_briefs.py +0 -0
  407. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/dimension_definition_loader.py +0 -0
  408. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/dimension_profiles.py +0 -0
  409. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/dimension_registry.py +0 -0
  410. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/embed_context.py +0 -0
  411. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/extraction/artifact_router.py +0 -0
  412. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/extraction/artifact_store.py +0 -0
  413. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/extraction/rule_extractors.py +0 -0
  414. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/graph_sanitize.py +0 -0
  415. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/hybrid_search.py +0 -0
  416. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/incremental_clustering.py +0 -0
  417. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/model_recommendations.py +0 -0
  418. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/query_embed_cache.py +0 -0
  419. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/schemas.py +0 -0
  420. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/service.py +0 -0
  421. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/signal_object_store.py +0 -0
  422. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/source_hydration.py +0 -0
  423. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/structured_signal.py +0 -0
  424. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/tool_index.py +0 -0
  425. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/topic_clustering.py +0 -0
  426. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/typed_stores/aggregates.py +0 -0
  427. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/typed_stores/commitments.py +0 -0
  428. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/typed_stores/rhythm.py +0 -0
  429. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  430. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/vector_codec.py +0 -0
  431. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/vector_math.py +0 -0
  432. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/signal/vector_settings.py +0 -0
  433. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/stats/__init__.py +0 -0
  434. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/stats/definitions.py +0 -0
  435. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/stats/engine.py +0 -0
  436. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/stats/fold.py +0 -0
  437. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/stats/insights.py +0 -0
  438. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/timeline_projection.py +0 -0
  439. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/timeline_rollup.py +0 -0
  440. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/__init__.py +0 -0
  441. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/badges.py +0 -0
  442. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/daily.py +0 -0
  443. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/dashboard.py +0 -0
  444. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/instruments.py +0 -0
  445. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/intents.py +0 -0
  446. {topos_node-1.3.36 → topos_node-1.3.37}/topos/features/triage/readiness.py +0 -0
  447. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/__init__.py +0 -0
  448. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/bundles.py +0 -0
  449. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/schema.py +0 -0
  450. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/service.py +0 -0
  451. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/store.py +0 -0
  452. {topos_node-1.3.36 → topos_node-1.3.37}/topos/filter_lab/worker.py +0 -0
  453. {topos_node-1.3.36 → topos_node-1.3.37}/topos/home_chat/__init__.py +0 -0
  454. {topos_node-1.3.36 → topos_node-1.3.37}/topos/home_chat/schema.py +0 -0
  455. {topos_node-1.3.36 → topos_node-1.3.37}/topos/home_chat/store.py +0 -0
  456. {topos_node-1.3.36 → topos_node-1.3.37}/topos/hosted_pool_lease.py +0 -0
  457. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/__init__.py +0 -0
  458. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/canonical_pipeline.py +0 -0
  459. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/checkpoints/__init__.py +0 -0
  460. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  461. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  462. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/inbox_crypto.py +0 -0
  463. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/inbox_drain.py +0 -0
  464. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/ingest_helpers.py +0 -0
  465. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/jobs.py +0 -0
  466. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/journal_location_fanout.py +0 -0
  467. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/journal_time_log_normalize.py +0 -0
  468. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/log_preview.py +0 -0
  469. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/manager.py +0 -0
  470. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parser.py +0 -0
  471. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/__init__.py +0 -0
  472. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/base.py +0 -0
  473. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/browser_parser.py +0 -0
  474. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/calendar_parser.py +0 -0
  475. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  476. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  477. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  478. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/documents_parser.py +0 -0
  479. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  480. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  481. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/grok_parser.py +0 -0
  482. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/messenger_parser.py +0 -0
  483. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  484. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/progress.py +0 -0
  485. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/reprocess.py +0 -0
  486. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/__init__.py +0 -0
  487. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/base.py +0 -0
  488. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/calendar.py +0 -0
  489. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/chatgpt.py +0 -0
  490. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/contact_importers.py +0 -0
  491. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/grok.py +0 -0
  492. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/signal_export_parser.py +0 -0
  493. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/sources/signal_reader.py +0 -0
  494. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/state_machine.py +0 -0
  495. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/triggers/__init__.py +0 -0
  496. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/triggers/file_trigger.py +0 -0
  497. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  498. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  499. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/validation/__init__.py +0 -0
  500. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/validation/base.py +0 -0
  501. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/validation/schema_registry.py +0 -0
  502. {topos_node-1.3.36 → topos_node-1.3.37}/topos/ingestion/validation/schema_validator.py +0 -0
  503. {topos_node-1.3.36 → topos_node-1.3.37}/topos/lineage/__init__.py +0 -0
  504. {topos_node-1.3.36 → topos_node-1.3.37}/topos/lineage/provenance.py +0 -0
  505. {topos_node-1.3.36 → topos_node-1.3.37}/topos/lineage/tracker.py +0 -0
  506. {topos_node-1.3.36 → topos_node-1.3.37}/topos/llm_integrations_storage.py +0 -0
  507. {topos_node-1.3.36 → topos_node-1.3.37}/topos/mcp_clients.py +0 -0
  508. {topos_node-1.3.36 → topos_node-1.3.37}/topos/mcp_stdio_proxy.py +0 -0
  509. {topos_node-1.3.36 → topos_node-1.3.37}/topos/observability/__init__.py +0 -0
  510. {topos_node-1.3.36 → topos_node-1.3.37}/topos/observability/alerts.py +0 -0
  511. {topos_node-1.3.36 → topos_node-1.3.37}/topos/observability/metrics.py +0 -0
  512. {topos_node-1.3.36 → topos_node-1.3.37}/topos/observability/tracing.py +0 -0
  513. {topos_node-1.3.36 → topos_node-1.3.37}/topos/openai_client.py +0 -0
  514. {topos_node-1.3.36 → topos_node-1.3.37}/topos/owner_key.py +0 -0
  515. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/__init__.py +0 -0
  516. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/audit.py +0 -0
  517. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/envelope.py +0 -0
  518. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/job_runner.py +0 -0
  519. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/job_store.py +0 -0
  520. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/stages.py +0 -0
  521. {topos_node-1.3.36 → topos_node-1.3.37}/topos/pipeline/stub_enqueue.py +0 -0
  522. {topos_node-1.3.36 → topos_node-1.3.37}/topos/principal.py +0 -0
  523. {topos_node-1.3.36 → topos_node-1.3.37}/topos/profiles.py +0 -0
  524. {topos_node-1.3.36 → topos_node-1.3.37}/topos/projections/__init__.py +0 -0
  525. {topos_node-1.3.36 → topos_node-1.3.37}/topos/projections/vector_index/__init__.py +0 -0
  526. {topos_node-1.3.36 → topos_node-1.3.37}/topos/projections/vector_index/base.py +0 -0
  527. {topos_node-1.3.36 → topos_node-1.3.37}/topos/projections/vector_index/builders.py +0 -0
  528. {topos_node-1.3.36 → topos_node-1.3.37}/topos/projections/vector_index/health_checks.py +0 -0
  529. {topos_node-1.3.36 → topos_node-1.3.37}/topos/protocol/__init__.py +0 -0
  530. {topos_node-1.3.36 → topos_node-1.3.37}/topos/protocol/handled_message_types.json +0 -0
  531. {topos_node-1.3.36 → topos_node-1.3.37}/topos/protocol/narrowing_vocabulary.json +0 -0
  532. {topos_node-1.3.36 → topos_node-1.3.37}/topos/protocol/query_field_contract.json +0 -0
  533. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/__init__.py +0 -0
  534. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/audit.py +0 -0
  535. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/closeness.py +0 -0
  536. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/cohort_resolvers.py +0 -0
  537. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/collaborators.py +0 -0
  538. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/ddr.py +0 -0
  539. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/disclosure.py +0 -0
  540. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/entity_window.py +0 -0
  541. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/exclusion.py +0 -0
  542. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/facts_direct.py +0 -0
  543. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/fingerprint.py +0 -0
  544. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/game_layer.py +0 -0
  545. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/grant_cache.py +0 -0
  546. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/inference.py +0 -0
  547. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/intent.py +0 -0
  548. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/manifest.py +0 -0
  549. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/manifest_validation.py +0 -0
  550. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/minimizer.py +0 -0
  551. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/narrowing.py +0 -0
  552. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/negotiation.py +0 -0
  553. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/packet_resolution.py +0 -0
  554. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/pipeline.py +0 -0
  555. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/planner.py +0 -0
  556. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/retrieval.py +0 -0
  557. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/runtime.py +0 -0
  558. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_arbiter.py +0 -0
  559. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_classifier.py +0 -0
  560. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_head.py +0 -0
  561. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_registry.json +0 -0
  562. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_registry_loader.py +0 -0
  563. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/scope_shadow.py +0 -0
  564. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/session.py +0 -0
  565. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/session_utils.py +0 -0
  566. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/source_generation.py +0 -0
  567. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/truth_facts.py +0 -0
  568. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/truth_prompts.py +0 -0
  569. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/turn_classifier.py +0 -0
  570. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/types.py +0 -0
  571. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/verify.py +0 -0
  572. {topos_node-1.3.36 → topos_node-1.3.37}/topos/query/verify_modes.py +0 -0
  573. {topos_node-1.3.36 → topos_node-1.3.37}/topos/rate_limit.py +0 -0
  574. {topos_node-1.3.36 → topos_node-1.3.37}/topos/relay_stamp.py +0 -0
  575. {topos_node-1.3.36 → topos_node-1.3.37}/topos/routines/__init__.py +0 -0
  576. {topos_node-1.3.36 → topos_node-1.3.37}/topos/routines/schema.py +0 -0
  577. {topos_node-1.3.36 → topos_node-1.3.37}/topos/routines/store.py +0 -0
  578. {topos_node-1.3.36 → topos_node-1.3.37}/topos/runtime_housekeeping.py +0 -0
  579. {topos_node-1.3.36 → topos_node-1.3.37}/topos/runtime_shutdown.py +0 -0
  580. {topos_node-1.3.36 → topos_node-1.3.37}/topos/runtime_update.py +0 -0
  581. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sanitization/__init__.py +0 -0
  582. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sanitization/nsfw_classifier.py +0 -0
  583. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sanitization/ollama_transforms.py +0 -0
  584. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sanitization/prewarm.py +0 -0
  585. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sanitization/privacy_filter.py +0 -0
  586. {topos_node-1.3.36 → topos_node-1.3.37}/topos/scope_resolution.py +0 -0
  587. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/__init__.py +0 -0
  588. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/container.py +0 -0
  589. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/embeddings/__init__.py +0 -0
  590. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/embeddings/base.py +0 -0
  591. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/embeddings/local.py +0 -0
  592. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/embeddings/remote.py +0 -0
  593. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/interfaces.py +0 -0
  594. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/llm/__init__.py +0 -0
  595. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/llm/base.py +0 -0
  596. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/local.py +0 -0
  597. {topos_node-1.3.36 → topos_node-1.3.37}/topos/services/postgres.py +0 -0
  598. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/__init__.py +0 -0
  599. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/bundled_canonical_triples.py +0 -0
  600. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/canonical_signal_defaults.py +0 -0
  601. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/declared_field_map_spec.py +0 -0
  602. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/definitions.py +0 -0
  603. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/install_service.py +0 -0
  604. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/registry.py +0 -0
  605. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/runtime_install.py +0 -0
  606. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/scrub_attribution.py +0 -0
  607. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sources/scrub_service.py +0 -0
  608. {topos_node-1.3.36 → topos_node-1.3.37}/topos/startup_banner.py +0 -0
  609. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/__init__.py +0 -0
  610. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/__init__.py +0 -0
  611. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/factory.py +0 -0
  612. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/fakes.py +0 -0
  613. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/postgres/stores.py +0 -0
  614. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/protocols.py +0 -0
  615. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/sqlite/__init__.py +0 -0
  616. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/sqlite/stores.py +0 -0
  617. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  618. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/__init__.py +0 -0
  619. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/activity_tables.py +0 -0
  620. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  621. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  622. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  623. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/ai_chat/model.py +0 -0
  624. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/ai_chat/tables.py +0 -0
  625. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  626. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/canonical_store.py +0 -0
  627. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/conversations_tables.py +0 -0
  628. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/journal_repair.py +0 -0
  629. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/mapping_store.py +0 -0
  630. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/canonical/postgres.py +0 -0
  631. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/__init__.py +0 -0
  632. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/client.py +0 -0
  633. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/connection_tuning.py +0 -0
  634. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/__init__.py +0 -0
  635. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  636. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  637. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  638. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  639. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  640. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/backup.py +0 -0
  641. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/backup_custody.py +0 -0
  642. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  643. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  644. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  645. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  646. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/community_names_v1.py +0 -0
  647. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/complexity_v1.py +0 -0
  648. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
  649. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  650. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  651. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  652. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  653. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
  654. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/documents_v1.py +0 -0
  655. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  656. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  657. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  658. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  659. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  660. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  661. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  662. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  663. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  664. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  665. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  666. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/episodes_v1.py +0 -0
  667. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  668. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
  669. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  670. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  671. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  672. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  673. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  674. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  675. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
  676. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  677. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  678. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
  679. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  680. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  681. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  682. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/registry.py +0 -0
  683. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/registry_checksums.json +0 -0
  684. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  685. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  686. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  687. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  688. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  689. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_objects.py +0 -0
  690. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  691. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  692. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  693. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  694. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  695. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  696. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  697. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  698. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  699. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  700. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  701. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  702. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  703. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  704. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  705. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  706. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  707. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  708. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  709. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  710. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  711. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  712. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/paths.py +0 -0
  713. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/postgres.py +0 -0
  714. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/schema.py +0 -0
  715. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/schema_probe.py +0 -0
  716. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/storage_breakdown.py +0 -0
  717. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/db/write_gate.py +0 -0
  718. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/derived_row_identity.py +0 -0
  719. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/enrichment/__init__.py +0 -0
  720. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  721. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  722. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/normalized/__init__.py +0 -0
  723. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/normalized/normalized_store.py +0 -0
  724. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/oplog/__init__.py +0 -0
  725. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/oplog/decision.py +0 -0
  726. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/oplog/oplog_store.py +0 -0
  727. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/oplog/postgres.py +0 -0
  728. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/person/identity_resolver.py +0 -0
  729. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/projections/__init__.py +0 -0
  730. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/projections/index_ops_store.py +0 -0
  731. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/projections/vector_index_store.py +0 -0
  732. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/__init__.py +0 -0
  733. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/browser_flat_tables.py +0 -0
  734. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/file_store.py +0 -0
  735. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/raw_store.py +0 -0
  736. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/raw_tables_manager.py +0 -0
  737. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/raw/sqlite_raw_store.py +0 -0
  738. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/security/encryption.py +0 -0
  739. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/signal_identity.py +0 -0
  740. {topos_node-1.3.36 → topos_node-1.3.37}/topos/storage/user_identity.py +0 -0
  741. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sync/__init__.py +0 -0
  742. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sync/client.py +0 -0
  743. {topos_node-1.3.36 → topos_node-1.3.37}/topos/sync_handlers.py +0 -0
  744. {topos_node-1.3.36 → topos_node-1.3.37}/topos/testing/__init__.py +0 -0
  745. {topos_node-1.3.36 → topos_node-1.3.37}/topos/testing/lifespan.py +0 -0
  746. {topos_node-1.3.36 → topos_node-1.3.37}/topos/uds.py +0 -0
  747. {topos_node-1.3.36 → topos_node-1.3.37}/topos/uma_contact_enrichment.py +0 -0
  748. {topos_node-1.3.36 → topos_node-1.3.37}/topos/uma_filters.py +0 -0
  749. {topos_node-1.3.36 → topos_node-1.3.37}/topos/uma_resource_id.py +0 -0
  750. {topos_node-1.3.36 → topos_node-1.3.37}/topos/uma_rpt.py +0 -0
  751. {topos_node-1.3.36 → topos_node-1.3.37}/topos/upgrades/__init__.py +0 -0
  752. {topos_node-1.3.36 → topos_node-1.3.37}/topos/upgrades/runner.py +0 -0
  753. {topos_node-1.3.36 → topos_node-1.3.37}/topos/utils/base_object.py +0 -0
  754. {topos_node-1.3.36 → topos_node-1.3.37}/topos/websocket_client.py +0 -0
  755. {topos_node-1.3.36 → topos_node-1.3.37}/topos_node.egg-info/dependency_links.txt +0 -0
  756. {topos_node-1.3.36 → topos_node-1.3.37}/topos_node.egg-info/entry_points.txt +0 -0
  757. {topos_node-1.3.36 → topos_node-1.3.37}/topos_node.egg-info/requires.txt +0 -0
  758. {topos_node-1.3.36 → topos_node-1.3.37}/topos_node.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.36
3
+ Version: 1.3.37
4
4
  Summary: Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://topos.dialogues.ai
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "topos-node"
7
- version = "1.3.36"
7
+ version = "1.3.37"
8
8
  description = "Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  """Topos Control Plane Version Information."""
2
2
 
3
- __version__ = "1.3.36"
4
- __version_info__ = (1, 3, 36)
3
+ __version__ = "1.3.37"
4
+ __version_info__ = (1, 3, 37)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -158,7 +158,7 @@ async def put_source_settings_endpoint(
158
158
  dataset_id: Optional[str] = Query(default=None),
159
159
  body: Optional[dict] = Body(default=None),
160
160
  ):
161
- """Set source settings (e.g. enabled). Valid for local_sync sources (imessage, signal)."""
161
+ """Set source settings (e.g. enabled, exclude_spam). Valid for local_sync sources (imessage, signal)."""
162
162
  source = REGISTRY.get(source_id)
163
163
  if not source:
164
164
  return {"status": "error", "error": "unknown source_id"}
@@ -167,14 +167,26 @@ async def put_source_settings_endpoint(
167
167
  dataset_id = dataset_id or (body.get("dataset_id") if body else None)
168
168
  if not dataset_id:
169
169
  return {"status": "error", "error": "dataset_id required"}
170
- enabled = body.get("enabled") if body else None
171
- if enabled is None:
172
- return {"status": "error", "error": "enabled required in body"}
170
+ body = body or {}
171
+ enabled = body.get("enabled")
172
+ posture_provided = "posture" in body
173
+ exclude_spam_provided = "exclude_spam" in body
174
+ if enabled is None and not posture_provided and not exclude_spam_provided:
175
+ return {"status": "error", "error": "enabled, posture, or exclude_spam required in body"}
173
176
  conn = get_db_connection()
174
177
  if not conn:
175
178
  return {"status": "error", "error": "Database not available"}
176
- put_source_settings(conn, dataset_id, source_id, enabled=enabled)
177
- return {"status": "ok", "dataset_id": dataset_id, "source_id": source_id, "enabled": bool(enabled)}
179
+ put_kwargs: dict = {"enabled": enabled}
180
+ if posture_provided:
181
+ put_kwargs["posture"] = body.get("posture")
182
+ if exclude_spam_provided:
183
+ put_kwargs["exclude_spam"] = bool(body.get("exclude_spam"))
184
+ try:
185
+ put_source_settings(conn, dataset_id, source_id, **put_kwargs)
186
+ except ValueError as exc:
187
+ return {"status": "error", "error": str(exc)}
188
+ settings = get_source_settings(conn, dataset_id, source_id) or {}
189
+ return {"status": "ok", "dataset_id": dataset_id, "source_id": source_id, **settings}
178
190
 
179
191
 
180
192
  @router.post("/sources/{source_id}/sync", dependencies=[Depends(require_api_key)])
@@ -198,6 +198,8 @@ async def handle_put_source_settings(message: Dict[str, Any]) -> Optional[Dict[s
198
198
  # present in the body — absent means "leave unchanged".
199
199
  posture_provided = "posture" in payload
200
200
  posture = payload.get("posture")
201
+ exclude_spam_provided = "exclude_spam" in payload
202
+ exclude_spam = payload.get("exclude_spam")
201
203
  if not source_id or not dataset_id:
202
204
  return {"id": req_id, "status": "error", "error": "source_id and dataset_id required"}
203
205
  source = REGISTRY.get(source_id)
@@ -208,16 +210,20 @@ async def handle_put_source_settings(message: Dict[str, Any]) -> Optional[Dict[s
208
210
  # enabled toggle is being set.
209
211
  if enabled is not None and getattr(source, "source_type", None) != "local_sync":
210
212
  return {"id": req_id, "status": "error", "error": "enabled only applies to local_sync sources"}
211
- if enabled is None and not posture_provided:
212
- return {"id": req_id, "status": "error", "error": "enabled or posture required in body"}
213
+ if exclude_spam_provided and getattr(source, "source_type", None) != "local_sync":
214
+ return {"id": req_id, "status": "error", "error": "exclude_spam only applies to local_sync sources"}
215
+ if enabled is None and not posture_provided and not exclude_spam_provided:
216
+ return {"id": req_id, "status": "error", "error": "enabled, posture, or exclude_spam required in body"}
213
217
  conn = hub.get_db_connection()
214
218
  if not conn:
215
219
  return {"id": req_id, "status": "error", "error": "Database not available"}
216
220
  try:
221
+ put_kwargs: Dict[str, Any] = {"enabled": enabled}
217
222
  if posture_provided:
218
- put_source_settings(conn, dataset_id, source_id, enabled=enabled, posture=posture)
219
- else:
220
- put_source_settings(conn, dataset_id, source_id, enabled=enabled)
223
+ put_kwargs["posture"] = posture
224
+ if exclude_spam_provided:
225
+ put_kwargs["exclude_spam"] = bool(exclude_spam)
226
+ put_source_settings(conn, dataset_id, source_id, **put_kwargs)
221
227
  except ValueError as exc:
222
228
  return {"id": req_id, "status": "error", "error": str(exc)}
223
229
  # Echo the effective settings back (posture reflects what was persisted /
@@ -229,6 +235,7 @@ async def handle_put_source_settings(message: Dict[str, Any]) -> Optional[Dict[s
229
235
  else:
230
236
  result_payload["enabled"] = bool(settings_data.get("enabled", True))
231
237
  result_payload["posture"] = settings_data.get("posture")
238
+ result_payload["exclude_spam"] = bool(settings_data.get("exclude_spam", True))
232
239
  return {"id": req_id, "status": "ok", "payload": result_payload}
233
240
 
234
241
  @handles("get_source_contacts")
@@ -110,6 +110,12 @@ class OllamaAdapter:
110
110
  except Exception:
111
111
  return False
112
112
 
113
+ def _ensure_server(self) -> None:
114
+ """Start a local Ollama if this request needs one and :11434 is down."""
115
+ from ..ollama_runtime import ensure_running
116
+
117
+ ensure_running(base_url=self._base_url)
118
+
113
119
  def model_supports_thinking(self, model: str) -> bool:
114
120
  """True when /api/show lists the 'thinking' capability for ``model``.
115
121
 
@@ -172,6 +178,7 @@ class OllamaAdapter:
172
178
  curated table — Ollama has no size for a tag that is not on disk
173
179
  (PLAN_LOCAL_MODEL_QUICKSTART D4).
174
180
  """
181
+ self._ensure_server()
175
182
  req = urllib.request.Request(f"{self._base_url}/api/tags", method="GET")
176
183
  try:
177
184
  with urllib.request.urlopen(req, timeout=10) as resp:
@@ -211,6 +218,7 @@ class OllamaAdapter:
211
218
  show the download to a human. A callback that raises must not abort a
212
219
  multi-gigabyte transfer that is otherwise healthy.
213
220
  """
221
+ self._ensure_server()
214
222
  body = {"model": model_name, "stream": stream}
215
223
  req = urllib.request.Request(
216
224
  f"{self._base_url}/api/pull",
@@ -361,6 +369,7 @@ class OllamaAdapter:
361
369
  # rejected think=false before keep thinking but get a wider output
362
370
  # budget so the CoT cannot starve the answer (Ollama returns thinking
363
371
  # in a separate field, so 'response' stays clean either way).
372
+ self._ensure_server()
364
373
  requested_think = think
365
374
  think = self.resolve_think(model, think)
366
375
  if (
@@ -0,0 +1,142 @@
1
+ """Start a local Ollama server when a request needs it and :11434 is down.
2
+
3
+ Reachability is already probed everywhere; nothing on the product path used
4
+ to spawn the server. Install opens Ollama.app after a one-click install —
5
+ this module does the same (or ``ollama serve``) at request time, only for a
6
+ localhost base URL, and only once under a process lock.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ import shutil
13
+ import subprocess
14
+ import threading
15
+ import time
16
+ from typing import Callable, Optional
17
+ from urllib.parse import urlparse
18
+
19
+ logger = logging.getLogger("topos.engine.ollama_runtime")
20
+
21
+ _LOCAL_HOSTS = frozenset({"localhost", "127.0.0.1", "::1"})
22
+ _WAIT_SEC = 20.0
23
+ _POLL_INTERVAL = 0.5
24
+
25
+ _LOCK = threading.Lock()
26
+
27
+
28
+ def _default_base_url() -> str:
29
+ try:
30
+ from ..config.settings import settings
31
+
32
+ return str(getattr(settings, "engine_ollama_base_url", None) or "http://localhost:11434").rstrip("/")
33
+ except Exception:
34
+ return "http://localhost:11434"
35
+
36
+
37
+ def is_local_base_url(url: str) -> bool:
38
+ raw = str(url or "").strip()
39
+ if not raw:
40
+ return False
41
+ parsed = urlparse(raw if "://" in raw else f"http://{raw}")
42
+ host = (parsed.hostname or "").lower()
43
+ return host in _LOCAL_HOSTS
44
+
45
+
46
+ def default_is_reachable(base_url: str) -> bool:
47
+ from .backends.ollama import OllamaAdapter
48
+
49
+ return bool(OllamaAdapter(base_url=base_url).is_reachable())
50
+
51
+
52
+ def default_app_present() -> bool:
53
+ from .ollama_install import default_app_present as _app_present
54
+
55
+ return bool(_app_present())
56
+
57
+
58
+ def default_open_app() -> None:
59
+ from .ollama_install import default_open_app as _open_app
60
+
61
+ _open_app()
62
+
63
+
64
+ def default_cli_present() -> bool:
65
+ return shutil.which("ollama") is not None
66
+
67
+
68
+ def default_spawn_serve() -> None:
69
+ subprocess.Popen(
70
+ ["ollama", "serve"],
71
+ stdout=subprocess.DEVNULL,
72
+ stderr=subprocess.DEVNULL,
73
+ start_new_session=True,
74
+ )
75
+
76
+
77
+ def ensure_running(
78
+ *,
79
+ base_url: Optional[str] = None,
80
+ is_reachable: Optional[Callable[[], bool]] = None,
81
+ is_local: Optional[Callable[[str], bool]] = None,
82
+ app_present: Optional[Callable[[], bool]] = None,
83
+ open_app: Optional[Callable[[], None]] = None,
84
+ cli_present: Optional[Callable[[], bool]] = None,
85
+ spawn_serve: Optional[Callable[[], None]] = None,
86
+ sleep: Optional[Callable[[float], None]] = None,
87
+ wait_sec: float = _WAIT_SEC,
88
+ poll_interval: float = _POLL_INTERVAL,
89
+ ) -> bool:
90
+ """Bring a local Ollama up if a request needs it.
91
+
92
+ Returns True when the server answers ``/api/tags`` (already up, or up
93
+ after we launched). Returns False when the URL is remote, nothing is
94
+ installed, or the wait timed out — callers then hit the existing 502 /
95
+ deferred path.
96
+ """
97
+ url = (base_url if base_url is not None else _default_base_url()).rstrip("/")
98
+ local_check = is_local if is_local is not None else is_local_base_url
99
+ if not local_check(url):
100
+ return False
101
+
102
+ reachable = is_reachable if is_reachable is not None else (lambda: default_is_reachable(url))
103
+ if reachable():
104
+ return True
105
+
106
+ with _LOCK:
107
+ if reachable():
108
+ return True
109
+
110
+ launched = False
111
+ present = app_present if app_present is not None else default_app_present
112
+ if present():
113
+ try:
114
+ (open_app if open_app is not None else default_open_app)()
115
+ launched = True
116
+ logger.info("opened Ollama.app; waiting for %s", url)
117
+ except Exception as exc: # noqa: BLE001 — launch is best-effort
118
+ logger.warning("failed to open Ollama.app: %s", exc)
119
+
120
+ if not launched:
121
+ has_cli = cli_present if cli_present is not None else default_cli_present
122
+ if has_cli():
123
+ try:
124
+ (spawn_serve if spawn_serve is not None else default_spawn_serve)()
125
+ launched = True
126
+ logger.info("spawned `ollama serve`; waiting for %s", url)
127
+ except Exception as exc: # noqa: BLE001
128
+ logger.warning("failed to spawn ollama serve: %s", exc)
129
+
130
+ if not launched:
131
+ logger.info("ollama is down and nothing on this machine can start it")
132
+ return False
133
+
134
+ sleeper = sleep if sleep is not None else time.sleep
135
+ deadline = time.monotonic() + float(wait_sec)
136
+ interval = max(0.0, float(poll_interval))
137
+ while time.monotonic() < deadline:
138
+ if reachable():
139
+ return True
140
+ sleeper(interval)
141
+ logger.warning("ollama did not become reachable at %s within %.1fs", url, wait_sec)
142
+ return False
@@ -64,6 +64,41 @@ def _run_local_sync_enrichment_if_enabled(
64
64
  )
65
65
 
66
66
 
67
+ def _as_bool(value: Any, *, default: bool = True) -> bool:
68
+ if value is None:
69
+ return default
70
+ if isinstance(value, bool):
71
+ return value
72
+ if isinstance(value, (int, float)):
73
+ return bool(value)
74
+ text = str(value).strip().lower()
75
+ if text in {"1", "true", "yes", "on"}:
76
+ return True
77
+ if text in {"0", "false", "no", "off"}:
78
+ return False
79
+ return default
80
+
81
+
82
+ def _resolve_exclude_spam(
83
+ options: Optional[Dict[str, Any]],
84
+ *,
85
+ db_conn: Any,
86
+ dataset_id: str,
87
+ ) -> bool:
88
+ """Default on. sync_options.exclude_spam wins over the stored source setting."""
89
+ if isinstance(options, dict) and "exclude_spam" in options:
90
+ return _as_bool(options.get("exclude_spam"), default=True)
91
+ try:
92
+ from ..storage.source_settings import get_source_settings
93
+
94
+ settings = get_source_settings(db_conn, dataset_id, SOURCE_ID_IMESSAGE) or {}
95
+ if "exclude_spam" in settings:
96
+ return _as_bool(settings.get("exclude_spam"), default=True)
97
+ except Exception:
98
+ logger.debug("exclude_spam setting lookup failed; defaulting to skip spam", exc_info=True)
99
+ return True
100
+
101
+
67
102
  def _resolve_sync_start_unix(options: Optional[Dict[str, Any]]) -> tuple[Optional[float], Optional[str]]:
68
103
  """Resolve sync start timestamp from sync options."""
69
104
  if not options:
@@ -318,16 +353,16 @@ def run_imessage_sync(
318
353
  ) -> Dict[str, Any]:
319
354
  """
320
355
  Run iMessage sync: load checkpoint → read from chat.db → parse → write to conversation_messages → save checkpoint.
321
- Returns dict with status, records_processed, last_record_id, error (if any).
356
+ Returns dict with status, records_processed, records_skipped, last_record_id, error (if any).
322
357
  """
323
358
  if not dataset_id:
324
- return {"status": "error", "error": "dataset_id required", "records_processed": 0}
359
+ return {"status": "error", "error": "dataset_id required", "records_processed": 0, "records_skipped": 0}
325
360
 
326
361
  if db_conn is None:
327
362
  from ..core.state import get_db_connection
328
363
  db_conn = get_db_connection()
329
364
  if db_conn is None:
330
- return {"status": "error", "error": "Database connection not available", "records_processed": 0}
365
+ return {"status": "error", "error": "Database connection not available", "records_processed": 0, "records_skipped": 0}
331
366
 
332
367
  store = checkpoint_store if checkpoint_store is not None else SqliteCheckpointStore(db_conn)
333
368
  checkpoint = store.get_checkpoint(dataset_id, IMESSAGE_SCHEMA_ID)
@@ -355,7 +390,7 @@ def run_imessage_sync(
355
390
  e,
356
391
  exc_info=True,
357
392
  )
358
- return {"status": "error", "error": str(e), "records_processed": 0}
393
+ return {"status": "error", "error": str(e), "records_processed": 0, "records_skipped": 0}
359
394
 
360
395
 
361
396
  def _run_imessage_sync_impl(
@@ -371,36 +406,39 @@ def _run_imessage_sync_impl(
371
406
  """Implementation of run_imessage_sync (called inside try so we never raise)."""
372
407
  start_unix, start_error = _resolve_sync_start_unix(sync_options)
373
408
  if start_error:
374
- return {"status": "error", "error": start_error, "records_processed": 0}
409
+ return {"status": "error", "error": start_error, "records_processed": 0, "records_skipped": 0}
375
410
 
376
411
  parser_cls = PARSER_REGISTRY.get(IMESSAGE_SCHEMA_ID)
377
412
  if not parser_cls:
378
- return {"status": "error", "error": "No parser for imessage.messages.v1", "records_processed": 0}
413
+ return {"status": "error", "error": "No parser for imessage.messages.v1", "records_processed": 0, "records_skipped": 0}
379
414
  parser = parser_cls(dataset_id=dataset_id, _schema_id=IMESSAGE_SCHEMA_ID)
380
415
  from ..storage.canonical import ConversationsTablesManager
381
416
  manager = ConversationsTablesManager(db_conn)
382
- from .sources.imessage_reader import read_imessage_rows_list, get_chat_db_path
417
+ from .sources.imessage_reader import read_imessage_batch, get_chat_db_path
383
418
  path = chat_db_path or get_chat_db_path()
419
+ exclude_spam = _resolve_exclude_spam(sync_options, db_conn=db_conn, dataset_id=dataset_id)
384
420
 
385
421
  # For bounded history sync, restart from row 0 and apply time filter.
386
422
  current_last_record_id = "0" if start_unix is not None else last_record_id
387
423
  final_last_record_id = last_record_id
388
424
  total_processed = 0
425
+ total_skipped = 0
389
426
  batch_num = 0
390
427
 
391
428
  while True:
392
429
  batch_num += 1
393
430
  try:
394
- rows = read_imessage_rows_list(
431
+ batch = read_imessage_batch(
395
432
  last_rowid=current_last_record_id if current_last_record_id != "0" else None,
396
433
  chat_db_path=path,
397
434
  batch_size=batch_size,
398
435
  start_unix=start_unix,
436
+ exclude_spam=exclude_spam,
399
437
  )
400
438
  except FileNotFoundError as e:
401
- return {"status": "error", "error": str(e), "records_processed": total_processed}
439
+ return {"status": "error", "error": str(e), "records_processed": total_processed, "records_skipped": total_skipped}
402
440
  except PermissionError as e:
403
- return {"status": "error", "error": str(e), "records_processed": total_processed}
441
+ return {"status": "error", "error": str(e), "records_processed": total_processed, "records_skipped": total_skipped}
404
442
  except OSError as e:
405
443
  logger.warning(
406
444
  "imessage read failed (OSError errno=%s) on batch %d: %s",
@@ -409,7 +447,7 @@ def _run_imessage_sync_impl(
409
447
  e,
410
448
  exc_info=True,
411
449
  )
412
- return {"status": "error", "error": str(e), "records_processed": total_processed}
450
+ return {"status": "error", "error": str(e), "records_processed": total_processed, "records_skipped": total_skipped}
413
451
  except sqlite3.Error as e:
414
452
  logger.warning(
415
453
  "imessage read failed (sqlite3.Error) on batch %d: %s",
@@ -417,12 +455,14 @@ def _run_imessage_sync_impl(
417
455
  e,
418
456
  exc_info=True,
419
457
  )
420
- return {"status": "error", "error": str(e), "records_processed": total_processed}
458
+ return {"status": "error", "error": str(e), "records_processed": total_processed, "records_skipped": total_skipped}
421
459
  except Exception as e:
422
460
  logger.warning("imessage read failed on batch %d: %s", batch_num, e, exc_info=True)
423
- return {"status": "error", "error": str(e), "records_processed": total_processed}
461
+ return {"status": "error", "error": str(e), "records_processed": total_processed, "records_skipped": total_skipped}
424
462
 
425
- if not rows:
463
+ rows = batch.rows
464
+ total_skipped += batch.records_skipped
465
+ if batch.scanned_count == 0:
426
466
  break
427
467
 
428
468
  # Persist raw iMessage payloads for traceability and debugging (non-fatal on failure).
@@ -440,7 +480,6 @@ def _run_imessage_sync_impl(
440
480
  logger.warning("[PIPELINE:RAW] iMessage raw write failed (non-fatal): %s", e)
441
481
 
442
482
  normalized_records: List[Any] = []
443
- max_rowid: Optional[int] = None
444
483
  for row in rows:
445
484
  raw = RawRecord(record_id=row["id"], payload=row)
446
485
  validation = parser.validate(raw)
@@ -449,9 +488,6 @@ def _run_imessage_sync_impl(
449
488
  continue
450
489
  norm = parser.parse(raw)
451
490
  normalized_records.append(norm)
452
- rid = row.get("ROWID")
453
- if rid is not None and (max_rowid is None or rid > max_rowid):
454
- max_rowid = rid
455
491
 
456
492
  if normalized_records:
457
493
  mapped_records = _map_normalized_records_with_canonical_mapper(
@@ -484,7 +520,12 @@ def _run_imessage_sync_impl(
484
520
  manager.upsert_message_batch(staging_records, dataset_id, SOURCE_ID_IMESSAGE)
485
521
  except Exception as e:
486
522
  logger.exception("ConversationsTablesManager.upsert_message_batch failed")
487
- return {"status": "error", "error": str(e), "records_processed": total_processed}
523
+ return {
524
+ "status": "error",
525
+ "error": str(e),
526
+ "records_processed": total_processed,
527
+ "records_skipped": total_skipped,
528
+ }
488
529
 
489
530
  canonical_messages = [
490
531
  {
@@ -509,25 +550,27 @@ def _run_imessage_sync_impl(
509
550
 
510
551
  total_processed += len(normalized_records)
511
552
 
512
- if max_rowid is None:
553
+ if batch.max_scanned_rowid is None:
513
554
  # Defensive: avoid infinite loops if no valid rowid in batch.
514
555
  break
515
556
 
516
- final_last_record_id = f"imessage:{max_rowid}"
557
+ final_last_record_id = f"imessage:{batch.max_scanned_rowid}"
517
558
  store.save_checkpoint(IngestionCheckpoint(
518
559
  dataset_id=dataset_id,
519
560
  schema_id=IMESSAGE_SCHEMA_ID,
520
561
  last_record_id=final_last_record_id,
521
- metadata={},
562
+ metadata={"exclude_spam": exclude_spam},
522
563
  ))
523
564
  current_last_record_id = final_last_record_id
524
565
 
525
- if len(rows) < batch_size:
566
+ if batch.scanned_count < batch_size:
526
567
  break
527
568
 
528
569
  return {
529
570
  "status": "ok",
530
571
  "records_processed": total_processed,
572
+ "records_skipped": total_skipped,
573
+ "exclude_spam": exclude_spam,
531
574
  "last_record_id": final_last_record_id,
532
575
  }
533
576