topos-node 1.3.0__tar.gz → 1.3.1__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.
- {topos_node-1.3.0/topos_node.egg-info → topos_node-1.3.1}/PKG-INFO +1 -1
- {topos_node-1.3.0 → topos_node-1.3.1}/pyproject.toml +1 -1
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/__version__.py +2 -2
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/app.py +39 -13
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/control_plane_client.py +4 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/usage_observation.py +6 -1
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/conversation_context.py +3 -1
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/upgrades/manifests.json +6 -4
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/upgrades/runner.py +206 -28
- {topos_node-1.3.0 → topos_node-1.3.1/topos_node.egg-info}/PKG-INFO +1 -1
- {topos_node-1.3.0 → topos_node-1.3.1}/LICENSE +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/MANIFEST.in +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/README.md +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/setup.cfg +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/shared/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/shared/filtering.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/shared/schema_registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/tests/test_extensions.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/tests/test_llm_integrations_storage.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/tests/test_protocol_handled_types.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/duckdb_adapter.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/messenger_communities.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/messenger_graph.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/messenger_labels.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/profiles.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/query_engine.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/analytics/raw_queries.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/analytics.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/app_registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/backup.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/compute_remote.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/conversation_context.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/data_commit.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/data_explorer_table_prefs.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/database_explorer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/db.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/device.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/engine_run.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/enrichment.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/enrichment_lab.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/facts_llm_config.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/filter_lab.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/health.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/home_chat.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/ingestion_api.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/ingestion_compat.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/ingestion_sources.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/intelligence_lifecycle.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/llm.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/local_mcp.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/messenger_analytics.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/privacy_disclose.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/query_api.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/runtime_bootstrap.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/sanitization_ollama_config.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/signal.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/signal_extraction_config.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/source_install.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/source_scrub.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/sources.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/sources_overview.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/sync.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/tool_index.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/ui_config.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/uma_data.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/upgrades.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/usage.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/api/user_identity.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/auth.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/demo_mappers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/documents_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/grok_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/models.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/canonicalization/resolver.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/cli/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/cli/__main__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/cli/commands.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/conversation_context_llm.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/facts_llm.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/sanitization_ollama.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/settings.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/signal_extraction.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/config/uvicorn_logging.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/contacts/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/contacts/identity.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/api_models.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/connection_resilience.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/device_helpers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/errors.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/events.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/common.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/config.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/contacts_import.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/database_explorer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/device.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/enrichment.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/enrichment_lab.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/filter_lab.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/home_chat.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/ingest.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/messages.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/messenger_analytics.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/query.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/routines.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/signal_features.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/sources.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/tool_index.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/handlers/uma.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/logging.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/metrics.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/routine_access.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/startup_banner.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/state.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/table_layers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/core/types.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/data_explorer_row_delete.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/data_explorer_table_prefs.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/data_explorer_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/canonical_writer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/content_policy.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/field_registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/privacy_layer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/disclosure/tier.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/generative_prompts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/generative_response.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/huggingface.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/ollama.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/openai.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/openai_compatible.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/redpill.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/backends/stub.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/client.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/engine.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/intake.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/memory_utils.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/model_cache.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/pipeline_memory.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/queue_manager.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/registration.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/result_formatter.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/router.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/scoped_token.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/tasks.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/transport.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/usage_guard.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/engine/validator.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/catalog.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/derived_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/job_writer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/url_classification_core.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/url_classification_enrichment_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/canonical/url_classification_signal_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/raw/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/raw/language_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/model_overrides.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/models/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/models/manager.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/models/mvp_defaults.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/models/registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/models/versioning.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/orchestrator.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/processor.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/progress_bar.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/registry_contract.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/signal_derivation_config.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/source_overrides.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment/website_classifier.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/bundles.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/model_resolve.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/schema.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/service.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/enrichment_lab/worker.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/evals/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/evals/enrichment_eval.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/extensions.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/consolidation.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/declared_mappings.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/dossier.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/edges.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/fact_materializer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/graph_enrichers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/graph_refresh.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/graph_search.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/linking.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/maintenance.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/reads.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/entities/resolver.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/extract.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/llm_extract.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/reads.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/facts/verdicts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/fit/evaluator.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/fit/opportunity_types.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/lifecycle/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/lifecycle/derived_scrub.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/lifecycle/exclusions.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/lifecycle/gc.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/provenance/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/provenance/posture.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/provenance/roles.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/brief_canonical_loader.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/brief_ontology.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/brief_renderer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/brief_schemas.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/chunking.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/cluster_labels.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/data_health.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/brief_ontologies.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/intentions.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/profile.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/relationships.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/time.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/definitions/work.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/dimension_briefs.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/dimension_definition_loader.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/dimension_profiles.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/dimension_registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/embed_context.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/extraction/artifact_router.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/extraction/artifact_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/extraction/rule_extractors.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/graph_sanitize.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/hybrid_search.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/incremental_clustering.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/model_recommendations.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/query_embed_cache.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/schemas.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/service.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/signal_object_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/source_hydration.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/structured_signal.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/tool_index.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/topic_clustering.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/typed_stores/aggregates.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/typed_stores/commitments.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/typed_stores/rhythm.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/vector_codec.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/vector_math.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/signal/vector_settings.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/stats/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/stats/definitions.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/stats/engine.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/stats/fold.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/stats/insights.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/timeline_projection.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/badges.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/daily.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/dashboard.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/instruments.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/intents.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/features/triage/readiness.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/bundles.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/schema.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/service.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/filter_lab/worker.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/home_chat/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/home_chat/schema.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/home_chat/store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/hosted_pool_lease.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/canonical_pipeline.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/checkpoints/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/inbox_crypto.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/inbox_drain.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/ingest_helpers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/jobs.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/journal_location_fanout.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/journal_time_log_normalize.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/local_sync.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/log_preview.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/manager.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/browser_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/calendar_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/documents_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/github_activity_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/grok_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/messenger_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/parsers/voxterm_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/progress.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/reprocess.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/calendar.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/chatgpt.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/contact_importers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/grok.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/imessage_reader.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/signal_export_parser.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/sources/signal_reader.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/state_machine.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/triggers/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/triggers/file_trigger.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/usage_inbox_dedupe.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/validation/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/validation/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/validation/schema_registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/ingestion/validation/schema_validator.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/lineage/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/lineage/provenance.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/lineage/tracker.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/llm_integrations_storage.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/mcp_stdio_proxy.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/observability/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/observability/alerts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/observability/metrics.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/observability/tracing.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/openai_client.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/audit.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/envelope.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/job_runner.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/job_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/stages.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/pipeline/stub_enqueue.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/projections/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/projections/vector_index/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/projections/vector_index/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/projections/vector_index/builders.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/projections/vector_index/health_checks.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/protocol/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/protocol/handled_message_types.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/audit.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/ddr.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/disclosure.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/fingerprint.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/game_layer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/grant_cache.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/inference.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/intent.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/manifest.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/manifest_validation.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/minimizer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/negotiation.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/pipeline.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/planner.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/retrieval.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/runtime.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/scope_registry.json +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/scope_registry_loader.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/session.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/session_utils.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/source_generation.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/truth_facts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/truth_prompts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/turn_classifier.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/types.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/verify.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/query/verify_modes.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/rate_limit.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/routines/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/routines/schema.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/routines/store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/runtime_housekeeping.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/runtime_shutdown.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/runtime_update.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sanitization/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sanitization/nsfw_classifier.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sanitization/ollama_transforms.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sanitization/prewarm.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sanitization/privacy_filter.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/scope_resolution.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/container.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/embeddings/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/embeddings/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/embeddings/local.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/embeddings/remote.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/interfaces.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/llm/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/llm/base.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/llm/openai.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/local.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/services/postgres.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/bundled_canonical_triples.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/canonical_signal_defaults.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/definitions.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/install_service.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/registry.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/runtime_install.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/scrub_attribution.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sources/scrub_service.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/startup_banner.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/factory.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/fakes.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/postgres/stores.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/protocols.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/sqlite/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/sqlite/stores.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/adapters/sqlite/vector_search.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/activity_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/ai_chat/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/ai_chat/mapper.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/ai_chat/model.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/ai_chat/tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/canonical_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/conversations_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/mapping_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/canonical/postgres.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/client.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/connection_tuning.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/actor_role_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/documents_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/episodes_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/remediation_person_model.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/scope_source_generation.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/signal_objects.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/paths.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/postgres.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/schema.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/storage_breakdown.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/db/write_gate.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/enrichment/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/normalized/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/normalized/normalized_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/oplog/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/oplog/decision.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/oplog/oplog_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/oplog/postgres.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/person/identity_resolver.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/projections/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/projections/index_ops_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/projections/vector_index_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/browser_flat_tables.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/file_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/raw_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/raw_tables_manager.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/raw/sqlite_raw_store.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/security/encryption.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/signal_identity.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/source_settings.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/storage/user_identity.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sync/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sync/client.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/sync_handlers.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/testing/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/testing/lifespan.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/uma_contact_enrichment.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/uma_filters.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/uma_resource_id.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/uma_rpt.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/upgrades/__init__.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/utils/base_object.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos/websocket_client.py +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos_node.egg-info/SOURCES.txt +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos_node.egg-info/dependency_links.txt +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos_node.egg-info/entry_points.txt +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos_node.egg-info/requires.txt +0 -0
- {topos_node-1.3.0 → topos_node-1.3.1}/topos_node.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "topos-node"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.1"
|
|
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"
|
|
@@ -5,6 +5,7 @@ import importlib.util
|
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
7
|
import sys
|
|
8
|
+
import threading
|
|
8
9
|
|
|
9
10
|
from fastapi import FastAPI
|
|
10
11
|
from fastapi.middleware.cors import CORSMiddleware
|
|
@@ -171,19 +172,9 @@ async def startup_event() -> None:
|
|
|
171
172
|
logger.info("Stage 9 migrations applied at startup: %d renames", len(result["applied"]))
|
|
172
173
|
except Exception as e:
|
|
173
174
|
logger.debug("Stage 9 migrations at startup (non-fatal): %s", e)
|
|
174
|
-
# Upgrade runner
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
# stale derived data meanwhile. Fresh installs stamp-and-skip.
|
|
178
|
-
try:
|
|
179
|
-
from .core.state import get_db_connection as _get_conn_for_upgrades
|
|
180
|
-
from .upgrades.runner import start_background as _start_upgrades
|
|
181
|
-
|
|
182
|
-
_upgrade_conn = state.db_conn if state.db_conn is not None else _get_conn_for_upgrades()
|
|
183
|
-
if _upgrade_conn is not None:
|
|
184
|
-
_start_upgrades(_upgrade_conn)
|
|
185
|
-
except Exception as e:
|
|
186
|
-
logger.warning("Upgrade runner at startup failed (non-fatal): %s", e)
|
|
175
|
+
# Upgrade runner is armed later — after control-plane / local readiness —
|
|
176
|
+
# so the React UI can fetch bootstrap data before enrichment reprocess
|
|
177
|
+
# contends for SQLite / Ollama / MPS. See _arm_upgrade_runner below.
|
|
187
178
|
try:
|
|
188
179
|
from .core.state import get_db_connection as _get_conn_for_pipeline
|
|
189
180
|
from .pipeline.job_runner import recover_pipeline_jobs, start_pipeline_worker
|
|
@@ -295,6 +286,41 @@ async def startup_event() -> None:
|
|
|
295
286
|
start_runtime_update_monitor()
|
|
296
287
|
start_update_hotkey_listener()
|
|
297
288
|
|
|
289
|
+
# Upgrade runner: plan/stamp cheaply, but defer heavy re-derivation until the
|
|
290
|
+
# UI can bootstrap (CP connected + grace). Fresh installs stamp-and-skip.
|
|
291
|
+
try:
|
|
292
|
+
from .core.state import get_db_connection as _get_conn_for_upgrades
|
|
293
|
+
from .upgrades.runner import (
|
|
294
|
+
ready_timeout_seconds as _upgrade_ready_timeout,
|
|
295
|
+
start_background as _start_upgrades,
|
|
296
|
+
ui_grace_seconds as _upgrade_ui_grace,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
_upgrade_conn = state.db_conn if state.db_conn is not None else _get_conn_for_upgrades()
|
|
300
|
+
if _upgrade_conn is not None:
|
|
301
|
+
_upgrade_ready = threading.Event()
|
|
302
|
+
_start_upgrades(
|
|
303
|
+
_upgrade_conn,
|
|
304
|
+
ready_event=_upgrade_ready,
|
|
305
|
+
ui_grace_s=_upgrade_ui_grace(),
|
|
306
|
+
ready_timeout_s=_upgrade_ready_timeout(),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
async def _signal_upgrade_ui_ready() -> None:
|
|
310
|
+
try:
|
|
311
|
+
if state.control_plane_client is not None:
|
|
312
|
+
await state.control_plane_client.wait_until_connected(
|
|
313
|
+
timeout_s=_upgrade_ready_timeout()
|
|
314
|
+
)
|
|
315
|
+
except Exception as ready_exc: # noqa: BLE001
|
|
316
|
+
logger.debug("Upgrade UI-ready wait ended: %s", ready_exc)
|
|
317
|
+
finally:
|
|
318
|
+
_upgrade_ready.set()
|
|
319
|
+
|
|
320
|
+
asyncio.create_task(_signal_upgrade_ui_ready())
|
|
321
|
+
except Exception as e:
|
|
322
|
+
logger.warning("Upgrade runner at startup failed (non-fatal): %s", e)
|
|
323
|
+
|
|
298
324
|
if settings.enable_sync and settings.topos_user_id:
|
|
299
325
|
state.sync_client = SyncClient(
|
|
300
326
|
sync_url=settings.get_sync_url(),
|
|
@@ -49,6 +49,10 @@ _FAST_INBOUND_MESSAGE_TYPES = frozenset(
|
|
|
49
49
|
"signal_entity_graph",
|
|
50
50
|
"signal_list_entities",
|
|
51
51
|
"signal_get_entity",
|
|
52
|
+
# Shell bootstrap / upgrade banner — must not sit behind inbound saturation
|
|
53
|
+
# while a version upgrade reprocess is walking sources.
|
|
54
|
+
"get_runtime_bootstrap",
|
|
55
|
+
"get_upgrade_status",
|
|
52
56
|
}
|
|
53
57
|
)
|
|
54
58
|
|
|
@@ -56,7 +56,12 @@ def resolve_llm_usage_purpose(
|
|
|
56
56
|
return origin_key
|
|
57
57
|
source_key = str(source_id or "").strip().lower()
|
|
58
58
|
# Signal derivation helpers reuse query_inference plumbing but are ingestion work.
|
|
59
|
-
if source_key in {
|
|
59
|
+
if source_key in {
|
|
60
|
+
"cluster_labeler",
|
|
61
|
+
"cluster_labels",
|
|
62
|
+
"topic_clusters",
|
|
63
|
+
"conversation_context",
|
|
64
|
+
}:
|
|
60
65
|
return PURPOSE_INGESTION_PIPELINE
|
|
61
66
|
subtype_key = str(subtype or "").strip().lower()
|
|
62
67
|
type_key = str(task_type or "").strip().lower()
|
|
@@ -70,7 +70,7 @@ def _parse_label(answer: Any) -> Optional[str]:
|
|
|
70
70
|
def _classify_with_model(model: str, excerpts: List[str]) -> Optional[str]:
|
|
71
71
|
from ...config.settings import settings # noqa: F401 — engine client env
|
|
72
72
|
from ...engine.client import get_engine_client_or_local
|
|
73
|
-
from ...engine.tasks import ModelRequest, ProcessingTask
|
|
73
|
+
from ...engine.tasks import ModelRequest, ProcessingTask, RequestedBy
|
|
74
74
|
|
|
75
75
|
task = ProcessingTask(
|
|
76
76
|
id="conversation_context",
|
|
@@ -83,6 +83,8 @@ def _classify_with_model(model: str, excerpts: List[str]) -> Optional[str]:
|
|
|
83
83
|
"context": "\n---\n".join(excerpts),
|
|
84
84
|
},
|
|
85
85
|
model_request=ModelRequest(provider="ollama", model=model),
|
|
86
|
+
# Piggybacked on dimension_summary / enrichment — not an interactive UI ask.
|
|
87
|
+
requested_by=RequestedBy(origin="ingestion_pipeline"),
|
|
86
88
|
)
|
|
87
89
|
try:
|
|
88
90
|
result = get_engine_client_or_local(None).run(task)
|
|
@@ -18,12 +18,13 @@
|
|
|
18
18
|
"params": {
|
|
19
19
|
"job_names": ["entities"],
|
|
20
20
|
"force_reprocess": true,
|
|
21
|
+
"include_signal": false,
|
|
21
22
|
"per_source": true,
|
|
22
23
|
"source_filter": "sources with canonical message/journal/activity records"
|
|
23
24
|
},
|
|
24
|
-
"progress": "GET /v1/
|
|
25
|
+
"progress": "TUI progress bar on the node + GET /v1/upgrade/status",
|
|
25
26
|
"idempotent": "record_mention is INSERT OR IGNORE; re-running converges",
|
|
26
|
-
"estimated_duration": "~10–20 min per 1.5k records (CPU-bound NER); node stays usable, serves stale graph meanwhile",
|
|
27
|
+
"estimated_duration": "~10–20 min per 1.5k records (CPU-bound NER); node stays usable, serves stale graph meanwhile; signal/LLM lane stays off (graph rebuild is the next step)",
|
|
27
28
|
"order": 1
|
|
28
29
|
},
|
|
29
30
|
{
|
|
@@ -76,12 +77,13 @@
|
|
|
76
77
|
"params": {
|
|
77
78
|
"job_names": ["attention_triage"],
|
|
78
79
|
"force_reprocess": true,
|
|
80
|
+
"include_signal": false,
|
|
79
81
|
"per_source": true,
|
|
80
82
|
"source_filter": "sources with canonical message/journal/activity records"
|
|
81
83
|
},
|
|
82
|
-
"progress": "GET /v1/
|
|
84
|
+
"progress": "TUI progress bar on the node + GET /v1/upgrade/status",
|
|
83
85
|
"idempotent": "verdicts are (day, record_id) upserts; signal objects no-op when unchanged",
|
|
84
|
-
"estimated_duration": "seconds–minutes depending on day span; CPU-bound instruments, no LLM",
|
|
86
|
+
"estimated_duration": "seconds–minutes depending on day span; CPU-bound instruments, no LLM (signal lane off)",
|
|
85
87
|
"order": 1
|
|
86
88
|
}
|
|
87
89
|
],
|
|
@@ -15,6 +15,11 @@ re-derivation steps all completed) against the shipped version and executes
|
|
|
15
15
|
* kill-switch: TOPOS_UPGRADE_RUNNER=off disables execution (nothing stamps,
|
|
16
16
|
so re-enabling picks up where it left off).
|
|
17
17
|
|
|
18
|
+
Heavy steps are deferred until the UI can bootstrap (control-plane ready +
|
|
19
|
+
grace window), then run in a daemon thread with a TUI progress bar. Enrichment
|
|
20
|
+
reprocess steps run only the declared ``job_names`` — they do NOT fan out into
|
|
21
|
+
the signal/LLM lane (that was starving startup UI traffic).
|
|
22
|
+
|
|
18
23
|
Executors are injectable for tests; the real ones dispatch step kinds to
|
|
19
24
|
engine internals (no HTTP self-calls).
|
|
20
25
|
"""
|
|
@@ -26,6 +31,7 @@ import logging
|
|
|
26
31
|
import os
|
|
27
32
|
import sqlite3
|
|
28
33
|
import threading
|
|
34
|
+
import time
|
|
29
35
|
from datetime import datetime, timezone
|
|
30
36
|
from typing import Any, Callable, Dict, List, Optional
|
|
31
37
|
|
|
@@ -35,12 +41,20 @@ logger = logging.getLogger("topos.upgrades.runner")
|
|
|
35
41
|
|
|
36
42
|
_BASELINE_KEY = "engine.upgrade.baseline"
|
|
37
43
|
_BOOTSTRAP_BASELINE = "1.1.0"
|
|
44
|
+
_DEFAULT_UI_GRACE_SECONDS = 20.0
|
|
45
|
+
_DEFAULT_READY_TIMEOUT_SECONDS = 60.0
|
|
38
46
|
|
|
39
47
|
ExecutorFn = Callable[[Dict[str, Any], sqlite3.Connection], Dict[str, Any]]
|
|
40
48
|
|
|
41
49
|
# Status snapshot for the /upgrade/status surface (module-level, single node).
|
|
42
50
|
_state_lock = threading.Lock()
|
|
43
|
-
_runner_state: Dict[str, Any] = {
|
|
51
|
+
_runner_state: Dict[str, Any] = {
|
|
52
|
+
"running": False,
|
|
53
|
+
"waiting_for_ui": False,
|
|
54
|
+
"current_step": None,
|
|
55
|
+
"progress": None,
|
|
56
|
+
"last_result": None,
|
|
57
|
+
}
|
|
44
58
|
|
|
45
59
|
|
|
46
60
|
def _now() -> str:
|
|
@@ -53,12 +67,66 @@ def _enabled() -> bool:
|
|
|
53
67
|
)
|
|
54
68
|
|
|
55
69
|
|
|
70
|
+
def _env_float(name: str, default: float) -> float:
|
|
71
|
+
raw = os.environ.get(name)
|
|
72
|
+
if raw is None or not str(raw).strip():
|
|
73
|
+
return default
|
|
74
|
+
try:
|
|
75
|
+
return max(0.0, float(raw))
|
|
76
|
+
except (TypeError, ValueError):
|
|
77
|
+
return default
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def ui_grace_seconds() -> float:
|
|
81
|
+
"""Seconds to wait after readiness so the React UI can fetch bootstrap data."""
|
|
82
|
+
return _env_float("TOPOS_UPGRADE_UI_GRACE_SECONDS", _DEFAULT_UI_GRACE_SECONDS)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def ready_timeout_seconds() -> float:
|
|
86
|
+
return _env_float("TOPOS_UPGRADE_READY_TIMEOUT_SECONDS", _DEFAULT_READY_TIMEOUT_SECONDS)
|
|
87
|
+
|
|
88
|
+
|
|
56
89
|
def _shipped_version() -> str:
|
|
57
90
|
from topos.__version__ import __version__
|
|
58
91
|
|
|
59
92
|
return __version__
|
|
60
93
|
|
|
61
94
|
|
|
95
|
+
def _set_runner_state(**updates: Any) -> None:
|
|
96
|
+
with _state_lock:
|
|
97
|
+
_runner_state.update(updates)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _progress_snapshot(
|
|
101
|
+
*,
|
|
102
|
+
step_id: str,
|
|
103
|
+
step_index: int,
|
|
104
|
+
steps_total: int,
|
|
105
|
+
unit_label: str,
|
|
106
|
+
completed: int,
|
|
107
|
+
total: int,
|
|
108
|
+
detail: Optional[str] = None,
|
|
109
|
+
) -> Dict[str, Any]:
|
|
110
|
+
total = max(0, int(total))
|
|
111
|
+
completed = max(0, min(int(completed), total if total else int(completed)))
|
|
112
|
+
fraction = (completed / total) if total else 0.0
|
|
113
|
+
# Blend step index with in-step fraction so multi-step upgrades read smoothly.
|
|
114
|
+
if steps_total > 0:
|
|
115
|
+
overall = (max(0, step_index) + fraction) / steps_total
|
|
116
|
+
else:
|
|
117
|
+
overall = fraction
|
|
118
|
+
return {
|
|
119
|
+
"step_id": step_id,
|
|
120
|
+
"step_index": step_index,
|
|
121
|
+
"steps_total": steps_total,
|
|
122
|
+
"unit_label": unit_label,
|
|
123
|
+
"completed": completed,
|
|
124
|
+
"total": total,
|
|
125
|
+
"percent": round(100.0 * overall, 1),
|
|
126
|
+
"detail": detail,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
62
130
|
def read_baseline(conn: sqlite3.Connection) -> Optional[str]:
|
|
63
131
|
try:
|
|
64
132
|
row = conn.execute(
|
|
@@ -186,28 +254,74 @@ def _real_source_ids(conn: sqlite3.Connection) -> List[str]:
|
|
|
186
254
|
|
|
187
255
|
|
|
188
256
|
def _exec_enrichment_reprocess(step: Dict[str, Any], conn: sqlite3.Connection) -> Dict[str, Any]:
|
|
189
|
-
"""Walk real sources through the enrichment core with force_reprocess.
|
|
257
|
+
"""Walk real sources through the enrichment core with force_reprocess.
|
|
258
|
+
|
|
259
|
+
Upgrade manifests declare specific ``job_names`` (e.g. attention_triage).
|
|
260
|
+
Unless a step explicitly sets ``include_signal: true``, we keep the signal /
|
|
261
|
+
LLM derivation lane OFF — otherwise every source fans out into embeddings,
|
|
262
|
+
cluster labeling, dimension briefs, and conversation-context LLM calls and
|
|
263
|
+
starves the UI during first boot after an upgrade.
|
|
264
|
+
"""
|
|
190
265
|
import asyncio
|
|
191
266
|
|
|
192
267
|
from ..api.enrichment import _process_enrichment_core
|
|
268
|
+
from ..enrichment.progress_bar import ProgressBar
|
|
193
269
|
|
|
194
270
|
params = step.get("params") or {}
|
|
195
271
|
job_names = params.get("job_names") or None
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
272
|
+
include_signal = bool(params.get("include_signal", False))
|
|
273
|
+
source_ids = _real_source_ids(conn)
|
|
274
|
+
step_id = str(step.get("id") or "enrichment_reprocess")
|
|
275
|
+
step_index = int(step.get("_runner_step_index") or 0)
|
|
276
|
+
steps_total = int(step.get("_runner_steps_total") or 1)
|
|
277
|
+
detail: Dict[str, Any] = {"sources": {}, "include_signal": include_signal}
|
|
278
|
+
def _run_sources(pbar: Optional[ProgressBar] = None) -> None:
|
|
279
|
+
for idx, source_id in enumerate(source_ids):
|
|
280
|
+
_set_runner_state(
|
|
281
|
+
progress=_progress_snapshot(
|
|
282
|
+
step_id=step_id,
|
|
283
|
+
step_index=step_index,
|
|
284
|
+
steps_total=steps_total,
|
|
285
|
+
unit_label="sources",
|
|
286
|
+
completed=idx,
|
|
287
|
+
total=len(source_ids),
|
|
288
|
+
detail=source_id,
|
|
204
289
|
)
|
|
205
290
|
)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
291
|
+
if pbar is not None:
|
|
292
|
+
pbar.set_description(f"Upgrade {step_id} · {source_id}")
|
|
293
|
+
try:
|
|
294
|
+
out = asyncio.run(
|
|
295
|
+
_process_enrichment_core(
|
|
296
|
+
source_id=source_id,
|
|
297
|
+
job_names=list(job_names) if job_names else None,
|
|
298
|
+
force_reprocess=bool(params.get("force_reprocess", True)),
|
|
299
|
+
include_signal=include_signal,
|
|
300
|
+
)
|
|
301
|
+
)
|
|
302
|
+
detail["sources"][source_id] = str(out.get("status") or "ok")
|
|
303
|
+
except ValueError:
|
|
304
|
+
detail["sources"][source_id] = "unknown_source_skipped"
|
|
305
|
+
except Exception as exc: # noqa: BLE001 — one source must not kill the walk
|
|
306
|
+
detail["sources"][source_id] = f"error: {exc}"
|
|
307
|
+
if pbar is not None:
|
|
308
|
+
pbar.update(1)
|
|
309
|
+
|
|
310
|
+
if source_ids:
|
|
311
|
+
with ProgressBar(total=len(source_ids), desc=f"Upgrade {step_id}", width=40) as pbar:
|
|
312
|
+
_run_sources(pbar)
|
|
313
|
+
else:
|
|
314
|
+
_run_sources(None)
|
|
315
|
+
_set_runner_state(
|
|
316
|
+
progress=_progress_snapshot(
|
|
317
|
+
step_id=step_id,
|
|
318
|
+
step_index=step_index,
|
|
319
|
+
steps_total=steps_total,
|
|
320
|
+
unit_label="sources",
|
|
321
|
+
completed=len(source_ids),
|
|
322
|
+
total=len(source_ids),
|
|
323
|
+
)
|
|
324
|
+
)
|
|
211
325
|
return detail
|
|
212
326
|
|
|
213
327
|
|
|
@@ -256,7 +370,9 @@ def run_pending_upgrades(
|
|
|
256
370
|
|
|
257
371
|
ran = failed = 0
|
|
258
372
|
failed_ids: set = set()
|
|
259
|
-
|
|
373
|
+
steps = list(plan["steps"])
|
|
374
|
+
steps_total = len(steps)
|
|
375
|
+
for step_index, step in enumerate(steps):
|
|
260
376
|
step_id = str(step["id"])
|
|
261
377
|
status = _ledger_status(conn, shipped_v, step_id)
|
|
262
378
|
if status == "done":
|
|
@@ -274,12 +390,26 @@ def run_pending_upgrades(
|
|
|
274
390
|
failed_ids.add(step_id)
|
|
275
391
|
failed += 1
|
|
276
392
|
continue
|
|
277
|
-
|
|
278
|
-
|
|
393
|
+
annotated = dict(step)
|
|
394
|
+
annotated["_runner_step_index"] = step_index
|
|
395
|
+
annotated["_runner_steps_total"] = steps_total
|
|
396
|
+
_set_runner_state(
|
|
397
|
+
running=True,
|
|
398
|
+
waiting_for_ui=False,
|
|
399
|
+
current_step=step_id,
|
|
400
|
+
progress=_progress_snapshot(
|
|
401
|
+
step_id=step_id,
|
|
402
|
+
step_index=step_index,
|
|
403
|
+
steps_total=steps_total,
|
|
404
|
+
unit_label="steps",
|
|
405
|
+
completed=0,
|
|
406
|
+
total=1,
|
|
407
|
+
),
|
|
408
|
+
)
|
|
279
409
|
_ledger_set(conn, shipped_v, step_id, "running", started=True)
|
|
280
410
|
logger.info("upgrade step %s (%s) starting", step_id, step["kind"])
|
|
281
411
|
try:
|
|
282
|
-
detail = executor(
|
|
412
|
+
detail = executor(annotated, conn)
|
|
283
413
|
_ledger_set(conn, shipped_v, step_id, "done", detail if isinstance(detail, dict) else None)
|
|
284
414
|
ran += 1
|
|
285
415
|
except Exception as exc: # noqa: BLE001 — ledger the failure, keep the node up
|
|
@@ -287,8 +417,7 @@ def run_pending_upgrades(
|
|
|
287
417
|
_ledger_set(conn, shipped_v, step_id, "failed", {"error": str(exc)})
|
|
288
418
|
failed_ids.add(step_id)
|
|
289
419
|
failed += 1
|
|
290
|
-
|
|
291
|
-
_runner_state.update(running=False, current_step=None)
|
|
420
|
+
_set_runner_state(running=False, waiting_for_ui=False, current_step=None, progress=None)
|
|
292
421
|
|
|
293
422
|
all_done = all(
|
|
294
423
|
_ledger_status(conn, shipped_v, str(s["id"])) == "done" for s in plan["steps"]
|
|
@@ -297,27 +426,74 @@ def run_pending_upgrades(
|
|
|
297
426
|
_stamp_baseline(conn, shipped_v)
|
|
298
427
|
logger.info("upgrade to %s complete (%d steps)", shipped_v, ran)
|
|
299
428
|
result = {"steps_run": ran, "steps_failed": failed, "baseline_advanced": all_done}
|
|
300
|
-
|
|
301
|
-
_runner_state["last_result"] = result
|
|
429
|
+
_set_runner_state(last_result=result)
|
|
302
430
|
return result
|
|
303
431
|
|
|
304
432
|
|
|
305
|
-
def start_background(
|
|
306
|
-
|
|
433
|
+
def start_background(
|
|
434
|
+
conn: sqlite3.Connection,
|
|
435
|
+
*,
|
|
436
|
+
ready_event: Optional[threading.Event] = None,
|
|
437
|
+
ui_grace_s: Optional[float] = None,
|
|
438
|
+
ready_timeout_s: Optional[float] = None,
|
|
439
|
+
) -> Optional[threading.Thread]:
|
|
440
|
+
"""Boot entrypoint: plan quickly; heavy steps wait for UI, then run off-loop.
|
|
441
|
+
|
|
442
|
+
``ready_event`` should be set once the control plane (or local HTTP) is able
|
|
443
|
+
to serve the React app's initial bootstrap. A grace window then lets those
|
|
444
|
+
requests finish before enrichment reprocess contends for SQLite / Ollama /
|
|
445
|
+
MPS. Fresh installs stamp-and-skip inline (no thread).
|
|
446
|
+
"""
|
|
307
447
|
if not _enabled():
|
|
308
448
|
return None
|
|
309
449
|
plan = plan_upgrade(conn)
|
|
310
450
|
if plan["fresh_install"] or not plan["steps"]:
|
|
311
451
|
run_pending_upgrades(conn) # cheap: stamp/no-op inline
|
|
312
452
|
return None
|
|
453
|
+
grace = _DEFAULT_UI_GRACE_SECONDS if ui_grace_s is None else max(0.0, float(ui_grace_s))
|
|
454
|
+
ready_timeout = (
|
|
455
|
+
_DEFAULT_READY_TIMEOUT_SECONDS if ready_timeout_s is None else max(0.0, float(ready_timeout_s))
|
|
456
|
+
)
|
|
313
457
|
logger.info(
|
|
314
|
-
"upgrade %s → %s: %d step(s) queued (%s)"
|
|
458
|
+
"upgrade %s → %s: %d step(s) queued (%s); waiting for UI readiness "
|
|
459
|
+
"(timeout=%.0fs, grace=%.0fs) before starting",
|
|
315
460
|
plan["baseline"], plan["shipped"], len(plan["steps"]),
|
|
316
461
|
", ".join(s["id"] for s in plan["steps"]),
|
|
462
|
+
ready_timeout,
|
|
463
|
+
grace,
|
|
317
464
|
)
|
|
318
|
-
|
|
319
|
-
|
|
465
|
+
_set_runner_state(
|
|
466
|
+
waiting_for_ui=True,
|
|
467
|
+
running=False,
|
|
468
|
+
current_step=None,
|
|
469
|
+
progress={
|
|
470
|
+
"step_id": None,
|
|
471
|
+
"percent": 0.0,
|
|
472
|
+
"detail": "waiting_for_ui",
|
|
473
|
+
"grace_seconds": grace,
|
|
474
|
+
},
|
|
320
475
|
)
|
|
476
|
+
|
|
477
|
+
def _target() -> None:
|
|
478
|
+
try:
|
|
479
|
+
if ready_event is not None:
|
|
480
|
+
signaled = ready_event.wait(timeout=ready_timeout if ready_timeout > 0 else None)
|
|
481
|
+
if not signaled:
|
|
482
|
+
logger.warning(
|
|
483
|
+
"upgrade ready-event timed out after %.0fs; starting anyway",
|
|
484
|
+
ready_timeout,
|
|
485
|
+
)
|
|
486
|
+
if grace > 0:
|
|
487
|
+
logger.info(
|
|
488
|
+
"UI grace: deferring upgrade work for %.0fs so bootstrap can finish",
|
|
489
|
+
grace,
|
|
490
|
+
)
|
|
491
|
+
time.sleep(grace)
|
|
492
|
+
run_pending_upgrades(conn)
|
|
493
|
+
finally:
|
|
494
|
+
_set_runner_state(waiting_for_ui=False)
|
|
495
|
+
|
|
496
|
+
thread = threading.Thread(target=_target, name="topos-upgrade-runner", daemon=True)
|
|
321
497
|
thread.start()
|
|
322
498
|
return thread
|
|
323
499
|
|
|
@@ -333,7 +509,9 @@ def runner_status(conn: sqlite3.Connection) -> Dict[str, Any]:
|
|
|
333
509
|
"fresh_install": plan["fresh_install"],
|
|
334
510
|
"pending_steps": [s["id"] for s in plan["steps"]],
|
|
335
511
|
"running": state["running"],
|
|
512
|
+
"waiting_for_ui": state.get("waiting_for_ui", False),
|
|
336
513
|
"current_step": state["current_step"],
|
|
514
|
+
"progress": state.get("progress"),
|
|
337
515
|
"last_result": state["last_result"],
|
|
338
516
|
"ledger": ledger_rows(conn),
|
|
339
517
|
}
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|