topos-node 0.1.7__tar.gz → 0.1.8__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 (255) hide show
  1. {topos_node-0.1.7 → topos_node-0.1.8}/PKG-INFO +1 -1
  2. {topos_node-0.1.7 → topos_node-0.1.8}/pyproject.toml +1 -1
  3. {topos_node-0.1.7 → topos_node-0.1.8}/topos/__version__.py +2 -2
  4. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/device.py +2 -2
  5. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/handlers.py +12 -1
  6. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/state.py +58 -0
  7. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/interfaces.py +1 -1
  8. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/local.py +2 -1
  9. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/postgres.py +68 -5
  10. {topos_node-0.1.7 → topos_node-0.1.8}/topos_node.egg-info/PKG-INFO +1 -1
  11. {topos_node-0.1.7 → topos_node-0.1.8}/LICENSE +0 -0
  12. {topos_node-0.1.7 → topos_node-0.1.8}/README.md +0 -0
  13. {topos_node-0.1.7 → topos_node-0.1.8}/setup.cfg +0 -0
  14. {topos_node-0.1.7 → topos_node-0.1.8}/shared/__init__.py +0 -0
  15. {topos_node-0.1.7 → topos_node-0.1.8}/shared/filtering.py +0 -0
  16. {topos_node-0.1.7 → topos_node-0.1.8}/shared/schema_registry.py +0 -0
  17. {topos_node-0.1.7 → topos_node-0.1.8}/topos/__init__.py +0 -0
  18. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/__init__.py +0 -0
  19. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/duckdb_adapter.py +0 -0
  20. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/messenger_communities.py +0 -0
  21. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/messenger_graph.py +0 -0
  22. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/messenger_labels.py +0 -0
  23. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/profiles.py +0 -0
  24. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/query_engine.py +0 -0
  25. {topos_node-0.1.7 → topos_node-0.1.8}/topos/analytics/raw_queries.py +0 -0
  26. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/__init__.py +0 -0
  27. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/analytics.py +0 -0
  28. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/app_registry.py +0 -0
  29. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/backup.py +0 -0
  30. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/compute_remote.py +0 -0
  31. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/data_commit.py +0 -0
  32. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/data_explorer_table_prefs.py +0 -0
  33. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/db.py +0 -0
  34. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/enrichment.py +0 -0
  35. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/filter_lab.py +0 -0
  36. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/health.py +0 -0
  37. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/ingestion_api.py +0 -0
  38. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/ingestion_compat.py +0 -0
  39. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/ingestion_sources.py +0 -0
  40. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/llm.py +0 -0
  41. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/local_mcp.py +0 -0
  42. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/messenger_analytics.py +0 -0
  43. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/query_api.py +0 -0
  44. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/sanitization_ollama_config.py +0 -0
  45. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/source_install.py +0 -0
  46. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/sources.py +0 -0
  47. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/sync.py +0 -0
  48. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/ui_config.py +0 -0
  49. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/uma_data.py +0 -0
  50. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/usage.py +0 -0
  51. {topos_node-0.1.7 → topos_node-0.1.8}/topos/api/user_identity.py +0 -0
  52. {topos_node-0.1.7 → topos_node-0.1.8}/topos/app.py +0 -0
  53. {topos_node-0.1.7 → topos_node-0.1.8}/topos/auth.py +0 -0
  54. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/__init__.py +0 -0
  55. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/mappers/__init__.py +0 -0
  56. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/mappers/base.py +0 -0
  57. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  58. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  59. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  60. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/models.py +0 -0
  61. {topos_node-0.1.7 → topos_node-0.1.8}/topos/canonicalization/resolver.py +0 -0
  62. {topos_node-0.1.7 → topos_node-0.1.8}/topos/cli/__init__.py +0 -0
  63. {topos_node-0.1.7 → topos_node-0.1.8}/topos/cli/__main__.py +0 -0
  64. {topos_node-0.1.7 → topos_node-0.1.8}/topos/cli/commands.py +0 -0
  65. {topos_node-0.1.7 → topos_node-0.1.8}/topos/config/__init__.py +0 -0
  66. {topos_node-0.1.7 → topos_node-0.1.8}/topos/config/sanitization_ollama.py +0 -0
  67. {topos_node-0.1.7 → topos_node-0.1.8}/topos/config/settings.py +0 -0
  68. {topos_node-0.1.7 → topos_node-0.1.8}/topos/contacts/__init__.py +0 -0
  69. {topos_node-0.1.7 → topos_node-0.1.8}/topos/contacts/identity.py +0 -0
  70. {topos_node-0.1.7 → topos_node-0.1.8}/topos/control_plane_client.py +0 -0
  71. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/__init__.py +0 -0
  72. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/api_models.py +0 -0
  73. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/connection_resilience.py +0 -0
  74. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/device_helpers.py +0 -0
  75. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/errors.py +0 -0
  76. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/events.py +0 -0
  77. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/logging.py +0 -0
  78. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/metrics.py +0 -0
  79. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/startup_banner.py +0 -0
  80. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/table_layers.py +0 -0
  81. {topos_node-0.1.7 → topos_node-0.1.8}/topos/core/types.py +0 -0
  82. {topos_node-0.1.7 → topos_node-0.1.8}/topos/data_explorer_table_prefs.py +0 -0
  83. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/__init__.py +0 -0
  84. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/backends/__init__.py +0 -0
  85. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/backends/base.py +0 -0
  86. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/backends/huggingface.py +0 -0
  87. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/backends/ollama.py +0 -0
  88. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/backends/stub.py +0 -0
  89. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/engine.py +0 -0
  90. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/intake.py +0 -0
  91. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/queue_manager.py +0 -0
  92. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/registration.py +0 -0
  93. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/result_formatter.py +0 -0
  94. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/router.py +0 -0
  95. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/scoped_token.py +0 -0
  96. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/tasks.py +0 -0
  97. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/transport.py +0 -0
  98. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/usage_guard.py +0 -0
  99. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/usage_observation.py +0 -0
  100. {topos_node-0.1.7 → topos_node-0.1.8}/topos/engine/validator.py +0 -0
  101. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/__init__.py +0 -0
  102. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/derived_tables.py +0 -0
  103. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/__init__.py +0 -0
  104. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/base.py +0 -0
  105. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  106. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  107. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  108. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  109. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  110. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  111. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/raw/__init__.py +0 -0
  112. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  113. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/raw/language_job.py +0 -0
  114. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  115. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  116. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/models/__init__.py +0 -0
  117. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/models/manager.py +0 -0
  118. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/models/registry.py +0 -0
  119. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/models/versioning.py +0 -0
  120. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/orchestrator.py +0 -0
  121. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/processor.py +0 -0
  122. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/progress_bar.py +0 -0
  123. {topos_node-0.1.7 → topos_node-0.1.8}/topos/enrichment/website_classifier.py +0 -0
  124. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/__init__.py +0 -0
  125. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/bundles.py +0 -0
  126. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/schema.py +0 -0
  127. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/service.py +0 -0
  128. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/store.py +0 -0
  129. {topos_node-0.1.7 → topos_node-0.1.8}/topos/filter_lab/worker.py +0 -0
  130. {topos_node-0.1.7 → topos_node-0.1.8}/topos/hosted_pool_lease.py +0 -0
  131. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/__init__.py +0 -0
  132. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/checkpoints/__init__.py +0 -0
  133. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  134. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  135. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/ingest_helpers.py +0 -0
  136. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/jobs.py +0 -0
  137. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/local_sync.py +0 -0
  138. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/log_preview.py +0 -0
  139. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/manager.py +0 -0
  140. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parser.py +0 -0
  141. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/__init__.py +0 -0
  142. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/base.py +0 -0
  143. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/browser_parser.py +0 -0
  144. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/calendar_parser.py +0 -0
  145. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  146. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  147. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/grok_parser.py +0 -0
  148. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/parsers/messenger_parser.py +0 -0
  149. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/progress.py +0 -0
  150. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/__init__.py +0 -0
  151. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/base.py +0 -0
  152. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/calendar.py +0 -0
  153. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/chatgpt.py +0 -0
  154. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/contact_importers.py +0 -0
  155. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/grok.py +0 -0
  156. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/imessage_reader.py +0 -0
  157. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/signal_export_parser.py +0 -0
  158. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/sources/signal_reader.py +0 -0
  159. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/state_machine.py +0 -0
  160. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/triggers/__init__.py +0 -0
  161. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/triggers/file_trigger.py +0 -0
  162. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  163. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/validation/__init__.py +0 -0
  164. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/validation/base.py +0 -0
  165. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/validation/schema_registry.py +0 -0
  166. {topos_node-0.1.7 → topos_node-0.1.8}/topos/ingestion/validation/schema_validator.py +0 -0
  167. {topos_node-0.1.7 → topos_node-0.1.8}/topos/lineage/__init__.py +0 -0
  168. {topos_node-0.1.7 → topos_node-0.1.8}/topos/lineage/provenance.py +0 -0
  169. {topos_node-0.1.7 → topos_node-0.1.8}/topos/lineage/tracker.py +0 -0
  170. {topos_node-0.1.7 → topos_node-0.1.8}/topos/mcp_stdio_proxy.py +0 -0
  171. {topos_node-0.1.7 → topos_node-0.1.8}/topos/observability/__init__.py +0 -0
  172. {topos_node-0.1.7 → topos_node-0.1.8}/topos/observability/alerts.py +0 -0
  173. {topos_node-0.1.7 → topos_node-0.1.8}/topos/observability/metrics.py +0 -0
  174. {topos_node-0.1.7 → topos_node-0.1.8}/topos/observability/tracing.py +0 -0
  175. {topos_node-0.1.7 → topos_node-0.1.8}/topos/openai_client.py +0 -0
  176. {topos_node-0.1.7 → topos_node-0.1.8}/topos/projections/__init__.py +0 -0
  177. {topos_node-0.1.7 → topos_node-0.1.8}/topos/projections/vector_index/__init__.py +0 -0
  178. {topos_node-0.1.7 → topos_node-0.1.8}/topos/projections/vector_index/base.py +0 -0
  179. {topos_node-0.1.7 → topos_node-0.1.8}/topos/projections/vector_index/builders.py +0 -0
  180. {topos_node-0.1.7 → topos_node-0.1.8}/topos/projections/vector_index/health_checks.py +0 -0
  181. {topos_node-0.1.7 → topos_node-0.1.8}/topos/rate_limit.py +0 -0
  182. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sanitization/__init__.py +0 -0
  183. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sanitization/ollama_transforms.py +0 -0
  184. {topos_node-0.1.7 → topos_node-0.1.8}/topos/scope_resolution.py +0 -0
  185. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/__init__.py +0 -0
  186. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/container.py +0 -0
  187. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/embeddings/__init__.py +0 -0
  188. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/embeddings/base.py +0 -0
  189. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/embeddings/local.py +0 -0
  190. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/embeddings/remote.py +0 -0
  191. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/llm/__init__.py +0 -0
  192. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/llm/base.py +0 -0
  193. {topos_node-0.1.7 → topos_node-0.1.8}/topos/services/llm/openai.py +0 -0
  194. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sources/__init__.py +0 -0
  195. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sources/definitions.py +0 -0
  196. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sources/install_service.py +0 -0
  197. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sources/registry.py +0 -0
  198. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sources/runtime_install.py +0 -0
  199. {topos_node-0.1.7 → topos_node-0.1.8}/topos/startup_banner.py +0 -0
  200. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/__init__.py +0 -0
  201. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/__init__.py +0 -0
  202. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  203. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  204. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  205. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/ai_chat/model.py +0 -0
  206. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/ai_chat/tables.py +0 -0
  207. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/canonical_store.py +0 -0
  208. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/conversations_tables.py +0 -0
  209. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/mapping_store.py +0 -0
  210. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/canonical/postgres.py +0 -0
  211. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/__init__.py +0 -0
  212. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/client.py +0 -0
  213. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/migrations/__init__.py +0 -0
  214. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  215. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/paths.py +0 -0
  216. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/postgres.py +0 -0
  217. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/db/schema.py +0 -0
  218. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/enrichment/__init__.py +0 -0
  219. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  220. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  221. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/normalized/__init__.py +0 -0
  222. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/normalized/normalized_store.py +0 -0
  223. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/oplog/__init__.py +0 -0
  224. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/oplog/decision.py +0 -0
  225. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/oplog/oplog_store.py +0 -0
  226. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/oplog/postgres.py +0 -0
  227. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/projections/__init__.py +0 -0
  228. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/projections/index_ops_store.py +0 -0
  229. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/projections/vector_index_store.py +0 -0
  230. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/__init__.py +0 -0
  231. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/browser_flat_tables.py +0 -0
  232. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/file_store.py +0 -0
  233. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/raw_store.py +0 -0
  234. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/raw_tables_manager.py +0 -0
  235. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/raw/sqlite_raw_store.py +0 -0
  236. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/security/encryption.py +0 -0
  237. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/signal_identity.py +0 -0
  238. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/source_settings.py +0 -0
  239. {topos_node-0.1.7 → topos_node-0.1.8}/topos/storage/user_identity.py +0 -0
  240. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sync/__init__.py +0 -0
  241. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sync/client.py +0 -0
  242. {topos_node-0.1.7 → topos_node-0.1.8}/topos/sync_handlers.py +0 -0
  243. {topos_node-0.1.7 → topos_node-0.1.8}/topos/testing/__init__.py +0 -0
  244. {topos_node-0.1.7 → topos_node-0.1.8}/topos/testing/lifespan.py +0 -0
  245. {topos_node-0.1.7 → topos_node-0.1.8}/topos/uma_contact_enrichment.py +0 -0
  246. {topos_node-0.1.7 → topos_node-0.1.8}/topos/uma_filters.py +0 -0
  247. {topos_node-0.1.7 → topos_node-0.1.8}/topos/uma_resource_id.py +0 -0
  248. {topos_node-0.1.7 → topos_node-0.1.8}/topos/uma_rpt.py +0 -0
  249. {topos_node-0.1.7 → topos_node-0.1.8}/topos/utils/base_object.py +0 -0
  250. {topos_node-0.1.7 → topos_node-0.1.8}/topos/websocket_client.py +0 -0
  251. {topos_node-0.1.7 → topos_node-0.1.8}/topos_node.egg-info/SOURCES.txt +0 -0
  252. {topos_node-0.1.7 → topos_node-0.1.8}/topos_node.egg-info/dependency_links.txt +0 -0
  253. {topos_node-0.1.7 → topos_node-0.1.8}/topos_node.egg-info/entry_points.txt +0 -0
  254. {topos_node-0.1.7 → topos_node-0.1.8}/topos_node.egg-info/requires.txt +0 -0
  255. {topos_node-0.1.7 → topos_node-0.1.8}/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: 0.1.7
3
+ Version: 0.1.8
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 = "0.1.7"
7
+ version = "0.1.8"
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__ = "0.1.7"
4
- __version_info__ = (0, 1, 7)
3
+ __version__ = "0.1.8"
4
+ __version_info__ = (0, 1, 8)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -12,12 +12,12 @@ router = APIRouter()
12
12
 
13
13
  @router.get("/device/info", response_model=DeviceInfoResponse, dependencies=[Depends(require_api_key)])
14
14
  async def get_device_info(services: Services = Depends(get_services)):
15
- return await services.device.get_device_info()
15
+ return await services.device.get_device_info(context=None)
16
16
 
17
17
 
18
18
  @router.get("/device_info", response_model=DeviceInfoResponse, dependencies=[Depends(require_api_key)])
19
19
  async def get_device_info_alias(services: Services = Depends(get_services)):
20
- return await services.device.get_device_info()
20
+ return await services.device.get_device_info(context=None)
21
21
 
22
22
 
23
23
  @router.post("/device_name", response_model=DeviceNameResponse, dependencies=[Depends(require_api_key)])
@@ -1139,6 +1139,15 @@ async def handle_control_plane_request(message: Dict[str, Any]) -> Optional[Dict
1139
1139
  _payload = message.get("payload") or {}
1140
1140
  _mcp_source = _payload.get("mcp_source")
1141
1141
  _mcp_requester_id = _payload.get("mcp_requester_id")
1142
+ if msg_type == "migrate_browser_plugin_app_id":
1143
+ from .state import _migrate_legacy_browser_plugin_app_ids
1144
+
1145
+ conn = get_db_connection()
1146
+ if not conn:
1147
+ return {"id": req_id, "status": "error", "error": "Database not available"}
1148
+ updated = _migrate_legacy_browser_plugin_app_ids(conn)
1149
+ return {"id": req_id, "status": "ok", "payload": {"updated_rows": updated}}
1150
+
1142
1151
  if msg_type == "get_request_counts":
1143
1152
  """Return UMA + MCP request counts from engine DB (for CP proxy or direct frontend)."""
1144
1153
  payload = message.get("payload") or {}
@@ -1759,8 +1768,10 @@ async def handle_control_plane_request(message: Dict[str, Any]) -> Optional[Dict
1759
1768
  except Exception as exc: # noqa: BLE001
1760
1769
  return {"id": req_id, "status": "error", "error": str(exc)}
1761
1770
  if msg_type == "get_device_info":
1771
+ payload = message.get("payload") or {}
1772
+ context = payload if isinstance(payload, dict) else {}
1762
1773
  try:
1763
- result = await get_services().device.get_device_info()
1774
+ result = await get_services().device.get_device_info(context=context)
1764
1775
  return {"id": req_id, "status": "ok", "payload": result.model_dump()}
1765
1776
  except Exception as exc: # noqa: BLE001
1766
1777
  return {"id": req_id, "status": "error", "error": str(exc)}
@@ -14,6 +14,8 @@ from typing import Any, Dict, Optional
14
14
 
15
15
  MCP_REQUEST_LOG_TABLE = "mcp_request_log"
16
16
  UMA_ACCESS_REQUESTS_TABLE = "uma_access_requests"
17
+ LEGACY_BROWSER_PLUGIN_APP_ID = "browser-plugin"
18
+ BROWSER_HISTORY_PLUGIN_APP_ID = "browser-history-plugin"
17
19
 
18
20
 
19
21
  def derive_uma_access_context(owner_user_id: str, requesting_user_id: Optional[str]) -> str:
@@ -401,6 +403,29 @@ def _ensure_uma_access_requests_table(conn: sqlite3.Connection) -> None:
401
403
  conn.commit()
402
404
  except Exception as exc:
403
405
  logger.warning("Failed to ensure uma_access_requests table exists: %s", exc)
406
+ else:
407
+ _migrate_legacy_browser_plugin_app_ids(conn)
408
+
409
+
410
+ def _migrate_legacy_browser_plugin_app_ids(conn: sqlite3.Connection) -> int:
411
+ """Rewrite engine Activity counts from browser-plugin → browser-history-plugin (idempotent)."""
412
+ try:
413
+ cursor = conn.execute(
414
+ f"UPDATE {UMA_ACCESS_REQUESTS_TABLE} SET app_id = ? WHERE app_id = ?",
415
+ (BROWSER_HISTORY_PLUGIN_APP_ID, LEGACY_BROWSER_PLUGIN_APP_ID),
416
+ )
417
+ if cursor.rowcount:
418
+ conn.commit()
419
+ logger.info(
420
+ "Migrated %s uma_access_requests rows: %s → %s",
421
+ cursor.rowcount,
422
+ LEGACY_BROWSER_PLUGIN_APP_ID,
423
+ BROWSER_HISTORY_PLUGIN_APP_ID,
424
+ )
425
+ return int(cursor.rowcount or 0)
426
+ except Exception as exc:
427
+ logger.warning("browser-plugin app_id migration on engine failed: %s", exc)
428
+ return 0
404
429
 
405
430
 
406
431
  def record_uma_request(
@@ -463,6 +488,7 @@ def get_uma_request_counts(
463
488
  "total_read_requests": 0,
464
489
  "total_write_requests": 0,
465
490
  "by_app": [],
491
+ "by_app_requester": [],
466
492
  "by_requesting_user": [],
467
493
  "access_attribution": {
468
494
  "window_days": since_days or 0,
@@ -510,6 +536,38 @@ def get_uma_request_counts(
510
536
  for aid, d in sorted(by_app.items())
511
537
  ]
512
538
 
539
+ cursor = conn.execute(
540
+ f"""SELECT app_id, requesting_user_id, requesting_user_email, request_type
541
+ FROM {UMA_ACCESS_REQUESTS_TABLE}
542
+ WHERE owner_user_id = ? AND created_at >= ?""",
543
+ (owner_user_id, since_ts),
544
+ )
545
+ by_app_req: Dict[str, Dict[str, Any]] = {}
546
+ for row in cursor.fetchall():
547
+ app_id_val = (row[0] or "").strip() if len(row) > 0 else ""
548
+ rid = (row[1] or "").strip() if len(row) > 1 else ""
549
+ remail = (row[2] or "").strip() if len(row) > 2 else ""
550
+ rt = (row[3] or "").strip().lower() if len(row) > 3 else ""
551
+ key = f"{app_id_val}\0{rid}\0{remail}"
552
+ if key not in by_app_req:
553
+ by_app_req[key] = {
554
+ "app_id": app_id_val or None,
555
+ "requesting_user_id": rid or None,
556
+ "requesting_user_email": remail or None,
557
+ "read_requests": 0,
558
+ "write_requests": 0,
559
+ }
560
+ if rt == "read":
561
+ by_app_req[key]["read_requests"] += 1
562
+ elif rt == "write":
563
+ by_app_req[key]["write_requests"] += 1
564
+ app_req_ranked = []
565
+ for d in by_app_req.values():
566
+ tr = int(d["read_requests"]) + int(d["write_requests"])
567
+ app_req_ranked.append({**d, "total_requests": tr})
568
+ app_req_ranked.sort(key=lambda x: -x["total_requests"])
569
+ out["by_app_requester"] = app_req_ranked[:50]
570
+
513
571
  cursor = conn.execute(
514
572
  f"""SELECT requesting_user_id, requesting_user_email, request_type, access_context
515
573
  FROM {UMA_ACCESS_REQUESTS_TABLE}
@@ -31,7 +31,7 @@ class SyncService(Protocol):
31
31
  class DeviceService(Protocol):
32
32
  async def get_pairing_code(self) -> PairingCodeResponse: ...
33
33
  async def pair_device(self, pairing_code: str, keep_existing_data: bool) -> PairDeviceResponse: ...
34
- async def get_device_info(self) -> DeviceInfoResponse: ...
34
+ async def get_device_info(self, context: Optional[Dict[str, Any]] = None) -> DeviceInfoResponse: ...
35
35
  async def set_device_name(self, device_name: str) -> DeviceNameResponse: ...
36
36
 
37
37
 
@@ -63,7 +63,8 @@ class LocalDeviceService:
63
63
  _ = (pairing_code, keep_existing_data)
64
64
  raise HTTPException(status_code=status.HTTP_501_NOT_IMPLEMENTED, detail="Pairing not implemented")
65
65
 
66
- async def get_device_info(self) -> DeviceInfoResponse:
66
+ async def get_device_info(self, context: Optional[Dict[str, Any]] = None) -> DeviceInfoResponse:
67
+ _ = context
67
68
  # Get user_id from database (set by connection_info handler) or fall back to settings
68
69
  user_id = None
69
70
  if state.db_conn:
@@ -7,7 +7,9 @@ from uuid import uuid4
7
7
 
8
8
  from fastapi import HTTPException, status
9
9
 
10
+ from ..__version__ import __version__
10
11
  from ..config.settings import settings
12
+ from ..core import state
11
13
  from ..core.api_models import (
12
14
  DeviceInfoResponse,
13
15
  DeviceNameResponse,
@@ -22,6 +24,7 @@ from ..storage.db.postgres import (
22
24
  connect_postgres,
23
25
  execute_query,
24
26
  fetch_all,
27
+ fetch_one,
25
28
  )
26
29
 
27
30
 
@@ -364,20 +367,80 @@ class PostgresDbService:
364
367
  }
365
368
 
366
369
 
370
+ def _hosted_postgres_version() -> Optional[str]:
371
+ try:
372
+ with connect_postgres() as conn:
373
+ row = fetch_one(conn, "SELECT version() AS version", ())
374
+ if row and row[0]:
375
+ return str(row[0]).strip() or None
376
+ except Exception:
377
+ return None
378
+ return None
379
+
380
+
381
+ def _hosted_dataset_id(context: Optional[Dict[str, Any]], user_id: Optional[str]) -> Optional[str]:
382
+ ctx = context if isinstance(context, dict) else {}
383
+ explicit = str(ctx.get("dataset_id") or "").strip()
384
+ if explicit:
385
+ return explicit
386
+ if not user_id:
387
+ return None
388
+ tenant_id = str(ctx.get("tenant_id") or "").strip()
389
+ if tenant_id:
390
+ return f"{user_id}:default:{tenant_id}"
391
+ default_dataset = (settings.topos_default_dataset_id or "default").strip() or "default"
392
+ return f"{user_id}:{default_dataset}"
393
+
394
+
367
395
  class HostedDeviceService:
368
396
  async def get_pairing_code(self) -> PairingCodeResponse:
369
- raise NotImplementedError("HostedDeviceService not implemented yet")
397
+ raise HTTPException(
398
+ status_code=status.HTTP_501_NOT_IMPLEMENTED,
399
+ detail="Pairing is not available for hosted runtimes",
400
+ )
370
401
 
371
402
  async def pair_device(self, pairing_code: str, keep_existing_data: bool) -> PairDeviceResponse:
372
403
  _ = (pairing_code, keep_existing_data)
373
- raise NotImplementedError("HostedDeviceService not implemented yet")
404
+ raise HTTPException(
405
+ status_code=status.HTTP_501_NOT_IMPLEMENTED,
406
+ detail="Pairing is not available for hosted runtimes",
407
+ )
374
408
 
375
- async def get_device_info(self) -> DeviceInfoResponse:
376
- raise NotImplementedError("HostedDeviceService not implemented yet")
409
+ async def get_device_info(self, context: Optional[Dict[str, Any]] = None) -> DeviceInfoResponse:
410
+ ctx = context if isinstance(context, dict) else {}
411
+ user_id = str(ctx.get("owner_user_id") or settings.topos_user_id or "").strip() or None
412
+ dataset_id = _hosted_dataset_id(ctx, user_id)
413
+ engine_mode = state.get_engine_mode()
414
+ device_name = (settings.engine_name or "").strip() or None
415
+
416
+ return DeviceInfoResponse(
417
+ user_id=user_id,
418
+ dataset_id=dataset_id,
419
+ sync_connected=False,
420
+ sync_enabled=False,
421
+ engine_class=state.get_engine_class(),
422
+ engine_mode=engine_mode,
423
+ llm_enabled=bool(settings.enable_llm and engine_mode == "full"),
424
+ database_mode=settings.topos_database_mode or "postgres",
425
+ database_version=_hosted_postgres_version(),
426
+ engine_name=device_name,
427
+ engine_version=__version__,
428
+ system={},
429
+ last_sync_at=None,
430
+ last_received_hlc_ts=None,
431
+ last_received_op_id=None,
432
+ oplog_count=None,
433
+ oplog_bytes=None,
434
+ ops_since_last_sync=None,
435
+ oplog_bytes_since_last_sync=None,
436
+ )
377
437
 
378
438
  async def set_device_name(self, device_name: str) -> DeviceNameResponse:
379
439
  _ = device_name
380
- raise NotImplementedError("HostedDeviceService not implemented yet")
440
+ raise HTTPException(
441
+ status_code=status.HTTP_501_NOT_IMPLEMENTED,
442
+ detail="Device rename is not available for hosted runtimes",
443
+ )
381
444
 
382
445
 
383
446
  class HostedSyncService:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 0.1.7
3
+ Version: 0.1.8
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