topos-node 1.3.47__tar.gz → 1.3.49__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 (767) hide show
  1. {topos_node-1.3.47/topos_node.egg-info → topos_node-1.3.49}/PKG-INFO +1 -1
  2. {topos_node-1.3.47 → topos_node-1.3.49}/pyproject.toml +1 -1
  3. {topos_node-1.3.47 → topos_node-1.3.49}/topos/__version__.py +2 -2
  4. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/ollama.py +10 -0
  5. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/engine.py +6 -1
  6. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/usage_observation.py +9 -2
  7. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/surfaces.py +21 -0
  8. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/ingest_helpers.py +36 -38
  9. {topos_node-1.3.47 → topos_node-1.3.49}/topos/protocol/narrowing_vocabulary.json +2 -0
  10. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/narrowing.py +2 -0
  11. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/pipeline.py +63 -1
  12. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/llm/openai.py +75 -1
  13. {topos_node-1.3.47 → topos_node-1.3.49}/topos/upgrades/manifests.json +18 -4
  14. {topos_node-1.3.47 → topos_node-1.3.49/topos_node.egg-info}/PKG-INFO +1 -1
  15. {topos_node-1.3.47 → topos_node-1.3.49}/LICENSE +0 -0
  16. {topos_node-1.3.47 → topos_node-1.3.49}/MANIFEST.in +0 -0
  17. {topos_node-1.3.47 → topos_node-1.3.49}/README.md +0 -0
  18. {topos_node-1.3.47 → topos_node-1.3.49}/setup.cfg +0 -0
  19. {topos_node-1.3.47 → topos_node-1.3.49}/shared/__init__.py +0 -0
  20. {topos_node-1.3.47 → topos_node-1.3.49}/shared/filtering.py +0 -0
  21. {topos_node-1.3.47 → topos_node-1.3.49}/shared/schema_registry.py +0 -0
  22. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_active_database_binding.py +0 -0
  23. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_active_ingestion_binding.py +0 -0
  24. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_extensions.py +0 -0
  25. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_gate_leg_hermeticity.py +0 -0
  26. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_llm_integrations_storage.py +0 -0
  27. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_local_gate_composition.py +0 -0
  28. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_owner_database_hermeticity.py +0 -0
  29. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_prewarm_first_run.py +0 -0
  30. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_profile_hygiene.py +0 -0
  31. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_profiles.py +0 -0
  32. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_protocol_handled_types.py +0 -0
  33. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_query_field_contract.py +0 -0
  34. {topos_node-1.3.47 → topos_node-1.3.49}/tests/test_system_computer_name.py +0 -0
  35. {topos_node-1.3.47 → topos_node-1.3.49}/topos/__init__.py +0 -0
  36. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/__init__.py +0 -0
  37. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/dataset_resolution.py +0 -0
  38. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/duckdb_adapter.py +0 -0
  39. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/luck_surface.py +0 -0
  40. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/messenger_communities.py +0 -0
  41. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/messenger_directed.py +0 -0
  42. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/messenger_graph.py +0 -0
  43. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/messenger_labels.py +0 -0
  44. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/person_graph.py +0 -0
  45. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/person_overlay.py +0 -0
  46. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/profiles.py +0 -0
  47. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/query_engine.py +0 -0
  48. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/raw_queries.py +0 -0
  49. {topos_node-1.3.47 → topos_node-1.3.49}/topos/analytics/relationship_reads.py +0 -0
  50. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/__init__.py +0 -0
  51. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/analytics.py +0 -0
  52. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/app_registry.py +0 -0
  53. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/backup.py +0 -0
  54. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/community_naming_config.py +0 -0
  55. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/compute_remote.py +0 -0
  56. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/connected_apps.py +0 -0
  57. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/conversation_context.py +0 -0
  58. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/data_commit.py +0 -0
  59. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/data_explorer_table_prefs.py +0 -0
  60. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/database_explorer.py +0 -0
  61. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/db.py +0 -0
  62. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/device.py +0 -0
  63. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/disk_space_config.py +0 -0
  64. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/engine_run.py +0 -0
  65. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/enrichment.py +0 -0
  66. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/enrichment_lab.py +0 -0
  67. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/facts_llm_config.py +0 -0
  68. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/filter_lab.py +0 -0
  69. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/health.py +0 -0
  70. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/home_chat.py +0 -0
  71. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/ingestion_api.py +0 -0
  72. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/ingestion_compat.py +0 -0
  73. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/ingestion_sources.py +0 -0
  74. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/intelligence_lifecycle.py +0 -0
  75. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/llm.py +0 -0
  76. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/local_mcp.py +0 -0
  77. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/messenger_analytics.py +0 -0
  78. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/privacy_disclose.py +0 -0
  79. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/query_api.py +0 -0
  80. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/runtime_bootstrap.py +0 -0
  81. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/sanitization_ollama_config.py +0 -0
  82. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/shell.py +0 -0
  83. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/signal.py +0 -0
  84. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/signal_extraction_config.py +0 -0
  85. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/source_install.py +0 -0
  86. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/source_scrub.py +0 -0
  87. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/sources.py +0 -0
  88. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/sources_overview.py +0 -0
  89. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/sync.py +0 -0
  90. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/tool_index.py +0 -0
  91. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/ui_config.py +0 -0
  92. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/uma_data.py +0 -0
  93. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/upgrades.py +0 -0
  94. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/usage.py +0 -0
  95. {topos_node-1.3.47 → topos_node-1.3.49}/topos/api/user_identity.py +0 -0
  96. {topos_node-1.3.47 → topos_node-1.3.49}/topos/app.py +0 -0
  97. {topos_node-1.3.47 → topos_node-1.3.49}/topos/auth.py +0 -0
  98. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/__init__.py +0 -0
  99. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/declared_field_map.py +0 -0
  100. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/__init__.py +0 -0
  101. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/base.py +0 -0
  102. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  103. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  104. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  105. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  106. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  107. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  108. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  109. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  110. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/models.py +0 -0
  111. {topos_node-1.3.47 → topos_node-1.3.49}/topos/canonicalization/resolver.py +0 -0
  112. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/__init__.py +0 -0
  113. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/__main__.py +0 -0
  114. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/assets/topos_blk_rounded.png +0 -0
  115. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/assets/topos_white.png +0 -0
  116. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/commands.py +0 -0
  117. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/profile_cmd.py +0 -0
  118. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/reprocess_cmd.py +0 -0
  119. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/setup_models_cmd.py +0 -0
  120. {topos_node-1.3.47 → topos_node-1.3.49}/topos/cli/tray.py +0 -0
  121. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/__init__.py +0 -0
  122. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/conversation_context_llm.py +0 -0
  123. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/facts_llm.py +0 -0
  124. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/local_model_builds.py +0 -0
  125. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/model_packs.py +0 -0
  126. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/node_function_providers.py +0 -0
  127. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/sanitization_ollama.py +0 -0
  128. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/settings.py +0 -0
  129. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/signal_extraction.py +0 -0
  130. {topos_node-1.3.47 → topos_node-1.3.49}/topos/config/uvicorn_logging.json +0 -0
  131. {topos_node-1.3.47 → topos_node-1.3.49}/topos/contacts/__init__.py +0 -0
  132. {topos_node-1.3.47 → topos_node-1.3.49}/topos/contacts/identity.py +0 -0
  133. {topos_node-1.3.47 → topos_node-1.3.49}/topos/control_plane_client.py +0 -0
  134. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/__init__.py +0 -0
  135. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/api_models.py +0 -0
  136. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/connection_resilience.py +0 -0
  137. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/db_health.py +0 -0
  138. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/device_helpers.py +0 -0
  139. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/errors.py +0 -0
  140. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/events.py +0 -0
  141. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/__init__.py +0 -0
  142. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/aggregate.py +0 -0
  143. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/common.py +0 -0
  144. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/complexity.py +0 -0
  145. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/config.py +0 -0
  146. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/contacts_import.py +0 -0
  147. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/database_explorer.py +0 -0
  148. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/derivation.py +0 -0
  149. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/device.py +0 -0
  150. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/enrichment.py +0 -0
  151. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/enrichment_lab.py +0 -0
  152. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/filter_lab.py +0 -0
  153. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/graph_query.py +0 -0
  154. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/graph_summary.py +0 -0
  155. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/home_chat.py +0 -0
  156. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/ingest.py +0 -0
  157. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/mcp_client_elevations.py +0 -0
  158. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/mcp_clients.py +0 -0
  159. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/messages.py +0 -0
  160. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/messenger_analytics.py +0 -0
  161. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/query.py +0 -0
  162. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/registry.py +0 -0
  163. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/routines.py +0 -0
  164. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/signal_features.py +0 -0
  165. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/sources.py +0 -0
  166. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/timeline_daily.py +0 -0
  167. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/tool_index.py +0 -0
  168. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/handlers/uma.py +0 -0
  169. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/logging.py +0 -0
  170. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/metrics.py +0 -0
  171. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/routine_access.py +0 -0
  172. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/startup_banner.py +0 -0
  173. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/state.py +0 -0
  174. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/table_layers.py +0 -0
  175. {topos_node-1.3.47 → topos_node-1.3.49}/topos/core/types.py +0 -0
  176. {topos_node-1.3.47 → topos_node-1.3.49}/topos/data_explorer_row_delete.py +0 -0
  177. {topos_node-1.3.47 → topos_node-1.3.49}/topos/data_explorer_table_prefs.py +0 -0
  178. {topos_node-1.3.47 → topos_node-1.3.49}/topos/data_explorer_tables.py +0 -0
  179. {topos_node-1.3.47 → topos_node-1.3.49}/topos/defaults.py +0 -0
  180. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/__init__.py +0 -0
  181. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/canonical_writer.py +0 -0
  182. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/content_policy.py +0 -0
  183. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/field_registry.py +0 -0
  184. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/privacy_layer.py +0 -0
  185. {topos_node-1.3.47 → topos_node-1.3.49}/topos/disclosure/tier.py +0 -0
  186. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/__init__.py +0 -0
  187. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/__init__.py +0 -0
  188. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/base.py +0 -0
  189. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/generative_prompts.py +0 -0
  190. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/generative_response.py +0 -0
  191. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/huggingface.py +0 -0
  192. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/openai.py +0 -0
  193. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/openai_compatible.py +0 -0
  194. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/redpill.py +0 -0
  195. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/backends/stub.py +0 -0
  196. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/client.py +0 -0
  197. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/disk_space.py +0 -0
  198. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/hosted_llm_wallet.py +0 -0
  199. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/intake.py +0 -0
  200. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/memory_utils.py +0 -0
  201. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/model_cache.py +0 -0
  202. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/model_manager.py +0 -0
  203. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/ollama_install.py +0 -0
  204. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/ollama_pull.py +0 -0
  205. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/ollama_runtime.py +0 -0
  206. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/ollama_setup_guidance.py +0 -0
  207. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/pipeline_memory.py +0 -0
  208. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/queue_manager.py +0 -0
  209. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/registration.py +0 -0
  210. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/result_formatter.py +0 -0
  211. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/router.py +0 -0
  212. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/scoped_token.py +0 -0
  213. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/tasks.py +0 -0
  214. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/torch_runtime.py +0 -0
  215. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/transport.py +0 -0
  216. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/usage_guard.py +0 -0
  217. {topos_node-1.3.47 → topos_node-1.3.49}/topos/engine/validator.py +0 -0
  218. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/__init__.py +0 -0
  219. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/catalog.py +0 -0
  220. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/derivation_recovery.py +0 -0
  221. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/derived_tables.py +0 -0
  222. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/job_readiness.py +0 -0
  223. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/job_writer.py +0 -0
  224. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/__init__.py +0 -0
  225. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/base.py +0 -0
  226. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  227. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  228. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  229. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  230. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  231. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  232. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  233. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  234. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
  235. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  236. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  237. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  238. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  239. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  240. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  241. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  242. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  243. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  244. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  245. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  246. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  247. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  248. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/raw/__init__.py +0 -0
  249. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  250. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/raw/language_job.py +0 -0
  251. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  252. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  253. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/model_overrides.py +0 -0
  254. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/models/__init__.py +0 -0
  255. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/models/manager.py +0 -0
  256. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/models/mvp_defaults.py +0 -0
  257. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/models/registry.py +0 -0
  258. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/models/versioning.py +0 -0
  259. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/orchestrator.py +0 -0
  260. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/pipeline_activity.py +0 -0
  261. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/processor.py +0 -0
  262. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/progress_bar.py +0 -0
  263. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/record_progress.py +0 -0
  264. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/registry_contract.py +0 -0
  265. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/signal_derivation_config.json +0 -0
  266. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment/source_overrides.py +0 -0
  267. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/__init__.py +0 -0
  268. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/bundles.py +0 -0
  269. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/model_resolve.py +0 -0
  270. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/schema.py +0 -0
  271. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/service.py +0 -0
  272. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/store.py +0 -0
  273. {topos_node-1.3.47 → topos_node-1.3.49}/topos/enrichment_lab/worker.py +0 -0
  274. {topos_node-1.3.47 → topos_node-1.3.49}/topos/evals/__init__.py +0 -0
  275. {topos_node-1.3.47 → topos_node-1.3.49}/topos/evals/enrichment_eval.py +0 -0
  276. {topos_node-1.3.47 → topos_node-1.3.49}/topos/extensions.py +0 -0
  277. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/__init__.py +0 -0
  278. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/canonical.py +0 -0
  279. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/engine.py +0 -0
  280. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/entropy.py +0 -0
  281. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/focus.py +0 -0
  282. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/graph_metrics.py +0 -0
  283. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/influence.py +0 -0
  284. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/projection.py +0 -0
  285. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/snapshots.py +0 -0
  286. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/store.py +0 -0
  287. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/topic_merge.py +0 -0
  288. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/topics.py +0 -0
  289. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/topics_daily.py +0 -0
  290. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/complexity/volatility.py +0 -0
  291. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/__init__.py +0 -0
  292. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  293. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  294. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
  295. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  296. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  297. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  298. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  299. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  300. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  301. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  302. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  303. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  304. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  305. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
  306. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  307. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  308. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  309. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  310. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  311. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  312. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
  313. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
  314. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  315. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
  316. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  317. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  318. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  319. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  320. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  321. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  322. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  323. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  324. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  325. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  326. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  327. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
  328. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/candidates.py +0 -0
  329. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/guard.py +0 -0
  330. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/kernels.py +0 -0
  331. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/net_subject_policy.py +0 -0
  332. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/packs.py +0 -0
  333. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/person_bridge.py +0 -0
  334. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/prefilter.py +0 -0
  335. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/registry.py +0 -0
  336. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/report_card.py +0 -0
  337. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/router.py +0 -0
  338. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/social_bench.py +0 -0
  339. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/social_kernels.py +0 -0
  340. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/synthesize.py +0 -0
  341. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/template.py +0 -0
  342. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/verify.py +0 -0
  343. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/derivation/writer.py +0 -0
  344. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/__init__.py +0 -0
  345. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/affinity.py +0 -0
  346. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/affinity_owner.py +0 -0
  347. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/affinity_quality.py +0 -0
  348. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/chatgpt_declared.py +0 -0
  349. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/community_names.py +0 -0
  350. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/community_naming.py +0 -0
  351. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/consolidation.py +0 -0
  352. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/context_vectors.py +0 -0
  353. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/cypher.py +0 -0
  354. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/declared_mappings.py +0 -0
  355. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/dossier.py +0 -0
  356. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/edges.py +0 -0
  357. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/fact_materializer.py +0 -0
  358. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/graph_enrichers.py +0 -0
  359. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/graph_refresh.py +0 -0
  360. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/graph_search.py +0 -0
  361. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/linking.py +0 -0
  362. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/maintenance.py +0 -0
  363. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/owner.py +0 -0
  364. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/reads.py +0 -0
  365. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/rebuild_subprocess.py +0 -0
  366. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/resolver.py +0 -0
  367. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/entities/structured_fields.py +0 -0
  368. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/__init__.py +0 -0
  369. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/extract.py +0 -0
  370. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/llm_extract.py +0 -0
  371. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/reads.py +0 -0
  372. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/store.py +0 -0
  373. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/facts/verdicts.py +0 -0
  374. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/fit/evaluator.py +0 -0
  375. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/fit/opportunity_types.json +0 -0
  376. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/__init__.py +0 -0
  377. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/blackhole.py +0 -0
  378. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/blackhole_guard.py +0 -0
  379. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/blackhole_llm.py +0 -0
  380. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  381. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/derived_scrub.py +0 -0
  382. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/exclusions.py +0 -0
  383. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/lifecycle/gc.py +0 -0
  384. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/provenance/__init__.py +0 -0
  385. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/provenance/posture.py +0 -0
  386. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/provenance/roles.py +0 -0
  387. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/__init__.py +0 -0
  388. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/brief_canonical_loader.py +0 -0
  389. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/brief_ontology.py +0 -0
  390. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/brief_renderer.py +0 -0
  391. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/brief_schemas.py +0 -0
  392. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/chunking.py +0 -0
  393. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/cluster_labels.py +0 -0
  394. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/conversation_context.py +0 -0
  395. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/conversation_windows.py +0 -0
  396. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/data_health.py +0 -0
  397. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  398. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/intentions.json +0 -0
  399. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/interests.json +0 -0
  400. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/memory.json +0 -0
  401. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/places.json +0 -0
  402. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/profile.json +0 -0
  403. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/relationships.json +0 -0
  404. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/resources.json +0 -0
  405. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  406. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/time.json +0 -0
  407. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/wellbeing.json +0 -0
  408. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/definitions/work.json +0 -0
  409. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/derived_index.py +0 -0
  410. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/derived_spec.py +0 -0
  411. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/dimension_briefs.py +0 -0
  412. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/dimension_definition_loader.py +0 -0
  413. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/dimension_profiles.py +0 -0
  414. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/dimension_registry.py +0 -0
  415. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/embed_context.py +0 -0
  416. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/extraction/artifact_router.py +0 -0
  417. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/extraction/artifact_store.py +0 -0
  418. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/extraction/rule_extractors.py +0 -0
  419. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/graph_sanitize.py +0 -0
  420. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/hybrid_search.py +0 -0
  421. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/incremental_clustering.py +0 -0
  422. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/model_recommendations.py +0 -0
  423. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/query_embed_cache.py +0 -0
  424. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/schemas.py +0 -0
  425. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/service.py +0 -0
  426. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/signal_object_store.py +0 -0
  427. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/source_hydration.py +0 -0
  428. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/structured_signal.py +0 -0
  429. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/tool_index.py +0 -0
  430. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/topic_clustering.py +0 -0
  431. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/typed_stores/aggregates.py +0 -0
  432. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/typed_stores/commitments.py +0 -0
  433. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/typed_stores/rhythm.py +0 -0
  434. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  435. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/vector_codec.py +0 -0
  436. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/vector_math.py +0 -0
  437. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/signal/vector_settings.py +0 -0
  438. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/stats/__init__.py +0 -0
  439. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/stats/definitions.py +0 -0
  440. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/stats/engine.py +0 -0
  441. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/stats/fold.py +0 -0
  442. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/stats/insights.py +0 -0
  443. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/timeline_projection.py +0 -0
  444. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/timeline_rollup.py +0 -0
  445. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/__init__.py +0 -0
  446. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/badges.py +0 -0
  447. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/daily.py +0 -0
  448. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/dashboard.py +0 -0
  449. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/instruments.py +0 -0
  450. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/intents.py +0 -0
  451. {topos_node-1.3.47 → topos_node-1.3.49}/topos/features/triage/readiness.py +0 -0
  452. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/__init__.py +0 -0
  453. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/bundles.py +0 -0
  454. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/schema.py +0 -0
  455. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/service.py +0 -0
  456. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/store.py +0 -0
  457. {topos_node-1.3.47 → topos_node-1.3.49}/topos/filter_lab/worker.py +0 -0
  458. {topos_node-1.3.47 → topos_node-1.3.49}/topos/home_chat/__init__.py +0 -0
  459. {topos_node-1.3.47 → topos_node-1.3.49}/topos/home_chat/schema.py +0 -0
  460. {topos_node-1.3.47 → topos_node-1.3.49}/topos/home_chat/store.py +0 -0
  461. {topos_node-1.3.47 → topos_node-1.3.49}/topos/hosted_pool_lease.py +0 -0
  462. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/__init__.py +0 -0
  463. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/canonical_pipeline.py +0 -0
  464. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/checkpoints/__init__.py +0 -0
  465. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  466. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  467. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/inbox_crypto.py +0 -0
  468. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/inbox_drain.py +0 -0
  469. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/jobs.py +0 -0
  470. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/journal_location_fanout.py +0 -0
  471. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/journal_time_log_normalize.py +0 -0
  472. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/local_exports.py +0 -0
  473. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/local_sync.py +0 -0
  474. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/log_preview.py +0 -0
  475. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/manager.py +0 -0
  476. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parser.py +0 -0
  477. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/__init__.py +0 -0
  478. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/base.py +0 -0
  479. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/browser_parser.py +0 -0
  480. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/calendar_parser.py +0 -0
  481. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  482. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/chatgpt_export.py +0 -0
  483. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  484. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  485. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/documents_parser.py +0 -0
  486. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  487. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  488. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/grok_parser.py +0 -0
  489. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/messenger_parser.py +0 -0
  490. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  491. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/progress.py +0 -0
  492. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/reprocess.py +0 -0
  493. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/__init__.py +0 -0
  494. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/base.py +0 -0
  495. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/calendar.py +0 -0
  496. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/chatgpt.py +0 -0
  497. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/contact_importers.py +0 -0
  498. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/grok.py +0 -0
  499. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/imessage_reader.py +0 -0
  500. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/signal_export_parser.py +0 -0
  501. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/sources/signal_reader.py +0 -0
  502. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/state_machine.py +0 -0
  503. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/triggers/__init__.py +0 -0
  504. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/triggers/file_trigger.py +0 -0
  505. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  506. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  507. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/validation/__init__.py +0 -0
  508. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/validation/base.py +0 -0
  509. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/validation/schema_registry.py +0 -0
  510. {topos_node-1.3.47 → topos_node-1.3.49}/topos/ingestion/validation/schema_validator.py +0 -0
  511. {topos_node-1.3.47 → topos_node-1.3.49}/topos/lineage/__init__.py +0 -0
  512. {topos_node-1.3.47 → topos_node-1.3.49}/topos/lineage/provenance.py +0 -0
  513. {topos_node-1.3.47 → topos_node-1.3.49}/topos/lineage/tracker.py +0 -0
  514. {topos_node-1.3.47 → topos_node-1.3.49}/topos/llm_integrations_storage.py +0 -0
  515. {topos_node-1.3.47 → topos_node-1.3.49}/topos/mcp_clients.py +0 -0
  516. {topos_node-1.3.47 → topos_node-1.3.49}/topos/mcp_stdio_proxy.py +0 -0
  517. {topos_node-1.3.47 → topos_node-1.3.49}/topos/observability/__init__.py +0 -0
  518. {topos_node-1.3.47 → topos_node-1.3.49}/topos/observability/alerts.py +0 -0
  519. {topos_node-1.3.47 → topos_node-1.3.49}/topos/observability/metrics.py +0 -0
  520. {topos_node-1.3.47 → topos_node-1.3.49}/topos/observability/tracing.py +0 -0
  521. {topos_node-1.3.47 → topos_node-1.3.49}/topos/openai_client.py +0 -0
  522. {topos_node-1.3.47 → topos_node-1.3.49}/topos/owner_key.py +0 -0
  523. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/__init__.py +0 -0
  524. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/audit.py +0 -0
  525. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/envelope.py +0 -0
  526. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/job_runner.py +0 -0
  527. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/job_store.py +0 -0
  528. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/stages.py +0 -0
  529. {topos_node-1.3.47 → topos_node-1.3.49}/topos/pipeline/stub_enqueue.py +0 -0
  530. {topos_node-1.3.47 → topos_node-1.3.49}/topos/principal.py +0 -0
  531. {topos_node-1.3.47 → topos_node-1.3.49}/topos/profiles.py +0 -0
  532. {topos_node-1.3.47 → topos_node-1.3.49}/topos/projections/__init__.py +0 -0
  533. {topos_node-1.3.47 → topos_node-1.3.49}/topos/projections/vector_index/__init__.py +0 -0
  534. {topos_node-1.3.47 → topos_node-1.3.49}/topos/projections/vector_index/base.py +0 -0
  535. {topos_node-1.3.47 → topos_node-1.3.49}/topos/projections/vector_index/builders.py +0 -0
  536. {topos_node-1.3.47 → topos_node-1.3.49}/topos/projections/vector_index/health_checks.py +0 -0
  537. {topos_node-1.3.47 → topos_node-1.3.49}/topos/protocol/__init__.py +0 -0
  538. {topos_node-1.3.47 → topos_node-1.3.49}/topos/protocol/handled_message_types.json +0 -0
  539. {topos_node-1.3.47 → topos_node-1.3.49}/topos/protocol/query_field_contract.json +0 -0
  540. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/__init__.py +0 -0
  541. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/aggregate.py +0 -0
  542. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/audit.py +0 -0
  543. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/closeness.py +0 -0
  544. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/cohort_resolvers.py +0 -0
  545. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/collaborators.py +0 -0
  546. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/ddr.py +0 -0
  547. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/disclosure.py +0 -0
  548. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/entity_window.py +0 -0
  549. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/exclusion.py +0 -0
  550. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/facts_direct.py +0 -0
  551. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/fingerprint.py +0 -0
  552. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/game_layer.py +0 -0
  553. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/grant_cache.py +0 -0
  554. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/graph_lane.py +0 -0
  555. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/inference.py +0 -0
  556. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/intent.py +0 -0
  557. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/manifest.py +0 -0
  558. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/manifest_validation.py +0 -0
  559. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/minimizer.py +0 -0
  560. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/negotiation.py +0 -0
  561. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/packet_resolution.py +0 -0
  562. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/planner.py +0 -0
  563. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/retrieval.py +0 -0
  564. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/runtime.py +0 -0
  565. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_arbiter.py +0 -0
  566. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_classifier.py +0 -0
  567. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_head.py +0 -0
  568. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_registry.json +0 -0
  569. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_registry_loader.py +0 -0
  570. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/scope_shadow.py +0 -0
  571. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/session.py +0 -0
  572. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/session_utils.py +0 -0
  573. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/source_generation.py +0 -0
  574. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/truth_facts.py +0 -0
  575. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/truth_prompts.py +0 -0
  576. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/turn_classifier.py +0 -0
  577. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/types.py +0 -0
  578. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/verify.py +0 -0
  579. {topos_node-1.3.47 → topos_node-1.3.49}/topos/query/verify_modes.py +0 -0
  580. {topos_node-1.3.47 → topos_node-1.3.49}/topos/rate_limit.py +0 -0
  581. {topos_node-1.3.47 → topos_node-1.3.49}/topos/relay_stamp.py +0 -0
  582. {topos_node-1.3.47 → topos_node-1.3.49}/topos/routines/__init__.py +0 -0
  583. {topos_node-1.3.47 → topos_node-1.3.49}/topos/routines/schema.py +0 -0
  584. {topos_node-1.3.47 → topos_node-1.3.49}/topos/routines/store.py +0 -0
  585. {topos_node-1.3.47 → topos_node-1.3.49}/topos/runtime_housekeeping.py +0 -0
  586. {topos_node-1.3.47 → topos_node-1.3.49}/topos/runtime_shutdown.py +0 -0
  587. {topos_node-1.3.47 → topos_node-1.3.49}/topos/runtime_update.py +0 -0
  588. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sanitization/__init__.py +0 -0
  589. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sanitization/nsfw_classifier.py +0 -0
  590. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sanitization/ollama_transforms.py +0 -0
  591. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sanitization/prewarm.py +0 -0
  592. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sanitization/privacy_filter.py +0 -0
  593. {topos_node-1.3.47 → topos_node-1.3.49}/topos/scope_resolution.py +0 -0
  594. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/__init__.py +0 -0
  595. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/container.py +0 -0
  596. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/embeddings/__init__.py +0 -0
  597. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/embeddings/base.py +0 -0
  598. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/embeddings/local.py +0 -0
  599. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/embeddings/remote.py +0 -0
  600. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/interfaces.py +0 -0
  601. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/llm/__init__.py +0 -0
  602. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/llm/base.py +0 -0
  603. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/local.py +0 -0
  604. {topos_node-1.3.47 → topos_node-1.3.49}/topos/services/postgres.py +0 -0
  605. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/__init__.py +0 -0
  606. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/bundled_canonical_triples.py +0 -0
  607. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/canonical_signal_defaults.py +0 -0
  608. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/declared_field_map_spec.py +0 -0
  609. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/definitions.py +0 -0
  610. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/install_service.py +0 -0
  611. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/registry.py +0 -0
  612. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/runtime_install.py +0 -0
  613. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/scrub_attribution.py +0 -0
  614. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sources/scrub_service.py +0 -0
  615. {topos_node-1.3.47 → topos_node-1.3.49}/topos/startup_banner.py +0 -0
  616. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/__init__.py +0 -0
  617. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/__init__.py +0 -0
  618. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/factory.py +0 -0
  619. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/fakes.py +0 -0
  620. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/postgres/stores.py +0 -0
  621. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/protocols.py +0 -0
  622. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/sqlite/__init__.py +0 -0
  623. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/sqlite/stores.py +0 -0
  624. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  625. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/__init__.py +0 -0
  626. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/activity_tables.py +0 -0
  627. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  628. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  629. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  630. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/ai_chat/model.py +0 -0
  631. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/ai_chat/tables.py +0 -0
  632. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  633. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/canonical_store.py +0 -0
  634. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/conversations_tables.py +0 -0
  635. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/journal_repair.py +0 -0
  636. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/mapping_store.py +0 -0
  637. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/canonical/postgres.py +0 -0
  638. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/__init__.py +0 -0
  639. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/client.py +0 -0
  640. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/connection_tuning.py +0 -0
  641. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/__init__.py +0 -0
  642. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  643. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  644. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  645. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  646. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  647. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/backup.py +0 -0
  648. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/backup_custody.py +0 -0
  649. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  650. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  651. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  652. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  653. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/community_names_v1.py +0 -0
  654. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/complexity_v1.py +0 -0
  655. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
  656. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  657. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  658. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  659. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  660. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
  661. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/documents_v1.py +0 -0
  662. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  663. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  664. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  665. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  666. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  667. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  668. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  669. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  670. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  671. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  672. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  673. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/episodes_v1.py +0 -0
  674. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  675. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
  676. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  677. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  678. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  679. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  680. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  681. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  682. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
  683. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  684. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  685. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
  686. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  687. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  688. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  689. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/registry.py +0 -0
  690. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/registry_checksums.json +0 -0
  691. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  692. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  693. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  694. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  695. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  696. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_objects.py +0 -0
  697. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  698. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  699. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  700. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  701. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  702. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  703. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  704. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  705. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  706. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  707. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  708. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  709. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  710. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  711. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  712. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  713. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  714. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  715. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  716. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  717. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  718. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  719. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/paths.py +0 -0
  720. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/postgres.py +0 -0
  721. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/schema.py +0 -0
  722. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/schema_probe.py +0 -0
  723. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/storage_breakdown.py +0 -0
  724. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/db/write_gate.py +0 -0
  725. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/derived_row_identity.py +0 -0
  726. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/enrichment/__init__.py +0 -0
  727. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  728. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  729. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/normalized/__init__.py +0 -0
  730. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/normalized/normalized_store.py +0 -0
  731. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/oplog/__init__.py +0 -0
  732. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/oplog/decision.py +0 -0
  733. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/oplog/oplog_store.py +0 -0
  734. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/oplog/postgres.py +0 -0
  735. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/person/identity_resolver.py +0 -0
  736. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/projections/__init__.py +0 -0
  737. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/projections/index_ops_store.py +0 -0
  738. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/projections/vector_index_store.py +0 -0
  739. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/__init__.py +0 -0
  740. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/browser_flat_tables.py +0 -0
  741. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/file_store.py +0 -0
  742. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/raw_store.py +0 -0
  743. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/raw_tables_manager.py +0 -0
  744. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/raw/sqlite_raw_store.py +0 -0
  745. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/security/encryption.py +0 -0
  746. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/signal_identity.py +0 -0
  747. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/source_settings.py +0 -0
  748. {topos_node-1.3.47 → topos_node-1.3.49}/topos/storage/user_identity.py +0 -0
  749. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sync/__init__.py +0 -0
  750. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sync/client.py +0 -0
  751. {topos_node-1.3.47 → topos_node-1.3.49}/topos/sync_handlers.py +0 -0
  752. {topos_node-1.3.47 → topos_node-1.3.49}/topos/testing/__init__.py +0 -0
  753. {topos_node-1.3.47 → topos_node-1.3.49}/topos/testing/lifespan.py +0 -0
  754. {topos_node-1.3.47 → topos_node-1.3.49}/topos/uds.py +0 -0
  755. {topos_node-1.3.47 → topos_node-1.3.49}/topos/uma_contact_enrichment.py +0 -0
  756. {topos_node-1.3.47 → topos_node-1.3.49}/topos/uma_filters.py +0 -0
  757. {topos_node-1.3.47 → topos_node-1.3.49}/topos/uma_resource_id.py +0 -0
  758. {topos_node-1.3.47 → topos_node-1.3.49}/topos/uma_rpt.py +0 -0
  759. {topos_node-1.3.47 → topos_node-1.3.49}/topos/upgrades/__init__.py +0 -0
  760. {topos_node-1.3.47 → topos_node-1.3.49}/topos/upgrades/runner.py +0 -0
  761. {topos_node-1.3.47 → topos_node-1.3.49}/topos/utils/base_object.py +0 -0
  762. {topos_node-1.3.47 → topos_node-1.3.49}/topos/websocket_client.py +0 -0
  763. {topos_node-1.3.47 → topos_node-1.3.49}/topos_node.egg-info/SOURCES.txt +0 -0
  764. {topos_node-1.3.47 → topos_node-1.3.49}/topos_node.egg-info/dependency_links.txt +0 -0
  765. {topos_node-1.3.47 → topos_node-1.3.49}/topos_node.egg-info/entry_points.txt +0 -0
  766. {topos_node-1.3.47 → topos_node-1.3.49}/topos_node.egg-info/requires.txt +0 -0
  767. {topos_node-1.3.47 → topos_node-1.3.49}/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.47
3
+ Version: 1.3.49
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.47"
7
+ version = "1.3.49"
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.47"
4
- __version_info__ = (1, 3, 47)
3
+ __version__ = "1.3.49"
4
+ __version_info__ = (1, 3, 49)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -455,13 +455,23 @@ class OllamaAdapter:
455
455
  prompt_tokens = int(data.get("prompt_eval_count") or 0)
456
456
  completion_tokens = int(data.get("eval_count") or 0)
457
457
  total_tokens = prompt_tokens + completion_tokens
458
+ # This is the DERIVATION lane, and it had no timing signal at
459
+ # all — no streaming, no heartbeats, no usage rows. It also
460
+ # alternates models with chat, which evicts weights and pays a
461
+ # cold load the chat lane then blames on itself. Capture the
462
+ # same split here so the two lanes are comparable.
463
+ from topos.services.llm.openai import _ollama_timings
464
+
465
+ timings = _ollama_timings(data)
458
466
  return {
459
467
  "text": data.get("response", ""),
460
468
  "usage": {
461
469
  "prompt_tokens": max(0, prompt_tokens),
462
470
  "completion_tokens": max(0, completion_tokens),
463
471
  "total_tokens": max(0, total_tokens),
472
+ **({"timings": timings} if timings else {}),
464
473
  },
474
+ **({"timings": timings} if timings else {}),
465
475
  }
466
476
  except urllib.error.HTTPError as e:
467
477
  # Include the response body: Ollama puts the actionable message
@@ -273,7 +273,12 @@ class Engine:
273
273
  origin=origin,
274
274
  source_id=normalized.source_id,
275
275
  duration_ms=duration_ms,
276
- ttfb_ms=duration_ms,
276
+ # Engine.run is NON-STREAMING: the whole body arrives at
277
+ # once, so there is no first-token moment to measure here.
278
+ # Passing duration as ttfb manufactured the sentinel that
279
+ # poisoned the column — leave it unset and let the absence
280
+ # be visible.
281
+ ttfb_ms=None,
277
282
  )
278
283
  except Exception:
279
284
  logger.debug("Failed to emit engine llm usage observation", exc_info=True)
@@ -370,9 +370,16 @@ def emit_engine_llm_usage_observation(
370
370
  "provider": provider_key,
371
371
  "model": model_key,
372
372
  }
373
- # Non-streaming Engine.run: first token/body arrives with the completed response.
373
+ # ttfb_ms is RECORDED OR ABSENT — never inferred from duration.
374
+ #
375
+ # It used to default to `resolved_duration`, and the result was that 120 of
376
+ # 135 home-chat rows carried ttfb_ms == duration_ms. Every percentile anyone
377
+ # computed from that column was a duration percentile wearing a TTFB label,
378
+ # and the one metric this system is now being tuned for was, in effect, not
379
+ # measured at all. An honest NULL is a gap you can see; a plausible wrong
380
+ # number is one you cannot.
374
381
  resolved_duration = int(duration_ms) if duration_ms is not None else None
375
- resolved_ttfb = int(ttfb_ms) if ttfb_ms is not None else resolved_duration
382
+ resolved_ttfb = int(ttfb_ms) if ttfb_ms is not None else None
376
383
  metadata: Dict[str, Any] = {
377
384
  "purpose": purpose,
378
385
  "provider": provider_key,
@@ -232,6 +232,27 @@ def run_pack_backfill(conn: sqlite3.Connection, pack_id: str, limit: int = 500)
232
232
  conn.commit()
233
233
  conn.commit()
234
234
  stats["quarantined"] = writer.stats.get("quarantined", 0) - stats.pop("quarantined0")
235
+
236
+ # A backfill IS a run. Without this the registry keeps last_run_at NULL and
237
+ # the lens card reads "never run" over a pack that just wrote facts —
238
+ # observed 2026-09-03 on values.motivation, 73 records in, 11 facts out,
239
+ # card still blank. mark_pack_run is otherwise only called at the end of an
240
+ # ingest batch (derivation_job.py:292), which a quiet node may never have.
241
+ from .registry import mark_pack_run
242
+ mark_pack_run(conn, pack_id, pack.version)
243
+
244
+ # Embed what we just wrote, or the owner can see these facts on the Facts
245
+ # page and cannot ask about them: the semantic lane reads signal_embeddings,
246
+ # and the embedding job runs only when an ingest batch happens. Idempotent
247
+ # and incremental by content hash, so this is cheap when there is nothing
248
+ # new. Never fatal — the facts are already committed, and a missing
249
+ # embedding is a degraded answer, not a lost fact.
250
+ try:
251
+ from ...features.signal.derived_index import index_derived_objects
252
+ stats["indexed"] = int(index_derived_objects(conn).get("embedded", 0) or 0)
253
+ except Exception: # noqa: BLE001 — see comment above: never fatal
254
+ stats["indexed"] = -1
255
+ conn.commit()
235
256
  return stats
236
257
 
237
258
 
@@ -16,6 +16,40 @@ from ..storage.raw.file_store import RawFileStore
16
16
  logger = logging.getLogger("topos.ingestion.ingest_helpers")
17
17
 
18
18
 
19
+ def chat_ui_raw_payload(payload: dict, *, job_id: str, dataset_id: str) -> dict:
20
+ """Map a chat UI-stream record to the v1 raw shape {id, thread_id, role, content, created_at}.
21
+
22
+ The v1 chat vocabulary — {id, thread_id, role} — is what the file importer,
23
+ the schema registry, and the browser extension all send. Older store_message
24
+ callers used {message_id, conversation_id, sender_type}. Read v1 first and
25
+ fall back to the legacy names, so a client on either vocabulary lands
26
+ correctly. Reading ONLY the legacy names (the prior behaviour) mislabelled
27
+ every extension message role=user (sender_type absent), merged every chat
28
+ under the dataset id (conversation_id absent), and minted a fresh id per
29
+ record (message_id absent), defeating message-id idempotency.
30
+ """
31
+ role = str(payload.get("role") or "").strip()
32
+ if not role:
33
+ sender_type = payload.get("sender_type", "human")
34
+ role = "user" if sender_type == "human" else str(sender_type)
35
+ created_at = payload.get("created_at")
36
+ if created_at is None:
37
+ ts = payload.get("ts")
38
+ if isinstance(ts, (int, float)):
39
+ created_at = ts
40
+ elif isinstance(ts, str):
41
+ created_at = ts
42
+ else:
43
+ created_at = datetime.now(timezone.utc).timestamp()
44
+ return {
45
+ "id": str(payload.get("id") or payload.get("message_id") or job_id),
46
+ "thread_id": payload.get("thread_id") or payload.get("conversation_id") or dataset_id,
47
+ "role": role,
48
+ "content": payload.get("content", ""),
49
+ "created_at": created_at,
50
+ }
51
+
52
+
19
53
  def _ui_stream_passes_payload_through(source: Any, source_id: str) -> bool:
20
54
  """True when ui_stream ingest should forward the client payload to the source parser."""
21
55
  if source_id.startswith("browser_"):
@@ -207,25 +241,7 @@ async def ingest_ui_payload(
207
241
  # Legacy path: ChatGPT UI only (backward compatibility when source_id omitted or chatgpt default)
208
242
  file_store = RawFileStore()
209
243
  job_id = job_id or str(uuid.uuid4())
210
- sender_type = payload.get("sender_type", "human")
211
- role = "user" if sender_type == "human" else sender_type
212
- content = payload.get("content", "")
213
- created_at = payload.get("created_at")
214
- if created_at is None:
215
- ts = payload.get("ts")
216
- if isinstance(ts, (int, float)):
217
- created_at = ts
218
- elif isinstance(ts, str):
219
- created_at = ts
220
- else:
221
- created_at = datetime.now(timezone.utc).timestamp()
222
- record = {
223
- "id": payload.get("message_id") or job_id,
224
- "thread_id": payload.get("conversation_id") or dataset_id,
225
- "role": role,
226
- "content": content,
227
- "created_at": created_at,
228
- }
244
+ record = chat_ui_raw_payload(payload, job_id=job_id, dataset_id=dataset_id)
229
245
  logger.info(
230
246
  "[PIPELINE:RAW] Appending UI message to raw store: job_id=%s, dataset_id=%s, message_id=%s, content_preview=%s",
231
247
  job_id,
@@ -382,25 +398,7 @@ async def _ingest_ui_payload_direct(
382
398
  )
383
399
  raw_payload.setdefault("record_id", record_id)
384
400
  else:
385
- sender_type = payload.get("sender_type", "human")
386
- role = "user" if sender_type == "human" else sender_type
387
- content = payload.get("content", "")
388
- created_at = payload.get("created_at")
389
- if created_at is None:
390
- ts = payload.get("ts")
391
- if isinstance(ts, (int, float)):
392
- created_at = ts
393
- elif isinstance(ts, str):
394
- created_at = ts
395
- else:
396
- created_at = datetime.now(timezone.utc).timestamp()
397
- raw_payload = {
398
- "id": payload.get("message_id") or job_id,
399
- "thread_id": payload.get("conversation_id") or dataset_id,
400
- "role": role,
401
- "content": content,
402
- "created_at": created_at,
403
- }
401
+ raw_payload = chat_ui_raw_payload(payload, job_id=job_id, dataset_id=dataset_id)
404
402
  record_id = raw_payload["id"]
405
403
  raw_record = RawRecord(record_id=record_id, payload=raw_payload)
406
404
 
@@ -95,6 +95,8 @@
95
95
  "graph_lane",
96
96
  "gate_vetoed",
97
97
  "grantee_scrub_facts",
98
+ "hosted_binding_text_withheld",
99
+ "owner_permission_claim_replaced",
98
100
  "grantee_scrub_scores",
99
101
  "grantee_scrub_semantic_hits",
100
102
  "grantee_scrub_summaries",
@@ -255,6 +255,8 @@ REASONS = frozenset(
255
255
  "no_source_connected",
256
256
  # --- engine: the grantee content filter, one per scrubbed artifact list
257
257
  "grantee_scrub_facts",
258
+ "hosted_binding_text_withheld",
259
+ "owner_permission_claim_replaced",
258
260
  "grantee_scrub_scores",
259
261
  "grantee_scrub_semantic_hits",
260
262
  "grantee_scrub_summaries",
@@ -25,7 +25,7 @@ from .inference import run_query_inference
25
25
  from .intent import compute_intent_hash
26
26
  from .manifest import ScopeResolutionManifest
27
27
  from .minimizer import DisclosureMinimizer
28
- from .narrowing import NarrowingLedger, result_is_empty
28
+ from .narrowing import STAGE_DISCLOSURE, NarrowingLedger, result_is_empty
29
29
  from . import narrowing as _N
30
30
  from .negotiation import DEFAULT_MAX_ROUNDS, build_narrow_request_response, qualify_intent
31
31
  from .retrieval import DefaultSignalRetrievalAdapter, resolve_retrieval_source_ids
@@ -48,6 +48,57 @@ _NOT_QUERIED_OUTCOMES = frozenset(
48
48
  )
49
49
 
50
50
 
51
+ #: Item containers in `public_result` that carry generated or quoted prose.
52
+ #: Declared rather than recursed, the same choice `disclosure._GRANTEE_DICT_ARTIFACTS`
53
+ #: makes and for the same reason: a new artifact has to be listed here, and the
54
+ #: listing is the review.
55
+ _HOSTED_FLOOR_ITEM_KEYS = ("summaries", "scores", "semantic_hits", "items", "facts")
56
+
57
+
58
+ def withhold_text_for_hosted_binding(
59
+ public_dict: Dict[str, Any], *, ledger: Optional[NarrowingLedger] = None
60
+ ) -> int:
61
+ """Strip prose from a floored turn's payload, keeping its shape.
62
+
63
+ Identity, provenance, rank and dates survive: a caller can still see THAT
64
+ something matched and how strongly, and the turn stays legible. The words
65
+ do not travel. Emptying the lists instead would be worse than useless —
66
+ an empty result is indistinguishable from a corpus that held nothing,
67
+ which is the false-absence failure this whole plan exists to end, so the
68
+ withholding is declared in the ledger rather than performed in silence.
69
+
70
+ Returns the number of text fields removed, so a caller can assert the cap
71
+ actually did something (a severed-wire lever, and the reason this is a
72
+ module-level function rather than an inline loop).
73
+ """
74
+ from .disclosure import _GRANTEE_TEXT_KEYS
75
+
76
+ removed = 0
77
+ for container in _HOSTED_FLOOR_ITEM_KEYS:
78
+ items = public_dict.get(container)
79
+ if not isinstance(items, list):
80
+ continue
81
+ for item in items:
82
+ if not isinstance(item, dict):
83
+ continue
84
+ for key in _GRANTEE_TEXT_KEYS:
85
+ if item.get(key):
86
+ item[key] = ""
87
+ removed += 1
88
+ # The free-text answer is the same content in one field.
89
+ if public_dict.get("answer") and public_dict.get("answer_type") not in ("band", "yes_no"):
90
+ public_dict["answer"] = ""
91
+ removed += 1
92
+ if removed and ledger is not None:
93
+ ledger.record(
94
+ STAGE_DISCLOSURE,
95
+ "excluded",
96
+ "hosted_binding_text_withheld",
97
+ dropped=removed,
98
+ )
99
+ return removed
100
+
101
+
51
102
  def _attach_narrowing(result: Dict[str, Any], ledger: NarrowingLedger) -> Dict[str, Any]:
52
103
  """Put the ledger on the response, and attribute any empty the body did not.
53
104
 
@@ -853,6 +904,17 @@ class QueryPipelineOrchestrator:
853
904
  public.payload = enforce_availability_inference_contract(public.payload)
854
905
 
855
906
  public_dict = public.to_dict()
907
+ # The hosted-binding floor reaches the ANSWER, not only the packet.
908
+ # `effective_packet_resolution` gates what the engine's own model reads;
909
+ # summary prose does not stop there — it rides `public_result` to
910
+ # whatever model writes the reply, and on a hosted pack that model is
911
+ # the hosted one. Measured on an owner snapshot 2026-09-03: a turn
912
+ # reporting `scores_only`/`hosted_binding` still carried 60,151
913
+ # characters of the owner's conversation text, byte-identical to the
914
+ # same query on a local binding. The protection read as active on the
915
+ # turn that carried the content out.
916
+ if _pr["effective"] == "scores_only" and _pr["reason"] == "hosted_binding":
917
+ withhold_text_for_hosted_binding(public_dict, ledger=ledger)
856
918
  # Declared, never silent: every turn says what resolution actually applied and
857
919
  # why (active / non_owner_floor / hosted_binding). Same post-hoc pattern as
858
920
  # `empty_cause` below.
@@ -181,7 +181,70 @@ async def _ollama_generate(payload: Dict[str, Any]) -> Dict[str, Any]:
181
181
  "completion_tokens": completion_tokens,
182
182
  "total_tokens": total_tokens,
183
183
  }
184
- return {"output": text, "model": resp_model, "usage": usage}
184
+ timings = _ollama_timings(data)
185
+ if timings:
186
+ usage = {**usage, "timings": timings}
187
+ return {"output": text, "model": resp_model, "usage": usage, "timings": timings}
188
+
189
+
190
+ #: Nanoseconds-to-milliseconds, rounded to whole ms — the resolution anyone
191
+ #: reasons about latency in. Ollama reports every duration in ns.
192
+ def _ms(value: Any) -> int:
193
+ try:
194
+ return int(round(float(value) / 1e6))
195
+ except (TypeError, ValueError):
196
+ return 0
197
+
198
+
199
+ def _ollama_timings(data: Dict[str, Any]) -> Dict[str, Any]:
200
+ """Split a generation into load, prefill and decode.
201
+
202
+ Ollama puts ``total_duration``, ``load_duration``, ``prompt_eval_duration``
203
+ and ``eval_duration`` on the SAME terminating JSON object we already read
204
+ token counts from, and every one of them was being thrown away — at four
205
+ parse sites, for the whole life of this codebase. A repo-wide search for
206
+ ``load_duration`` found two hits, both prose in a plan document: it was
207
+ specified and never built.
208
+
209
+ Without the split, "the model was slow" is unanswerable. With it the three
210
+ causes separate cleanly. Measured on this machine 2026-09-03:
211
+
212
+ * ``load`` — weights into memory. Cold 5,695 ms on a 27B, warm 4.7 ms. The
213
+ 544x separation is why ``cold`` below is a threshold and not a guess.
214
+ * ``prefill`` — reading the prompt. THE one that matters: it IS
215
+ time-to-first-token, ~65-90 tok/s, and 78 s of a real turn.
216
+ * ``decode`` — writing the answer, 3.4-10.1 tok/s. Caching cannot touch it.
217
+
218
+ ``prefill_cached`` is a prefix-cache hit, and it is deliberately NOT
219
+ ``prompt_eval_duration == 0``: measured hits ran 74-191 ms on a 3B and
220
+ ~6,300 ms on a 27B, and ``prompt_eval_count`` still reports the FULL prompt
221
+ on a hit, so the duration is the only signal there is.
222
+ """
223
+ load_ms = _ms(data.get("load_duration"))
224
+ prefill_ms = _ms(data.get("prompt_eval_duration"))
225
+ decode_ms = _ms(data.get("eval_duration"))
226
+ prompt_toks = int(data.get("prompt_eval_count") or 0)
227
+ completion_toks = int(data.get("eval_count") or 0)
228
+ timings: Dict[str, Any] = {
229
+ "load_ms": load_ms,
230
+ "prefill_ms": prefill_ms,
231
+ "decode_ms": decode_ms,
232
+ "total_ms": _ms(data.get("total_duration")),
233
+ # A cold load is 3 orders of magnitude from a warm one; 1s sits in the
234
+ # empty middle of that gap rather than near either edge.
235
+ "cold": load_ms >= 1000,
236
+ }
237
+ if prompt_toks and prefill_ms > 0:
238
+ timings["prefill_tok_s"] = round(prompt_toks * 1000.0 / prefill_ms, 1)
239
+ if completion_toks and decode_ms > 0:
240
+ timings["decode_tok_s"] = round(completion_toks * 1000.0 / decode_ms, 1)
241
+ # A hit still reports the full prompt_eval_count, so infer from the RATE:
242
+ # anything an order of magnitude above the machine's real prefill speed is
243
+ # cache reuse, not arithmetic.
244
+ rate = timings.get("prefill_tok_s")
245
+ if isinstance(rate, float) and rate > 500.0:
246
+ timings["prefill_cached"] = True
247
+ return timings
185
248
 
186
249
 
187
250
  async def _ollama_stream_generate(
@@ -245,6 +308,9 @@ async def _ollama_stream_generate(
245
308
  prompt_tokens = 0
246
309
  completion_tokens = 0
247
310
  done_reason = ""
311
+ # Stays empty when the stream ends without a terminating frame — a dropped
312
+ # connection must not raise a NameError on the way out.
313
+ timings: Dict[str, Any] = {}
248
314
  # Liveness (plan §2): phase-aware heartbeats whenever nothing else flows —
249
315
  # 10s pre-first-token (load + prefill are silent), 30s mid-stream. Emitted
250
316
  # frames of any kind reset the clock.
@@ -306,6 +372,7 @@ async def _ollama_stream_generate(
306
372
  prompt_tokens = int(data.get("prompt_eval_count") or prompt_tokens)
307
373
  completion_tokens = int(data.get("eval_count") or completion_tokens)
308
374
  done_reason = str(data.get("done_reason") or "")
375
+ timings = _ollama_timings(data)
309
376
  except httpx.RequestError as exc:
310
377
  raise HTTPException(
311
378
  status_code=status.HTTP_502_BAD_GATEWAY,
@@ -335,6 +402,13 @@ async def _ollama_stream_generate(
335
402
  "total_tokens": total_tokens,
336
403
  }
337
404
  result: Dict[str, Any] = {"output": text, "model": resp_model, "usage": usage}
405
+ # Nested under usage on purpose: the browser whitelists exactly
406
+ # output/model/usage (homeLlmStream.ts:415), and the control plane passes
407
+ # the payload through verbatim (_final_payload, llm_generation_sse.py:353),
408
+ # so timings reach the UI with NO control-plane change.
409
+ if timings:
410
+ result["usage"] = {**usage, "timings": timings}
411
+ result["timings"] = timings
338
412
  if thinking_chars:
339
413
  result["thinking_chars"] = thinking_chars
340
414
  if done_reason:
@@ -795,16 +795,30 @@
795
795
  "id": "index-goals-into-derived-index",
796
796
  "kind": "derived_rebuild",
797
797
  "title": "Embed stated goals into the derived index",
798
- "targets": [
799
- "derived_object_index"
800
- ],
801
798
  "why": "Goals were the last uncovered derived type: measured on a live node 2026-09-03, 1,548 user_goals + 68 Goal objects carried the owner's own prose and NONE were embedded, so 'what am I trying to achieve commercially?' reached a GitHub dossier and a stray fact while the goals sat one table away. The index pass is incremental by content hash, so this embeds only the newly-renderable goal objects; dossiers, facts and edges are unchanged.",
802
799
  "cost": "seconds",
803
- "consent": "auto"
800
+ "consent": "auto",
801
+ "params": {
802
+ "targets": [
803
+ "derived_object_index"
804
+ ]
805
+ }
804
806
  }
805
807
  ],
806
808
  "notes": []
807
809
  },
810
+ {
811
+ "version": "1.3.48",
812
+ "summary": "Release 1.3.48.",
813
+ "steps": [],
814
+ "notes": []
815
+ },
816
+ {
817
+ "version": "1.3.49",
818
+ "summary": "Release 1.3.49.",
819
+ "steps": [],
820
+ "notes": []
821
+ },
808
822
  {
809
823
  "version": "unreleased",
810
824
  "summary": "Staging entry for in-flight PRs. cut_release.py stamps this with the next version at release cut. Never executed by steps_between.",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.47
3
+ Version: 1.3.49
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
File without changes
File without changes
File without changes
File without changes
File without changes