ltcai 11.5.2 → 11.7.0
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.
- package/README.md +93 -148
- package/bin/ltcai.js +234 -24
- package/docs/CHANGELOG.md +119 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +8 -6
- package/docs/ENTERPRISE.md +2 -1
- package/docs/MULTI_AGENT_RUNTIME.md +12 -5
- package/docs/ONBOARDING.md +1 -1
- package/docs/OPERATIONS.md +6 -3
- package/docs/REALTIME_COLLABORATION.md +1 -1
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +1 -1
- package/docs/WORKFLOW_DESIGNER.md +3 -2
- package/docs/kg-schema.md +1 -1
- package/docs/v11.6.0_ONE_DOOR_PLAN.md +170 -0
- package/lattice_brain/__init__.py +42 -79
- package/lattice_brain/graph/__init__.py +9 -24
- package/lattice_brain/graph/_kg_common/__init__.py +13 -24
- package/lattice_brain/ingestion/__init__.py +19 -58
- package/lattice_brain/ingestion/pipeline.py +20 -398
- package/lattice_brain/multimodal/__init__.py +7 -18
- package/lattice_brain/multimodal/images.py +6 -264
- package/lattice_brain/multimodal/video.py +8 -247
- package/lattice_brain/runtime/__init__.py +8 -79
- package/lattice_brain/runtime/hooks.py +22 -584
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agent_worker_seam.py +7 -80
- package/latticeai/api/health.py +6 -20
- package/latticeai/api/local_files.py +16 -613
- package/latticeai/api/models.py +12 -87
- package/latticeai/api/search.py +17 -255
- package/latticeai/api/tools.py +69 -750
- package/latticeai/api/voice_capture.py +8 -70
- package/latticeai/api/worker_compute.py +842 -0
- package/latticeai/api/worker_seams.py +216 -0
- package/latticeai/app_factory.py +23 -232
- package/latticeai/cli/entrypoint.py +36 -249
- package/latticeai/core/agent_permission.py +16 -91
- package/latticeai/core/messages.py +89 -531
- package/latticeai/runtime/access_runtime.py +0 -14
- package/latticeai/runtime/bootstrap.py +10 -21
- package/latticeai/runtime/brain_runtime.py +35 -43
- package/latticeai/runtime/build_phases/__init__.py +21 -37
- package/latticeai/runtime/build_phases/features.py +99 -389
- package/latticeai/runtime/build_phases/foundation.py +82 -392
- package/latticeai/runtime/build_phases/web.py +91 -408
- package/latticeai/runtime/build_phases/worker_profile.py +244 -0
- package/latticeai/runtime/lifespan_runtime.py +7 -16
- package/latticeai/runtime/platform_services_runtime.py +1 -15
- package/latticeai/runtime/runtime_context.py +13 -130
- package/latticeai/runtime/security_runtime.py +10 -103
- package/latticeai/services/architecture_readiness.py +82 -43
- package/latticeai/services/model_runtime/__init__.py +2 -11
- package/latticeai/services/model_runtime/service.py +4 -28
- package/latticeai/services/p_reinforce.py +10 -261
- package/latticeai/services/product_readiness.py +31 -38
- package/latticeai/services/search_service.py +37 -795
- package/latticeai/services/tool_dispatch.py +30 -386
- package/latticeai/services/voice_capture.py +13 -107
- package/latticeai/tools/__init__.py +22 -49
- package/latticeai/tools/commands.py +0 -163
- package/latticeai/tools/computer.py +0 -39
- package/latticeai/tools/documents.py +1 -134
- package/latticeai/tools/filesystem.py +1 -247
- package/latticeai/tools/knowledge.py +1 -52
- package/latticeai/tools/local_files.py +0 -20
- package/latticeai/worker_app.py +75 -0
- package/package.json +2 -3
- package/requirements.txt +0 -5
- package/scripts/agent_eval.py +16 -28
- package/scripts/brain_quality_eval.py +20 -183
- package/scripts/bump_version.py +5 -5
- package/scripts/check_current_release_docs.mjs +7 -4
- package/scripts/check_openapi_drift.mjs +10 -0
- package/scripts/check_server_i18n.mjs +2 -18
- package/scripts/compose_openapi.py +377 -0
- package/scripts/export_openapi.py +32 -4
- package/scripts/gen_messages_catalog_fixture.py +302 -0
- package/scripts/gen_openapi_fragments.py +365 -0
- package/scripts/gen_redact_fixture.py +196 -0
- package/scripts/gen_worker_allowlist_fixture.py +115 -0
- package/scripts/generate_agent_parity_fixtures.py +33 -14
- package/scripts/openapi_route_families.json +2161 -0
- package/scripts/release_screen_claims.json +54 -0
- package/scripts/run_integration_tests.mjs +134 -29
- package/scripts/run_sidecar_e2e.mjs +104 -11
- package/scripts/wheel_smoke.py +32 -22
- package/src-tauri/Cargo.lock +375 -9
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/backend.rs +151 -45
- package/src-tauri/src/main.rs +18 -18
- package/src-tauri/src/topology.rs +58 -88
- package/src-tauri/tauri.conf.json +1 -2
- package/static/app/asset-manifest.json +41 -41
- package/static/app/assets/{Act-DcQizkl1.js → Act-BPcVAbOL.js} +1 -1
- package/static/app/assets/AdminConsole-Bw1ATQL0.js +1 -0
- package/static/app/assets/{Brain-3VCSHFcn.js → Brain-CT92Kos0.js} +2 -2
- package/static/app/assets/{BrainHome-Qm8eaztx.js → BrainHome-CFBkt1K_.js} +1 -1
- package/static/app/assets/{BrainSignals-DS9BtKOW.js → BrainSignals-ReLWF2H8.js} +1 -1
- package/static/app/assets/Capture-BsTokYkk.js +1 -0
- package/static/app/assets/{Chronicle-BGvuAchH.js → Chronicle-B6f0T9id.js} +1 -1
- package/static/app/assets/{CommandPalette-Bqhm0Urn.js → CommandPalette-CuvjTv1u.js} +1 -1
- package/static/app/assets/{Library-BV6NnF0a.js → Library-BGJbG9Hd.js} +1 -1
- package/static/app/assets/{LivingBrain-GzenJchP.js → LivingBrain-DGYK_Jsa.js} +1 -1
- package/static/app/assets/{ProductFlow-DEP6-vML.js → ProductFlow-DXBC6brE.js} +1 -1
- package/static/app/assets/{ReviewCard-CNZ7XjWG.js → ReviewCard-HXRle3qq.js} +2 -2
- package/static/app/assets/System-CMHSO9qM.js +1 -0
- package/static/app/assets/arrow-left-BfmkskWx.js +1 -0
- package/static/app/assets/{bot-B_K1Tdmw.js → bot-Cn8bWRuq.js} +1 -1
- package/static/app/assets/{brain-DWyaV1L1.js → brain-CQJberbE.js} +1 -1
- package/static/app/assets/{button-aTn4s84A.js → button-Ct9f2_oT.js} +1 -1
- package/static/app/assets/circle-check-DruOxB-4.js +1 -0
- package/static/app/assets/{circle-pause-xKgeGXkT.js → circle-pause-CmzC_apg.js} +1 -1
- package/static/app/assets/{circle-play-DkT6tYPX.js → circle-play-D8mW2aQ7.js} +1 -1
- package/static/app/assets/{cpu-85xYObUC.js → cpu-DZcdd0PZ.js} +1 -1
- package/static/app/assets/{download-B5Fm7YXo.js → download-bv1KEPGQ.js} +1 -1
- package/static/app/assets/{folder-open-kk2Xa52u.js → folder-open-d-Pip5gr.js} +1 -1
- package/static/app/assets/{hard-drive-DkA3zBW_.js → hard-drive-D20iavUb.js} +1 -1
- package/static/app/assets/index-D9x-kSNy.css +2 -0
- package/static/app/assets/{index-BMPdTmlY.js → index-Do83hDzJ.js} +3 -3
- package/static/app/assets/{input-B0nRf2jO.js → input-BLXVNmj1.js} +1 -1
- package/static/app/assets/{link-2-Dwb4gnTc.js → link-2-BPJOFlAy.js} +1 -1
- package/static/app/assets/{permissionCopy-CQDUBrOZ.js → permissionCopy-ChdJd493.js} +1 -1
- package/static/app/assets/primitives-Cv5tbZBY.js +1 -0
- package/static/app/assets/search-CT9aho2j.js +1 -0
- package/static/app/assets/{share-2-BsrxFglO.js → share-2-YNX_NtMU.js} +1 -1
- package/static/app/assets/{shield-alert-5BStfp2_.js → shield-alert-DuQ3zrVL.js} +1 -1
- package/static/app/assets/{textarea-Cg8IUA-k.js → textarea-DqwLnli4.js} +1 -1
- package/static/app/assets/{useFocusTrap-CYKvE46M.js → useFocusTrap-ZVI98jaW.js} +1 -1
- package/static/app/assets/{useMutation-CSn9t1op.js → useMutation-CVC4qv_D.js} +1 -1
- package/static/app/assets/{useQuery-CY2OI2uy.js → useQuery-C7BeG4HU.js} +1 -1
- package/static/app/assets/{utils-Ddol2RWD.js → utils-CiFtIdZq.js} +1 -1
- package/static/app/assets/{workspace-BqDwOz_p.js → workspace-DQz9vIId.js} +1 -1
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/lattice_brain/archive.py +0 -522
- package/lattice_brain/context.py +0 -325
- package/lattice_brain/conversations.py +0 -382
- package/lattice_brain/core.py +0 -82
- package/lattice_brain/graph/_kg_contract.py +0 -249
- package/lattice_brain/graph/curator.py +0 -676
- package/lattice_brain/graph/discovery.py +0 -595
- package/lattice_brain/graph/discovery_index/__init__.py +0 -35
- package/lattice_brain/graph/discovery_index/cleanup.py +0 -182
- package/lattice_brain/graph/discovery_index/extract.py +0 -137
- package/lattice_brain/graph/discovery_index/scan.py +0 -411
- package/lattice_brain/graph/discovery_index/upsert.py +0 -495
- package/lattice_brain/graph/documents.py +0 -380
- package/lattice_brain/graph/fusion.py +0 -395
- package/lattice_brain/graph/identity.py +0 -175
- package/lattice_brain/graph/image_vectors.py +0 -230
- package/lattice_brain/graph/ingest.py +0 -829
- package/lattice_brain/graph/network.py +0 -205
- package/lattice_brain/graph/proactive.py +0 -724
- package/lattice_brain/graph/projection/__init__.py +0 -42
- package/lattice_brain/graph/projection/curation.py +0 -500
- package/lattice_brain/graph/projection/v2_schema.py +0 -518
- package/lattice_brain/graph/provenance.py +0 -524
- package/lattice_brain/graph/rerank.py +0 -163
- package/lattice_brain/graph/retrieval/__init__.py +0 -54
- package/lattice_brain/graph/retrieval/context.py +0 -197
- package/lattice_brain/graph/retrieval/graph_view.py +0 -319
- package/lattice_brain/graph/retrieval/hybrid.py +0 -488
- package/lattice_brain/graph/retrieval/maintenance.py +0 -121
- package/lattice_brain/graph/retrieval/signals.py +0 -95
- package/lattice_brain/graph/retrieval_docgen.py +0 -253
- package/lattice_brain/graph/retrieval_policy.py +0 -180
- package/lattice_brain/graph/retrieval_reads.py +0 -769
- package/lattice_brain/graph/retrieval_vector/__init__.py +0 -42
- package/lattice_brain/graph/retrieval_vector/fingerprint.py +0 -97
- package/lattice_brain/graph/retrieval_vector/indexing.py +0 -347
- package/lattice_brain/graph/retrieval_vector/search.py +0 -560
- package/lattice_brain/graph/retrieval_vector/status.py +0 -374
- package/lattice_brain/graph/schema.py +0 -792
- package/lattice_brain/graph/store.py +0 -268
- package/lattice_brain/graph/vector_index/__init__.py +0 -85
- package/lattice_brain/graph/vector_index/base.py +0 -167
- package/lattice_brain/graph/vector_index/brute_force.py +0 -110
- package/lattice_brain/graph/vector_index/hnsw.py +0 -290
- package/lattice_brain/graph/vector_index/jobs.py +0 -287
- package/lattice_brain/graph/vector_index/quantized.py +0 -148
- package/lattice_brain/graph/vector_index/selector.py +0 -161
- package/lattice_brain/graph/write_master.py +0 -308
- package/lattice_brain/ingestion/_contract.py +0 -90
- package/lattice_brain/ingestion/folder_scan.py +0 -57
- package/lattice_brain/ingestion/folders.py +0 -258
- package/lattice_brain/ingestion/jobs_api.py +0 -107
- package/lattice_brain/ingestion/routing.py +0 -295
- package/lattice_brain/ingestion_jobs.py +0 -380
- package/lattice_brain/memory.py +0 -75
- package/lattice_brain/portability/__init__.py +0 -90
- package/lattice_brain/portability/_contract.py +0 -42
- package/lattice_brain/portability/backups.py +0 -338
- package/lattice_brain/portability/bundles.py +0 -136
- package/lattice_brain/portability/constants.py +0 -93
- package/lattice_brain/portability/fsops.py +0 -138
- package/lattice_brain/portability/service.py +0 -41
- package/lattice_brain/portability/sharing.py +0 -710
- package/lattice_brain/quality.py +0 -543
- package/lattice_brain/retrieval_benchmark_fixtures.py +0 -92
- package/lattice_brain/runtime/agent_runtime.py +0 -859
- package/lattice_brain/runtime/contracts.py +0 -460
- package/lattice_brain/runtime/multi_agent.py +0 -942
- package/lattice_brain/runtime/statuses.py +0 -10
- package/lattice_brain/sealed_box.py +0 -240
- package/lattice_brain/self_model.py +0 -675
- package/lattice_brain/sensitivity.py +0 -94
- package/lattice_brain/storage/__init__.py +0 -22
- package/lattice_brain/storage/base.py +0 -100
- package/lattice_brain/storage/docker.py +0 -105
- package/lattice_brain/storage/factory.py +0 -31
- package/lattice_brain/storage/migration.py +0 -191
- package/lattice_brain/storage/postgres.py +0 -123
- package/lattice_brain/storage/sqlite.py +0 -143
- package/lattice_brain/synthesis.py +0 -824
- package/lattice_brain/workflow.py +0 -497
- package/latticeai/api/admin.py +0 -471
- package/latticeai/api/agent_registry.py +0 -105
- package/latticeai/api/agents.py +0 -228
- package/latticeai/api/auth.py +0 -383
- package/latticeai/api/automation_intelligence.py +0 -401
- package/latticeai/api/brain_intelligence.py +0 -199
- package/latticeai/api/browser.py +0 -493
- package/latticeai/api/change_proposals.py +0 -89
- package/latticeai/api/chat.py +0 -572
- package/latticeai/api/chat_agent_http.py +0 -892
- package/latticeai/api/chat_contracts.py +0 -73
- package/latticeai/api/chat_documents.py +0 -276
- package/latticeai/api/chat_helpers.py +0 -460
- package/latticeai/api/chat_history.py +0 -101
- package/latticeai/api/chat_hybrid.py +0 -113
- package/latticeai/api/chat_intents.py +0 -646
- package/latticeai/api/chat_stream.py +0 -216
- package/latticeai/api/chronicle.py +0 -63
- package/latticeai/api/command_center.py +0 -51
- package/latticeai/api/computer_use.py +0 -474
- package/latticeai/api/evidence_actions.py +0 -48
- package/latticeai/api/features.py +0 -70
- package/latticeai/api/funnel_metrics.py +0 -31
- package/latticeai/api/garden.py +0 -34
- package/latticeai/api/hooks.py +0 -165
- package/latticeai/api/index_jobs.py +0 -145
- package/latticeai/api/invitations.py +0 -100
- package/latticeai/api/knowledge_graph.py +0 -536
- package/latticeai/api/marketplace.py +0 -105
- package/latticeai/api/mcp.py +0 -482
- package/latticeai/api/memory.py +0 -270
- package/latticeai/api/network.py +0 -81
- package/latticeai/api/network_boundary.py +0 -225
- package/latticeai/api/permission_mode.py +0 -61
- package/latticeai/api/permissions.py +0 -436
- package/latticeai/api/plugins.py +0 -126
- package/latticeai/api/portability.py +0 -391
- package/latticeai/api/project_sessions.py +0 -114
- package/latticeai/api/realtime.py +0 -118
- package/latticeai/api/review_queue.py +0 -364
- package/latticeai/api/security_dashboard.py +0 -604
- package/latticeai/api/setup.py +0 -319
- package/latticeai/api/static_routes.py +0 -354
- package/latticeai/api/ui_redirects.py +0 -26
- package/latticeai/api/workflow_designer.py +0 -394
- package/latticeai/api/workspace.py +0 -856
- package/latticeai/api/workspace_scope.py +0 -125
- package/latticeai/core/agent/__init__.py +0 -93
- package/latticeai/core/agent/_contract.py +0 -79
- package/latticeai/core/agent/context.py +0 -57
- package/latticeai/core/agent/deps.py +0 -125
- package/latticeai/core/agent/execution.py +0 -622
- package/latticeai/core/agent/planning.py +0 -145
- package/latticeai/core/agent/recovery.py +0 -157
- package/latticeai/core/agent/runtime.py +0 -210
- package/latticeai/core/agent/verification.py +0 -231
- package/latticeai/core/agent_eval.py +0 -739
- package/latticeai/core/agent_helpers.py +0 -493
- package/latticeai/core/agent_profiles.py +0 -110
- package/latticeai/core/agent_prompts.py +0 -171
- package/latticeai/core/agent_registry.py +0 -232
- package/latticeai/core/agent_state.py +0 -41
- package/latticeai/core/agent_trace.py +0 -104
- package/latticeai/core/artifact_ledger.py +0 -109
- package/latticeai/core/audit.py +0 -260
- package/latticeai/core/builtin_hooks.py +0 -105
- package/latticeai/core/context_builder.py +0 -394
- package/latticeai/core/document_generator.py +0 -103
- package/latticeai/core/enterprise.py +0 -154
- package/latticeai/core/enterprise_admin.py +0 -158
- package/latticeai/core/file_generation/__init__.py +0 -115
- package/latticeai/core/file_generation/bundles.py +0 -76
- package/latticeai/core/file_generation/extraction.py +0 -154
- package/latticeai/core/file_generation/inference.py +0 -235
- package/latticeai/core/file_generation/orchestration.py +0 -152
- package/latticeai/core/file_generation/prompting.py +0 -117
- package/latticeai/core/file_generation/repair.py +0 -114
- package/latticeai/core/file_generation/sanitize.py +0 -61
- package/latticeai/core/file_generation/validation.py +0 -201
- package/latticeai/core/invitations.py +0 -132
- package/latticeai/core/legacy_compatibility.py +0 -243
- package/latticeai/core/logging_safety.py +0 -46
- package/latticeai/core/marketplace.py +0 -293
- package/latticeai/core/mcp_catalog.py +0 -452
- package/latticeai/core/mcp_registry.py +0 -506
- package/latticeai/core/network_boundary.py +0 -168
- package/latticeai/core/oidc.py +0 -208
- package/latticeai/core/plugins.py +0 -432
- package/latticeai/core/product_hardening.py +0 -218
- package/latticeai/core/project_sessions.py +0 -337
- package/latticeai/core/realtime.py +0 -238
- package/latticeai/core/run_explain.py +0 -426
- package/latticeai/core/run_store.py +0 -252
- package/latticeai/core/timezones.py +0 -80
- package/latticeai/core/workspace_computer_memory.py +0 -84
- package/latticeai/core/workspace_graph_trace.py +0 -155
- package/latticeai/core/workspace_indexing.py +0 -102
- package/latticeai/core/workspace_memory.py +0 -77
- package/latticeai/core/workspace_onboarding.py +0 -104
- package/latticeai/core/workspace_os.py +0 -978
- package/latticeai/core/workspace_os_constants.py +0 -126
- package/latticeai/core/workspace_os_state.py +0 -180
- package/latticeai/core/workspace_os_utils.py +0 -103
- package/latticeai/core/workspace_permissions.py +0 -101
- package/latticeai/core/workspace_plugins.py +0 -97
- package/latticeai/core/workspace_relationships.py +0 -99
- package/latticeai/core/workspace_reorganization.py +0 -335
- package/latticeai/core/workspace_review_items.py +0 -112
- package/latticeai/core/workspace_runs.py +0 -726
- package/latticeai/core/workspace_skills.py +0 -109
- package/latticeai/core/workspace_snapshots.py +0 -198
- package/latticeai/core/workspace_timeline.py +0 -110
- package/latticeai/integrations/__init__.py +0 -0
- package/latticeai/integrations/telegram_bot/__init__.py +0 -123
- package/latticeai/integrations/telegram_bot/__main__.py +0 -17
- package/latticeai/integrations/telegram_bot/config.py +0 -86
- package/latticeai/integrations/telegram_bot/dispatch.py +0 -311
- package/latticeai/integrations/telegram_bot/flows.py +0 -478
- package/latticeai/integrations/telegram_bot/helpers.py +0 -322
- package/latticeai/integrations/telegram_bot/screens.py +0 -394
- package/latticeai/runtime/audit_runtime.py +0 -76
- package/latticeai/runtime/automation_runtime.py +0 -81
- package/latticeai/runtime/chat_wiring.py +0 -141
- package/latticeai/runtime/context_runtime.py +0 -66
- package/latticeai/runtime/feature_toggle_wiring.py +0 -157
- package/latticeai/runtime/history_runtime.py +0 -163
- package/latticeai/runtime/history_writer.py +0 -138
- package/latticeai/runtime/hooks_runtime.py +0 -77
- package/latticeai/runtime/model_wiring.py +0 -68
- package/latticeai/runtime/namespace_runtime.py +0 -163
- package/latticeai/runtime/network_boundary_wiring.py +0 -117
- package/latticeai/runtime/network_config_runtime.py +0 -56
- package/latticeai/runtime/permission_mode_wiring.py +0 -112
- package/latticeai/runtime/persistence_runtime.py +0 -159
- package/latticeai/runtime/platform_runtime_wiring.py +0 -89
- package/latticeai/runtime/review_wiring.py +0 -42
- package/latticeai/runtime/router_registration.py +0 -693
- package/latticeai/runtime/service_singletons.py +0 -55
- package/latticeai/runtime/sso_config_runtime.py +0 -128
- package/latticeai/runtime/user_key_runtime.py +0 -106
- package/latticeai/runtime/web_runtime.py +0 -92
- package/latticeai/server_app.py +0 -51
- package/latticeai/services/app_context.py +0 -130
- package/latticeai/services/automation_execution.py +0 -266
- package/latticeai/services/automation_intelligence.py +0 -614
- package/latticeai/services/brain_automation.py +0 -191
- package/latticeai/services/brain_intelligence/__init__.py +0 -58
- package/latticeai/services/brain_intelligence/_contract.py +0 -71
- package/latticeai/services/brain_intelligence/consistency.py +0 -193
- package/latticeai/services/brain_intelligence/constants.py +0 -47
- package/latticeai/services/brain_intelligence/digest.py +0 -258
- package/latticeai/services/brain_intelligence/health.py +0 -331
- package/latticeai/services/brain_intelligence/proposals.py +0 -259
- package/latticeai/services/brain_intelligence/sampling.py +0 -84
- package/latticeai/services/brain_intelligence/service.py +0 -48
- package/latticeai/services/change_proposals.py +0 -471
- package/latticeai/services/chat_service.py +0 -243
- package/latticeai/services/chronicle.py +0 -555
- package/latticeai/services/cloud_egress_audit.py +0 -85
- package/latticeai/services/cloud_extraction.py +0 -129
- package/latticeai/services/cloud_streaming.py +0 -268
- package/latticeai/services/cloud_token_guard.py +0 -84
- package/latticeai/services/command_center.py +0 -548
- package/latticeai/services/evidence_actions.py +0 -258
- package/latticeai/services/feature_toggles.py +0 -502
- package/latticeai/services/folder_watch.py +0 -520
- package/latticeai/services/funnel_metrics.py +0 -307
- package/latticeai/services/hybrid_chat.py +0 -316
- package/latticeai/services/hybrid_context.py +0 -228
- package/latticeai/services/hybrid_policy.py +0 -129
- package/latticeai/services/interop_bridges.py +0 -978
- package/latticeai/services/local_knowledge.py +0 -465
- package/latticeai/services/memory_service/__init__.py +0 -52
- package/latticeai/services/memory_service/_contract.py +0 -100
- package/latticeai/services/memory_service/brief.py +0 -431
- package/latticeai/services/memory_service/constants.py +0 -57
- package/latticeai/services/memory_service/maintenance.py +0 -138
- package/latticeai/services/memory_service/manager.py +0 -186
- package/latticeai/services/memory_service/proof.py +0 -136
- package/latticeai/services/memory_service/recall.py +0 -225
- package/latticeai/services/memory_service/service.py +0 -48
- package/latticeai/services/memory_service/stores.py +0 -110
- package/latticeai/services/mode_store.py +0 -132
- package/latticeai/services/model_recommendation.py +0 -224
- package/latticeai/services/model_runtime/cloud.py +0 -87
- package/latticeai/services/network_boundary_service.py +0 -117
- package/latticeai/services/obsidian_bridge.py +0 -609
- package/latticeai/services/openai_compatible_adapter.py +0 -101
- package/latticeai/services/permission_mode_service.py +0 -122
- package/latticeai/services/platform_runtime.py +0 -366
- package/latticeai/services/review_queue.py +0 -380
- package/latticeai/services/router_context.py +0 -59
- package/latticeai/services/run_executor.py +0 -387
- package/latticeai/services/self_model_service.py +0 -171
- package/latticeai/services/setup_detection.py +0 -147
- package/latticeai/services/triggers.py +0 -378
- package/latticeai/services/upload_service.py +0 -172
- package/latticeai/services/workspace_service.py +0 -165
- package/latticeai/setup/__init__.py +0 -25
- package/latticeai/setup/auto_setup.py +0 -846
- package/latticeai/setup/demo_corpus.py +0 -98
- package/latticeai/setup/wizard/__init__.py +0 -126
- package/latticeai/setup/wizard/catalog.py +0 -175
- package/latticeai/setup/wizard/detect.py +0 -302
- package/latticeai/setup/wizard/install.py +0 -348
- package/latticeai/setup/wizard/paths.py +0 -165
- package/latticeai/setup/wizard/plans.py +0 -74
- package/latticeai/setup/wizard/recommend.py +0 -320
- package/scripts/bench_agent_smoke.py +0 -409
- package/scripts/bench_models.py +0 -540
- package/scripts/bench_vector_index.py +0 -295
- package/scripts/funnel_soft_gate.py +0 -192
- package/scripts/generate_agent_loop_fixtures.py +0 -994
- package/scripts/generate_rust_parity_fixtures.py +0 -908
- package/scripts/migrate_brain_storage.py +0 -57
- package/scripts/parity_fixture_corpus_context.py +0 -162
- package/scripts/parity_fixture_corpus_docgen.py +0 -341
- package/scripts/profile_kg.py +0 -355
- package/server.py +0 -30
- package/static/app/assets/AdminConsole-cf4npybT.js +0 -1
- package/static/app/assets/Capture-DiQ219jW.js +0 -1
- package/static/app/assets/System-CieofHQa.js +0 -1
- package/static/app/assets/arrow-left-kfsrk0mv.js +0 -1
- package/static/app/assets/circle-check-qqLug9nU.js +0 -1
- package/static/app/assets/index-DxmOfNRi.css +0 -2
- package/static/app/assets/primitives-SNp0LRJz.js +0 -1
- package/static/app/assets/search-BcHqkjoy.js +0 -1
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
"""What the vector index currently knows, and what it still owes.
|
|
2
|
-
|
|
3
|
-
``index_status`` / ``vector_freshness`` / ``vector_queue`` — the honesty
|
|
4
|
-
surface that reports coverage, staleness, and pending work rather than
|
|
5
|
-
letting a half-built index look complete. Moved verbatim out of
|
|
6
|
-
``retrieval_vector.py`` (v11.3.0 decomposition).
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
from typing import TYPE_CHECKING
|
|
12
|
-
|
|
13
|
-
# ruff: noqa: F403,F405
|
|
14
|
-
from .._kg_common import * # noqa: F403,F401
|
|
15
|
-
from ..vector_index import VectorEmbedQueue
|
|
16
|
-
|
|
17
|
-
# Typing-only base (runtime value is `object`, so the store's MRO is
|
|
18
|
-
# unchanged). Reporting on the index means asking the halves that build and
|
|
19
|
-
# query it — source items and incremental indexing from .indexing, the
|
|
20
|
-
# fingerprint it reaches through, and the backend selection from .search. They
|
|
21
|
-
# are named as bases rather than re-declared, so the signatures cannot drift.
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from .indexing import _VectorIndexingMixin
|
|
24
|
-
from .search import _VectorSearchMixin
|
|
25
|
-
|
|
26
|
-
class _Core(_VectorIndexingMixin, _VectorSearchMixin):
|
|
27
|
-
"""The sibling halves this one reaches through ``self``."""
|
|
28
|
-
else:
|
|
29
|
-
_Core = object
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class _VectorStatusMixin(_Core):
|
|
33
|
-
"""Vector index status/freshness. Composed into the public mixin."""
|
|
34
|
-
|
|
35
|
-
def index_status(self) -> Dict[str, Any]:
|
|
36
|
-
storage_capabilities = None
|
|
37
|
-
try:
|
|
38
|
-
storage_capabilities = self.storage_engine.capabilities().as_dict()
|
|
39
|
-
except Exception as exc:
|
|
40
|
-
storage_capabilities = {
|
|
41
|
-
"engine": "sqlite",
|
|
42
|
-
"available": False,
|
|
43
|
-
"reason": str(exc),
|
|
44
|
-
}
|
|
45
|
-
with self._connect() as conn:
|
|
46
|
-
vector_counts = {
|
|
47
|
-
row["item_type"]: row["count"]
|
|
48
|
-
for row in conn.execute(
|
|
49
|
-
"SELECT item_type, COUNT(*) AS count FROM vector_embeddings GROUP BY item_type"
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
# Materialised on purpose, unlike the rebuild path: status walks
|
|
53
|
-
# this set twice (once for ids, once to classify each item) and
|
|
54
|
-
# reports a count, none of which a one-shot iterator can serve.
|
|
55
|
-
source_items = list(self._iter_vector_source_items(conn))
|
|
56
|
-
vector_rows = {
|
|
57
|
-
row["item_id"]: row
|
|
58
|
-
for row in conn.execute(
|
|
59
|
-
"""
|
|
60
|
-
SELECT item_id, text_hash, embedding_dim, embedding_model, indexed_at
|
|
61
|
-
FROM vector_embeddings
|
|
62
|
-
"""
|
|
63
|
-
).fetchall()
|
|
64
|
-
}
|
|
65
|
-
latest_rows = conn.execute(
|
|
66
|
-
"""
|
|
67
|
-
SELECT id, operation, status, requested_at, started_at, completed_at,
|
|
68
|
-
items_total, items_indexed, items_skipped, error_message, metadata_json
|
|
69
|
-
FROM vector_index_operations
|
|
70
|
-
ORDER BY requested_at DESC, id DESC
|
|
71
|
-
LIMIT 5
|
|
72
|
-
"""
|
|
73
|
-
).fetchall()
|
|
74
|
-
missing = stale = ready = 0
|
|
75
|
-
source_item_ids = {str(item["item_id"]) for item in source_items}
|
|
76
|
-
backlog_by_type: Dict[str, int] = {}
|
|
77
|
-
backlog_reasons: Dict[str, int] = {}
|
|
78
|
-
backlog_samples: List[Dict[str, Any]] = []
|
|
79
|
-
|
|
80
|
-
def add_backlog(item: Dict[str, Any], reason: str) -> None:
|
|
81
|
-
item_type = str(item.get("item_type") or "unknown")
|
|
82
|
-
backlog_by_type[item_type] = backlog_by_type.get(item_type, 0) + 1
|
|
83
|
-
backlog_reasons[reason] = backlog_reasons.get(reason, 0) + 1
|
|
84
|
-
if len(backlog_samples) >= 20:
|
|
85
|
-
return
|
|
86
|
-
backlog_samples.append(
|
|
87
|
-
{
|
|
88
|
-
"item_id": item.get("item_id"),
|
|
89
|
-
"item_type": item_type,
|
|
90
|
-
"source_node": item.get("source_node"),
|
|
91
|
-
"reason": reason,
|
|
92
|
-
"metadata": {
|
|
93
|
-
key: value
|
|
94
|
-
for key, value in dict(item.get("metadata") or {}).items()
|
|
95
|
-
if key in {"node_type", "source", "conversation_id", "parent_source_node"}
|
|
96
|
-
},
|
|
97
|
-
}
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
for item in source_items:
|
|
101
|
-
vector_row = vector_rows.get(item["item_id"])
|
|
102
|
-
expected_hash = _sha256_text(_clean_text(item["text"]))
|
|
103
|
-
if not vector_row:
|
|
104
|
-
missing += 1
|
|
105
|
-
add_backlog(item, "missing_vector")
|
|
106
|
-
elif (
|
|
107
|
-
vector_row["text_hash"] != expected_hash
|
|
108
|
-
or vector_row["embedding_dim"] != self._embedding_model.dim
|
|
109
|
-
or vector_row["embedding_model"] != self._embedding_model.model_id
|
|
110
|
-
):
|
|
111
|
-
stale += 1
|
|
112
|
-
reason = "text_changed"
|
|
113
|
-
if vector_row["embedding_model"] != self._embedding_model.model_id:
|
|
114
|
-
reason = "model_changed"
|
|
115
|
-
elif vector_row["embedding_dim"] != self._embedding_model.dim:
|
|
116
|
-
reason = "dimension_changed"
|
|
117
|
-
add_backlog(item, reason)
|
|
118
|
-
else:
|
|
119
|
-
ready += 1
|
|
120
|
-
pending = missing + stale
|
|
121
|
-
orphaned_items = max(0, len(set(vector_rows) - source_item_ids))
|
|
122
|
-
coverage_ratio = round(ready / len(source_items), 6) if source_items else 1.0
|
|
123
|
-
latest_completed = None
|
|
124
|
-
for row in latest_rows:
|
|
125
|
-
if row["status"] == "completed":
|
|
126
|
-
latest_completed = row
|
|
127
|
-
break
|
|
128
|
-
latency_budget: Dict[str, Any] = {
|
|
129
|
-
"target_rebuild_ms": 10_000,
|
|
130
|
-
"last_rebuild_duration_ms": None,
|
|
131
|
-
"last_items_per_second": None,
|
|
132
|
-
"within_target": None,
|
|
133
|
-
}
|
|
134
|
-
if latest_completed is not None:
|
|
135
|
-
metadata = _safe_loads(latest_completed["metadata_json"])
|
|
136
|
-
duration_ms = metadata.get("duration_ms")
|
|
137
|
-
items_total = int(latest_completed["items_total"] or 0)
|
|
138
|
-
if isinstance(duration_ms, (int, float)) and duration_ms > 0:
|
|
139
|
-
latency_budget.update(
|
|
140
|
-
{
|
|
141
|
-
"last_rebuild_duration_ms": round(float(duration_ms), 2),
|
|
142
|
-
"last_items_per_second": round(items_total / (float(duration_ms) / 1000.0), 2),
|
|
143
|
-
"within_target": float(duration_ms) <= 10_000,
|
|
144
|
-
}
|
|
145
|
-
)
|
|
146
|
-
embedder_status = self.embedder_fingerprint_status()
|
|
147
|
-
return {
|
|
148
|
-
"status": "ready" if pending == 0 else "needs_reindex",
|
|
149
|
-
"embedder": embedder_status,
|
|
150
|
-
"storage": {
|
|
151
|
-
"db_path": str(self.db_path),
|
|
152
|
-
"backend": "sqlite",
|
|
153
|
-
"embedding_model": self._embedding_model.model_id,
|
|
154
|
-
"embedding_dim": self._embedding_model.dim,
|
|
155
|
-
# Honest capability report: trigram FTS5 keyword index, or
|
|
156
|
-
# LIKE-scan fallback when this SQLite build lacks it.
|
|
157
|
-
"fts_enabled": bool(getattr(self, "_fts_enabled", False)),
|
|
158
|
-
"engine": storage_capabilities,
|
|
159
|
-
"vector_search_backend": (
|
|
160
|
-
storage_capabilities.get("vector_backend")
|
|
161
|
-
if isinstance(storage_capabilities, dict)
|
|
162
|
-
else "bruteforce-cosine"
|
|
163
|
-
),
|
|
164
|
-
"vector_search_mode": (
|
|
165
|
-
(storage_capabilities.get("metadata") or {}).get("vector_mode")
|
|
166
|
-
if isinstance(storage_capabilities, dict)
|
|
167
|
-
else "fallback"
|
|
168
|
-
),
|
|
169
|
-
"sqlite_vec_ann_available": (
|
|
170
|
-
bool((storage_capabilities.get("metadata") or {}).get("sqlite_vec_ann_available"))
|
|
171
|
-
if isinstance(storage_capabilities, dict)
|
|
172
|
-
else False
|
|
173
|
-
),
|
|
174
|
-
# v11.1.0: which in-process index scores a search, and — when
|
|
175
|
-
# the configured one could not be used — the reason it was
|
|
176
|
-
# substituted, so an unavailable optional extra is visible
|
|
177
|
-
# here instead of only showing up as "search feels slow".
|
|
178
|
-
"vector_index": self._vector_index_selection().as_dict(),
|
|
179
|
-
},
|
|
180
|
-
"source_items": len(source_items),
|
|
181
|
-
"indexed_items": sum(vector_counts.values()),
|
|
182
|
-
"ready_items": ready,
|
|
183
|
-
"missing_items": missing,
|
|
184
|
-
"stale_items": stale,
|
|
185
|
-
"pending_items": pending,
|
|
186
|
-
"by_item_type": vector_counts,
|
|
187
|
-
"scale": {
|
|
188
|
-
"version": 1,
|
|
189
|
-
"coverage_ratio": coverage_ratio,
|
|
190
|
-
"coverage_percent": round(coverage_ratio * 100.0, 2),
|
|
191
|
-
"source_items": len(source_items),
|
|
192
|
-
"ready_items": ready,
|
|
193
|
-
"pending_items": pending,
|
|
194
|
-
"missing_items": missing,
|
|
195
|
-
"stale_items": stale,
|
|
196
|
-
"orphaned_items": orphaned_items,
|
|
197
|
-
"backlog_by_item_type": backlog_by_type,
|
|
198
|
-
"backlog_reasons": backlog_reasons,
|
|
199
|
-
"backlog_samples": backlog_samples,
|
|
200
|
-
"incremental_reindex_recommended": pending > 0,
|
|
201
|
-
# A stale embedder means every old-model row must be re-embedded;
|
|
202
|
-
# only a full rebuild (which re-records the fingerprint) heals it.
|
|
203
|
-
"full_rebuild_recommended": bool(
|
|
204
|
-
orphaned_items > 0 or embedder_status["stale_embedder"]
|
|
205
|
-
),
|
|
206
|
-
"latency_budget": latency_budget,
|
|
207
|
-
},
|
|
208
|
-
"operations": [
|
|
209
|
-
{
|
|
210
|
-
"id": row["id"],
|
|
211
|
-
"operation": row["operation"],
|
|
212
|
-
"status": row["status"],
|
|
213
|
-
"requested_at": row["requested_at"],
|
|
214
|
-
"started_at": row["started_at"],
|
|
215
|
-
"completed_at": row["completed_at"],
|
|
216
|
-
"items_total": row["items_total"],
|
|
217
|
-
"items_indexed": row["items_indexed"],
|
|
218
|
-
"items_skipped": row["items_skipped"],
|
|
219
|
-
"error_message": row["error_message"],
|
|
220
|
-
"metadata": _safe_loads(row["metadata_json"]),
|
|
221
|
-
}
|
|
222
|
-
for row in latest_rows
|
|
223
|
-
],
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
def vector_freshness(self) -> Dict[str, Any]:
|
|
227
|
-
"""Compact vector-index freshness summary for API surfaces (v9.8.0).
|
|
228
|
-
|
|
229
|
-
Reduces :meth:`index_status` (``pending = missing + stale``) to the
|
|
230
|
-
fixed contract ``{"status", "pending_items", "total_items", "detail"}``
|
|
231
|
-
with ``status`` in ``ready`` / ``pending`` / ``stale_embedder`` /
|
|
232
|
-
``unavailable``. ``stale_embedder`` (review Wave 2.2) is reported only
|
|
233
|
-
when the recorded embedder fingerprint differs from the current
|
|
234
|
-
embedder AND rows indexed under the old model still exist — the index
|
|
235
|
-
needs a full rebuild, not an incremental sync.
|
|
236
|
-
|
|
237
|
-
Never raises: environments where the embedding provider or index
|
|
238
|
-
storage cannot be used report ``"unavailable"`` with the cause in
|
|
239
|
-
``detail`` instead of surfacing an exception to the API layer.
|
|
240
|
-
"""
|
|
241
|
-
try:
|
|
242
|
-
status = self.index_status()
|
|
243
|
-
except Exception as exc: # noqa: BLE001 — freshness must degrade, not fail
|
|
244
|
-
return {
|
|
245
|
-
"status": "unavailable",
|
|
246
|
-
"pending_items": 0,
|
|
247
|
-
"total_items": 0,
|
|
248
|
-
"detail": f"vector index status unavailable: {exc}",
|
|
249
|
-
}
|
|
250
|
-
return self._vector_freshness_summary(status)
|
|
251
|
-
|
|
252
|
-
def _vector_freshness_summary(self, status: Dict[str, Any]) -> Dict[str, Any]:
|
|
253
|
-
"""The freshness reduction of an already-read :meth:`index_status`.
|
|
254
|
-
|
|
255
|
-
Split out so :meth:`vector_freshness_breakdown` can report both shapes
|
|
256
|
-
from one index scan; ``index_status`` walks every source item, and
|
|
257
|
-
calling it twice to answer one question about freshness would double
|
|
258
|
-
the most expensive read in this module.
|
|
259
|
-
"""
|
|
260
|
-
pending = int(status.get("pending_items") or 0)
|
|
261
|
-
total = int(status.get("source_items") or 0)
|
|
262
|
-
embedder = status.get("embedder") or {}
|
|
263
|
-
if embedder.get("stale_embedder"):
|
|
264
|
-
old_model_rows = 0
|
|
265
|
-
try:
|
|
266
|
-
with self._connect() as conn:
|
|
267
|
-
old_model_rows = int(
|
|
268
|
-
conn.execute(
|
|
269
|
-
"SELECT COUNT(*) AS c FROM vector_embeddings "
|
|
270
|
-
"WHERE embedding_model<>? OR embedding_dim<>?",
|
|
271
|
-
(
|
|
272
|
-
self._embedding_model.model_id,
|
|
273
|
-
int(self._embedding_model.dim),
|
|
274
|
-
),
|
|
275
|
-
).fetchone()["c"]
|
|
276
|
-
)
|
|
277
|
-
except Exception: # noqa: BLE001 — keep the existing statuses on failure
|
|
278
|
-
old_model_rows = 0
|
|
279
|
-
if old_model_rows > 0:
|
|
280
|
-
recorded = embedder.get("recorded") or {}
|
|
281
|
-
return {
|
|
282
|
-
"status": "stale_embedder",
|
|
283
|
-
"pending_items": pending,
|
|
284
|
-
"total_items": total,
|
|
285
|
-
"detail": (
|
|
286
|
-
f"embedding model changed ({recorded.get('model_id')} → "
|
|
287
|
-
f"{self._embedding_model.model_id}); {old_model_rows} indexed "
|
|
288
|
-
"rows still use the previous model — run a full vector index rebuild"
|
|
289
|
-
),
|
|
290
|
-
}
|
|
291
|
-
if pending > 0:
|
|
292
|
-
return {
|
|
293
|
-
"status": "pending",
|
|
294
|
-
"pending_items": pending,
|
|
295
|
-
"total_items": total,
|
|
296
|
-
"detail": (
|
|
297
|
-
f"{pending} of {total} items are missing or stale in the vector index"
|
|
298
|
-
),
|
|
299
|
-
}
|
|
300
|
-
detail = (
|
|
301
|
-
"vector index is up to date"
|
|
302
|
-
if total
|
|
303
|
-
else "vector index is empty (no indexable items yet)"
|
|
304
|
-
)
|
|
305
|
-
return {
|
|
306
|
-
"status": "ready",
|
|
307
|
-
"pending_items": 0,
|
|
308
|
-
"total_items": total,
|
|
309
|
-
"detail": detail,
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
@property
|
|
313
|
-
def vector_queue(self) -> VectorEmbedQueue:
|
|
314
|
-
"""This store's durable pending-embed backlog (created on demand).
|
|
315
|
-
|
|
316
|
-
Built lazily rather than in ``__init__`` so opening a graph never
|
|
317
|
-
creates a table nobody asked for, and hung off the store so the
|
|
318
|
-
ingestion pipeline and the freshness report share one backlog instead
|
|
319
|
-
of each keeping a private view of it.
|
|
320
|
-
"""
|
|
321
|
-
queue = getattr(self, "_vector_queue", None)
|
|
322
|
-
if queue is None:
|
|
323
|
-
queue = VectorEmbedQueue(
|
|
324
|
-
db_path=self.db_path, indexer=self.index_node_incremental
|
|
325
|
-
)
|
|
326
|
-
self._vector_queue = queue
|
|
327
|
-
return queue
|
|
328
|
-
|
|
329
|
-
def vector_freshness_breakdown(self) -> Dict[str, Any]:
|
|
330
|
-
"""The four numbers behind :meth:`vector_freshness` (v11.1.0).
|
|
331
|
-
|
|
332
|
-
``vector_freshness()`` answers one question — *is the index behind?* —
|
|
333
|
-
and its four keys are a frozen wire contract that surfaces already
|
|
334
|
-
read, so this is a sibling rather than an extension of it. The split
|
|
335
|
-
matters because "12 pending" hides two different situations: twelve
|
|
336
|
-
items never embedded (a new import) and twelve items whose text
|
|
337
|
-
changed under an existing embedding (edits). Only the second means
|
|
338
|
-
current answers are quietly wrong.
|
|
339
|
-
|
|
340
|
-
``queued`` counts the durable background backlog
|
|
341
|
-
(:class:`~lattice_brain.graph.vector_index.VectorEmbedQueue`), and is
|
|
342
|
-
``None`` when that queue has no database to persist to — never ``0``,
|
|
343
|
-
which would claim an empty backlog nobody measured.
|
|
344
|
-
|
|
345
|
-
Never raises: an unreadable index reports ``status="unavailable"``
|
|
346
|
-
with the cause in ``detail`` and zeroed counts.
|
|
347
|
-
"""
|
|
348
|
-
status: Dict[str, Any] = {}
|
|
349
|
-
summary: Dict[str, Any]
|
|
350
|
-
try:
|
|
351
|
-
status = self.index_status()
|
|
352
|
-
except Exception as exc: # noqa: BLE001 — freshness must degrade, not fail
|
|
353
|
-
summary = {
|
|
354
|
-
"status": "unavailable",
|
|
355
|
-
"pending_items": 0,
|
|
356
|
-
"total_items": 0,
|
|
357
|
-
"detail": f"vector index status unavailable: {exc}",
|
|
358
|
-
}
|
|
359
|
-
else:
|
|
360
|
-
summary = self._vector_freshness_summary(status)
|
|
361
|
-
breakdown: Dict[str, Any] = {
|
|
362
|
-
"status": summary["status"],
|
|
363
|
-
"detail": summary["detail"],
|
|
364
|
-
"embedded": int(status.get("ready_items") or 0),
|
|
365
|
-
"pending": int(summary["pending_items"]),
|
|
366
|
-
"missing": int(status.get("missing_items") or 0),
|
|
367
|
-
"stale": int(status.get("stale_items") or 0),
|
|
368
|
-
"total": int(summary["total_items"]),
|
|
369
|
-
"queued": None,
|
|
370
|
-
}
|
|
371
|
-
queue = self.vector_queue
|
|
372
|
-
if queue.available:
|
|
373
|
-
breakdown["queued"] = int(queue.pending_count())
|
|
374
|
-
return breakdown
|