topos-node 1.3.39__tar.gz → 1.3.41__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 (765) hide show
  1. {topos_node-1.3.39/topos_node.egg-info → topos_node-1.3.41}/PKG-INFO +1 -1
  2. {topos_node-1.3.39 → topos_node-1.3.41}/pyproject.toml +1 -1
  3. {topos_node-1.3.39 → topos_node-1.3.41}/topos/__version__.py +2 -2
  4. topos_node-1.3.41/topos/api/ingestion_api.py +155 -0
  5. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/__init__.py +1 -0
  6. topos_node-1.3.41/topos/core/handlers/graph_summary.py +76 -0
  7. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/ingest.py +72 -0
  8. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/privacy_layer.py +52 -7
  9. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/entities_job.py +14 -1
  10. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/orchestrator.py +35 -5
  11. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/projection.py +9 -1
  12. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/edges.py +12 -2
  13. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/graph_refresh.py +55 -0
  14. topos_node-1.3.41/topos/features/signal/conversation_windows.py +263 -0
  15. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/canonical_pipeline.py +73 -0
  16. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/ingest_helpers.py +16 -1
  17. topos_node-1.3.41/topos/ingestion/local_exports.py +713 -0
  18. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/manager.py +180 -6
  19. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/chatgpt_export.py +46 -1
  20. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/triggers/file_trigger.py +23 -2
  21. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/job_runner.py +43 -1
  22. {topos_node-1.3.39 → topos_node-1.3.41}/topos/protocol/handled_message_types.json +3 -0
  23. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/retrieval.py +16 -1
  24. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/file_store.py +21 -1
  25. {topos_node-1.3.39 → topos_node-1.3.41}/topos/upgrades/manifests.json +27 -0
  26. {topos_node-1.3.39 → topos_node-1.3.41/topos_node.egg-info}/PKG-INFO +1 -1
  27. {topos_node-1.3.39 → topos_node-1.3.41}/topos_node.egg-info/SOURCES.txt +3 -0
  28. topos_node-1.3.39/topos/api/ingestion_api.py +0 -80
  29. {topos_node-1.3.39 → topos_node-1.3.41}/LICENSE +0 -0
  30. {topos_node-1.3.39 → topos_node-1.3.41}/MANIFEST.in +0 -0
  31. {topos_node-1.3.39 → topos_node-1.3.41}/README.md +0 -0
  32. {topos_node-1.3.39 → topos_node-1.3.41}/setup.cfg +0 -0
  33. {topos_node-1.3.39 → topos_node-1.3.41}/shared/__init__.py +0 -0
  34. {topos_node-1.3.39 → topos_node-1.3.41}/shared/filtering.py +0 -0
  35. {topos_node-1.3.39 → topos_node-1.3.41}/shared/schema_registry.py +0 -0
  36. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_active_database_binding.py +0 -0
  37. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_active_ingestion_binding.py +0 -0
  38. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_extensions.py +0 -0
  39. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_gate_leg_hermeticity.py +0 -0
  40. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_llm_integrations_storage.py +0 -0
  41. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_local_gate_composition.py +0 -0
  42. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_owner_database_hermeticity.py +0 -0
  43. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_prewarm_first_run.py +0 -0
  44. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_profile_hygiene.py +0 -0
  45. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_profiles.py +0 -0
  46. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_protocol_handled_types.py +0 -0
  47. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_query_field_contract.py +0 -0
  48. {topos_node-1.3.39 → topos_node-1.3.41}/tests/test_system_computer_name.py +0 -0
  49. {topos_node-1.3.39 → topos_node-1.3.41}/topos/__init__.py +0 -0
  50. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/__init__.py +0 -0
  51. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/dataset_resolution.py +0 -0
  52. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/duckdb_adapter.py +0 -0
  53. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/luck_surface.py +0 -0
  54. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/messenger_communities.py +0 -0
  55. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/messenger_directed.py +0 -0
  56. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/messenger_graph.py +0 -0
  57. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/messenger_labels.py +0 -0
  58. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/person_graph.py +0 -0
  59. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/person_overlay.py +0 -0
  60. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/profiles.py +0 -0
  61. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/query_engine.py +0 -0
  62. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/raw_queries.py +0 -0
  63. {topos_node-1.3.39 → topos_node-1.3.41}/topos/analytics/relationship_reads.py +0 -0
  64. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/__init__.py +0 -0
  65. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/analytics.py +0 -0
  66. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/app_registry.py +0 -0
  67. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/backup.py +0 -0
  68. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/community_naming_config.py +0 -0
  69. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/compute_remote.py +0 -0
  70. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/connected_apps.py +0 -0
  71. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/conversation_context.py +0 -0
  72. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/data_commit.py +0 -0
  73. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/data_explorer_table_prefs.py +0 -0
  74. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/database_explorer.py +0 -0
  75. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/db.py +0 -0
  76. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/device.py +0 -0
  77. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/disk_space_config.py +0 -0
  78. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/engine_run.py +0 -0
  79. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/enrichment.py +0 -0
  80. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/enrichment_lab.py +0 -0
  81. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/facts_llm_config.py +0 -0
  82. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/filter_lab.py +0 -0
  83. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/health.py +0 -0
  84. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/home_chat.py +0 -0
  85. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/ingestion_compat.py +0 -0
  86. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/ingestion_sources.py +0 -0
  87. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/intelligence_lifecycle.py +0 -0
  88. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/llm.py +0 -0
  89. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/local_mcp.py +0 -0
  90. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/messenger_analytics.py +0 -0
  91. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/privacy_disclose.py +0 -0
  92. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/query_api.py +0 -0
  93. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/runtime_bootstrap.py +0 -0
  94. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/sanitization_ollama_config.py +0 -0
  95. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/shell.py +0 -0
  96. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/signal.py +0 -0
  97. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/signal_extraction_config.py +0 -0
  98. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/source_install.py +0 -0
  99. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/source_scrub.py +0 -0
  100. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/sources.py +0 -0
  101. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/sources_overview.py +0 -0
  102. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/sync.py +0 -0
  103. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/tool_index.py +0 -0
  104. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/ui_config.py +0 -0
  105. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/uma_data.py +0 -0
  106. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/upgrades.py +0 -0
  107. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/usage.py +0 -0
  108. {topos_node-1.3.39 → topos_node-1.3.41}/topos/api/user_identity.py +0 -0
  109. {topos_node-1.3.39 → topos_node-1.3.41}/topos/app.py +0 -0
  110. {topos_node-1.3.39 → topos_node-1.3.41}/topos/auth.py +0 -0
  111. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/__init__.py +0 -0
  112. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/declared_field_map.py +0 -0
  113. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/__init__.py +0 -0
  114. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/base.py +0 -0
  115. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  116. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  117. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  118. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  119. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  120. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  121. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  122. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  123. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/models.py +0 -0
  124. {topos_node-1.3.39 → topos_node-1.3.41}/topos/canonicalization/resolver.py +0 -0
  125. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/__init__.py +0 -0
  126. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/__main__.py +0 -0
  127. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/assets/topos_blk_rounded.png +0 -0
  128. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/assets/topos_white.png +0 -0
  129. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/commands.py +0 -0
  130. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/profile_cmd.py +0 -0
  131. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/reprocess_cmd.py +0 -0
  132. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/setup_models_cmd.py +0 -0
  133. {topos_node-1.3.39 → topos_node-1.3.41}/topos/cli/tray.py +0 -0
  134. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/__init__.py +0 -0
  135. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/conversation_context_llm.py +0 -0
  136. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/facts_llm.py +0 -0
  137. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/local_model_builds.py +0 -0
  138. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/model_packs.py +0 -0
  139. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/node_function_providers.py +0 -0
  140. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/sanitization_ollama.py +0 -0
  141. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/settings.py +0 -0
  142. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/signal_extraction.py +0 -0
  143. {topos_node-1.3.39 → topos_node-1.3.41}/topos/config/uvicorn_logging.json +0 -0
  144. {topos_node-1.3.39 → topos_node-1.3.41}/topos/contacts/__init__.py +0 -0
  145. {topos_node-1.3.39 → topos_node-1.3.41}/topos/contacts/identity.py +0 -0
  146. {topos_node-1.3.39 → topos_node-1.3.41}/topos/control_plane_client.py +0 -0
  147. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/__init__.py +0 -0
  148. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/api_models.py +0 -0
  149. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/connection_resilience.py +0 -0
  150. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/db_health.py +0 -0
  151. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/device_helpers.py +0 -0
  152. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/errors.py +0 -0
  153. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/events.py +0 -0
  154. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/common.py +0 -0
  155. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/complexity.py +0 -0
  156. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/config.py +0 -0
  157. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/contacts_import.py +0 -0
  158. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/database_explorer.py +0 -0
  159. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/derivation.py +0 -0
  160. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/device.py +0 -0
  161. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/enrichment.py +0 -0
  162. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/enrichment_lab.py +0 -0
  163. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/filter_lab.py +0 -0
  164. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/graph_query.py +0 -0
  165. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/home_chat.py +0 -0
  166. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/mcp_client_elevations.py +0 -0
  167. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/mcp_clients.py +0 -0
  168. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/messages.py +0 -0
  169. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/messenger_analytics.py +0 -0
  170. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/query.py +0 -0
  171. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/registry.py +0 -0
  172. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/routines.py +0 -0
  173. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/signal_features.py +0 -0
  174. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/sources.py +0 -0
  175. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/timeline_daily.py +0 -0
  176. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/tool_index.py +0 -0
  177. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/handlers/uma.py +0 -0
  178. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/logging.py +0 -0
  179. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/metrics.py +0 -0
  180. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/routine_access.py +0 -0
  181. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/startup_banner.py +0 -0
  182. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/state.py +0 -0
  183. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/table_layers.py +0 -0
  184. {topos_node-1.3.39 → topos_node-1.3.41}/topos/core/types.py +0 -0
  185. {topos_node-1.3.39 → topos_node-1.3.41}/topos/data_explorer_row_delete.py +0 -0
  186. {topos_node-1.3.39 → topos_node-1.3.41}/topos/data_explorer_table_prefs.py +0 -0
  187. {topos_node-1.3.39 → topos_node-1.3.41}/topos/data_explorer_tables.py +0 -0
  188. {topos_node-1.3.39 → topos_node-1.3.41}/topos/defaults.py +0 -0
  189. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/__init__.py +0 -0
  190. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/canonical_writer.py +0 -0
  191. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/content_policy.py +0 -0
  192. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/field_registry.py +0 -0
  193. {topos_node-1.3.39 → topos_node-1.3.41}/topos/disclosure/tier.py +0 -0
  194. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/__init__.py +0 -0
  195. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/__init__.py +0 -0
  196. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/base.py +0 -0
  197. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/generative_prompts.py +0 -0
  198. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/generative_response.py +0 -0
  199. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/huggingface.py +0 -0
  200. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/ollama.py +0 -0
  201. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/openai.py +0 -0
  202. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/openai_compatible.py +0 -0
  203. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/redpill.py +0 -0
  204. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/backends/stub.py +0 -0
  205. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/client.py +0 -0
  206. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/disk_space.py +0 -0
  207. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/engine.py +0 -0
  208. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/hosted_llm_wallet.py +0 -0
  209. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/intake.py +0 -0
  210. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/memory_utils.py +0 -0
  211. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/model_cache.py +0 -0
  212. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/model_manager.py +0 -0
  213. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/ollama_install.py +0 -0
  214. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/ollama_pull.py +0 -0
  215. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/ollama_runtime.py +0 -0
  216. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/ollama_setup_guidance.py +0 -0
  217. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/pipeline_memory.py +0 -0
  218. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/queue_manager.py +0 -0
  219. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/registration.py +0 -0
  220. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/result_formatter.py +0 -0
  221. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/router.py +0 -0
  222. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/scoped_token.py +0 -0
  223. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/tasks.py +0 -0
  224. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/torch_runtime.py +0 -0
  225. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/transport.py +0 -0
  226. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/usage_guard.py +0 -0
  227. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/usage_observation.py +0 -0
  228. {topos_node-1.3.39 → topos_node-1.3.41}/topos/engine/validator.py +0 -0
  229. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/__init__.py +0 -0
  230. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/catalog.py +0 -0
  231. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/derivation_recovery.py +0 -0
  232. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/derived_tables.py +0 -0
  233. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/job_readiness.py +0 -0
  234. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/job_writer.py +0 -0
  235. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/__init__.py +0 -0
  236. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/base.py +0 -0
  237. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  238. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  239. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  240. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  241. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  242. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  243. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  244. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  245. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
  246. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  247. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  248. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  249. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  250. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  251. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  252. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  253. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  254. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  255. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  256. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  257. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  258. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/raw/__init__.py +0 -0
  259. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  260. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/raw/language_job.py +0 -0
  261. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  262. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  263. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/model_overrides.py +0 -0
  264. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/models/__init__.py +0 -0
  265. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/models/manager.py +0 -0
  266. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/models/mvp_defaults.py +0 -0
  267. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/models/registry.py +0 -0
  268. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/models/versioning.py +0 -0
  269. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/pipeline_activity.py +0 -0
  270. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/processor.py +0 -0
  271. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/progress_bar.py +0 -0
  272. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/record_progress.py +0 -0
  273. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/registry_contract.py +0 -0
  274. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/signal_derivation_config.json +0 -0
  275. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment/source_overrides.py +0 -0
  276. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/__init__.py +0 -0
  277. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/bundles.py +0 -0
  278. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/model_resolve.py +0 -0
  279. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/schema.py +0 -0
  280. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/service.py +0 -0
  281. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/store.py +0 -0
  282. {topos_node-1.3.39 → topos_node-1.3.41}/topos/enrichment_lab/worker.py +0 -0
  283. {topos_node-1.3.39 → topos_node-1.3.41}/topos/evals/__init__.py +0 -0
  284. {topos_node-1.3.39 → topos_node-1.3.41}/topos/evals/enrichment_eval.py +0 -0
  285. {topos_node-1.3.39 → topos_node-1.3.41}/topos/extensions.py +0 -0
  286. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/__init__.py +0 -0
  287. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/canonical.py +0 -0
  288. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/engine.py +0 -0
  289. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/entropy.py +0 -0
  290. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/focus.py +0 -0
  291. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/graph_metrics.py +0 -0
  292. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/influence.py +0 -0
  293. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/snapshots.py +0 -0
  294. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/store.py +0 -0
  295. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/topic_merge.py +0 -0
  296. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/topics.py +0 -0
  297. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/topics_daily.py +0 -0
  298. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/complexity/volatility.py +0 -0
  299. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/__init__.py +0 -0
  300. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  301. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  302. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
  303. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  304. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  305. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  306. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  307. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  308. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  309. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  310. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  311. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  312. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  313. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
  314. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  315. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  316. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  317. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  318. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  319. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  320. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
  321. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
  322. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  323. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
  324. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  325. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  326. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  327. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  328. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  329. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  330. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  331. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  332. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  333. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  334. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  335. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
  336. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/candidates.py +0 -0
  337. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/guard.py +0 -0
  338. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/kernels.py +0 -0
  339. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/net_subject_policy.py +0 -0
  340. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/packs.py +0 -0
  341. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/person_bridge.py +0 -0
  342. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/prefilter.py +0 -0
  343. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/registry.py +0 -0
  344. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/report_card.py +0 -0
  345. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/router.py +0 -0
  346. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/social_bench.py +0 -0
  347. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/social_kernels.py +0 -0
  348. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/surfaces.py +0 -0
  349. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/synthesize.py +0 -0
  350. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/template.py +0 -0
  351. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/verify.py +0 -0
  352. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/derivation/writer.py +0 -0
  353. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/__init__.py +0 -0
  354. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/affinity.py +0 -0
  355. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/affinity_owner.py +0 -0
  356. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/affinity_quality.py +0 -0
  357. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/chatgpt_declared.py +0 -0
  358. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/community_names.py +0 -0
  359. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/community_naming.py +0 -0
  360. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/consolidation.py +0 -0
  361. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/context_vectors.py +0 -0
  362. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/cypher.py +0 -0
  363. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/declared_mappings.py +0 -0
  364. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/dossier.py +0 -0
  365. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/fact_materializer.py +0 -0
  366. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/graph_enrichers.py +0 -0
  367. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/graph_search.py +0 -0
  368. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/linking.py +0 -0
  369. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/maintenance.py +0 -0
  370. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/owner.py +0 -0
  371. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/reads.py +0 -0
  372. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/rebuild_subprocess.py +0 -0
  373. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/resolver.py +0 -0
  374. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/entities/structured_fields.py +0 -0
  375. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/__init__.py +0 -0
  376. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/extract.py +0 -0
  377. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/llm_extract.py +0 -0
  378. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/reads.py +0 -0
  379. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/store.py +0 -0
  380. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/facts/verdicts.py +0 -0
  381. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/fit/evaluator.py +0 -0
  382. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/fit/opportunity_types.json +0 -0
  383. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/__init__.py +0 -0
  384. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/blackhole.py +0 -0
  385. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/blackhole_guard.py +0 -0
  386. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/blackhole_llm.py +0 -0
  387. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  388. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/derived_scrub.py +0 -0
  389. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/exclusions.py +0 -0
  390. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/lifecycle/gc.py +0 -0
  391. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/provenance/__init__.py +0 -0
  392. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/provenance/posture.py +0 -0
  393. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/provenance/roles.py +0 -0
  394. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/__init__.py +0 -0
  395. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/brief_canonical_loader.py +0 -0
  396. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/brief_ontology.py +0 -0
  397. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/brief_renderer.py +0 -0
  398. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/brief_schemas.py +0 -0
  399. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/chunking.py +0 -0
  400. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/cluster_labels.py +0 -0
  401. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/conversation_context.py +0 -0
  402. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/data_health.py +0 -0
  403. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  404. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/intentions.json +0 -0
  405. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/interests.json +0 -0
  406. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/memory.json +0 -0
  407. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/places.json +0 -0
  408. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/profile.json +0 -0
  409. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/relationships.json +0 -0
  410. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/resources.json +0 -0
  411. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  412. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/time.json +0 -0
  413. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/wellbeing.json +0 -0
  414. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/definitions/work.json +0 -0
  415. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/derived_index.py +0 -0
  416. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/derived_spec.py +0 -0
  417. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/dimension_briefs.py +0 -0
  418. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/dimension_definition_loader.py +0 -0
  419. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/dimension_profiles.py +0 -0
  420. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/dimension_registry.py +0 -0
  421. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/embed_context.py +0 -0
  422. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/extraction/artifact_router.py +0 -0
  423. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/extraction/artifact_store.py +0 -0
  424. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/extraction/rule_extractors.py +0 -0
  425. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/graph_sanitize.py +0 -0
  426. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/hybrid_search.py +0 -0
  427. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/incremental_clustering.py +0 -0
  428. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/model_recommendations.py +0 -0
  429. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/query_embed_cache.py +0 -0
  430. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/schemas.py +0 -0
  431. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/service.py +0 -0
  432. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/signal_object_store.py +0 -0
  433. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/source_hydration.py +0 -0
  434. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/structured_signal.py +0 -0
  435. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/tool_index.py +0 -0
  436. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/topic_clustering.py +0 -0
  437. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/typed_stores/aggregates.py +0 -0
  438. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/typed_stores/commitments.py +0 -0
  439. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/typed_stores/rhythm.py +0 -0
  440. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  441. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/vector_codec.py +0 -0
  442. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/vector_math.py +0 -0
  443. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/signal/vector_settings.py +0 -0
  444. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/stats/__init__.py +0 -0
  445. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/stats/definitions.py +0 -0
  446. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/stats/engine.py +0 -0
  447. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/stats/fold.py +0 -0
  448. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/stats/insights.py +0 -0
  449. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/timeline_projection.py +0 -0
  450. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/timeline_rollup.py +0 -0
  451. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/__init__.py +0 -0
  452. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/badges.py +0 -0
  453. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/daily.py +0 -0
  454. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/dashboard.py +0 -0
  455. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/instruments.py +0 -0
  456. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/intents.py +0 -0
  457. {topos_node-1.3.39 → topos_node-1.3.41}/topos/features/triage/readiness.py +0 -0
  458. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/__init__.py +0 -0
  459. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/bundles.py +0 -0
  460. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/schema.py +0 -0
  461. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/service.py +0 -0
  462. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/store.py +0 -0
  463. {topos_node-1.3.39 → topos_node-1.3.41}/topos/filter_lab/worker.py +0 -0
  464. {topos_node-1.3.39 → topos_node-1.3.41}/topos/home_chat/__init__.py +0 -0
  465. {topos_node-1.3.39 → topos_node-1.3.41}/topos/home_chat/schema.py +0 -0
  466. {topos_node-1.3.39 → topos_node-1.3.41}/topos/home_chat/store.py +0 -0
  467. {topos_node-1.3.39 → topos_node-1.3.41}/topos/hosted_pool_lease.py +0 -0
  468. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/__init__.py +0 -0
  469. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/checkpoints/__init__.py +0 -0
  470. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  471. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  472. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/inbox_crypto.py +0 -0
  473. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/inbox_drain.py +0 -0
  474. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/jobs.py +0 -0
  475. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/journal_location_fanout.py +0 -0
  476. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/journal_time_log_normalize.py +0 -0
  477. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/local_sync.py +0 -0
  478. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/log_preview.py +0 -0
  479. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parser.py +0 -0
  480. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/__init__.py +0 -0
  481. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/base.py +0 -0
  482. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/browser_parser.py +0 -0
  483. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/calendar_parser.py +0 -0
  484. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  485. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  486. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  487. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/documents_parser.py +0 -0
  488. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  489. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  490. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/grok_parser.py +0 -0
  491. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/messenger_parser.py +0 -0
  492. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  493. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/progress.py +0 -0
  494. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/reprocess.py +0 -0
  495. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/__init__.py +0 -0
  496. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/base.py +0 -0
  497. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/calendar.py +0 -0
  498. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/chatgpt.py +0 -0
  499. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/contact_importers.py +0 -0
  500. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/grok.py +0 -0
  501. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/imessage_reader.py +0 -0
  502. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/signal_export_parser.py +0 -0
  503. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/sources/signal_reader.py +0 -0
  504. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/state_machine.py +0 -0
  505. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/triggers/__init__.py +0 -0
  506. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  507. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  508. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/validation/__init__.py +0 -0
  509. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/validation/base.py +0 -0
  510. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/validation/schema_registry.py +0 -0
  511. {topos_node-1.3.39 → topos_node-1.3.41}/topos/ingestion/validation/schema_validator.py +0 -0
  512. {topos_node-1.3.39 → topos_node-1.3.41}/topos/lineage/__init__.py +0 -0
  513. {topos_node-1.3.39 → topos_node-1.3.41}/topos/lineage/provenance.py +0 -0
  514. {topos_node-1.3.39 → topos_node-1.3.41}/topos/lineage/tracker.py +0 -0
  515. {topos_node-1.3.39 → topos_node-1.3.41}/topos/llm_integrations_storage.py +0 -0
  516. {topos_node-1.3.39 → topos_node-1.3.41}/topos/mcp_clients.py +0 -0
  517. {topos_node-1.3.39 → topos_node-1.3.41}/topos/mcp_stdio_proxy.py +0 -0
  518. {topos_node-1.3.39 → topos_node-1.3.41}/topos/observability/__init__.py +0 -0
  519. {topos_node-1.3.39 → topos_node-1.3.41}/topos/observability/alerts.py +0 -0
  520. {topos_node-1.3.39 → topos_node-1.3.41}/topos/observability/metrics.py +0 -0
  521. {topos_node-1.3.39 → topos_node-1.3.41}/topos/observability/tracing.py +0 -0
  522. {topos_node-1.3.39 → topos_node-1.3.41}/topos/openai_client.py +0 -0
  523. {topos_node-1.3.39 → topos_node-1.3.41}/topos/owner_key.py +0 -0
  524. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/__init__.py +0 -0
  525. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/audit.py +0 -0
  526. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/envelope.py +0 -0
  527. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/job_store.py +0 -0
  528. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/stages.py +0 -0
  529. {topos_node-1.3.39 → topos_node-1.3.41}/topos/pipeline/stub_enqueue.py +0 -0
  530. {topos_node-1.3.39 → topos_node-1.3.41}/topos/principal.py +0 -0
  531. {topos_node-1.3.39 → topos_node-1.3.41}/topos/profiles.py +0 -0
  532. {topos_node-1.3.39 → topos_node-1.3.41}/topos/projections/__init__.py +0 -0
  533. {topos_node-1.3.39 → topos_node-1.3.41}/topos/projections/vector_index/__init__.py +0 -0
  534. {topos_node-1.3.39 → topos_node-1.3.41}/topos/projections/vector_index/base.py +0 -0
  535. {topos_node-1.3.39 → topos_node-1.3.41}/topos/projections/vector_index/builders.py +0 -0
  536. {topos_node-1.3.39 → topos_node-1.3.41}/topos/projections/vector_index/health_checks.py +0 -0
  537. {topos_node-1.3.39 → topos_node-1.3.41}/topos/protocol/__init__.py +0 -0
  538. {topos_node-1.3.39 → topos_node-1.3.41}/topos/protocol/narrowing_vocabulary.json +0 -0
  539. {topos_node-1.3.39 → topos_node-1.3.41}/topos/protocol/query_field_contract.json +0 -0
  540. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/__init__.py +0 -0
  541. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/audit.py +0 -0
  542. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/closeness.py +0 -0
  543. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/cohort_resolvers.py +0 -0
  544. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/collaborators.py +0 -0
  545. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/ddr.py +0 -0
  546. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/disclosure.py +0 -0
  547. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/entity_window.py +0 -0
  548. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/exclusion.py +0 -0
  549. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/facts_direct.py +0 -0
  550. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/fingerprint.py +0 -0
  551. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/game_layer.py +0 -0
  552. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/grant_cache.py +0 -0
  553. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/inference.py +0 -0
  554. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/intent.py +0 -0
  555. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/manifest.py +0 -0
  556. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/manifest_validation.py +0 -0
  557. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/minimizer.py +0 -0
  558. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/narrowing.py +0 -0
  559. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/negotiation.py +0 -0
  560. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/packet_resolution.py +0 -0
  561. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/pipeline.py +0 -0
  562. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/planner.py +0 -0
  563. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/runtime.py +0 -0
  564. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_arbiter.py +0 -0
  565. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_classifier.py +0 -0
  566. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_head.py +0 -0
  567. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_registry.json +0 -0
  568. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_registry_loader.py +0 -0
  569. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/scope_shadow.py +0 -0
  570. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/session.py +0 -0
  571. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/session_utils.py +0 -0
  572. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/source_generation.py +0 -0
  573. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/truth_facts.py +0 -0
  574. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/truth_prompts.py +0 -0
  575. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/turn_classifier.py +0 -0
  576. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/types.py +0 -0
  577. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/verify.py +0 -0
  578. {topos_node-1.3.39 → topos_node-1.3.41}/topos/query/verify_modes.py +0 -0
  579. {topos_node-1.3.39 → topos_node-1.3.41}/topos/rate_limit.py +0 -0
  580. {topos_node-1.3.39 → topos_node-1.3.41}/topos/relay_stamp.py +0 -0
  581. {topos_node-1.3.39 → topos_node-1.3.41}/topos/routines/__init__.py +0 -0
  582. {topos_node-1.3.39 → topos_node-1.3.41}/topos/routines/schema.py +0 -0
  583. {topos_node-1.3.39 → topos_node-1.3.41}/topos/routines/store.py +0 -0
  584. {topos_node-1.3.39 → topos_node-1.3.41}/topos/runtime_housekeeping.py +0 -0
  585. {topos_node-1.3.39 → topos_node-1.3.41}/topos/runtime_shutdown.py +0 -0
  586. {topos_node-1.3.39 → topos_node-1.3.41}/topos/runtime_update.py +0 -0
  587. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sanitization/__init__.py +0 -0
  588. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sanitization/nsfw_classifier.py +0 -0
  589. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sanitization/ollama_transforms.py +0 -0
  590. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sanitization/prewarm.py +0 -0
  591. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sanitization/privacy_filter.py +0 -0
  592. {topos_node-1.3.39 → topos_node-1.3.41}/topos/scope_resolution.py +0 -0
  593. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/__init__.py +0 -0
  594. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/container.py +0 -0
  595. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/embeddings/__init__.py +0 -0
  596. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/embeddings/base.py +0 -0
  597. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/embeddings/local.py +0 -0
  598. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/embeddings/remote.py +0 -0
  599. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/interfaces.py +0 -0
  600. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/llm/__init__.py +0 -0
  601. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/llm/base.py +0 -0
  602. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/llm/openai.py +0 -0
  603. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/local.py +0 -0
  604. {topos_node-1.3.39 → topos_node-1.3.41}/topos/services/postgres.py +0 -0
  605. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/__init__.py +0 -0
  606. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/bundled_canonical_triples.py +0 -0
  607. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/canonical_signal_defaults.py +0 -0
  608. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/declared_field_map_spec.py +0 -0
  609. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/definitions.py +0 -0
  610. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/install_service.py +0 -0
  611. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/registry.py +0 -0
  612. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/runtime_install.py +0 -0
  613. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/scrub_attribution.py +0 -0
  614. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sources/scrub_service.py +0 -0
  615. {topos_node-1.3.39 → topos_node-1.3.41}/topos/startup_banner.py +0 -0
  616. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/__init__.py +0 -0
  617. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/__init__.py +0 -0
  618. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/factory.py +0 -0
  619. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/fakes.py +0 -0
  620. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/postgres/stores.py +0 -0
  621. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/protocols.py +0 -0
  622. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/sqlite/__init__.py +0 -0
  623. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/sqlite/stores.py +0 -0
  624. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  625. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/__init__.py +0 -0
  626. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/activity_tables.py +0 -0
  627. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  628. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  629. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  630. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/ai_chat/model.py +0 -0
  631. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/ai_chat/tables.py +0 -0
  632. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  633. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/canonical_store.py +0 -0
  634. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/conversations_tables.py +0 -0
  635. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/journal_repair.py +0 -0
  636. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/mapping_store.py +0 -0
  637. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/canonical/postgres.py +0 -0
  638. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/__init__.py +0 -0
  639. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/client.py +0 -0
  640. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/connection_tuning.py +0 -0
  641. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/__init__.py +0 -0
  642. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  643. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  644. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  645. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  646. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  647. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/backup.py +0 -0
  648. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/backup_custody.py +0 -0
  649. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  650. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  651. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  652. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  653. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/community_names_v1.py +0 -0
  654. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/complexity_v1.py +0 -0
  655. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
  656. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  657. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  658. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  659. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  660. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
  661. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/documents_v1.py +0 -0
  662. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  663. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  664. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  665. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  666. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  667. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  668. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  669. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  670. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  671. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  672. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  673. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/episodes_v1.py +0 -0
  674. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  675. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
  676. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  677. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  678. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  679. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  680. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  681. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  682. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
  683. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  684. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  685. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
  686. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  687. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  688. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  689. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/registry.py +0 -0
  690. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/registry_checksums.json +0 -0
  691. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  692. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  693. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  694. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  695. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  696. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_objects.py +0 -0
  697. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  698. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  699. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  700. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  701. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  702. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  703. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  704. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  705. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  706. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  707. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  708. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  709. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  710. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  711. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  712. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  713. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  714. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  715. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  716. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  717. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  718. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  719. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/paths.py +0 -0
  720. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/postgres.py +0 -0
  721. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/schema.py +0 -0
  722. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/schema_probe.py +0 -0
  723. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/storage_breakdown.py +0 -0
  724. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/db/write_gate.py +0 -0
  725. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/derived_row_identity.py +0 -0
  726. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/enrichment/__init__.py +0 -0
  727. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  728. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  729. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/normalized/__init__.py +0 -0
  730. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/normalized/normalized_store.py +0 -0
  731. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/oplog/__init__.py +0 -0
  732. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/oplog/decision.py +0 -0
  733. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/oplog/oplog_store.py +0 -0
  734. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/oplog/postgres.py +0 -0
  735. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/person/identity_resolver.py +0 -0
  736. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/projections/__init__.py +0 -0
  737. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/projections/index_ops_store.py +0 -0
  738. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/projections/vector_index_store.py +0 -0
  739. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/__init__.py +0 -0
  740. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/browser_flat_tables.py +0 -0
  741. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/raw_store.py +0 -0
  742. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/raw_tables_manager.py +0 -0
  743. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/raw/sqlite_raw_store.py +0 -0
  744. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/security/encryption.py +0 -0
  745. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/signal_identity.py +0 -0
  746. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/source_settings.py +0 -0
  747. {topos_node-1.3.39 → topos_node-1.3.41}/topos/storage/user_identity.py +0 -0
  748. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sync/__init__.py +0 -0
  749. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sync/client.py +0 -0
  750. {topos_node-1.3.39 → topos_node-1.3.41}/topos/sync_handlers.py +0 -0
  751. {topos_node-1.3.39 → topos_node-1.3.41}/topos/testing/__init__.py +0 -0
  752. {topos_node-1.3.39 → topos_node-1.3.41}/topos/testing/lifespan.py +0 -0
  753. {topos_node-1.3.39 → topos_node-1.3.41}/topos/uds.py +0 -0
  754. {topos_node-1.3.39 → topos_node-1.3.41}/topos/uma_contact_enrichment.py +0 -0
  755. {topos_node-1.3.39 → topos_node-1.3.41}/topos/uma_filters.py +0 -0
  756. {topos_node-1.3.39 → topos_node-1.3.41}/topos/uma_resource_id.py +0 -0
  757. {topos_node-1.3.39 → topos_node-1.3.41}/topos/uma_rpt.py +0 -0
  758. {topos_node-1.3.39 → topos_node-1.3.41}/topos/upgrades/__init__.py +0 -0
  759. {topos_node-1.3.39 → topos_node-1.3.41}/topos/upgrades/runner.py +0 -0
  760. {topos_node-1.3.39 → topos_node-1.3.41}/topos/utils/base_object.py +0 -0
  761. {topos_node-1.3.39 → topos_node-1.3.41}/topos/websocket_client.py +0 -0
  762. {topos_node-1.3.39 → topos_node-1.3.41}/topos_node.egg-info/dependency_links.txt +0 -0
  763. {topos_node-1.3.39 → topos_node-1.3.41}/topos_node.egg-info/entry_points.txt +0 -0
  764. {topos_node-1.3.39 → topos_node-1.3.41}/topos_node.egg-info/requires.txt +0 -0
  765. {topos_node-1.3.39 → topos_node-1.3.41}/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.39
3
+ Version: 1.3.41
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.39"
7
+ version = "1.3.41"
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.39"
4
- __version_info__ = (1, 3, 39)
3
+ __version__ = "1.3.41"
4
+ __version_info__ = (1, 3, 41)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -0,0 +1,155 @@
1
+ from __future__ import annotations
2
+
3
+ from fastapi import APIRouter, Body, Depends, HTTPException, Request
4
+
5
+ from ..auth import require_api_key
6
+ from ..ingestion.reprocess import reprocess_source
7
+ from .ingestion_sources import ingest_source
8
+
9
+ router = APIRouter()
10
+
11
+
12
+ @router.post("/ingestion/start")
13
+ async def start_ingestion() -> dict:
14
+ return {"status": "stub"}
15
+
16
+
17
+ @router.post("/ingestion/progress")
18
+ async def report_progress() -> dict:
19
+ return {"status": "stub"}
20
+
21
+
22
+ @router.post("/ingestion/reprocess", dependencies=[Depends(require_api_key)])
23
+ async def ingestion_reprocess(payload: dict = Body(default_factory=dict)) -> dict:
24
+ """Re-run raw→canonical for a source (optional newest-N via ``limit``).
25
+
26
+ Body:
27
+ - source_id (required)
28
+ - dataset_id (required)
29
+ - from_stage: ``raw`` (default) | ``canonical``
30
+ - limit: optional int — newest N raw rows only
31
+ - run_enrichment: optional bool (default true)
32
+ - force / sync_batch_id: optional
33
+ """
34
+ try:
35
+ limit_raw = payload.get("limit")
36
+ limit = int(limit_raw) if limit_raw is not None and str(limit_raw).strip() != "" else None
37
+ return await reprocess_source(
38
+ source_id=str(payload["source_id"]),
39
+ dataset_id=str(payload["dataset_id"]),
40
+ from_stage=payload.get("from_stage") or "raw",
41
+ sync_batch_id=payload.get("sync_batch_id"),
42
+ force=bool(payload.get("force", False)),
43
+ limit=limit,
44
+ run_enrichment=bool(payload.get("run_enrichment", True)),
45
+ )
46
+ except KeyError as exc:
47
+ raise HTTPException(status_code=400, detail=f"Missing field: {exc}") from exc
48
+ except ValueError as exc:
49
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
50
+
51
+
52
+ @router.get("/ingestion/audit", dependencies=[Depends(require_api_key)])
53
+ async def get_ingestion_audit(sync_batch_id: str) -> dict:
54
+ from ..core.state import get_db_connection
55
+ from ..pipeline.audit import SQLiteIngestAuditStore
56
+
57
+ conn = get_db_connection()
58
+ if not conn:
59
+ raise HTTPException(status_code=503, detail="Database unavailable")
60
+ store = SQLiteIngestAuditStore(conn)
61
+ return {"sync_batch_id": sync_batch_id, "stages": store.query_by_batch(sync_batch_id)}
62
+
63
+
64
+ @router.post("/ingestion/upload", dependencies=[Depends(require_api_key)])
65
+ async def upload_ingestion_file(request: Request) -> dict:
66
+ return await ingest_source("chatgpt_file_ingestion", request)
67
+
68
+
69
+ @router.get("/ingestion/local-exports", dependencies=[Depends(require_api_key)])
70
+ async def list_local_exports() -> dict:
71
+ """Exports sitting on this machine, for the import screen to offer.
72
+
73
+ The node is the only party that can answer this: a browser cannot read a
74
+ filesystem, and cannot produce an absolute path even for a file the user
75
+ picks. So the node looks, and hands back opaque handles plus labels a person
76
+ can recognise -- never the paths themselves.
77
+
78
+ Bounded and stateless by construction (see ``local_exports``): a few known
79
+ folders, shallow, symlinks skipped, time-boxed, nothing written down.
80
+ """
81
+ import asyncio
82
+
83
+ from ..ingestion.local_exports import find_exports
84
+
85
+ result = await asyncio.to_thread(find_exports)
86
+ return result.as_payload()
87
+
88
+
89
+ @router.get("/ingestion/local-exports/{handle}/describe", dependencies=[Depends(require_api_key)])
90
+ async def describe_local_export(handle: str) -> dict:
91
+ """What is inside one discovered export: conversation count and date range.
92
+
93
+ Separate from discovery on purpose. Listing candidates reads only an
94
+ archive's central directory and stays in the low hundreds of milliseconds;
95
+ this opens the conversations file and parses it, which is about a second on
96
+ a 52 MB export. Paying that for every row of a scan to inform a choice about
97
+ one of them would be the wrong trade.
98
+
99
+ It exists because a window is measured against today while an export is
100
+ fixed in the past, and nothing in the UI could see the gap: a six-month
101
+ window against a fourteen-month-old export drops every conversation and
102
+ completes successfully with nothing imported.
103
+ """
104
+ import asyncio
105
+
106
+ from ..ingestion.local_exports import describe_export, resolve
107
+
108
+ path = await asyncio.to_thread(resolve, handle)
109
+ if path is None:
110
+ raise HTTPException(
111
+ status_code=404,
112
+ detail="That export is no longer where we found it. Scan again and pick it.",
113
+ )
114
+ try:
115
+ return await asyncio.to_thread(describe_export, path)
116
+ except Exception as exc: # noqa: BLE001 — a describe failure must not block the import
117
+ raise HTTPException(status_code=422, detail=f"Could not read that export: {exc}") from exc
118
+
119
+
120
+ @router.post("/ingestion/upload-local-path", dependencies=[Depends(require_api_key)])
121
+ async def upload_ingestion_local_path(
122
+ request: Request, payload: dict = Body(default_factory=dict)
123
+ ) -> dict:
124
+ """Ingest a file that is already on this machine. No bytes cross a network.
125
+
126
+ Accepts either a ``handle`` from ``/ingestion/local-exports`` -- the path
127
+ never leaves the node -- or an explicit ``file_path``, which is still how
128
+ someone points at an export outside the searched folders.
129
+ """
130
+ from ..ingestion.local_exports import resolve
131
+
132
+ dataset_id = payload.get("dataset_id")
133
+ file_path = payload.get("file_path")
134
+ handle = str(payload.get("handle") or "").strip()
135
+
136
+ if handle and not file_path:
137
+ resolved = resolve(handle)
138
+ if resolved is None:
139
+ # Handles are re-found rather than remembered, so a stale one means
140
+ # the file moved or went away -- not that the user did anything odd.
141
+ raise HTTPException(
142
+ status_code=404,
143
+ detail="That export is no longer where we found it. Scan again and pick it.",
144
+ )
145
+ file_path = str(resolved)
146
+
147
+ if not file_path:
148
+ raise HTTPException(status_code=400, detail="Provide a handle or a file_path.")
149
+
150
+ return await ingest_source(
151
+ "chatgpt_file_ingestion",
152
+ request,
153
+ dataset_id=dataset_id,
154
+ file_path=file_path,
155
+ )
@@ -170,6 +170,7 @@ from . import ( # noqa: F401 (imported for handler registration side effects)
170
170
  complexity,
171
171
  timeline_daily,
172
172
  graph_query,
173
+ graph_summary,
173
174
  )
174
175
 
175
176
 
@@ -0,0 +1,76 @@
1
+ """How much is in the graph — the smallest possible answer.
2
+
3
+ Why this exists rather than a count taken from ``/v1/signal/graph``: that
4
+ endpoint returns node and edge LISTS, capped at 200 and 500, and no totals. To
5
+ learn "how many" from it you would fetch rows you throw away, and still not
6
+ know the answer once the graph passed the cap.
7
+
8
+ Why not carry the number on the ingestion job instead: the progress channel is
9
+ a fixed set of columns on the control plane's ``ingestion_jobs`` table, with no
10
+ JSON field, and ``stage_event`` is filtered down to four keys. Adding it there
11
+ means a schema migration on the production database — a real cost to pay for a
12
+ reassurance line, and a change that is hard to take back.
13
+
14
+ So: three COUNT(*) queries, read on demand, owned by nothing.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import asyncio
20
+ from typing import Any, Dict, Optional
21
+
22
+ from .registry import handles
23
+
24
+
25
+ def _counts() -> Dict[str, Any]:
26
+ from ...core.state import get_db_connection
27
+
28
+ conn = get_db_connection()
29
+ if conn is None:
30
+ return {"available": False}
31
+
32
+ out: Dict[str, Any] = {"available": True}
33
+ # Each table is counted independently and a failure on one is not a failure
34
+ # of the reply: a missing table on an older node should cost that number,
35
+ # not the whole answer.
36
+ for key, table in (
37
+ ("nodes", "graph_nodes"),
38
+ ("edges", "graph_edges"),
39
+ ("entities", "entities"),
40
+ ):
41
+ try:
42
+ row = conn.execute(f"SELECT COUNT(*) FROM {table}").fetchone() # noqa: S608 — fixed names
43
+ out[key] = int(row[0]) if row else 0
44
+ except Exception: # noqa: BLE001
45
+ out[key] = None
46
+ try:
47
+ # The column is `last_run_at` -- what _mark_materialized writes. This read
48
+ # `materialized_at`, which does not exist, and the per-field try/except
49
+ # turned that into a permanent null rather than an error: shipped in
50
+ # 1.3.40 and noticed only because the live reply carried the null.
51
+ row = conn.execute(
52
+ "SELECT MAX(last_run_at) FROM graph_materialization_state"
53
+ ).fetchone()
54
+ out["materialized_at"] = row[0] if row else None
55
+ except Exception: # noqa: BLE001
56
+ out["materialized_at"] = None
57
+ return out
58
+
59
+
60
+ @handles("graph_summary")
61
+ async def handle_graph_summary(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
62
+ """Node, edge and entity counts, for a screen that wants to show growth.
63
+
64
+ The reason it is worth showing during an import: entity data lands at the
65
+ third of twenty stages and the graph is materialised twice, so these numbers
66
+ move long before the import finishes. Watching them move is the difference
67
+ between a long wait and a long wait you can see the point of.
68
+ """
69
+ req_id = message.get("id")
70
+ if not req_id:
71
+ return None
72
+ try:
73
+ payload = await asyncio.to_thread(_counts)
74
+ return {"id": req_id, "status": "ok", "payload": payload}
75
+ except Exception as exc: # noqa: BLE001
76
+ return {"id": req_id, "status": "error", "error": str(exc)}
@@ -365,6 +365,22 @@ async def handle_start_ingestion(message: Dict[str, Any]) -> Optional[Dict[str,
365
365
  file_url = payload.get("file_url")
366
366
  file_base64 = payload.get("file_base64")
367
367
  file_path = payload.get("file_path")
368
+ local_handle = str(payload.get("local_export_handle") or "").strip()
369
+ if local_handle and not file_path:
370
+ # A handle from `list_local_exports`. The path was never sent to the
371
+ # browser, so it is resolved here — and only ever to something still
372
+ # inside a searched folder, which is what makes a handle safe to accept
373
+ # back over the relay.
374
+ from ...ingestion.local_exports import resolve as _resolve_local_export
375
+
376
+ resolved = _resolve_local_export(local_handle)
377
+ if resolved is None:
378
+ return {
379
+ "id": req_id,
380
+ "status": "error",
381
+ "error": "That export is no longer where we found it. Scan again and pick it.",
382
+ }
383
+ file_path = str(resolved)
368
384
  job_id = payload.get("job_id")
369
385
  source_id = payload.get("source_id") # Optional source_id from control plane
370
386
  source_definition = payload.get("source_definition")
@@ -481,6 +497,62 @@ async def handle_ingestion_reprocess(message: Dict[str, Any]) -> Optional[Dict[s
481
497
  except Exception as exc: # noqa: BLE001
482
498
  return {"id": req_id, "status": "error", "error": str(exc)}
483
499
 
500
+ @handles("list_local_exports")
501
+ async def handle_list_local_exports(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
502
+ """Exports sitting on this machine, for the import screen to offer.
503
+
504
+ Only the node can answer this. A browser cannot read a filesystem, and
505
+ cannot produce an absolute path even for a file the user picks — so without
506
+ this the only way to reach the free import path was to type one out by hand.
507
+
508
+ What comes back is opaque handles and labels a person can recognise, never
509
+ paths: the reply travels to the browser over the relay, and a home-directory
510
+ path carries the account name and whatever else lives beside it.
511
+ """
512
+ req_id = message.get("id")
513
+ if not req_id:
514
+ return None
515
+ try:
516
+ import asyncio
517
+
518
+ from ...ingestion.local_exports import find_exports
519
+
520
+ result = await asyncio.to_thread(find_exports)
521
+ return {"id": req_id, "status": "ok", "payload": result.as_payload()}
522
+ except Exception as exc: # noqa: BLE001
523
+ return {"id": req_id, "status": "error", "error": str(exc)}
524
+
525
+
526
+ @handles("describe_local_export")
527
+ async def handle_describe_local_export(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
528
+ """Conversation count and date range for one discovered export.
529
+
530
+ The window a person picks is measured from today; the export is fixed in
531
+ the past. Nothing in the UI could see that gap, so a six-month window
532
+ against a fourteen-month-old file imported nothing and said it succeeded.
533
+ This is the number that closes it, read where the dates are.
534
+ """
535
+ req_id = message.get("id")
536
+ if not req_id:
537
+ return None
538
+ payload = message.get("payload") or {}
539
+ handle = str(payload.get("handle") or "").strip()
540
+ if not handle:
541
+ return {"id": req_id, "status": "error", "error": "handle required"}
542
+ try:
543
+ import asyncio
544
+
545
+ from ...ingestion.local_exports import describe_export, resolve
546
+
547
+ path = await asyncio.to_thread(resolve, handle)
548
+ if path is None:
549
+ return {"id": req_id, "status": "error", "error": "export no longer found"}
550
+ described = await asyncio.to_thread(describe_export, path)
551
+ return {"id": req_id, "status": "ok", "payload": described}
552
+ except Exception as exc: # noqa: BLE001
553
+ return {"id": req_id, "status": "error", "error": str(exc)}
554
+
555
+
484
556
  @handles("get_ingestion_audit")
485
557
  async def handle_get_ingestion_audit(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
486
558
  req_id = message.get("id")
@@ -169,13 +169,36 @@ class PrivacyLayerClient:
169
169
  return {"status": "failed", "error": str(last_exc), "items": []}
170
170
 
171
171
 
172
+ # Names for the two model passes below. They are reported to the caller's
173
+ # progress callback and surface verbatim in the UI, so they are written for a
174
+ # person watching an import rather than for a log grep.
175
+ #
176
+ # "Filtering private information" rather than "checking for private details":
177
+ # this pass does not merely look. It detects PII spans and REDACTS them into
178
+ # the disclosure copy, which is the whole point of the layer — the node is
179
+ # preparing what it can safely show. A name that says "checking" describes an
180
+ # inspection and undersells the thing the product actually does for you.
181
+ PRIVACY_STAGE_REDACT = "filtering private information"
182
+ PRIVACY_STAGE_NSFW = "checking for sensitive content"
183
+
184
+ # How many records to send per call. NOT a throughput choice: both engine
185
+ # backends (redact_privacy_batch, classify_nsfw_batch) loop over `items` one at
186
+ # a time, so grouping 32 records buys no batched inference -- it is purely
187
+ # transport. The only thing the group size decides is how often progress can
188
+ # move. Measured on a live import: ~3.75s per record on CPU, so a group of 32
189
+ # meant the bar stepped once every two minutes and read as frozen; at 4 it
190
+ # moves about every fifteen seconds. The per-call overhead is a dict and a
191
+ # thread hop against ~15s of model work.
192
+ PRIVACY_PROGRESS_CHUNK = 4
193
+
194
+
172
195
  async def run_privacy_disclosure_layer(
173
196
  conn,
174
197
  canonical_messages: List[Dict[str, Any]],
175
198
  *,
176
199
  source_group: Optional[str] = None,
177
200
  client: Optional[PrivacyLayerClient] = None,
178
- progress_callback: Optional[Callable[[int, int], None]] = None,
201
+ progress_callback: Optional[Callable[[int, int, str], None]] = None,
179
202
  nsfw_only: bool = False,
180
203
  ) -> Dict[str, Any]:
181
204
  """Mandatory post-canonical Platform Privacy Layer: PII disclosure + NSFW tags.
@@ -242,7 +265,7 @@ async def run_privacy_disclosure_layer(
242
265
  table = canonical_table_for_message(msg, source_group=source_group)
243
266
  if not table:
244
267
  if progress_callback:
245
- progress_callback(idx + 1, total)
268
+ progress_callback(idx + 1, total, PRIVACY_STAGE_REDACT)
246
269
  continue
247
270
  record_id = (
248
271
  msg.get("message_id")
@@ -252,7 +275,7 @@ async def run_privacy_disclosure_layer(
252
275
  )
253
276
  if not record_id:
254
277
  if progress_callback:
255
- progress_callback(idx + 1, total)
278
+ progress_callback(idx + 1, total, PRIVACY_STAGE_REDACT)
256
279
  continue
257
280
  record_id = str(record_id)
258
281
  for field in fields_for_table(table):
@@ -284,10 +307,24 @@ async def run_privacy_disclosure_layer(
284
307
 
285
308
  from ..sanitization.privacy_filter import PRIVACY_DISCLOSE_MAX_BATCH
286
309
 
287
- for i in range(0, len(flat_pending), PRIVACY_DISCLOSE_MAX_BATCH):
288
- batch = flat_pending[i : i + PRIVACY_DISCLOSE_MAX_BATCH]
310
+ # Report against the batched work, not the message list: this loop is
311
+ # where the model time goes, and the old callback fired only on the
312
+ # branches that SKIP a message -- so a run with nothing to skip
313
+ # reported nothing at all, for its entire duration.
314
+ _redact_total = len(flat_pending)
315
+ _redact_done = 0
316
+ _redact_chunk = min(PRIVACY_DISCLOSE_MAX_BATCH, PRIVACY_PROGRESS_CHUNK)
317
+ for i in range(0, len(flat_pending), _redact_chunk):
318
+ batch = flat_pending[i : i + _redact_chunk]
289
319
  items = [{"id": e["batch_key"], "text": e["raw"]} for e in batch]
320
+ if progress_callback:
321
+ progress_callback(_redact_done, _redact_total, PRIVACY_STAGE_REDACT)
290
322
  result = await privacy_client.redact_batch(items)
323
+ _redact_done += len(batch)
324
+ # Also after: without this the final group never reports, and the
325
+ # stage appears to stop one group short of its own total.
326
+ if progress_callback:
327
+ progress_callback(_redact_done, _redact_total, PRIVACY_STAGE_REDACT)
291
328
  if result.get("status") in ("unavailable", "failed"):
292
329
  failed_batches += 1
293
330
  logger.warning(
@@ -349,10 +386,18 @@ async def run_privacy_disclosure_layer(
349
386
  from ..sanitization.nsfw_classifier import NSFW_CLASSIFY_MAX_BATCH
350
387
 
351
388
  nsfw_items = list(nsfw_pending.items())
352
- for i in range(0, len(nsfw_items), NSFW_CLASSIFY_MAX_BATCH):
353
- batch = nsfw_items[i : i + NSFW_CLASSIFY_MAX_BATCH]
389
+ _nsfw_total = len(nsfw_items)
390
+ _nsfw_done = 0
391
+ _nsfw_chunk = min(NSFW_CLASSIFY_MAX_BATCH, PRIVACY_PROGRESS_CHUNK)
392
+ for i in range(0, len(nsfw_items), _nsfw_chunk):
393
+ batch = nsfw_items[i : i + _nsfw_chunk]
354
394
  items = [{"id": key, "text": entry["text"]} for key, entry in batch]
395
+ if progress_callback:
396
+ progress_callback(_nsfw_done, _nsfw_total, PRIVACY_STAGE_NSFW)
355
397
  nsfw_result = await privacy_client.classify_nsfw_batch(items)
398
+ _nsfw_done += len(batch)
399
+ if progress_callback:
400
+ progress_callback(_nsfw_done, _nsfw_total, PRIVACY_STAGE_NSFW)
356
401
  if nsfw_result.get("status") in ("failed",):
357
402
  nsfw_failed_batches += 1
358
403
  continue
@@ -317,7 +317,20 @@ class EntitiesJob(BaseEnrichmentJob):
317
317
  from ....features.entities.edges import record_cooccurrence_pairs
318
318
 
319
319
  for record_id, ids in entities_by_record.items():
320
- event_at = (msg_by_id.get(record_id) or {}).get("event_at")
320
+ # Tolerant lookup, like every other read of a record's time in
321
+ # this file. `msg_by_id` holds RAW canonical messages, and the
322
+ # canonical groups disagree on the column (see
323
+ # _EVENT_AT_FIELDS) — reading only "event_at" left every
324
+ # co-occurrence edge undated for any group that names it
325
+ # otherwise. Measured on a real import: 9,242 of 9,242
326
+ # co-occurrence edges had no time, while the declared lane
327
+ # beside them, which already used this lookup, was fully dated.
328
+ # Undated edges cannot be placed in a temporal view at all.
329
+ msg_for_event = msg_by_id.get(record_id) or {}
330
+ event_at = next(
331
+ (msg_for_event.get(f) for f in _EVENT_AT_FIELDS if msg_for_event.get(f)),
332
+ None,
333
+ )
321
334
  for src, dst in record_cooccurrence_pairs(ids):
322
335
  update_edge(
323
336
  conn,
@@ -181,7 +181,11 @@ class EnrichmentOrchestrator(BaseObject):
181
181
  jobs_percent = ((job_idx - 1) / total_jobs * 100) if total_jobs > 0 else 0
182
182
  # Call orchestrator progress callback with job-level info
183
183
  progress_callback(
184
- processed_count=0, # Not used for job-level tracking
184
+ # The real within-job position. This was pinned to 0
185
+ # with a note that it was unused -- true when the only
186
+ # consumer was a percentage, but a caller showing
187
+ # "N of M" then reads zero for a whole job.
188
+ processed_count=current_count,
185
189
  total_count=total_count,
186
190
  job_name=job_name,
187
191
  job_percent=jobs_percent,
@@ -279,7 +283,11 @@ class EnrichmentOrchestrator(BaseObject):
279
283
  job_progress_percent = (job_idx / total_jobs * 100) if total_jobs > 0 else 100
280
284
  # Update with messages processed so far (cumulative across jobs)
281
285
  # Job is 100% complete
282
- progress_callback(messages_processed_so_far, total_messages, job_name, job_progress_percent, 100.0)
286
+ # Within-job counts, matching the mid-job callback above.
287
+ # This passed a CUMULATIVE total against a per-job
288
+ # denominator, so the fourth job of ten reported
289
+ # "2,904 of 726" to anyone rendering the pair.
290
+ progress_callback(total_messages, total_messages, job_name, job_progress_percent, 100.0)
283
291
 
284
292
  results["jobs_run"] += 1
285
293
  except Exception as exc:
@@ -297,7 +305,10 @@ class EnrichmentOrchestrator(BaseObject):
297
305
  if progress_callback:
298
306
  job_progress_percent = (job_idx / total_jobs * 100) if total_jobs > 0 else 100
299
307
  # Mark job as 100% complete (even if failed, we've moved past it)
300
- progress_callback(messages_processed_so_far, total_messages, job.get_job_name(), job_progress_percent, 100.0)
308
+ # Within-job counts, as above: a failed job has still
309
+ # been moved past, but it did not process more messages
310
+ # than it was given.
311
+ progress_callback(total_messages, total_messages, job.get_job_name(), job_progress_percent, 100.0)
301
312
 
302
313
  logger.debug(
303
314
  "[PIPELINE:ENRICHMENT] %s: Enrichment complete: %d jobs run, %d total records created",
@@ -498,7 +509,25 @@ class SignalDerivationOrchestrator(EnrichmentOrchestrator):
498
509
  continue
499
510
  job_name = job.get_job_name()
500
511
  try:
501
- records = await job.enrich(canonical_messages)
512
+ # Report like the canonical lane: a start post, a per-record
513
+ # callback, and a completion post. This lane used to make ONE
514
+ # call per job, after the job, with processed=0 and progress=100
515
+ # -- so every signal stage read "0 of 726" for its whole
516
+ # duration and the bar jumped to the end of the stage the moment
517
+ # it began. Observed live: "deriving emo 27, 0/726" on screen for
518
+ # 34 minutes while TopicsJob logged 264/726 underneath it.
519
+ _total_msgs = len(canonical_messages)
520
+ _jobs_pct_before = ((job_idx - 1) / total_jobs * 100) if total_jobs > 0 else 0.0
521
+
522
+ def _signal_job_progress(current_count: int, total_count: int, *, _name: str = job_name, _before: float = _jobs_pct_before) -> None:
523
+ if not progress_callback:
524
+ return
525
+ pct = (current_count / total_count * 100) if total_count > 0 else 0.0
526
+ progress_callback(current_count, total_count, _name, _before, pct)
527
+
528
+ if progress_callback:
529
+ progress_callback(0, _total_msgs, job_name, _jobs_pct_before, 0.0)
530
+ records = await job.enrich(canonical_messages, progress_callback=_signal_job_progress)
502
531
  if records and records[0].get("_deferred"):
503
532
  deferral_error = str(records[0].get("error"))
504
533
  results["deferred_jobs"].append(job_name)
@@ -572,7 +601,8 @@ class SignalDerivationOrchestrator(EnrichmentOrchestrator):
572
601
 
573
602
  await _offload_write(_settle_debt)
574
603
  if progress_callback:
575
- progress_callback(0, len(canonical_messages), job_name, (job_idx / total_jobs) * 100, 100.0)
604
+ # Within-job counts at completion, matching the canonical lane.
605
+ progress_callback(_total_msgs, _total_msgs, job_name, (job_idx / total_jobs) * 100, 100.0)
576
606
  except Exception as exc:
577
607
  logger.error("[PIPELINE:SIGNAL_DERIVE] job %s failed: %s", job_name, exc)
578
608
  results["errors"].append({"job": job_name, "error": str(exc)})
@@ -401,7 +401,15 @@ class EvidenceCache:
401
401
  for row in conn.execute(
402
402
  f"""
403
403
  SELECT src_entity_id, dst_entity_id, edge_type, weight, evidence_count,
404
- COALESCE(last_event_at, valid_from, created_at) AS event_at
404
+ -- last_event_at ONLY. valid_from is when the node started
405
+ -- believing the relation (a recompute's clock for part_of
406
+ -- and other structural edges) and created_at is the row's
407
+ -- own birth; neither is an event. The fallback made an
408
+ -- undated edge report activity at rebuild time, which is
409
+ -- the defect fixed for the graph window in edges.py.
410
+ -- EvidenceCache.add tolerates None: weight still counts,
411
+ -- no date is invented.
412
+ last_event_at AS event_at
405
413
  FROM entity_edges
406
414
  WHERE valid_to IS NULL
407
415
  AND LOWER(TRIM(edge_type)) IN ({placeholders})
@@ -562,11 +562,21 @@ def graph_snapshot(
562
562
  clause = ""
563
563
  else:
564
564
  clause = " AND valid_to IS NULL"
565
+ # A TIME window asks "did anything happen between these dates". Only
566
+ # last_event_at answers that. valid_from is when the node started BELIEVING
567
+ # the relation -- for a structural edge written by a recompute (semantic
568
+ # affinity, part_of) that is the recompute's clock, and it carries no event
569
+ # at all. The old COALESCE fallback read that clock as activity, so every
570
+ # entity touched by a rebuild appeared in "the last 11 days" no matter when
571
+ # it was last mentioned: 69 of 4,602 dormant entities on the reference node,
572
+ # 60 of them through exactly these undated edges. An undated edge is no
573
+ # evidence of activity in any window; it stays in the unwindowed views,
574
+ # where valid_from remains the right recency key for ORDER BY.
565
575
  if after:
566
- clause += " AND COALESCE(last_event_at, valid_from) >= ?"
576
+ clause += " AND last_event_at IS NOT NULL AND last_event_at >= ?"
567
577
  where_params.append(after)
568
578
  if before:
569
- clause += " AND COALESCE(last_event_at, valid_from) <= ?"
579
+ clause += " AND last_event_at IS NOT NULL AND last_event_at <= ?"
570
580
  where_params.append(before)
571
581
 
572
582
  where_sql = (