topos-node 1.2.5__tar.gz → 1.2.7__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 (541) hide show
  1. {topos_node-1.2.5/topos_node.egg-info → topos_node-1.2.7}/PKG-INFO +1 -1
  2. {topos_node-1.2.5 → topos_node-1.2.7}/pyproject.toml +1 -1
  3. {topos_node-1.2.5 → topos_node-1.2.7}/topos/__version__.py +2 -2
  4. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/tool_index.py +5 -0
  5. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/query.py +13 -0
  6. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/tool_index.py +8 -0
  7. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/tool_index.py +57 -1
  8. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/game_layer.py +4 -0
  9. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/retrieval.py +111 -15
  10. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/sqlite/stores.py +9 -2
  11. {topos_node-1.2.5 → topos_node-1.2.7/topos_node.egg-info}/PKG-INFO +1 -1
  12. {topos_node-1.2.5 → topos_node-1.2.7}/LICENSE +0 -0
  13. {topos_node-1.2.5 → topos_node-1.2.7}/MANIFEST.in +0 -0
  14. {topos_node-1.2.5 → topos_node-1.2.7}/README.md +0 -0
  15. {topos_node-1.2.5 → topos_node-1.2.7}/setup.cfg +0 -0
  16. {topos_node-1.2.5 → topos_node-1.2.7}/shared/__init__.py +0 -0
  17. {topos_node-1.2.5 → topos_node-1.2.7}/shared/filtering.py +0 -0
  18. {topos_node-1.2.5 → topos_node-1.2.7}/shared/schema_registry.py +0 -0
  19. {topos_node-1.2.5 → topos_node-1.2.7}/tests/test_extensions.py +0 -0
  20. {topos_node-1.2.5 → topos_node-1.2.7}/tests/test_llm_integrations_storage.py +0 -0
  21. {topos_node-1.2.5 → topos_node-1.2.7}/tests/test_protocol_handled_types.py +0 -0
  22. {topos_node-1.2.5 → topos_node-1.2.7}/topos/__init__.py +0 -0
  23. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/__init__.py +0 -0
  24. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/duckdb_adapter.py +0 -0
  25. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/messenger_communities.py +0 -0
  26. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/messenger_graph.py +0 -0
  27. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/messenger_labels.py +0 -0
  28. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/profiles.py +0 -0
  29. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/query_engine.py +0 -0
  30. {topos_node-1.2.5 → topos_node-1.2.7}/topos/analytics/raw_queries.py +0 -0
  31. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/__init__.py +0 -0
  32. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/analytics.py +0 -0
  33. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/app_registry.py +0 -0
  34. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/backup.py +0 -0
  35. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/compute_remote.py +0 -0
  36. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/data_commit.py +0 -0
  37. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/data_explorer_table_prefs.py +0 -0
  38. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/database_explorer.py +0 -0
  39. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/db.py +0 -0
  40. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/device.py +0 -0
  41. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/engine_run.py +0 -0
  42. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/enrichment.py +0 -0
  43. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/enrichment_lab.py +0 -0
  44. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/filter_lab.py +0 -0
  45. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/health.py +0 -0
  46. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/home_chat.py +0 -0
  47. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/ingestion_api.py +0 -0
  48. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/ingestion_compat.py +0 -0
  49. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/ingestion_sources.py +0 -0
  50. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/intelligence_lifecycle.py +0 -0
  51. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/llm.py +0 -0
  52. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/local_mcp.py +0 -0
  53. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/messenger_analytics.py +0 -0
  54. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/privacy_disclose.py +0 -0
  55. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/query_api.py +0 -0
  56. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/runtime_bootstrap.py +0 -0
  57. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/sanitization_ollama_config.py +0 -0
  58. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/signal.py +0 -0
  59. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/signal_extraction_config.py +0 -0
  60. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/source_install.py +0 -0
  61. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/source_scrub.py +0 -0
  62. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/sources.py +0 -0
  63. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/sources_overview.py +0 -0
  64. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/sync.py +0 -0
  65. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/ui_config.py +0 -0
  66. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/uma_data.py +0 -0
  67. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/upgrades.py +0 -0
  68. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/usage.py +0 -0
  69. {topos_node-1.2.5 → topos_node-1.2.7}/topos/api/user_identity.py +0 -0
  70. {topos_node-1.2.5 → topos_node-1.2.7}/topos/app.py +0 -0
  71. {topos_node-1.2.5 → topos_node-1.2.7}/topos/auth.py +0 -0
  72. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/__init__.py +0 -0
  73. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/__init__.py +0 -0
  74. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/base.py +0 -0
  75. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  76. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  77. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  78. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  79. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  80. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  81. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  82. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  83. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/models.py +0 -0
  84. {topos_node-1.2.5 → topos_node-1.2.7}/topos/canonicalization/resolver.py +0 -0
  85. {topos_node-1.2.5 → topos_node-1.2.7}/topos/cli/__init__.py +0 -0
  86. {topos_node-1.2.5 → topos_node-1.2.7}/topos/cli/__main__.py +0 -0
  87. {topos_node-1.2.5 → topos_node-1.2.7}/topos/cli/commands.py +0 -0
  88. {topos_node-1.2.5 → topos_node-1.2.7}/topos/config/__init__.py +0 -0
  89. {topos_node-1.2.5 → topos_node-1.2.7}/topos/config/sanitization_ollama.py +0 -0
  90. {topos_node-1.2.5 → topos_node-1.2.7}/topos/config/settings.py +0 -0
  91. {topos_node-1.2.5 → topos_node-1.2.7}/topos/config/signal_extraction.py +0 -0
  92. {topos_node-1.2.5 → topos_node-1.2.7}/topos/config/uvicorn_logging.json +0 -0
  93. {topos_node-1.2.5 → topos_node-1.2.7}/topos/contacts/__init__.py +0 -0
  94. {topos_node-1.2.5 → topos_node-1.2.7}/topos/contacts/identity.py +0 -0
  95. {topos_node-1.2.5 → topos_node-1.2.7}/topos/control_plane_client.py +0 -0
  96. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/__init__.py +0 -0
  97. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/api_models.py +0 -0
  98. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/connection_resilience.py +0 -0
  99. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/device_helpers.py +0 -0
  100. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/errors.py +0 -0
  101. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/events.py +0 -0
  102. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/__init__.py +0 -0
  103. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/common.py +0 -0
  104. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/config.py +0 -0
  105. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/contacts_import.py +0 -0
  106. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/database_explorer.py +0 -0
  107. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/device.py +0 -0
  108. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/enrichment.py +0 -0
  109. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/enrichment_lab.py +0 -0
  110. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/filter_lab.py +0 -0
  111. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/home_chat.py +0 -0
  112. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/ingest.py +0 -0
  113. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/messages.py +0 -0
  114. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/messenger_analytics.py +0 -0
  115. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/registry.py +0 -0
  116. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/routines.py +0 -0
  117. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/signal_features.py +0 -0
  118. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/sources.py +0 -0
  119. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/handlers/uma.py +0 -0
  120. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/logging.py +0 -0
  121. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/metrics.py +0 -0
  122. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/routine_access.py +0 -0
  123. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/startup_banner.py +0 -0
  124. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/state.py +0 -0
  125. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/table_layers.py +0 -0
  126. {topos_node-1.2.5 → topos_node-1.2.7}/topos/core/types.py +0 -0
  127. {topos_node-1.2.5 → topos_node-1.2.7}/topos/data_explorer_row_delete.py +0 -0
  128. {topos_node-1.2.5 → topos_node-1.2.7}/topos/data_explorer_table_prefs.py +0 -0
  129. {topos_node-1.2.5 → topos_node-1.2.7}/topos/data_explorer_tables.py +0 -0
  130. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/__init__.py +0 -0
  131. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/canonical_writer.py +0 -0
  132. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/content_policy.py +0 -0
  133. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/field_registry.py +0 -0
  134. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/privacy_layer.py +0 -0
  135. {topos_node-1.2.5 → topos_node-1.2.7}/topos/disclosure/tier.py +0 -0
  136. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/__init__.py +0 -0
  137. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/__init__.py +0 -0
  138. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/base.py +0 -0
  139. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/generative_prompts.py +0 -0
  140. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/generative_response.py +0 -0
  141. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/huggingface.py +0 -0
  142. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/ollama.py +0 -0
  143. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/openai.py +0 -0
  144. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/openai_compatible.py +0 -0
  145. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/redpill.py +0 -0
  146. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/backends/stub.py +0 -0
  147. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/client.py +0 -0
  148. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/engine.py +0 -0
  149. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/intake.py +0 -0
  150. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/memory_utils.py +0 -0
  151. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/model_cache.py +0 -0
  152. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/pipeline_memory.py +0 -0
  153. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/queue_manager.py +0 -0
  154. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/registration.py +0 -0
  155. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/result_formatter.py +0 -0
  156. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/router.py +0 -0
  157. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/scoped_token.py +0 -0
  158. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/tasks.py +0 -0
  159. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/transport.py +0 -0
  160. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/usage_guard.py +0 -0
  161. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/usage_observation.py +0 -0
  162. {topos_node-1.2.5 → topos_node-1.2.7}/topos/engine/validator.py +0 -0
  163. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/__init__.py +0 -0
  164. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/catalog.py +0 -0
  165. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/derived_tables.py +0 -0
  166. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/job_writer.py +0 -0
  167. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/__init__.py +0 -0
  168. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/base.py +0 -0
  169. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  170. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  171. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  172. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  173. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  174. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  175. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  176. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  177. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  178. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  179. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  180. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  181. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  182. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  183. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  184. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  185. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  186. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  187. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/url_classification_core.py +0 -0
  188. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/url_classification_enrichment_job.py +0 -0
  189. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/canonical/url_classification_signal_job.py +0 -0
  190. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/raw/__init__.py +0 -0
  191. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  192. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/raw/language_job.py +0 -0
  193. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  194. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  195. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/model_overrides.py +0 -0
  196. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/models/__init__.py +0 -0
  197. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/models/manager.py +0 -0
  198. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/models/mvp_defaults.py +0 -0
  199. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/models/registry.py +0 -0
  200. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/models/versioning.py +0 -0
  201. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/orchestrator.py +0 -0
  202. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/processor.py +0 -0
  203. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/progress_bar.py +0 -0
  204. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/registry_contract.py +0 -0
  205. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/signal_derivation_config.json +0 -0
  206. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/source_overrides.py +0 -0
  207. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment/website_classifier.py +0 -0
  208. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/__init__.py +0 -0
  209. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/bundles.py +0 -0
  210. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/model_resolve.py +0 -0
  211. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/schema.py +0 -0
  212. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/service.py +0 -0
  213. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/store.py +0 -0
  214. {topos_node-1.2.5 → topos_node-1.2.7}/topos/enrichment_lab/worker.py +0 -0
  215. {topos_node-1.2.5 → topos_node-1.2.7}/topos/evals/__init__.py +0 -0
  216. {topos_node-1.2.5 → topos_node-1.2.7}/topos/evals/enrichment_eval.py +0 -0
  217. {topos_node-1.2.5 → topos_node-1.2.7}/topos/extensions.py +0 -0
  218. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/__init__.py +0 -0
  219. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/consolidation.py +0 -0
  220. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/declared_mappings.py +0 -0
  221. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/dossier.py +0 -0
  222. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/edges.py +0 -0
  223. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/fact_materializer.py +0 -0
  224. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/graph_enrichers.py +0 -0
  225. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/graph_refresh.py +0 -0
  226. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/graph_search.py +0 -0
  227. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/linking.py +0 -0
  228. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/maintenance.py +0 -0
  229. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/reads.py +0 -0
  230. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/entities/resolver.py +0 -0
  231. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/facts/__init__.py +0 -0
  232. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/facts/extract.py +0 -0
  233. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/facts/llm_extract.py +0 -0
  234. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/facts/reads.py +0 -0
  235. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/facts/store.py +0 -0
  236. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/fit/evaluator.py +0 -0
  237. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/fit/opportunity_types.json +0 -0
  238. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/lifecycle/__init__.py +0 -0
  239. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/lifecycle/derived_scrub.py +0 -0
  240. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/lifecycle/exclusions.py +0 -0
  241. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/lifecycle/gc.py +0 -0
  242. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/provenance/__init__.py +0 -0
  243. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/provenance/posture.py +0 -0
  244. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/provenance/roles.py +0 -0
  245. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/__init__.py +0 -0
  246. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/brief_canonical_loader.py +0 -0
  247. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/brief_ontology.py +0 -0
  248. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/brief_renderer.py +0 -0
  249. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/brief_schemas.py +0 -0
  250. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/chunking.py +0 -0
  251. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/cluster_labels.py +0 -0
  252. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/data_health.py +0 -0
  253. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  254. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/intentions.json +0 -0
  255. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/profile.json +0 -0
  256. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/relationships.json +0 -0
  257. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  258. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/time.json +0 -0
  259. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/definitions/work.json +0 -0
  260. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/dimension_briefs.py +0 -0
  261. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/dimension_definition_loader.py +0 -0
  262. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/dimension_profiles.py +0 -0
  263. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/dimension_registry.py +0 -0
  264. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/embed_context.py +0 -0
  265. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/extraction/artifact_router.py +0 -0
  266. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/extraction/artifact_store.py +0 -0
  267. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/extraction/rule_extractors.py +0 -0
  268. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/graph_sanitize.py +0 -0
  269. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/hybrid_search.py +0 -0
  270. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/incremental_clustering.py +0 -0
  271. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/model_recommendations.py +0 -0
  272. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/query_embed_cache.py +0 -0
  273. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/schemas.py +0 -0
  274. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/service.py +0 -0
  275. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/signal_object_store.py +0 -0
  276. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/source_hydration.py +0 -0
  277. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/structured_signal.py +0 -0
  278. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/topic_clustering.py +0 -0
  279. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/typed_stores/aggregates.py +0 -0
  280. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  281. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/vector_codec.py +0 -0
  282. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/vector_math.py +0 -0
  283. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/signal/vector_settings.py +0 -0
  284. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/stats/__init__.py +0 -0
  285. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/stats/definitions.py +0 -0
  286. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/stats/engine.py +0 -0
  287. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/stats/fold.py +0 -0
  288. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/stats/insights.py +0 -0
  289. {topos_node-1.2.5 → topos_node-1.2.7}/topos/features/timeline_projection.py +0 -0
  290. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/__init__.py +0 -0
  291. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/bundles.py +0 -0
  292. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/schema.py +0 -0
  293. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/service.py +0 -0
  294. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/store.py +0 -0
  295. {topos_node-1.2.5 → topos_node-1.2.7}/topos/filter_lab/worker.py +0 -0
  296. {topos_node-1.2.5 → topos_node-1.2.7}/topos/home_chat/__init__.py +0 -0
  297. {topos_node-1.2.5 → topos_node-1.2.7}/topos/home_chat/schema.py +0 -0
  298. {topos_node-1.2.5 → topos_node-1.2.7}/topos/home_chat/store.py +0 -0
  299. {topos_node-1.2.5 → topos_node-1.2.7}/topos/hosted_pool_lease.py +0 -0
  300. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/__init__.py +0 -0
  301. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/canonical_pipeline.py +0 -0
  302. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/checkpoints/__init__.py +0 -0
  303. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  304. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  305. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/inbox_crypto.py +0 -0
  306. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/inbox_drain.py +0 -0
  307. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/ingest_helpers.py +0 -0
  308. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/jobs.py +0 -0
  309. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/journal_location_fanout.py +0 -0
  310. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/journal_time_log_normalize.py +0 -0
  311. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/local_sync.py +0 -0
  312. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/log_preview.py +0 -0
  313. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/manager.py +0 -0
  314. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parser.py +0 -0
  315. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/__init__.py +0 -0
  316. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/base.py +0 -0
  317. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/browser_parser.py +0 -0
  318. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/calendar_parser.py +0 -0
  319. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  320. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  321. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  322. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/documents_parser.py +0 -0
  323. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  324. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  325. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/grok_parser.py +0 -0
  326. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/messenger_parser.py +0 -0
  327. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  328. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/progress.py +0 -0
  329. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/reprocess.py +0 -0
  330. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/__init__.py +0 -0
  331. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/base.py +0 -0
  332. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/calendar.py +0 -0
  333. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/chatgpt.py +0 -0
  334. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/contact_importers.py +0 -0
  335. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/grok.py +0 -0
  336. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/imessage_reader.py +0 -0
  337. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/signal_export_parser.py +0 -0
  338. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/sources/signal_reader.py +0 -0
  339. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/state_machine.py +0 -0
  340. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/triggers/__init__.py +0 -0
  341. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/triggers/file_trigger.py +0 -0
  342. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  343. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  344. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/validation/__init__.py +0 -0
  345. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/validation/base.py +0 -0
  346. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/validation/schema_registry.py +0 -0
  347. {topos_node-1.2.5 → topos_node-1.2.7}/topos/ingestion/validation/schema_validator.py +0 -0
  348. {topos_node-1.2.5 → topos_node-1.2.7}/topos/lineage/__init__.py +0 -0
  349. {topos_node-1.2.5 → topos_node-1.2.7}/topos/lineage/provenance.py +0 -0
  350. {topos_node-1.2.5 → topos_node-1.2.7}/topos/lineage/tracker.py +0 -0
  351. {topos_node-1.2.5 → topos_node-1.2.7}/topos/llm_integrations_storage.py +0 -0
  352. {topos_node-1.2.5 → topos_node-1.2.7}/topos/mcp_stdio_proxy.py +0 -0
  353. {topos_node-1.2.5 → topos_node-1.2.7}/topos/observability/__init__.py +0 -0
  354. {topos_node-1.2.5 → topos_node-1.2.7}/topos/observability/alerts.py +0 -0
  355. {topos_node-1.2.5 → topos_node-1.2.7}/topos/observability/metrics.py +0 -0
  356. {topos_node-1.2.5 → topos_node-1.2.7}/topos/observability/tracing.py +0 -0
  357. {topos_node-1.2.5 → topos_node-1.2.7}/topos/openai_client.py +0 -0
  358. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/__init__.py +0 -0
  359. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/audit.py +0 -0
  360. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/envelope.py +0 -0
  361. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/job_runner.py +0 -0
  362. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/job_store.py +0 -0
  363. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/stages.py +0 -0
  364. {topos_node-1.2.5 → topos_node-1.2.7}/topos/pipeline/stub_enqueue.py +0 -0
  365. {topos_node-1.2.5 → topos_node-1.2.7}/topos/projections/__init__.py +0 -0
  366. {topos_node-1.2.5 → topos_node-1.2.7}/topos/projections/vector_index/__init__.py +0 -0
  367. {topos_node-1.2.5 → topos_node-1.2.7}/topos/projections/vector_index/base.py +0 -0
  368. {topos_node-1.2.5 → topos_node-1.2.7}/topos/projections/vector_index/builders.py +0 -0
  369. {topos_node-1.2.5 → topos_node-1.2.7}/topos/projections/vector_index/health_checks.py +0 -0
  370. {topos_node-1.2.5 → topos_node-1.2.7}/topos/protocol/__init__.py +0 -0
  371. {topos_node-1.2.5 → topos_node-1.2.7}/topos/protocol/handled_message_types.json +0 -0
  372. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/__init__.py +0 -0
  373. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/audit.py +0 -0
  374. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/ddr.py +0 -0
  375. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/disclosure.py +0 -0
  376. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/fingerprint.py +0 -0
  377. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/grant_cache.py +0 -0
  378. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/inference.py +0 -0
  379. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/intent.py +0 -0
  380. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/manifest.py +0 -0
  381. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/manifest_validation.py +0 -0
  382. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/minimizer.py +0 -0
  383. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/negotiation.py +0 -0
  384. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/pipeline.py +0 -0
  385. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/planner.py +0 -0
  386. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/runtime.py +0 -0
  387. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/scope_registry.json +0 -0
  388. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/scope_registry_loader.py +0 -0
  389. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/session.py +0 -0
  390. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/session_utils.py +0 -0
  391. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/source_generation.py +0 -0
  392. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/turn_classifier.py +0 -0
  393. {topos_node-1.2.5 → topos_node-1.2.7}/topos/query/types.py +0 -0
  394. {topos_node-1.2.5 → topos_node-1.2.7}/topos/rate_limit.py +0 -0
  395. {topos_node-1.2.5 → topos_node-1.2.7}/topos/routines/__init__.py +0 -0
  396. {topos_node-1.2.5 → topos_node-1.2.7}/topos/routines/schema.py +0 -0
  397. {topos_node-1.2.5 → topos_node-1.2.7}/topos/routines/store.py +0 -0
  398. {topos_node-1.2.5 → topos_node-1.2.7}/topos/runtime_shutdown.py +0 -0
  399. {topos_node-1.2.5 → topos_node-1.2.7}/topos/runtime_update.py +0 -0
  400. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sanitization/__init__.py +0 -0
  401. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sanitization/nsfw_classifier.py +0 -0
  402. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sanitization/ollama_transforms.py +0 -0
  403. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sanitization/prewarm.py +0 -0
  404. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sanitization/privacy_filter.py +0 -0
  405. {topos_node-1.2.5 → topos_node-1.2.7}/topos/scope_resolution.py +0 -0
  406. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/__init__.py +0 -0
  407. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/container.py +0 -0
  408. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/embeddings/__init__.py +0 -0
  409. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/embeddings/base.py +0 -0
  410. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/embeddings/local.py +0 -0
  411. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/embeddings/remote.py +0 -0
  412. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/interfaces.py +0 -0
  413. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/llm/__init__.py +0 -0
  414. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/llm/base.py +0 -0
  415. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/llm/openai.py +0 -0
  416. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/local.py +0 -0
  417. {topos_node-1.2.5 → topos_node-1.2.7}/topos/services/postgres.py +0 -0
  418. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/__init__.py +0 -0
  419. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/bundled_canonical_triples.py +0 -0
  420. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/canonical_signal_defaults.py +0 -0
  421. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/definitions.py +0 -0
  422. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/install_service.py +0 -0
  423. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/registry.py +0 -0
  424. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/runtime_install.py +0 -0
  425. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/scrub_attribution.py +0 -0
  426. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sources/scrub_service.py +0 -0
  427. {topos_node-1.2.5 → topos_node-1.2.7}/topos/startup_banner.py +0 -0
  428. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/__init__.py +0 -0
  429. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/__init__.py +0 -0
  430. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/factory.py +0 -0
  431. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/fakes.py +0 -0
  432. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/postgres/stores.py +0 -0
  433. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/protocols.py +0 -0
  434. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/sqlite/__init__.py +0 -0
  435. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  436. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/__init__.py +0 -0
  437. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/activity_tables.py +0 -0
  438. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  439. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  440. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  441. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/ai_chat/model.py +0 -0
  442. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/ai_chat/tables.py +0 -0
  443. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  444. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/canonical_store.py +0 -0
  445. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/conversations_tables.py +0 -0
  446. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/mapping_store.py +0 -0
  447. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/canonical/postgres.py +0 -0
  448. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/__init__.py +0 -0
  449. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/client.py +0 -0
  450. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/connection_tuning.py +0 -0
  451. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/__init__.py +0 -0
  452. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  453. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  454. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  455. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  456. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  457. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  458. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  459. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/documents_v1.py +0 -0
  460. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  461. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/episodes_v1.py +0 -0
  462. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  463. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  464. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  465. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  466. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  467. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  468. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  469. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  470. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  471. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  472. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  473. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/signal_objects.py +0 -0
  474. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  475. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  476. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  477. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  478. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  479. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  480. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  481. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  482. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  483. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  484. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  485. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  486. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  487. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  488. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  489. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  490. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  491. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  492. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  493. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  494. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  495. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/paths.py +0 -0
  496. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/postgres.py +0 -0
  497. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/schema.py +0 -0
  498. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/storage_breakdown.py +0 -0
  499. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/db/write_gate.py +0 -0
  500. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/enrichment/__init__.py +0 -0
  501. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  502. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  503. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/normalized/__init__.py +0 -0
  504. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/normalized/normalized_store.py +0 -0
  505. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/oplog/__init__.py +0 -0
  506. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/oplog/decision.py +0 -0
  507. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/oplog/oplog_store.py +0 -0
  508. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/oplog/postgres.py +0 -0
  509. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/person/identity_resolver.py +0 -0
  510. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/projections/__init__.py +0 -0
  511. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/projections/index_ops_store.py +0 -0
  512. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/projections/vector_index_store.py +0 -0
  513. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/__init__.py +0 -0
  514. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/browser_flat_tables.py +0 -0
  515. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/file_store.py +0 -0
  516. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/raw_store.py +0 -0
  517. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/raw_tables_manager.py +0 -0
  518. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/raw/sqlite_raw_store.py +0 -0
  519. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/security/encryption.py +0 -0
  520. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/signal_identity.py +0 -0
  521. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/source_settings.py +0 -0
  522. {topos_node-1.2.5 → topos_node-1.2.7}/topos/storage/user_identity.py +0 -0
  523. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sync/__init__.py +0 -0
  524. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sync/client.py +0 -0
  525. {topos_node-1.2.5 → topos_node-1.2.7}/topos/sync_handlers.py +0 -0
  526. {topos_node-1.2.5 → topos_node-1.2.7}/topos/testing/__init__.py +0 -0
  527. {topos_node-1.2.5 → topos_node-1.2.7}/topos/testing/lifespan.py +0 -0
  528. {topos_node-1.2.5 → topos_node-1.2.7}/topos/uma_contact_enrichment.py +0 -0
  529. {topos_node-1.2.5 → topos_node-1.2.7}/topos/uma_filters.py +0 -0
  530. {topos_node-1.2.5 → topos_node-1.2.7}/topos/uma_resource_id.py +0 -0
  531. {topos_node-1.2.5 → topos_node-1.2.7}/topos/uma_rpt.py +0 -0
  532. {topos_node-1.2.5 → topos_node-1.2.7}/topos/upgrades/__init__.py +0 -0
  533. {topos_node-1.2.5 → topos_node-1.2.7}/topos/upgrades/manifests.json +0 -0
  534. {topos_node-1.2.5 → topos_node-1.2.7}/topos/upgrades/runner.py +0 -0
  535. {topos_node-1.2.5 → topos_node-1.2.7}/topos/utils/base_object.py +0 -0
  536. {topos_node-1.2.5 → topos_node-1.2.7}/topos/websocket_client.py +0 -0
  537. {topos_node-1.2.5 → topos_node-1.2.7}/topos_node.egg-info/SOURCES.txt +0 -0
  538. {topos_node-1.2.5 → topos_node-1.2.7}/topos_node.egg-info/dependency_links.txt +0 -0
  539. {topos_node-1.2.5 → topos_node-1.2.7}/topos_node.egg-info/entry_points.txt +0 -0
  540. {topos_node-1.2.5 → topos_node-1.2.7}/topos_node.egg-info/requires.txt +0 -0
  541. {topos_node-1.2.5 → topos_node-1.2.7}/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.2.5
3
+ Version: 1.2.7
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.2.5"
7
+ version = "1.2.7"
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.2.5"
4
- __version_info__ = (1, 2, 5)
3
+ __version__ = "1.2.7"
4
+ __version_info__ = (1, 2, 7)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -40,6 +40,10 @@ class RetrieveToolsRequest(BaseModel):
40
40
  query: str
41
41
  connector_scope: Optional[str] = None
42
42
  k: int = 8
43
+ # Per-connector identity-tool override (PLAN_HELP_NUDGE A2): bare names to
44
+ # ride along beyond IDENTITY_TOOL_NAMES, for connectors whose identity tool
45
+ # has a nonstandard name (e.g. GraphQL ``viewer``).
46
+ identity_tools: Optional[List[str]] = None
43
47
 
44
48
 
45
49
  def _require_conn():
@@ -74,6 +78,7 @@ def tools_retrieve(body: RetrieveToolsRequest):
74
78
  body.query,
75
79
  connector_scope=body.connector_scope,
76
80
  k=body.k,
81
+ extra_identity_names=body.identity_tools or (),
77
82
  )
78
83
 
79
84
 
@@ -50,11 +50,24 @@ async def handle_query(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
50
50
  "session_id": payload.get("query_session_id") or payload.get("session_id"),
51
51
  },
52
52
  }
53
+ # Client-supplied reference instant (offset-aware ISO): "yesterday"
54
+ # resolves against the USER's calendar day, not this server's UTC day.
55
+ # Unparseable/absent → None → planner wall clock.
56
+ query_now = None
57
+ raw_now = str(payload.get("now") or "").strip()
58
+ if raw_now:
59
+ try:
60
+ from datetime import datetime
61
+
62
+ query_now = datetime.fromisoformat(raw_now.replace("Z", "+00:00"))
63
+ except ValueError:
64
+ logger.debug("unparseable query now=%r ignored", raw_now)
53
65
  result = await get_query_orchestrator(conn=hub.get_db_connection()).execute(
54
66
  query_text=intent,
55
67
  scope_id=scope_id,
56
68
  access_mode=str(payload.get("access_mode") or "summary"),
57
69
  manifest=manifest,
70
+ now=query_now,
58
71
  query_session_id=payload.get("query_session_id") or payload.get("session_id"),
59
72
  filter_manifest=filter_manifest,
60
73
  field_transforms=payload.get("field_transforms"),
@@ -66,6 +66,13 @@ async def handle_tools_retrieve(message: Dict[str, Any]) -> Optional[Dict[str, A
66
66
  query = str(payload.get("query") or "").strip()
67
67
  if not query:
68
68
  return {"id": req_id, "status": "error", "error": "query is required"}
69
+ # Per-connector identity-tool override (PLAN_HELP_NUDGE A2).
70
+ raw_identity = payload.get("identity_tools")
71
+ identity_tools = (
72
+ [str(n) for n in raw_identity if str(n or "").strip()]
73
+ if isinstance(raw_identity, list)
74
+ else []
75
+ )
69
76
  try:
70
77
  from ...features.signal.tool_index import retrieve_tools
71
78
 
@@ -75,6 +82,7 @@ async def handle_tools_retrieve(message: Dict[str, Any]) -> Optional[Dict[str, A
75
82
  query,
76
83
  connector_scope=payload.get("connector_scope"),
77
84
  k=int(payload.get("k") or 8),
85
+ extra_identity_names=identity_tools,
78
86
  )
79
87
  return {"id": req_id, "status": "ok", "payload": result}
80
88
  except Exception as exc: # noqa: BLE001
@@ -47,6 +47,16 @@ _TABLE = "tool_index"
47
47
  # with a workable move.
48
48
  CORE_TOOL_NAMES: tuple[str, ...] = ("query_scope", "describe_connector", "list_connectors")
49
49
 
50
+ # Identity-shaped bare tool names that ride along in scoped retrievals
51
+ # (PLAN_HELP_NUDGE A2). Identity tools never rank for task-verb queries ("what
52
+ # were my commits" embeds nothing profile-shaped — get_me sat 24/27 by cosine
53
+ # on the live GitHub index) yet they are the prerequisite for any first-person
54
+ # question: without the login the model fills in a placeholder username and
55
+ # confidently reports empty results.
56
+ IDENTITY_TOOL_NAMES: frozenset[str] = frozenset(
57
+ {"get_me", "whoami", "me", "get_current_user", "get_authenticated_user", "about_me"}
58
+ )
59
+
50
60
  # Wire-name shape for remote connector tools: remote__{connector}__{tool}.
51
61
  _REMOTE_WIRE_RE = re.compile(r"^remote__(?P<connector>[^_].*?)__(?P<tool>.+)$")
52
62
 
@@ -263,11 +273,22 @@ def retrieve_tools(
263
273
  connector_scope: Optional[str] = None,
264
274
  k: int = 8,
265
275
  embed_fn: Optional[EmbedFn] = None,
276
+ extra_identity_names: Sequence[str] = (),
266
277
  ) -> Dict[str, Any]:
267
278
  """Rank indexed tools for a query; always carries CORE_TOOL_NAMES.
268
279
 
269
280
  Returns {"tools": [{name, connector_id, description, similarity}], "core",
270
- "backend": "cosine" | "keyword_fallback", "model", "indexed_count", "k"}.
281
+ "identity", "backend": "cosine" | "keyword_fallback", "model",
282
+ "indexed_count", "k"}.
283
+
284
+ When ``connector_scope`` is set, the scoped connector's identity-shaped
285
+ tools (IDENTITY_TOOL_NAMES, plus ``extra_identity_names`` for connectors
286
+ whose identity tool has a nonstandard bare name, e.g. GraphQL ``viewer``)
287
+ always ride along regardless of similarity. Matched names are echoed in the
288
+ ``identity`` field (empty when unscoped or nothing matched). Ride-alongs
289
+ outside the top-k carry ``injected: True`` (``similarity: None`` when no
290
+ score was computable, e.g. a dims-stale row) — so ``tools`` may exceed
291
+ ``k`` and isn't strictly similarity-sorted at the tail.
271
292
  """
272
293
  ensure_table(conn)
273
294
  k = max(1, min(int(k or 8), 50))
@@ -308,9 +329,44 @@ def retrieve_tools(
308
329
 
309
330
  scored.sort(key=lambda pair: pair[0], reverse=True)
310
331
  top = [{**meta, "similarity": round(score, 6)} for score, meta in scored[:k]]
332
+
333
+ # Identity ride-along (PLAN_HELP_NUDGE A2): rows is already scope-filtered
334
+ # (WHERE connector_id = ?), so matching here can never pull in another
335
+ # connector's identity tool.
336
+ identity: List[str] = []
337
+ if scope:
338
+ wanted = IDENTITY_TOOL_NAMES | {
339
+ str(n).strip() for n in extra_identity_names if str(n).strip()
340
+ }
341
+ top_names = {t["name"] for t in top}
342
+ scored_by_name = {meta["name"]: score for score, meta in scored}
343
+ for name, connector, description, _model, _blob in rows:
344
+ name = str(name)
345
+ if _bare_name(name) not in wanted or name in identity:
346
+ continue
347
+ identity.append(name)
348
+ if name in top_names:
349
+ continue # already ranked into the top-k on its own; no flag
350
+ entry: Dict[str, Any] = {
351
+ "name": name,
352
+ "connector_id": str(connector),
353
+ "description": str(description),
354
+ # Keep the computed (low) score when the scan produced one; a
355
+ # dims-stale/decode-skipped row gets None — don't invent one.
356
+ "similarity": round(scored_by_name[name], 6) if name in scored_by_name else None,
357
+ "injected": True,
358
+ }
359
+ top.append(entry)
360
+ if not identity:
361
+ logger.debug(
362
+ "tool_index scoped retrieval found no identity tool to inject (scope=%s)",
363
+ scope,
364
+ )
365
+
311
366
  return {
312
367
  "tools": top,
313
368
  "core": list(CORE_TOOL_NAMES),
369
+ "identity": identity,
314
370
  "backend": backend,
315
371
  "model": active_model_label() if embed_fn is None else "injected",
316
372
  "indexed_count": len(rows),
@@ -165,6 +165,10 @@ class DefaultGameLayer:
165
165
  elif access_mode == "summary":
166
166
  payload["answer_type"] = "summary"
167
167
  payload["summaries"] = context_packet.get("summaries") or []
168
+ # Planner-parsed date window (present only when retrieval honored
169
+ # one) — lets synthesis state the searched range explicitly.
170
+ if context_packet.get("time_window"):
171
+ payload["time_window"] = context_packet["time_window"]
168
172
  else:
169
173
  payload["answer_type"] = "raw"
170
174
  payload["rows"] = context_packet.get("rows") or []
@@ -587,21 +587,57 @@ def _resolve_source_ids(
587
587
  return resolve_retrieval_source_ids(manifest, installed_source_ids)
588
588
 
589
589
 
590
+ def _parse_instant(raw: Any) -> Optional[datetime]:
591
+ if not raw:
592
+ return None
593
+ try:
594
+ ts = datetime.fromisoformat(str(raw).replace("Z", "+00:00"))
595
+ except ValueError:
596
+ return None
597
+ return ts if ts.tzinfo else ts.replace(tzinfo=timezone.utc)
598
+
599
+
590
600
  def _parse_row_timestamp(row: Dict[str, Any]) -> Optional[datetime]:
591
601
  for field in ("event_at", "ts", "occurred_at", "created_at"):
592
- raw = row.get(field)
593
- if not raw:
594
- continue
595
- try:
596
- ts = datetime.fromisoformat(str(raw).replace("Z", "+00:00"))
597
- if ts.tzinfo is None:
598
- ts = ts.replace(tzinfo=timezone.utc)
602
+ ts = _parse_instant(row.get(field))
603
+ if ts is not None:
599
604
  return ts
600
- except ValueError:
601
- continue
602
605
  return None
603
606
 
604
607
 
608
+ def _prefer_time_window(
609
+ items: List[Dict[str, Any]],
610
+ time_range: Optional[Tuple[str, str]],
611
+ ) -> List[Dict[str, Any]]:
612
+ """Keep the items inside the plan's time window when any exist.
613
+
614
+ Soft fallback, mirroring the vector lane's unscoped retry: a time-scoped
615
+ ask over a lane with nothing in-window degrades to dated-but-out-of-window
616
+ evidence rather than an empty lane — but every returned item is annotated
617
+ with `in_time_window` so synthesis can say "nothing from yesterday; most
618
+ recent instead" rather than passing off stale items as in-range. Undated
619
+ items count as out-of-window: they cannot evidence a date-scoped claim.
620
+ """
621
+ if not time_range or not items:
622
+ return items
623
+ start = _parse_instant(time_range[0])
624
+ end = _parse_instant(time_range[1])
625
+ if start is None or end is None:
626
+ return items
627
+ in_window: List[Dict[str, Any]] = []
628
+ for item in items:
629
+ ts = _parse_row_timestamp(item)
630
+ if ts is not None and start <= ts <= end:
631
+ in_window.append(item)
632
+ if in_window:
633
+ for item in in_window:
634
+ item["in_time_window"] = True
635
+ return in_window
636
+ for item in items:
637
+ item["in_time_window"] = False
638
+ return items
639
+
640
+
605
641
  def _apply_filter_manifest_rows(
606
642
  rows: List[Dict[str, Any]],
607
643
  filter_manifest: Optional[Dict[str, Any]],
@@ -641,6 +677,7 @@ def _load_user_goal_summaries(
641
677
  source_ids: Optional[List[str]] = None,
642
678
  limit: int = _SUMMARY_ITEM_CAP,
643
679
  conn: Optional[Any] = None,
680
+ time_range: Optional[Tuple[str, str]] = None,
644
681
  ) -> List[Dict[str, Any]]:
645
682
  try:
646
683
  # Prefer the query's own connection (multi-db verification, seeded evals);
@@ -652,20 +689,40 @@ def _load_user_goal_summaries(
652
689
  if conn is None:
653
690
  return []
654
691
  params: List[Any] = []
655
- query = "SELECT goal_id, record_id, source_id, goal_text FROM user_goals"
692
+ # event_at is the source message's time from the unified timeline
693
+ # (user_goals.record_id = message_id); created_at is only ingest time.
694
+ # Without a date field goals can never answer "yesterday's goals" and
695
+ # dodge recency decay entirely.
696
+ select = (
697
+ "SELECT g.goal_id, g.record_id, g.source_id, g.goal_text, g.created_at,"
698
+ " (SELECT MAX(t.event_at) FROM timeline t WHERE t.record_id = g.record_id)"
699
+ " FROM user_goals g"
700
+ )
701
+ where = ""
656
702
  if source_ids:
657
703
  placeholders = ",".join("?" for _ in source_ids)
658
- query += f" WHERE source_id IN ({placeholders})"
704
+ where = f" WHERE g.source_id IN ({placeholders})"
659
705
  params.extend(source_ids)
660
- query += " ORDER BY created_at DESC LIMIT ?"
706
+ tail = " ORDER BY g.created_at DESC LIMIT ?"
661
707
  params.append(max(limit * 3, 50))
662
- rows = conn.execute(query, tuple(params)).fetchall()
708
+ try:
709
+ rows = conn.execute(select + where + tail, tuple(params)).fetchall()
710
+ except Exception:
711
+ # Databases predating the timeline projection: dated by ingest only.
712
+ rows = [
713
+ (*row, None)
714
+ for row in conn.execute(
715
+ "SELECT goal_id, record_id, source_id, goal_text, created_at"
716
+ " FROM user_goals" + where.replace("g.", "") + tail.replace("g.", ""),
717
+ tuple(params),
718
+ ).fetchall()
719
+ ]
663
720
  items: List[Dict[str, Any]] = []
664
721
  tokens = _query_tokens(query_text)
665
722
  query_lower = (query_text or "").lower()
666
723
  goal_intent = any(term in query_lower for term in _EXTRA_SURFACE_TERMS)
667
724
  seen_texts: set = set()
668
- for goal_id, record_id, source_id, goal_text in rows:
725
+ for goal_id, record_id, source_id, goal_text, created_at, event_at in rows:
669
726
  text = str(goal_text or "").strip()
670
727
  if not text:
671
728
  continue
@@ -686,10 +743,13 @@ def _load_user_goal_summaries(
686
743
  "record_id": record_id,
687
744
  "source_id": source_id,
688
745
  "dimension": "work",
746
+ "event_at": event_at or created_at,
747
+ "created_at": created_at,
689
748
  "relevance_score": round(_goal_relevance(text, query_text), 4),
690
749
  "retrieval_source": "user_goal",
691
750
  }
692
751
  )
752
+ items = _prefer_time_window(items, time_range)
693
753
  items.sort(key=lambda item: float(item.get("relevance_score") or 0.0), reverse=True)
694
754
  return items[:limit]
695
755
  except Exception as exc:
@@ -1035,6 +1095,14 @@ def _load_canonical_summary_items(
1035
1095
  "relevance_score": round(_canonical_relevance(text, query_text), 4),
1036
1096
  "retrieval_source": f"canonical:{table}",
1037
1097
  }
1098
+ # Per-table event-time column (same keys the recency sort in
1099
+ # _list_canonical_rows uses); without it canonical rows can neither
1100
+ # decay in fusion nor answer a date-scoped ask.
1101
+ for ts_key in ("event_at", "starts_at", "occurred_at", "entry_at"):
1102
+ ts_val = clean.get(ts_key) or row.get(ts_key)
1103
+ if ts_val:
1104
+ item["event_at"] = ts_val
1105
+ break
1038
1106
  if owner is not None:
1039
1107
  item["owner_authored"] = owner
1040
1108
  items.append(item)
@@ -1440,6 +1508,9 @@ def _semantic_hits(
1440
1508
  "similarity": item.get("similarity"),
1441
1509
  "source_id": item.get("source_id"),
1442
1510
  "signal_dimension": item.get("signal_dimension"),
1511
+ # Without the event time, vector items are exempt from
1512
+ # recency decay by accident and undated at synthesis.
1513
+ "event_at": item.get("event_at"),
1443
1514
  }
1444
1515
  )
1445
1516
  return hits, result.get("error")
@@ -2059,7 +2130,10 @@ def _build_summary_items(
2059
2130
  str(s).strip() for s in (manifest.default_source_ids or []) if str(s).strip()
2060
2131
  ] or (source_ids or None)
2061
2132
  goal_items = _load_user_goal_summaries(
2062
- query_text, source_ids=goal_source_ids or None, conn=bundle_conn
2133
+ query_text,
2134
+ source_ids=goal_source_ids or None,
2135
+ conn=bundle_conn,
2136
+ time_range=getattr(plan, "time_range", None) if plan else None,
2063
2137
  )
2064
2138
 
2065
2139
  canonical_items = _load_canonical_summary_items(
@@ -2073,6 +2147,9 @@ def _build_summary_items(
2073
2147
  conn=bundle_conn,
2074
2148
  exposure_visible=exposure_visible,
2075
2149
  )
2150
+ canonical_items = _prefer_time_window(
2151
+ canonical_items, getattr(plan, "time_range", None) if plan else None
2152
+ )
2076
2153
 
2077
2154
  # Interaction browse ("who do I talk to"): the contact registry is the
2078
2155
  # ground truth of interaction partners — mention-only names (someone the
@@ -2162,6 +2239,7 @@ def _build_summary_items(
2162
2239
  "record_id": hit.get("record_id"),
2163
2240
  "source_id": hit.get("source_id"),
2164
2241
  "signal_dimension": hit.get("signal_dimension"),
2242
+ "event_at": hit.get("event_at"),
2165
2243
  "relevance_score": round(similarity, 4),
2166
2244
  "retrieval_source": "vector",
2167
2245
  }
@@ -2236,6 +2314,12 @@ def _build_summary_items(
2236
2314
  "retrieval_source": "signal_fact",
2237
2315
  }
2238
2316
  )
2317
+ # Same time-window preference as the goal lane: dimension facts now carry
2318
+ # created_at (and sometimes event_at) — a "yesterday" ask keeps in-window
2319
+ # facts when any exist, annotated fallback otherwise.
2320
+ fact_items = _prefer_time_window(
2321
+ fact_items, getattr(plan, "time_range", None) if plan else None
2322
+ )
2239
2323
  fact_items.sort(key=lambda item: float(item.get("relevance_score") or 0.0), reverse=True)
2240
2324
  if first_person:
2241
2325
  # The dimension-dump lane carries raw stat payloads too — the same
@@ -2608,6 +2692,18 @@ class DefaultSignalRetrievalAdapter:
2608
2692
  )
2609
2693
  if summaries:
2610
2694
  touched.append("signal")
2695
+ # Surface the planner's parsed window so synthesis can state
2696
+ # which dates were searched ("nothing from 2026-07-16") instead
2697
+ # of inferring it from per-item timestamps. Summary mode only:
2698
+ # its lanes honor the window; raw/inference do not yet
2699
+ # (PLAN_TEMPORAL_COHERENCE.md M5/M6) and must not claim to.
2700
+ if plan is not None and (plan.time_range or plan.as_of):
2701
+ window: Dict[str, Any] = {"source": "query_planner"}
2702
+ if plan.time_range:
2703
+ window["from"], window["to"] = plan.time_range
2704
+ if plan.as_of:
2705
+ window["as_of"] = plan.as_of
2706
+ packet["time_window"] = window
2611
2707
  else:
2612
2708
  summaries = []
2613
2709
  for dim in manifest.primary_dimensions:
@@ -609,7 +609,7 @@ class SQLiteSignalFeatureStore:
609
609
  return summary_id
610
610
 
611
611
  def _list_rows(self, table: str, *, dimension: Optional[str], limit: int, offset: int) -> ListPage:
612
- query = f"SELECT payload_json FROM {table}"
612
+ query = f"SELECT payload_json, created_at FROM {table}"
613
613
  params: List[Any] = []
614
614
  if dimension is not None:
615
615
  query += " WHERE dimension=?"
@@ -618,7 +618,14 @@ class SQLiteSignalFeatureStore:
618
618
  total = int(count[0]) if count else 0
619
619
  query += " ORDER BY rowid LIMIT ? OFFSET ?"
620
620
  params.extend([limit, offset])
621
- items = [json.loads(r[0]) for r in self._conn.execute(query, params).fetchall()]
621
+ items: List[Dict[str, Any]] = []
622
+ for payload_json, created_at in self._conn.execute(query, params).fetchall():
623
+ item = json.loads(payload_json)
624
+ # The row timestamp lives in the column, not the payload; without it
625
+ # facts are undated downstream (no recency decay, no time filtering).
626
+ if created_at:
627
+ item.setdefault("created_at", created_at)
628
+ items.append(item)
622
629
  return ListPage(items=items, total=total, offset=offset, limit=limit)
623
630
 
624
631
  def get_by_dimension(self, dimension: str, *, limit: int = 100, offset: int = 0) -> ListPage:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.2.5
3
+ Version: 1.2.7
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
File without changes
File without changes
File without changes
File without changes
File without changes