ltcai 11.5.1 → 11.6.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.
Files changed (473) hide show
  1. package/README.md +92 -117
  2. package/bin/ltcai.js +234 -24
  3. package/docs/CHANGELOG.md +129 -0
  4. package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
  5. package/docs/DEVELOPMENT.md +8 -6
  6. package/docs/ENTERPRISE.md +2 -1
  7. package/docs/HYBRID_CLOUD_KG_STREAMING.md +8 -4
  8. package/docs/MULTI_AGENT_RUNTIME.md +12 -5
  9. package/docs/ONBOARDING.md +1 -1
  10. package/docs/OPERATIONS.md +6 -3
  11. package/docs/REALTIME_COLLABORATION.md +1 -1
  12. package/docs/TRUST_MODEL.md +1 -1
  13. package/docs/WHY_LATTICE.md +1 -1
  14. package/docs/WORKFLOW_DESIGNER.md +3 -2
  15. package/docs/architecture.md +4 -4
  16. package/docs/kg-schema.md +1 -1
  17. package/docs/v11.5.2_TIGHT_SHIP_PLAN.md +144 -0
  18. package/docs/v11.6.0_ONE_DOOR_PLAN.md +170 -0
  19. package/lattice_brain/__init__.py +42 -79
  20. package/lattice_brain/graph/__init__.py +9 -24
  21. package/lattice_brain/graph/_kg_common/__init__.py +13 -24
  22. package/lattice_brain/ingestion/__init__.py +19 -58
  23. package/lattice_brain/ingestion/pipeline.py +20 -398
  24. package/lattice_brain/multimodal/__init__.py +7 -18
  25. package/lattice_brain/multimodal/images.py +6 -264
  26. package/lattice_brain/multimodal/video.py +8 -247
  27. package/lattice_brain/runtime/__init__.py +8 -79
  28. package/lattice_brain/runtime/hooks.py +22 -597
  29. package/latticeai/__init__.py +1 -1
  30. package/latticeai/api/agent_worker_seam.py +7 -80
  31. package/latticeai/api/health.py +26 -20
  32. package/latticeai/api/local_files.py +25 -608
  33. package/latticeai/api/models.py +12 -87
  34. package/latticeai/api/search.py +17 -231
  35. package/latticeai/api/tools.py +69 -750
  36. package/latticeai/api/voice_capture.py +8 -70
  37. package/latticeai/api/worker_compute.py +842 -0
  38. package/latticeai/api/worker_seams.py +216 -0
  39. package/latticeai/app_factory.py +23 -232
  40. package/latticeai/cli/entrypoint.py +36 -249
  41. package/latticeai/cli/runtime.py +7 -3
  42. package/latticeai/core/agent_permission.py +16 -91
  43. package/latticeai/core/config.py +47 -3
  44. package/latticeai/core/csrf.py +28 -2
  45. package/latticeai/core/embedding_providers/__init__.py +3 -5
  46. package/latticeai/core/embedding_providers/base.py +1 -1
  47. package/latticeai/core/embedding_providers/text.py +1 -1
  48. package/latticeai/core/http_origin.py +146 -0
  49. package/latticeai/core/io_utils.py +2 -11
  50. package/latticeai/core/messages.py +94 -531
  51. package/latticeai/core/model_compat.py +2 -8
  52. package/latticeai/core/module_probe.py +37 -0
  53. package/latticeai/core/security.py +13 -0
  54. package/latticeai/core/sessions.py +3 -2
  55. package/latticeai/core/sse.py +25 -0
  56. package/latticeai/core/users.py +0 -9
  57. package/latticeai/models/router/documents.py +0 -35
  58. package/latticeai/models/router/registry.py +0 -4
  59. package/latticeai/runtime/access_runtime.py +16 -18
  60. package/latticeai/runtime/bootstrap.py +10 -21
  61. package/latticeai/runtime/brain_runtime.py +35 -43
  62. package/latticeai/runtime/build_phases/__init__.py +21 -37
  63. package/latticeai/runtime/build_phases/features.py +101 -389
  64. package/latticeai/runtime/build_phases/foundation.py +82 -392
  65. package/latticeai/runtime/build_phases/web.py +91 -406
  66. package/latticeai/runtime/build_phases/worker_profile.py +244 -0
  67. package/latticeai/runtime/lifespan_runtime.py +7 -16
  68. package/latticeai/runtime/platform_services_runtime.py +1 -15
  69. package/latticeai/runtime/runtime_context.py +14 -143
  70. package/latticeai/runtime/security_runtime.py +10 -103
  71. package/latticeai/services/architecture_readiness.py +82 -43
  72. package/latticeai/services/model_capability_registry.py +0 -15
  73. package/latticeai/services/model_catalog.py +0 -7
  74. package/latticeai/services/model_loading.py +3 -2
  75. package/latticeai/services/model_runtime/__init__.py +2 -68
  76. package/latticeai/services/model_runtime/engines.py +27 -128
  77. package/latticeai/services/model_runtime/loading.py +2 -2
  78. package/latticeai/services/model_runtime/service.py +4 -28
  79. package/latticeai/services/p_reinforce.py +10 -261
  80. package/latticeai/services/product_readiness.py +31 -38
  81. package/latticeai/services/search_service.py +37 -795
  82. package/latticeai/services/tool_dispatch.py +30 -390
  83. package/latticeai/services/voice_capture.py +13 -107
  84. package/latticeai/tools/__init__.py +22 -49
  85. package/latticeai/tools/commands.py +0 -163
  86. package/latticeai/tools/computer.py +0 -39
  87. package/latticeai/tools/documents.py +1 -134
  88. package/latticeai/tools/filesystem.py +1 -247
  89. package/latticeai/tools/knowledge.py +1 -52
  90. package/latticeai/tools/local_files.py +0 -20
  91. package/latticeai/worker_app.py +75 -0
  92. package/package.json +3 -6
  93. package/requirements.txt +0 -5
  94. package/scripts/agent_eval.py +16 -28
  95. package/scripts/brain_quality_eval.py +20 -183
  96. package/scripts/bump_version.py +19 -6
  97. package/scripts/check_current_release_docs.mjs +7 -4
  98. package/scripts/check_legacy_debt.mjs +1 -1
  99. package/scripts/check_openapi_drift.mjs +10 -0
  100. package/scripts/check_server_i18n.mjs +2 -18
  101. package/scripts/compose_openapi.py +377 -0
  102. package/scripts/export_openapi.py +32 -4
  103. package/scripts/gen_messages_catalog_fixture.py +302 -0
  104. package/scripts/gen_openapi_fragments.py +365 -0
  105. package/scripts/gen_redact_fixture.py +196 -0
  106. package/scripts/gen_worker_allowlist_fixture.py +115 -0
  107. package/scripts/generate_agent_parity_fixtures.py +33 -14
  108. package/scripts/openapi_route_families.json +2161 -0
  109. package/scripts/release_screen_claims.json +31 -0
  110. package/scripts/run_integration_tests.mjs +134 -29
  111. package/scripts/run_sidecar_e2e.mjs +104 -11
  112. package/scripts/wheel_smoke.py +32 -22
  113. package/src-tauri/Cargo.lock +375 -9
  114. package/src-tauri/Cargo.toml +1 -1
  115. package/src-tauri/src/backend.rs +223 -43
  116. package/src-tauri/src/main.rs +27 -17
  117. package/src-tauri/src/topology.rs +58 -88
  118. package/src-tauri/tauri.conf.json +2 -3
  119. package/static/app/asset-manifest.json +41 -41
  120. package/static/app/assets/{Act-Drs_jd-O.js → Act-CToZnOHz.js} +1 -1
  121. package/static/app/assets/{AdminConsole-BqNx5oF6.js → AdminConsole-D5kbrBu8.js} +1 -1
  122. package/static/app/assets/{Brain-C7bdNmz-.js → Brain-C6zCdv4S.js} +1 -1
  123. package/static/app/assets/{BrainHome-DcTnINcI.js → BrainHome-D4n3EDUt.js} +1 -1
  124. package/static/app/assets/{BrainSignals-Df1MRIPD.js → BrainSignals-CzeZ-vQ9.js} +1 -1
  125. package/static/app/assets/{Capture-Dgsxvnbx.js → Capture-DPcyTczq.js} +1 -1
  126. package/static/app/assets/{Chronicle-BrkTxJK1.js → Chronicle-D3Nx-oWS.js} +1 -1
  127. package/static/app/assets/{CommandPalette-DDziw7Oj.js → CommandPalette-DPPvpp28.js} +1 -1
  128. package/static/app/assets/{Library-CYxeuraA.js → Library-Co2qTu3I.js} +1 -1
  129. package/static/app/assets/{LivingBrain-CNp6mvCm.js → LivingBrain-Bsmzwy8_.js} +1 -1
  130. package/static/app/assets/{ProductFlow-BVsowu3Z.js → ProductFlow-CBLdmesT.js} +1 -1
  131. package/static/app/assets/{ReviewCard-D1LbOfJS.js → ReviewCard-CfR6DLs7.js} +1 -1
  132. package/static/app/assets/{System-DcRAq7wj.js → System-Ce-P2YL6.js} +1 -1
  133. package/static/app/assets/arrow-left-DD5jFGHV.js +1 -0
  134. package/static/app/assets/{bot-BK2xQ9mN.js → bot-C5-XIww2.js} +1 -1
  135. package/static/app/assets/{brain-BZNztFBb.js → brain-CFRJUvdX.js} +1 -1
  136. package/static/app/assets/{button-CjueubVZ.js → button-DI1KcQP-.js} +1 -1
  137. package/static/app/assets/circle-check-CY20XMCh.js +1 -0
  138. package/static/app/assets/{circle-pause-HRjSmpyY.js → circle-pause-C8HHyood.js} +1 -1
  139. package/static/app/assets/{circle-play-CMcKDVwu.js → circle-play-Cufc235E.js} +1 -1
  140. package/static/app/assets/{cpu-B_MyTfYr.js → cpu-DW2_JVsv.js} +1 -1
  141. package/static/app/assets/{download-CTy0EByV.js → download-gbdKTBb8.js} +1 -1
  142. package/static/app/assets/{folder-open-DF6bLhTg.js → folder-open-C9ydyX33.js} +1 -1
  143. package/static/app/assets/{hard-drive-CpWHG77C.js → hard-drive-BxNMzBM3.js} +1 -1
  144. package/static/app/assets/index-BovSWRmQ.css +2 -0
  145. package/static/app/assets/{index-Dd6abJHX.js → index-q9XyDY7A.js} +3 -3
  146. package/static/app/assets/{input-bVgIRN3s.js → input-GLD94Y_K.js} +1 -1
  147. package/static/app/assets/{link-2-bg6CG5Vk.js → link-2-B4Y0gz1S.js} +1 -1
  148. package/static/app/assets/{permissionCopy-DFTf1HDZ.js → permissionCopy-CxrV0fvU.js} +1 -1
  149. package/static/app/assets/{primitives-D7D-sQ3T.js → primitives-2ANdAsu2.js} +1 -1
  150. package/static/app/assets/search-DTxtjQ07.js +1 -0
  151. package/static/app/assets/{share-2-BLzo7U4L.js → share-2-DxArfiuI.js} +1 -1
  152. package/static/app/assets/{shield-alert-BmngqnsJ.js → shield-alert-CgftuFFs.js} +1 -1
  153. package/static/app/assets/{textarea-DOSlAQQ3.js → textarea-BHVBAoCr.js} +1 -1
  154. package/static/app/assets/{useFocusTrap-pZhgeee4.js → useFocusTrap-Dzq2j_OG.js} +1 -1
  155. package/static/app/assets/{useMutation-BMDwNk4I.js → useMutation-BcqfMLNq.js} +1 -1
  156. package/static/app/assets/{useQuery-CSjKttRo.js → useQuery-DBzLKCOv.js} +1 -1
  157. package/static/app/assets/{utils-D3u_yv7B.js → utils-B-Aah1bO.js} +1 -1
  158. package/static/app/assets/{workspace-H3bMjYXC.js → workspace-B6fFhoko.js} +1 -1
  159. package/static/app/index.html +4 -4
  160. package/static/sw.js +1 -1
  161. package/desktop/electron/README.md +0 -9
  162. package/desktop/electron/main.cjs +0 -58
  163. package/desktop/electron/preload.cjs +0 -5
  164. package/lattice_brain/archive.py +0 -522
  165. package/lattice_brain/context.py +0 -325
  166. package/lattice_brain/conversations.py +0 -382
  167. package/lattice_brain/core.py +0 -82
  168. package/lattice_brain/graph/_kg_contract.py +0 -249
  169. package/lattice_brain/graph/curator.py +0 -676
  170. package/lattice_brain/graph/discovery.py +0 -595
  171. package/lattice_brain/graph/discovery_index/__init__.py +0 -35
  172. package/lattice_brain/graph/discovery_index/cleanup.py +0 -182
  173. package/lattice_brain/graph/discovery_index/extract.py +0 -137
  174. package/lattice_brain/graph/discovery_index/scan.py +0 -411
  175. package/lattice_brain/graph/discovery_index/upsert.py +0 -495
  176. package/lattice_brain/graph/documents.py +0 -380
  177. package/lattice_brain/graph/fusion.py +0 -395
  178. package/lattice_brain/graph/identity.py +0 -175
  179. package/lattice_brain/graph/image_vectors.py +0 -230
  180. package/lattice_brain/graph/ingest.py +0 -829
  181. package/lattice_brain/graph/network.py +0 -205
  182. package/lattice_brain/graph/proactive.py +0 -724
  183. package/lattice_brain/graph/projection/__init__.py +0 -42
  184. package/lattice_brain/graph/projection/curation.py +0 -500
  185. package/lattice_brain/graph/projection/v2_schema.py +0 -546
  186. package/lattice_brain/graph/provenance.py +0 -524
  187. package/lattice_brain/graph/rerank.py +0 -163
  188. package/lattice_brain/graph/retrieval/__init__.py +0 -54
  189. package/lattice_brain/graph/retrieval/context.py +0 -197
  190. package/lattice_brain/graph/retrieval/graph_view.py +0 -319
  191. package/lattice_brain/graph/retrieval/hybrid.py +0 -488
  192. package/lattice_brain/graph/retrieval/maintenance.py +0 -121
  193. package/lattice_brain/graph/retrieval/signals.py +0 -95
  194. package/lattice_brain/graph/retrieval_docgen.py +0 -253
  195. package/lattice_brain/graph/retrieval_policy.py +0 -180
  196. package/lattice_brain/graph/retrieval_reads.py +0 -769
  197. package/lattice_brain/graph/retrieval_vector/__init__.py +0 -42
  198. package/lattice_brain/graph/retrieval_vector/fingerprint.py +0 -97
  199. package/lattice_brain/graph/retrieval_vector/indexing.py +0 -347
  200. package/lattice_brain/graph/retrieval_vector/search.py +0 -560
  201. package/lattice_brain/graph/retrieval_vector/status.py +0 -374
  202. package/lattice_brain/graph/schema.py +0 -792
  203. package/lattice_brain/graph/store.py +0 -268
  204. package/lattice_brain/graph/vector_index/__init__.py +0 -85
  205. package/lattice_brain/graph/vector_index/base.py +0 -170
  206. package/lattice_brain/graph/vector_index/brute_force.py +0 -114
  207. package/lattice_brain/graph/vector_index/hnsw.py +0 -293
  208. package/lattice_brain/graph/vector_index/jobs.py +0 -287
  209. package/lattice_brain/graph/vector_index/quantized.py +0 -151
  210. package/lattice_brain/graph/vector_index/selector.py +0 -161
  211. package/lattice_brain/graph/write_master.py +0 -308
  212. package/lattice_brain/ingestion/_contract.py +0 -90
  213. package/lattice_brain/ingestion/folder_scan.py +0 -57
  214. package/lattice_brain/ingestion/folders.py +0 -258
  215. package/lattice_brain/ingestion/jobs_api.py +0 -107
  216. package/lattice_brain/ingestion/routing.py +0 -295
  217. package/lattice_brain/ingestion_jobs.py +0 -383
  218. package/lattice_brain/memory.py +0 -102
  219. package/lattice_brain/portability/__init__.py +0 -90
  220. package/lattice_brain/portability/_contract.py +0 -42
  221. package/lattice_brain/portability/backups.py +0 -338
  222. package/lattice_brain/portability/bundles.py +0 -136
  223. package/lattice_brain/portability/constants.py +0 -93
  224. package/lattice_brain/portability/fsops.py +0 -138
  225. package/lattice_brain/portability/service.py +0 -41
  226. package/lattice_brain/portability/sharing.py +0 -714
  227. package/lattice_brain/quality.py +0 -592
  228. package/lattice_brain/retrieval_benchmark_fixtures.py +0 -92
  229. package/lattice_brain/runtime/agent_runtime.py +0 -859
  230. package/lattice_brain/runtime/contracts.py +0 -460
  231. package/lattice_brain/runtime/multi_agent.py +0 -942
  232. package/lattice_brain/runtime/statuses.py +0 -10
  233. package/lattice_brain/sealed_box.py +0 -244
  234. package/lattice_brain/self_model.py +0 -675
  235. package/lattice_brain/sensitivity.py +0 -94
  236. package/lattice_brain/storage/__init__.py +0 -22
  237. package/lattice_brain/storage/base.py +0 -100
  238. package/lattice_brain/storage/docker.py +0 -105
  239. package/lattice_brain/storage/factory.py +0 -31
  240. package/lattice_brain/storage/migration.py +0 -191
  241. package/lattice_brain/storage/postgres.py +0 -123
  242. package/lattice_brain/storage/sqlite.py +0 -143
  243. package/lattice_brain/synthesis.py +0 -824
  244. package/lattice_brain/workflow.py +0 -497
  245. package/latticeai/api/admin.py +0 -471
  246. package/latticeai/api/agent_registry.py +0 -105
  247. package/latticeai/api/agents.py +0 -228
  248. package/latticeai/api/auth.py +0 -360
  249. package/latticeai/api/automation_intelligence.py +0 -401
  250. package/latticeai/api/brain_intelligence.py +0 -199
  251. package/latticeai/api/browser.py +0 -493
  252. package/latticeai/api/change_proposals.py +0 -89
  253. package/latticeai/api/chat.py +0 -572
  254. package/latticeai/api/chat_agent_http.py +0 -901
  255. package/latticeai/api/chat_contracts.py +0 -73
  256. package/latticeai/api/chat_documents.py +0 -276
  257. package/latticeai/api/chat_helpers.py +0 -463
  258. package/latticeai/api/chat_history.py +0 -101
  259. package/latticeai/api/chat_hybrid.py +0 -113
  260. package/latticeai/api/chat_intents.py +0 -646
  261. package/latticeai/api/chat_stream.py +0 -216
  262. package/latticeai/api/chronicle.py +0 -63
  263. package/latticeai/api/command_center.py +0 -51
  264. package/latticeai/api/computer_use.py +0 -485
  265. package/latticeai/api/evidence_actions.py +0 -48
  266. package/latticeai/api/features.py +0 -70
  267. package/latticeai/api/funnel_metrics.py +0 -31
  268. package/latticeai/api/garden.py +0 -34
  269. package/latticeai/api/hooks.py +0 -165
  270. package/latticeai/api/index_jobs.py +0 -145
  271. package/latticeai/api/invitations.py +0 -100
  272. package/latticeai/api/knowledge_graph.py +0 -536
  273. package/latticeai/api/marketplace.py +0 -105
  274. package/latticeai/api/mcp.py +0 -482
  275. package/latticeai/api/memory.py +0 -270
  276. package/latticeai/api/network.py +0 -81
  277. package/latticeai/api/network_boundary.py +0 -225
  278. package/latticeai/api/permission_mode.py +0 -61
  279. package/latticeai/api/permissions.py +0 -410
  280. package/latticeai/api/plugins.py +0 -126
  281. package/latticeai/api/portability.py +0 -391
  282. package/latticeai/api/project_sessions.py +0 -114
  283. package/latticeai/api/realtime.py +0 -118
  284. package/latticeai/api/review_queue.py +0 -364
  285. package/latticeai/api/security_dashboard.py +0 -604
  286. package/latticeai/api/setup.py +0 -319
  287. package/latticeai/api/static_routes.py +0 -351
  288. package/latticeai/api/ui_redirects.py +0 -26
  289. package/latticeai/api/workflow_designer.py +0 -394
  290. package/latticeai/api/workspace.py +0 -856
  291. package/latticeai/api/workspace_scope.py +0 -125
  292. package/latticeai/core/agent/__init__.py +0 -93
  293. package/latticeai/core/agent/_contract.py +0 -79
  294. package/latticeai/core/agent/context.py +0 -57
  295. package/latticeai/core/agent/deps.py +0 -125
  296. package/latticeai/core/agent/execution.py +0 -622
  297. package/latticeai/core/agent/planning.py +0 -145
  298. package/latticeai/core/agent/recovery.py +0 -157
  299. package/latticeai/core/agent/runtime.py +0 -210
  300. package/latticeai/core/agent/verification.py +0 -231
  301. package/latticeai/core/agent_eval.py +0 -739
  302. package/latticeai/core/agent_helpers.py +0 -493
  303. package/latticeai/core/agent_profiles.py +0 -110
  304. package/latticeai/core/agent_prompts.py +0 -171
  305. package/latticeai/core/agent_registry.py +0 -232
  306. package/latticeai/core/agent_state.py +0 -41
  307. package/latticeai/core/agent_trace.py +0 -104
  308. package/latticeai/core/artifact_ledger.py +0 -109
  309. package/latticeai/core/audit.py +0 -260
  310. package/latticeai/core/builtin_hooks.py +0 -105
  311. package/latticeai/core/context_builder.py +0 -394
  312. package/latticeai/core/document_generator.py +0 -103
  313. package/latticeai/core/enterprise.py +0 -157
  314. package/latticeai/core/enterprise_admin.py +0 -158
  315. package/latticeai/core/file_generation/__init__.py +0 -115
  316. package/latticeai/core/file_generation/bundles.py +0 -76
  317. package/latticeai/core/file_generation/extraction.py +0 -154
  318. package/latticeai/core/file_generation/inference.py +0 -235
  319. package/latticeai/core/file_generation/orchestration.py +0 -152
  320. package/latticeai/core/file_generation/prompting.py +0 -117
  321. package/latticeai/core/file_generation/repair.py +0 -114
  322. package/latticeai/core/file_generation/sanitize.py +0 -61
  323. package/latticeai/core/file_generation/validation.py +0 -201
  324. package/latticeai/core/graph_curator.py +0 -11
  325. package/latticeai/core/hooks.py +0 -11
  326. package/latticeai/core/invitations.py +0 -131
  327. package/latticeai/core/legacy_compatibility.py +0 -243
  328. package/latticeai/core/local_embeddings.py +0 -104
  329. package/latticeai/core/logging_safety.py +0 -46
  330. package/latticeai/core/marketplace.py +0 -293
  331. package/latticeai/core/mcp_catalog.py +0 -452
  332. package/latticeai/core/mcp_registry.py +0 -506
  333. package/latticeai/core/multi_agent.py +0 -11
  334. package/latticeai/core/network_boundary.py +0 -168
  335. package/latticeai/core/oidc.py +0 -208
  336. package/latticeai/core/plugins.py +0 -432
  337. package/latticeai/core/product_hardening.py +0 -218
  338. package/latticeai/core/project_sessions.py +0 -337
  339. package/latticeai/core/realtime.py +0 -238
  340. package/latticeai/core/run_explain.py +0 -423
  341. package/latticeai/core/run_store.py +0 -252
  342. package/latticeai/core/timezones.py +0 -80
  343. package/latticeai/core/workflow_engine.py +0 -11
  344. package/latticeai/core/workspace_computer_memory.py +0 -84
  345. package/latticeai/core/workspace_graph_trace.py +0 -161
  346. package/latticeai/core/workspace_indexing.py +0 -102
  347. package/latticeai/core/workspace_memory.py +0 -77
  348. package/latticeai/core/workspace_onboarding.py +0 -104
  349. package/latticeai/core/workspace_os.py +0 -988
  350. package/latticeai/core/workspace_os_constants.py +0 -126
  351. package/latticeai/core/workspace_os_state.py +0 -180
  352. package/latticeai/core/workspace_os_utils.py +0 -69
  353. package/latticeai/core/workspace_permissions.py +0 -101
  354. package/latticeai/core/workspace_plugins.py +0 -97
  355. package/latticeai/core/workspace_relationships.py +0 -99
  356. package/latticeai/core/workspace_reorganization.py +0 -335
  357. package/latticeai/core/workspace_review_items.py +0 -118
  358. package/latticeai/core/workspace_runs.py +0 -732
  359. package/latticeai/core/workspace_skills.py +0 -114
  360. package/latticeai/core/workspace_snapshots.py +0 -198
  361. package/latticeai/core/workspace_timeline.py +0 -110
  362. package/latticeai/integrations/__init__.py +0 -0
  363. package/latticeai/integrations/telegram_bot/__init__.py +0 -123
  364. package/latticeai/integrations/telegram_bot/__main__.py +0 -17
  365. package/latticeai/integrations/telegram_bot/config.py +0 -86
  366. package/latticeai/integrations/telegram_bot/dispatch.py +0 -311
  367. package/latticeai/integrations/telegram_bot/flows.py +0 -478
  368. package/latticeai/integrations/telegram_bot/helpers.py +0 -322
  369. package/latticeai/integrations/telegram_bot/screens.py +0 -394
  370. package/latticeai/runtime/audit_runtime.py +0 -76
  371. package/latticeai/runtime/automation_runtime.py +0 -81
  372. package/latticeai/runtime/chat_wiring.py +0 -141
  373. package/latticeai/runtime/context_runtime.py +0 -66
  374. package/latticeai/runtime/feature_toggle_wiring.py +0 -163
  375. package/latticeai/runtime/history_runtime.py +0 -163
  376. package/latticeai/runtime/history_writer.py +0 -138
  377. package/latticeai/runtime/hooks_runtime.py +0 -77
  378. package/latticeai/runtime/model_wiring.py +0 -68
  379. package/latticeai/runtime/namespace_runtime.py +0 -163
  380. package/latticeai/runtime/network_boundary_wiring.py +0 -128
  381. package/latticeai/runtime/network_config_runtime.py +0 -56
  382. package/latticeai/runtime/permission_mode_wiring.py +0 -119
  383. package/latticeai/runtime/persistence_runtime.py +0 -159
  384. package/latticeai/runtime/platform_runtime_wiring.py +0 -89
  385. package/latticeai/runtime/review_wiring.py +0 -42
  386. package/latticeai/runtime/router_registration.py +0 -689
  387. package/latticeai/runtime/sso_config_runtime.py +0 -128
  388. package/latticeai/runtime/user_key_runtime.py +0 -106
  389. package/latticeai/runtime/web_runtime.py +0 -92
  390. package/latticeai/server_app.py +0 -51
  391. package/latticeai/services/app_context.py +0 -130
  392. package/latticeai/services/automation_execution.py +0 -266
  393. package/latticeai/services/automation_intelligence.py +0 -614
  394. package/latticeai/services/brain_automation.py +0 -191
  395. package/latticeai/services/brain_intelligence/__init__.py +0 -58
  396. package/latticeai/services/brain_intelligence/_contract.py +0 -71
  397. package/latticeai/services/brain_intelligence/consistency.py +0 -193
  398. package/latticeai/services/brain_intelligence/constants.py +0 -47
  399. package/latticeai/services/brain_intelligence/digest.py +0 -258
  400. package/latticeai/services/brain_intelligence/health.py +0 -331
  401. package/latticeai/services/brain_intelligence/proposals.py +0 -264
  402. package/latticeai/services/brain_intelligence/sampling.py +0 -84
  403. package/latticeai/services/brain_intelligence/service.py +0 -48
  404. package/latticeai/services/change_proposals.py +0 -505
  405. package/latticeai/services/chat_service.py +0 -243
  406. package/latticeai/services/chronicle.py +0 -557
  407. package/latticeai/services/cloud_egress_audit.py +0 -85
  408. package/latticeai/services/cloud_extraction.py +0 -129
  409. package/latticeai/services/cloud_streaming.py +0 -268
  410. package/latticeai/services/cloud_token_guard.py +0 -84
  411. package/latticeai/services/command_center.py +0 -548
  412. package/latticeai/services/evidence_actions.py +0 -255
  413. package/latticeai/services/feature_toggles.py +0 -502
  414. package/latticeai/services/folder_watch.py +0 -520
  415. package/latticeai/services/funnel_metrics.py +0 -307
  416. package/latticeai/services/hybrid_chat.py +0 -316
  417. package/latticeai/services/hybrid_context.py +0 -228
  418. package/latticeai/services/hybrid_policy.py +0 -178
  419. package/latticeai/services/ingestion.py +0 -11
  420. package/latticeai/services/interop_bridges.py +0 -978
  421. package/latticeai/services/kg_portability.py +0 -11
  422. package/latticeai/services/local_knowledge.py +0 -465
  423. package/latticeai/services/memory_service/__init__.py +0 -52
  424. package/latticeai/services/memory_service/_contract.py +0 -100
  425. package/latticeai/services/memory_service/brief.py +0 -431
  426. package/latticeai/services/memory_service/constants.py +0 -57
  427. package/latticeai/services/memory_service/maintenance.py +0 -138
  428. package/latticeai/services/memory_service/manager.py +0 -186
  429. package/latticeai/services/memory_service/proof.py +0 -136
  430. package/latticeai/services/memory_service/recall.py +0 -225
  431. package/latticeai/services/memory_service/service.py +0 -48
  432. package/latticeai/services/memory_service/stores.py +0 -110
  433. package/latticeai/services/model_recommendation.py +0 -224
  434. package/latticeai/services/model_runtime/cloud.py +0 -87
  435. package/latticeai/services/multimodal_streaming.py +0 -129
  436. package/latticeai/services/network_boundary_service.py +0 -154
  437. package/latticeai/services/obsidian_bridge.py +0 -609
  438. package/latticeai/services/openai_compatible_adapter.py +0 -101
  439. package/latticeai/services/permission_mode_service.py +0 -170
  440. package/latticeai/services/platform_runtime.py +0 -366
  441. package/latticeai/services/review_queue.py +0 -380
  442. package/latticeai/services/router_context.py +0 -59
  443. package/latticeai/services/run_executor.py +0 -387
  444. package/latticeai/services/self_model_service.py +0 -171
  445. package/latticeai/services/setup_detection.py +0 -81
  446. package/latticeai/services/triggers.py +0 -378
  447. package/latticeai/services/upload_service.py +0 -185
  448. package/latticeai/services/workspace_service.py +0 -171
  449. package/latticeai/setup/__init__.py +0 -25
  450. package/latticeai/setup/auto_setup.py +0 -857
  451. package/latticeai/setup/demo_corpus.py +0 -98
  452. package/latticeai/setup/wizard/__init__.py +0 -126
  453. package/latticeai/setup/wizard/catalog.py +0 -172
  454. package/latticeai/setup/wizard/detect.py +0 -323
  455. package/latticeai/setup/wizard/install.py +0 -348
  456. package/latticeai/setup/wizard/paths.py +0 -168
  457. package/latticeai/setup/wizard/plans.py +0 -74
  458. package/latticeai/setup/wizard/recommend.py +0 -320
  459. package/scripts/bench_agent_smoke.py +0 -409
  460. package/scripts/bench_models.py +0 -540
  461. package/scripts/bench_vector_index.py +0 -295
  462. package/scripts/funnel_soft_gate.py +0 -192
  463. package/scripts/generate_agent_loop_fixtures.py +0 -907
  464. package/scripts/generate_rust_parity_fixtures.py +0 -1000
  465. package/scripts/measure_brain_home_fill.mjs +0 -141
  466. package/scripts/migrate_brain_storage.py +0 -57
  467. package/scripts/parity_fixture_corpus_docgen.py +0 -341
  468. package/scripts/profile_kg.py +0 -355
  469. package/server.py +0 -30
  470. package/static/app/assets/arrow-left-BHYmOTWU.js +0 -1
  471. package/static/app/assets/circle-check-CLeWJr67.js +0 -1
  472. package/static/app/assets/index-DxmOfNRi.css +0 -2
  473. package/static/app/assets/search-BgSVX6NG.js +0 -1
@@ -1,42 +0,0 @@
1
- """The derived vector index: build it, report on it, search it.
2
-
3
- v11.3.0 turned this module into a package. ``KnowledgeGraphVectorMixin`` is
4
- now composed from four cohesive sub-mixins — embedder fingerprint, index
5
- build, index status, and search — each moved here verbatim. Every name this
6
- module exported before still resolves from
7
- ``lattice_brain.graph.retrieval_vector``.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- # ruff: noqa: F403,F405
13
- from .._kg_common import * # noqa: F403,F401
14
- from .fingerprint import _VectorFingerprintMixin
15
- from .indexing import _VectorIndexingMixin
16
- from .search import ( # noqa: F401
17
- DEFAULT_VECTOR_MAX_CANDIDATES,
18
- VECTOR_MAX_CANDIDATES_CEILING,
19
- VECTOR_MAX_CANDIDATES_ENV,
20
- VECTOR_SCAN_BATCH,
21
- _configured_vector_max_candidates,
22
- _VectorSearchMixin,
23
- )
24
- from .status import _VectorStatusMixin
25
-
26
-
27
- # Base order is most-composed-first (status → indexing → fingerprint, then
28
- # search): each half names the ones it calls as its typing-only base, and C3
29
- # needs a subclass ahead of the class it extends. The method sets are disjoint,
30
- # so at runtime the order changes nothing.
31
- class KnowledgeGraphVectorMixin(
32
- _VectorStatusMixin,
33
- _VectorIndexingMixin,
34
- _VectorFingerprintMixin,
35
- _VectorSearchMixin,
36
- ):
37
- """Vector-embedding index build/status/search, split out of retrieval.
38
-
39
- Composed into KnowledgeGraphStore alongside KnowledgeGraphRetrievalMixin;
40
- both mixins share the same instance, so vector methods still reach sibling
41
- retrieval/write helpers (e.g. self._vector_text_for_node) through the MRO.
42
- """
@@ -1,97 +0,0 @@
1
- """Which embedder actually built the index, recorded in ``graph_meta``.
2
-
3
- ``vector_search`` filters on the current model/dim, so swapping the embedder
4
- silently yields zero vector rows; the fingerprint turns that into the honest
5
- ``stale_embedder`` signal. Moved verbatim out of ``retrieval_vector.py``.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- from typing import TYPE_CHECKING
11
-
12
- # ruff: noqa: F403,F405
13
- from .._kg_common import * # noqa: F403,F401
14
-
15
- # The cross-mixin surface (`_connect`, `_upsert_node`, …) is declared in
16
- # `_kg_contract.KnowledgeGraphCore`. It is a typing-only base: at runtime this
17
- # is `object`, so the MRO of `KnowledgeGraphStore` is unchanged.
18
- if TYPE_CHECKING:
19
- from .._kg_contract import KnowledgeGraphCore as _Core
20
- else:
21
- _Core = object
22
-
23
-
24
- class _VectorFingerprintMixin(_Core):
25
- """Embedder-fingerprint read/write. Composed into the public mixin."""
26
-
27
- # ── embedder fingerprint (review Wave 2.2 — stale_embedder) ──────────────
28
- # vector_search filters on the CURRENT model/dim, so swapping the embedder
29
- # silently yields zero vector rows. The fingerprint persisted in graph_meta
30
- # records which embedder actually built the index; a mismatch is surfaced
31
- # as the honest ``stale_embedder`` signal instead of a silent degradation.
32
-
33
- _EMBEDDER_FINGERPRINT_KEY = "embedder_fingerprint"
34
-
35
- def _embedder_fingerprint_record(
36
- self, conn: sqlite3.Connection
37
- ) -> Optional[Dict[str, Any]]:
38
- """Read the recorded embedder fingerprint from graph_meta (or None)."""
39
- row = conn.execute(
40
- "SELECT value FROM graph_meta WHERE key=?",
41
- (self._EMBEDDER_FINGERPRINT_KEY,),
42
- ).fetchone()
43
- if not row:
44
- return None
45
- payload = _safe_loads(row["value"])
46
- if not isinstance(payload, dict) or not payload.get("model_id"):
47
- return None
48
- try:
49
- dim = int(payload.get("dim") or 0)
50
- except (TypeError, ValueError):
51
- dim = 0
52
- return {"model_id": str(payload["model_id"]), "dim": dim}
53
-
54
- def _write_embedder_fingerprint(self, conn: sqlite3.Connection) -> Dict[str, Any]:
55
- """Persist the CURRENT embedder identity (same transaction as caller)."""
56
- fingerprint = {
57
- "model_id": self._embedding_model.model_id,
58
- "dim": int(self._embedding_model.dim),
59
- }
60
- conn.execute(
61
- "INSERT OR REPLACE INTO graph_meta(key, value) VALUES (?, ?)",
62
- (self._EMBEDDER_FINGERPRINT_KEY, _json(fingerprint)),
63
- )
64
- return fingerprint
65
-
66
- def record_embedder_fingerprint(self) -> Dict[str, Any]:
67
- """Record the current embedder (model_id + dim) as the index builder."""
68
- with self._connect() as conn:
69
- return self._write_embedder_fingerprint(conn)
70
-
71
- def embedder_fingerprint_status(self) -> Dict[str, Any]:
72
- """Compare the current embedder against the recorded index fingerprint.
73
-
74
- Returns ``{"current": {model_id, dim}, "recorded": {...} | None,
75
- "stale_embedder": bool}``. ``stale_embedder`` is True only when a
76
- fingerprint was recorded AND it differs from the current embedder —
77
- an unrecorded index (legacy DBs, nothing indexed yet) is honestly
78
- "unknown", never reported stale. Never raises.
79
- """
80
- current = {
81
- "model_id": self._embedding_model.model_id,
82
- "dim": int(self._embedding_model.dim),
83
- }
84
- recorded: Optional[Dict[str, Any]] = None
85
- try:
86
- with self._connect() as conn:
87
- recorded = self._embedder_fingerprint_record(conn)
88
- except Exception: # noqa: BLE001 — status must degrade, never raise
89
- recorded = None
90
- stale = bool(
91
- recorded is not None
92
- and (
93
- recorded.get("model_id") != current["model_id"]
94
- or recorded.get("dim") != current["dim"]
95
- )
96
- )
97
- return {"current": current, "recorded": recorded, "stale_embedder": stale}
@@ -1,347 +0,0 @@
1
- """Building the vector index: incremental upserts and full rebuilds.
2
-
3
- Moved verbatim out of ``retrieval_vector.py`` (v11.3.0 decomposition).
4
- """
5
-
6
- from __future__ import annotations
7
-
8
- from typing import TYPE_CHECKING
9
-
10
- # ruff: noqa: F403,F405
11
- from .._kg_common import * # noqa: F403,F401
12
-
13
- # Typing-only base (runtime value is `object`, so the store's MRO is
14
- # unchanged). Every build path records which embedder produced the rows, so
15
- # this half calls the fingerprint half through `self`; naming it as the base
16
- # states that assumption and carries the store contract
17
- # (`_connect`, `_upsert_node`, …) along with it.
18
- if TYPE_CHECKING:
19
- from .fingerprint import _VectorFingerprintMixin as _Core
20
- else:
21
- _Core = object
22
-
23
-
24
- class _VectorIndexingMixin(_Core):
25
- """Vector index build/refresh. Composed into the public mixin."""
26
-
27
- def _vector_text_hashes(self, conn: sqlite3.Connection) -> Dict[str, str]:
28
- """``item_id -> text_hash`` for rows already embedded by *this* embedder.
29
-
30
- The incremental rebuild's job is mostly deciding what it does *not*
31
- have to do, and it used to ask that question with one ``SELECT`` per
32
- candidate item — a round trip per node and per chunk on every run,
33
- almost all of which answer "unchanged". One query returning two short
34
- columns replaces all of them.
35
-
36
- Rows written by a different embedder are left out, so they compare as
37
- missing and get re-embedded, which is what an embedder swap requires.
38
- """
39
- return {
40
- row["item_id"]: row["text_hash"]
41
- for row in conn.execute(
42
- """
43
- SELECT item_id, text_hash
44
- FROM vector_embeddings
45
- WHERE embedding_model=? AND embedding_dim=?
46
- """,
47
- (self._embedding_model.model_id, self._embedding_model.dim),
48
- ).fetchall()
49
- }
50
-
51
- def _iter_vector_source_items(
52
- self,
53
- conn: sqlite3.Connection,
54
- *,
55
- include_nodes: bool = True,
56
- include_chunks: bool = True,
57
- ) -> Iterator[Dict[str, Any]]:
58
- """Stream the graph's embeddable text, one item at a time.
59
-
60
- Yields rather than returns a list. Every caller consumes this exactly
61
- once in a ``for``, and building the list first meant a rebuild held
62
- the full text of every node and chunk in memory simultaneously — the
63
- one shape guaranteed to fail on precisely the large graph that most
64
- needs the index.
65
- """
66
- if include_nodes:
67
- for row in conn.execute(
68
- """
69
- SELECT id, type, title, summary, metadata_json
70
- FROM nodes
71
- WHERE type <> 'Chunk'
72
- ORDER BY updated_at DESC, id ASC
73
- """
74
- ).fetchall():
75
- metadata = _safe_loads(row["metadata_json"])
76
- text = self._vector_text_for_node(
77
- title=row["title"],
78
- summary=row["summary"] or "",
79
- metadata=metadata,
80
- )
81
- if text:
82
- yield {
83
- "item_id": row["id"],
84
- "item_type": "node",
85
- "source_node": row["id"],
86
- "text": text,
87
- "metadata": {"node_type": row["type"], **metadata},
88
- }
89
- if include_chunks:
90
- for row in conn.execute(
91
- """
92
- SELECT c.id, c.source_node AS parent_source_node, c.text, c.metadata_json
93
- FROM chunks c
94
- JOIN nodes n ON n.id=c.id
95
- ORDER BY c.created_at DESC, c.id ASC
96
- """
97
- ).fetchall():
98
- metadata = _safe_loads(row["metadata_json"])
99
- text = _clean_text(row["text"] or "")
100
- if text:
101
- yield {
102
- "item_id": row["id"],
103
- "item_type": "chunk",
104
- "source_node": row["id"],
105
- "text": text,
106
- "metadata": {
107
- **metadata,
108
- "parent_source_node": row["parent_source_node"],
109
- },
110
- }
111
-
112
- def index_node_incremental(self, node_id: str) -> Dict[str, Any]:
113
- """Embed/index only ``node_id`` and its chunks (incremental sync).
114
-
115
- The item construction mirrors :meth:`_iter_vector_source_items` exactly
116
- (same ids, same ``source_node``/``parent_source_node`` semantics), so
117
- anything this method indexes is indistinguishable from a full
118
- :meth:`rebuild_vector_index` pass — and anything it *fails* to index
119
- stays visible as ``missing``/``stale`` backlog in :meth:`index_status`,
120
- where a later rebuild picks it up.
121
-
122
- Never raises: embedding-provider or storage failures are reported as
123
- ``{"status": "failed", ...}`` so ingestion callers can degrade instead
124
- of losing an already-persisted write.
125
- """
126
- node_id = str(node_id or "").strip()
127
- started = time.perf_counter()
128
- summary: Dict[str, Any] = {
129
- "node_id": node_id,
130
- "items_total": 0,
131
- "items_indexed": 0,
132
- "items_skipped": 0,
133
- }
134
- if not node_id:
135
- return {**summary, "status": "skipped", "detail": "node_id required"}
136
- try:
137
- with self._connect() as conn:
138
- row = conn.execute(
139
- "SELECT id, type, title, summary, metadata_json FROM nodes WHERE id=?",
140
- (node_id,),
141
- ).fetchone()
142
- if row is None:
143
- return {**summary, "status": "skipped", "detail": "node not found"}
144
- items: List[Dict[str, Any]] = []
145
- if row["type"] != "Chunk":
146
- metadata = _safe_loads(row["metadata_json"])
147
- text = self._vector_text_for_node(
148
- title=row["title"],
149
- summary=row["summary"] or "",
150
- metadata=metadata,
151
- )
152
- if text:
153
- items.append(
154
- {
155
- "item_id": row["id"],
156
- "item_type": "node",
157
- "source_node": row["id"],
158
- "text": text,
159
- "metadata": {"node_type": row["type"], **metadata},
160
- }
161
- )
162
- for chunk_row in conn.execute(
163
- """
164
- SELECT c.id, c.source_node AS parent_source_node, c.text, c.metadata_json
165
- FROM chunks c
166
- JOIN nodes n ON n.id=c.id
167
- WHERE c.source_node=?
168
- ORDER BY c.created_at ASC, c.id ASC
169
- """,
170
- (node_id,),
171
- ).fetchall():
172
- metadata = _safe_loads(chunk_row["metadata_json"])
173
- text = _clean_text(chunk_row["text"] or "")
174
- if text:
175
- items.append(
176
- {
177
- "item_id": chunk_row["id"],
178
- "item_type": "chunk",
179
- "source_node": chunk_row["id"],
180
- "text": text,
181
- "metadata": {
182
- **metadata,
183
- "parent_source_node": chunk_row["parent_source_node"],
184
- },
185
- }
186
- )
187
- indexed = skipped = 0
188
- for item in items:
189
- if self._upsert_vector_item(conn, **item):
190
- indexed += 1
191
- else:
192
- skipped += 1
193
- if indexed and self._embedder_fingerprint_record(conn) is None:
194
- # First successful vector write establishes the fingerprint;
195
- # later incremental writes never overwrite it (only a full
196
- # rebuild may flip it after an embedder swap).
197
- self._write_embedder_fingerprint(conn)
198
- summary.update(
199
- {
200
- "items_total": len(items),
201
- "items_indexed": indexed,
202
- "items_skipped": skipped,
203
- }
204
- )
205
- return {
206
- **summary,
207
- "status": "indexed" if indexed else "noop",
208
- "duration_ms": round((time.perf_counter() - started) * 1000, 2),
209
- "embedding_model": self._embedding_model.model_id,
210
- }
211
- except Exception as exc: # noqa: BLE001 — incremental sync must never raise
212
- return {
213
- **summary,
214
- "status": "failed",
215
- "detail": str(exc),
216
- "duration_ms": round((time.perf_counter() - started) * 1000, 2),
217
- }
218
-
219
- def rebuild_vector_index(
220
- self,
221
- *,
222
- full: bool = False,
223
- include_nodes: bool = True,
224
- include_chunks: bool = True,
225
- ) -> Dict[str, Any]:
226
- """Rebuild the derived vector index without mutating graph content."""
227
- op_id = f"vector-op:{_sha256_text(f'{time.time()}:{os.getpid()}')[:24]}"
228
- requested_at = _now()
229
- started = time.perf_counter()
230
- try:
231
- with self._connect() as conn:
232
- conn.execute(
233
- """
234
- INSERT INTO vector_index_operations(
235
- id, operation, status, requested_at, started_at, metadata_json
236
- )
237
- VALUES (?, ?, 'running', ?, ?, ?)
238
- """,
239
- (
240
- op_id,
241
- "rebuild_full" if full else "rebuild_incremental",
242
- requested_at,
243
- requested_at,
244
- _json(
245
- {
246
- "include_nodes": include_nodes,
247
- "include_chunks": include_chunks,
248
- }
249
- ),
250
- ),
251
- )
252
- if full:
253
- filters = []
254
- if include_nodes:
255
- filters.append("'node'")
256
- if include_chunks:
257
- filters.append("'chunk'")
258
- if filters:
259
- conn.execute(
260
- f"DELETE FROM vector_embeddings WHERE item_type IN ({','.join(filters)})"
261
- )
262
- # After a full wipe nothing is current by definition, so the
263
- # prefetch would only be a wasted scan of a table we just
264
- # emptied. Incremental is where it pays: it turns "one SELECT
265
- # per item, nearly all of which say unchanged" into one query.
266
- known = {} if full else self._vector_text_hashes(conn)
267
- total = indexed = skipped = 0
268
- for item in self._iter_vector_source_items(
269
- conn,
270
- include_nodes=include_nodes,
271
- include_chunks=include_chunks,
272
- ):
273
- total += 1
274
- if known.get(item["item_id"]) == _sha256_text(_clean_text(item["text"])):
275
- skipped += 1
276
- continue
277
- if self._upsert_vector_item(conn, **item):
278
- indexed += 1
279
- else:
280
- skipped += 1
281
- duration_ms = round((time.perf_counter() - started) * 1000, 2)
282
- conn.execute(
283
- """
284
- UPDATE vector_index_operations
285
- SET status='completed', completed_at=?, items_total=?,
286
- items_indexed=?, items_skipped=?, metadata_json=?
287
- WHERE id=?
288
- """,
289
- (
290
- _now(),
291
- total,
292
- indexed,
293
- skipped,
294
- _json(
295
- {
296
- "include_nodes": include_nodes,
297
- "include_chunks": include_chunks,
298
- "duration_ms": duration_ms,
299
- "embedding_model": self._embedding_model.model_id,
300
- "embedding_dim": self._embedding_model.dim,
301
- }
302
- ),
303
- op_id,
304
- ),
305
- )
306
- # A successful rebuild (re)establishes which embedder built
307
- # the index — this is the only path that may flip a recorded
308
- # fingerprint after an embedder swap.
309
- self._write_embedder_fingerprint(conn)
310
- return {
311
- "status": "completed",
312
- "operation_id": op_id,
313
- "full": bool(full),
314
- "items_total": total,
315
- "items_indexed": indexed,
316
- "items_skipped": skipped,
317
- "duration_ms": duration_ms,
318
- "embedding_model": self._embedding_model.model_id,
319
- "embedding_dim": self._embedding_model.dim,
320
- }
321
- except Exception as exc:
322
- duration_ms = round((time.perf_counter() - started) * 1000, 2)
323
- with self._connect() as conn:
324
- conn.execute(
325
- """
326
- INSERT INTO vector_index_operations(
327
- id, operation, status, requested_at, started_at, completed_at,
328
- error_message, metadata_json
329
- )
330
- VALUES (?, ?, 'failed', ?, ?, ?, ?, ?)
331
- ON CONFLICT(id) DO UPDATE SET
332
- status='failed',
333
- completed_at=excluded.completed_at,
334
- error_message=excluded.error_message,
335
- metadata_json=excluded.metadata_json
336
- """,
337
- (
338
- op_id,
339
- "rebuild_full" if full else "rebuild_incremental",
340
- requested_at,
341
- requested_at,
342
- _now(),
343
- str(exc),
344
- _json({"duration_ms": duration_ms}),
345
- ),
346
- )
347
- raise