ltcai 11.5.2 → 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.
- package/README.md +91 -148
- package/bin/ltcai.js +234 -24
- package/docs/CHANGELOG.md +75 -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 +21 -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-CToZnOHz.js} +1 -1
- package/static/app/assets/{AdminConsole-cf4npybT.js → AdminConsole-D5kbrBu8.js} +1 -1
- package/static/app/assets/{Brain-3VCSHFcn.js → Brain-C6zCdv4S.js} +1 -1
- package/static/app/assets/{BrainHome-Qm8eaztx.js → BrainHome-D4n3EDUt.js} +1 -1
- package/static/app/assets/{BrainSignals-DS9BtKOW.js → BrainSignals-CzeZ-vQ9.js} +1 -1
- package/static/app/assets/{Capture-DiQ219jW.js → Capture-DPcyTczq.js} +1 -1
- package/static/app/assets/{Chronicle-BGvuAchH.js → Chronicle-D3Nx-oWS.js} +1 -1
- package/static/app/assets/{CommandPalette-Bqhm0Urn.js → CommandPalette-DPPvpp28.js} +1 -1
- package/static/app/assets/{Library-BV6NnF0a.js → Library-Co2qTu3I.js} +1 -1
- package/static/app/assets/{LivingBrain-GzenJchP.js → LivingBrain-Bsmzwy8_.js} +1 -1
- package/static/app/assets/{ProductFlow-DEP6-vML.js → ProductFlow-CBLdmesT.js} +1 -1
- package/static/app/assets/{ReviewCard-CNZ7XjWG.js → ReviewCard-CfR6DLs7.js} +1 -1
- package/static/app/assets/{System-CieofHQa.js → System-Ce-P2YL6.js} +1 -1
- package/static/app/assets/arrow-left-DD5jFGHV.js +1 -0
- package/static/app/assets/{bot-B_K1Tdmw.js → bot-C5-XIww2.js} +1 -1
- package/static/app/assets/{brain-DWyaV1L1.js → brain-CFRJUvdX.js} +1 -1
- package/static/app/assets/{button-aTn4s84A.js → button-DI1KcQP-.js} +1 -1
- package/static/app/assets/circle-check-CY20XMCh.js +1 -0
- package/static/app/assets/{circle-pause-xKgeGXkT.js → circle-pause-C8HHyood.js} +1 -1
- package/static/app/assets/{circle-play-DkT6tYPX.js → circle-play-Cufc235E.js} +1 -1
- package/static/app/assets/{cpu-85xYObUC.js → cpu-DW2_JVsv.js} +1 -1
- package/static/app/assets/{download-B5Fm7YXo.js → download-gbdKTBb8.js} +1 -1
- package/static/app/assets/{folder-open-kk2Xa52u.js → folder-open-C9ydyX33.js} +1 -1
- package/static/app/assets/{hard-drive-DkA3zBW_.js → hard-drive-BxNMzBM3.js} +1 -1
- package/static/app/assets/index-BovSWRmQ.css +2 -0
- package/static/app/assets/{index-BMPdTmlY.js → index-q9XyDY7A.js} +3 -3
- package/static/app/assets/{input-B0nRf2jO.js → input-GLD94Y_K.js} +1 -1
- package/static/app/assets/{link-2-Dwb4gnTc.js → link-2-B4Y0gz1S.js} +1 -1
- package/static/app/assets/{permissionCopy-CQDUBrOZ.js → permissionCopy-CxrV0fvU.js} +1 -1
- package/static/app/assets/{primitives-SNp0LRJz.js → primitives-2ANdAsu2.js} +1 -1
- package/static/app/assets/search-DTxtjQ07.js +1 -0
- package/static/app/assets/{share-2-BsrxFglO.js → share-2-DxArfiuI.js} +1 -1
- package/static/app/assets/{shield-alert-5BStfp2_.js → shield-alert-CgftuFFs.js} +1 -1
- package/static/app/assets/{textarea-Cg8IUA-k.js → textarea-BHVBAoCr.js} +1 -1
- package/static/app/assets/{useFocusTrap-CYKvE46M.js → useFocusTrap-Dzq2j_OG.js} +1 -1
- package/static/app/assets/{useMutation-CSn9t1op.js → useMutation-BcqfMLNq.js} +1 -1
- package/static/app/assets/{useQuery-CY2OI2uy.js → useQuery-DBzLKCOv.js} +1 -1
- package/static/app/assets/{utils-Ddol2RWD.js → utils-B-Aah1bO.js} +1 -1
- package/static/app/assets/{workspace-BqDwOz_p.js → workspace-B6fFhoko.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/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/search-BcHqkjoy.js +0 -1
|
@@ -21,6 +21,27 @@
|
|
|
21
21
|
"specific, not less."
|
|
22
22
|
],
|
|
23
23
|
|
|
24
|
+
"11.6.0": {
|
|
25
|
+
"_why": [
|
|
26
|
+
"One Door release: the product server moved from Python/FastAPI to the",
|
|
27
|
+
"Rust lattice-host, every write moved into the native KG write engine,",
|
|
28
|
+
"and the Python package became a 28-route AI worker. The frontend",
|
|
29
|
+
"bundle is untouched — the same React sources, the same routes, the",
|
|
30
|
+
"same copy — so no captured screen changes on purpose, and all",
|
|
31
|
+
"thirteen are measured but not gated.",
|
|
32
|
+
"",
|
|
33
|
+
"Worth stating because it is the one thing that could surprise a",
|
|
34
|
+
"reader: the screens are served by a different process now, and the",
|
|
35
|
+
"capture still runs against tests/visual/mock_server.cjs, so these",
|
|
36
|
+
"shots prove the frontend did not move, not that the new server",
|
|
37
|
+
"renders them. The live proof for that is the gateway integration",
|
|
38
|
+
"test and the release smoke, not this gate.",
|
|
39
|
+
"",
|
|
40
|
+
"Known jitter: 05-memory-graph moves ~2-3% between captures from the",
|
|
41
|
+
"cytoscape layout (11.3.0-11.5.2 observed)."
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
|
|
24
45
|
"11.5.2": {
|
|
25
46
|
"_why": [
|
|
26
47
|
"Tight Ship release: deletions, consolidation and front-door fixes —",
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Start an isolated Lattice product server and run the live-server integration
|
|
4
|
+
* suite (`tests/integration/`) against it.
|
|
5
|
+
*
|
|
6
|
+
* v11.6.0 "One Door": the front door is `lattice-host`, which supervises the
|
|
7
|
+
* Python AI worker (`latticeai.worker_app`) on an internal port behind it.
|
|
8
|
+
* This runner used to start `uvicorn server:app` — a root `server.py` the
|
|
9
|
+
* release deleted — so it now boots the same binary the product ships, exactly
|
|
10
|
+
* the way scripts/run_sidecar_e2e.mjs does.
|
|
11
|
+
*
|
|
12
|
+
* Isolation rule, unchanged: never touch the developer's real HOME / ~/.ltcai /
|
|
13
|
+
* Brain vault / agent workspace.
|
|
14
|
+
*/
|
|
15
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
16
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
4
17
|
import { tmpdir } from "node:os";
|
|
5
18
|
import { join } from "node:path";
|
|
6
19
|
|
|
@@ -16,7 +29,60 @@ if (!/^\d+$/.test(port) || Number(port) < 1 || Number(port) > 65535) {
|
|
|
16
29
|
// supplied live server through LTCAI_TEST_BASE_URL.
|
|
17
30
|
const baseUrl = `http://${host}:${port}`;
|
|
18
31
|
const venvPython = join(process.cwd(), ".venv", "bin", "python");
|
|
19
|
-
const
|
|
32
|
+
const requestedPython = process.env.PYTHON || (existsSync(venvPython) ? venvPython : "python3");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The interpreter, as an absolute path.
|
|
36
|
+
*
|
|
37
|
+
* `LTCAI_PYTHON` is handed to `lattice-host`, which spawns the worker with a
|
|
38
|
+
* `PATH` **prefixed** by `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`
|
|
39
|
+
* (supervisor/worker_env.rs — GUI processes inherit a minimal PATH). A bare
|
|
40
|
+
* name like `python3` is therefore looked up against a different PATH than the
|
|
41
|
+
* one this runner validated it on: on GitHub Actions the interpreter that
|
|
42
|
+
* `pip install -e "."` populated lives under /opt/hostedtoolcache, but the
|
|
43
|
+
* child finds /usr/bin/python3 first and dies with "No module named uvicorn"
|
|
44
|
+
* — the worker exit 1 that turned every proxied route into a 502. Resolving to
|
|
45
|
+
* `sys.executable` means the interpreter cannot change identity when it
|
|
46
|
+
* crosses the process boundary.
|
|
47
|
+
*/
|
|
48
|
+
function resolveInterpreter(candidate) {
|
|
49
|
+
const probe = spawnSync(candidate, ["-c", "import sys; print(sys.executable)"], {
|
|
50
|
+
encoding: "utf8",
|
|
51
|
+
});
|
|
52
|
+
const resolved = probe.status === 0 ? String(probe.stdout || "").trim() : "";
|
|
53
|
+
// An unresolvable candidate is passed through untouched so the supervisor
|
|
54
|
+
// reports the failure in its own words rather than this helper's.
|
|
55
|
+
return resolved && existsSync(resolved) ? resolved : candidate;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const python = resolveInterpreter(requestedPython);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The `lattice-host` binary this run should exercise.
|
|
62
|
+
*
|
|
63
|
+
* An explicit pin wins (same names bin/ltcai.js accepts). Otherwise the
|
|
64
|
+
* current tree is built: a stale `rust/target/release/lattice-host` left over
|
|
65
|
+
* from an older version would otherwise be tested instead of this checkout.
|
|
66
|
+
* `cargo build` is a no-op when the tree is already built.
|
|
67
|
+
*/
|
|
68
|
+
function resolveHostBinary() {
|
|
69
|
+
const pinned = process.env.LATTICEAI_HOST_BIN || process.env.LTCAI_HOST;
|
|
70
|
+
if (pinned) {
|
|
71
|
+
if (!existsSync(pinned)) throw new Error(`lattice-host not found at ${pinned}`);
|
|
72
|
+
return pinned;
|
|
73
|
+
}
|
|
74
|
+
const built = join(process.cwd(), "rust", "target", "debug", "lattice-host");
|
|
75
|
+
if (process.env.LTCAI_SKIP_HOST_BUILD !== "1") {
|
|
76
|
+
console.log("[integration] cargo build -p lattice-host");
|
|
77
|
+
const build = spawnSync("cargo", ["build", "-p", "lattice-host"], {
|
|
78
|
+
stdio: "inherit",
|
|
79
|
+
cwd: join(process.cwd(), "rust"),
|
|
80
|
+
});
|
|
81
|
+
if (build.status !== 0) throw new Error("cargo build -p lattice-host failed");
|
|
82
|
+
}
|
|
83
|
+
if (!existsSync(built)) throw new Error(`lattice-host missing: ${built}`);
|
|
84
|
+
return built;
|
|
85
|
+
}
|
|
20
86
|
|
|
21
87
|
// Integration tests must never discover or mutate the developer's real HOME,
|
|
22
88
|
// ~/.ltcai, Brain vault, or agent workspace. Keep every user-state path under
|
|
@@ -52,6 +118,9 @@ const isolatedEnv = {
|
|
|
52
118
|
LATTICEAI_BRAIN_DIR: sandbox.brain,
|
|
53
119
|
LATTICEAI_AGENT_ROOT: sandbox.agent,
|
|
54
120
|
LATTICEAI_OBSIDIAN_VAULT_DIR: sandbox.vault,
|
|
121
|
+
// The supervisor resolves the worker interpreter itself; naming it keeps
|
|
122
|
+
// the choice the same one this runner made (repo .venv, else python3).
|
|
123
|
+
LTCAI_PYTHON: python,
|
|
55
124
|
LATTICEAI_STORAGE_ENGINE: "sqlite",
|
|
56
125
|
LATTICEAI_POSTGRES_DSN: "",
|
|
57
126
|
LATTICEAI_REQUIRE_AUTH: "false",
|
|
@@ -74,6 +143,32 @@ function cleanupSandbox() {
|
|
|
74
143
|
}
|
|
75
144
|
process.once("exit", cleanupSandbox);
|
|
76
145
|
|
|
146
|
+
/**
|
|
147
|
+
* The supervised worker's own stdout/stderr.
|
|
148
|
+
*
|
|
149
|
+
* `lattice-host` redirects them into `$HOME/.ltcai/desktop-sidecar.log` and
|
|
150
|
+
* `.err.log` (supervisor/worker_env.rs), and this runner rewrites HOME into a
|
|
151
|
+
* sandbox it deletes on the way out — so a worker that dies takes the only
|
|
152
|
+
* explanation with it and CI shows nothing but a 502. Print the tail before
|
|
153
|
+
* cleanup: those lines are the difference between "the gateway returned 502"
|
|
154
|
+
* and "that interpreter has no uvicorn".
|
|
155
|
+
*/
|
|
156
|
+
function dumpWorkerLogs() {
|
|
157
|
+
for (const name of ["desktop-sidecar.err.log", "desktop-sidecar.log"]) {
|
|
158
|
+
const path = join(sandbox.home, ".ltcai", name);
|
|
159
|
+
if (!existsSync(path)) {
|
|
160
|
+
console.error(`[integration] ${name}: not written`);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const lines = readFileSync(path, "utf8").replace(/\n+$/, "").split("\n");
|
|
164
|
+
const tail = lines.slice(-80);
|
|
165
|
+
console.error(
|
|
166
|
+
`[integration] ---- ${name} (last ${tail.length} of ${lines.length} lines) ----`,
|
|
167
|
+
);
|
|
168
|
+
console.error(tail.join("\n") || "(empty)");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
77
172
|
function run(command, args, options = {}) {
|
|
78
173
|
return new Promise((resolve, reject) => {
|
|
79
174
|
const child = spawn(command, args, {
|
|
@@ -90,7 +185,10 @@ function delay(ms) {
|
|
|
90
185
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
91
186
|
}
|
|
92
187
|
|
|
93
|
-
|
|
188
|
+
// 120 s, not 30: the gate now covers two boots — this process binds the
|
|
189
|
+
// gateway immediately, but /health is proxied and only answers once the
|
|
190
|
+
// supervised Python worker has imported and bound its own port.
|
|
191
|
+
async function waitForHealth(url, timeoutMs = 120000) {
|
|
94
192
|
const deadline = Date.now() + timeoutMs;
|
|
95
193
|
let lastError = "";
|
|
96
194
|
while (Date.now() < deadline) {
|
|
@@ -123,31 +221,38 @@ function stop(child) {
|
|
|
123
221
|
});
|
|
124
222
|
}
|
|
125
223
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
[
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
224
|
+
async function main() {
|
|
225
|
+
console.log(`[integration] sandbox ${sandboxRoot}`);
|
|
226
|
+
console.log(`[integration] worker interpreter ${python}`);
|
|
227
|
+
const hostBinary = resolveHostBinary();
|
|
228
|
+
console.log(`[integration] starting ${hostBinary} at ${baseUrl}`);
|
|
229
|
+
// The shipped topology: lattice-host serves the product on `port` and
|
|
230
|
+
// supervises the Python worker on a free port behind it. Do not
|
|
231
|
+
// double-append /health — the wait helper already probes `${url}/health`,
|
|
232
|
+
// which the gateway proxies to the worker, so a 200 there means both
|
|
233
|
+
// processes are up.
|
|
234
|
+
const server = spawn(
|
|
235
|
+
hostBinary,
|
|
236
|
+
["--port", port],
|
|
237
|
+
{ stdio: "inherit", env: isolatedEnv, cwd: process.cwd() },
|
|
238
|
+
);
|
|
135
239
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
240
|
+
let exitCode = 1;
|
|
241
|
+
try {
|
|
242
|
+
await waitForHealth(baseUrl);
|
|
243
|
+
console.log("[integration] front door healthy — running pytest");
|
|
244
|
+
const result = await run(python, ["-m", "pytest", "tests/integration/", "-v"], {
|
|
245
|
+
env: { LTCAI_TEST_BASE_URL: baseUrl },
|
|
246
|
+
});
|
|
247
|
+
exitCode = result.code || 0;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.error(String(error?.message || error));
|
|
250
|
+
} finally {
|
|
251
|
+
if (exitCode !== 0) dumpWorkerLogs();
|
|
252
|
+
await stop(server);
|
|
253
|
+
cleanupSandbox();
|
|
254
|
+
}
|
|
255
|
+
process.exit(exitCode);
|
|
151
256
|
}
|
|
152
257
|
|
|
153
|
-
|
|
258
|
+
main();
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Start an isolated Lattice
|
|
3
|
+
* Start an isolated Lattice product server and run Playwright first-value E2E
|
|
4
4
|
* against it (Wave 3.2 residual / v9.9.5).
|
|
5
5
|
*
|
|
6
|
+
* v11.6.0 "One Door": the front door is `lattice-host`, which supervises the
|
|
7
|
+
* Python AI worker (`latticeai.worker_app`) on an internal port behind it.
|
|
8
|
+
* This runner used to start `uvicorn server:app` — a root `server.py` the
|
|
9
|
+
* release deleted — so it now boots the same binary the product ships.
|
|
10
|
+
*
|
|
6
11
|
* Mirrors scripts/run_integration_tests.mjs isolation rules: never touch
|
|
7
12
|
* the developer's real HOME / ~/.ltcai / Brain vault.
|
|
8
13
|
*/
|
|
9
|
-
import { spawn } from "node:child_process";
|
|
10
|
-
import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
14
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
15
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
11
16
|
import { tmpdir } from "node:os";
|
|
12
17
|
import { join } from "node:path";
|
|
13
18
|
|
|
@@ -21,7 +26,60 @@ if (!/^\d+$/.test(port) || Number(port) < 1 || Number(port) > 65535) {
|
|
|
21
26
|
}
|
|
22
27
|
const baseUrl = `http://${host}:${port}`;
|
|
23
28
|
const venvPython = join(process.cwd(), ".venv", "bin", "python");
|
|
24
|
-
const
|
|
29
|
+
const requestedPython = process.env.PYTHON || (existsSync(venvPython) ? venvPython : "python3");
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The interpreter, as an absolute path.
|
|
33
|
+
*
|
|
34
|
+
* `LTCAI_PYTHON` is handed to `lattice-host`, which spawns the worker with a
|
|
35
|
+
* `PATH` **prefixed** by `/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`
|
|
36
|
+
* (supervisor/worker_env.rs — GUI processes inherit a minimal PATH). A bare
|
|
37
|
+
* name like `python3` is therefore looked up against a different PATH than the
|
|
38
|
+
* one this runner validated it on: on GitHub Actions the interpreter that
|
|
39
|
+
* `pip install -e "."` populated lives under /opt/hostedtoolcache, but the
|
|
40
|
+
* child finds /usr/bin/python3 first and dies with "No module named uvicorn"
|
|
41
|
+
* — the worker exit 1 that turned every proxied route into a 502. Resolving to
|
|
42
|
+
* `sys.executable` means the interpreter cannot change identity when it
|
|
43
|
+
* crosses the process boundary.
|
|
44
|
+
*/
|
|
45
|
+
function resolveInterpreter(candidate) {
|
|
46
|
+
const probe = spawnSync(candidate, ["-c", "import sys; print(sys.executable)"], {
|
|
47
|
+
encoding: "utf8",
|
|
48
|
+
});
|
|
49
|
+
const resolved = probe.status === 0 ? String(probe.stdout || "").trim() : "";
|
|
50
|
+
// An unresolvable candidate is passed through untouched so the supervisor
|
|
51
|
+
// reports the failure in its own words rather than this helper's.
|
|
52
|
+
return resolved && existsSync(resolved) ? resolved : candidate;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const python = resolveInterpreter(requestedPython);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The `lattice-host` binary this run should exercise.
|
|
59
|
+
*
|
|
60
|
+
* An explicit pin wins (same names bin/ltcai.js accepts). Otherwise the
|
|
61
|
+
* current tree is built: a stale `rust/target/release/lattice-host` left over
|
|
62
|
+
* from an older version would otherwise be tested instead of this checkout.
|
|
63
|
+
* `cargo build` is a no-op when the tree is already built.
|
|
64
|
+
*/
|
|
65
|
+
function resolveHostBinary() {
|
|
66
|
+
const pinned = process.env.LATTICEAI_HOST_BIN || process.env.LTCAI_HOST;
|
|
67
|
+
if (pinned) {
|
|
68
|
+
if (!existsSync(pinned)) throw new Error(`lattice-host not found at ${pinned}`);
|
|
69
|
+
return pinned;
|
|
70
|
+
}
|
|
71
|
+
const built = join(process.cwd(), "rust", "target", "debug", "lattice-host");
|
|
72
|
+
if (process.env.LTCAI_SKIP_HOST_BUILD !== "1") {
|
|
73
|
+
console.log("[e2e] cargo build -p lattice-host");
|
|
74
|
+
const build = spawnSync("cargo", ["build", "-p", "lattice-host"], {
|
|
75
|
+
stdio: "inherit",
|
|
76
|
+
cwd: join(process.cwd(), "rust"),
|
|
77
|
+
});
|
|
78
|
+
if (build.status !== 0) throw new Error("cargo build -p lattice-host failed");
|
|
79
|
+
}
|
|
80
|
+
if (!existsSync(built)) throw new Error(`lattice-host missing: ${built}`);
|
|
81
|
+
return built;
|
|
82
|
+
}
|
|
25
83
|
|
|
26
84
|
const sandboxRoot = mkdtempSync(join(tmpdir(), "ltcai-e2e-"));
|
|
27
85
|
const sandbox = {
|
|
@@ -53,6 +111,9 @@ const isolatedEnv = {
|
|
|
53
111
|
LATTICEAI_BRAIN_DIR: sandbox.brain,
|
|
54
112
|
LATTICEAI_AGENT_ROOT: sandbox.agent,
|
|
55
113
|
LATTICEAI_OBSIDIAN_VAULT_DIR: sandbox.vault,
|
|
114
|
+
// The supervisor resolves the worker interpreter itself; naming it keeps
|
|
115
|
+
// the choice the same one this runner made (repo .venv, else python3).
|
|
116
|
+
LTCAI_PYTHON: python,
|
|
56
117
|
LATTICEAI_STORAGE_ENGINE: "sqlite",
|
|
57
118
|
LATTICEAI_POSTGRES_DSN: "",
|
|
58
119
|
LATTICEAI_REQUIRE_AUTH: "false",
|
|
@@ -76,11 +137,38 @@ function cleanupSandbox() {
|
|
|
76
137
|
}
|
|
77
138
|
process.once("exit", cleanupSandbox);
|
|
78
139
|
|
|
140
|
+
/**
|
|
141
|
+
* The supervised worker's own stdout/stderr.
|
|
142
|
+
*
|
|
143
|
+
* `lattice-host` redirects them into `$HOME/.ltcai/desktop-sidecar.log` and
|
|
144
|
+
* `.err.log` (supervisor/worker_env.rs), and this runner rewrites HOME into a
|
|
145
|
+
* sandbox it deletes on the way out — so a worker that dies takes the only
|
|
146
|
+
* explanation with it and CI shows nothing but a 502. Print the tail before
|
|
147
|
+
* cleanup: those lines are the difference between "the gateway returned 502"
|
|
148
|
+
* and "that interpreter has no uvicorn".
|
|
149
|
+
*/
|
|
150
|
+
function dumpWorkerLogs() {
|
|
151
|
+
for (const name of ["desktop-sidecar.err.log", "desktop-sidecar.log"]) {
|
|
152
|
+
const path = join(sandbox.home, ".ltcai", name);
|
|
153
|
+
if (!existsSync(path)) {
|
|
154
|
+
console.error(`[e2e] ${name}: not written`);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const lines = readFileSync(path, "utf8").replace(/\n+$/, "").split("\n");
|
|
158
|
+
const tail = lines.slice(-80);
|
|
159
|
+
console.error(`[e2e] ---- ${name} (last ${tail.length} of ${lines.length} lines) ----`);
|
|
160
|
+
console.error(tail.join("\n") || "(empty)");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
79
164
|
function delay(ms) {
|
|
80
165
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
81
166
|
}
|
|
82
167
|
|
|
83
|
-
|
|
168
|
+
// 120 s, not 60: the gate now covers two boots — this process binds the
|
|
169
|
+
// gateway immediately, but /health is proxied and only answers once the
|
|
170
|
+
// supervised Python worker has imported and bound its own port.
|
|
171
|
+
async function waitForHealth(url, timeoutMs = 120000) {
|
|
84
172
|
const deadline = Date.now() + timeoutMs;
|
|
85
173
|
let lastError = "";
|
|
86
174
|
while (Date.now() < deadline) {
|
|
@@ -115,13 +203,17 @@ function stop(child) {
|
|
|
115
203
|
|
|
116
204
|
async function main() {
|
|
117
205
|
console.log(`[e2e] sandbox ${sandboxRoot}`);
|
|
118
|
-
console.log(`[e2e]
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
//
|
|
206
|
+
console.log(`[e2e] worker interpreter ${python}`);
|
|
207
|
+
const hostBinary = resolveHostBinary();
|
|
208
|
+
console.log(`[e2e] starting ${hostBinary} at ${baseUrl}`);
|
|
209
|
+
// The shipped topology: lattice-host serves the product on `port` and
|
|
210
|
+
// supervises the Python worker on a free port behind it. Do not
|
|
211
|
+
// double-append /health — the wait helper already probes `${url}/health`,
|
|
212
|
+
// which the gateway proxies to the worker, so a 200 there means both
|
|
213
|
+
// processes are up.
|
|
122
214
|
const server = spawn(
|
|
123
|
-
|
|
124
|
-
["
|
|
215
|
+
hostBinary,
|
|
216
|
+
["--port", port],
|
|
125
217
|
{ stdio: "inherit", env: isolatedEnv, cwd: process.cwd() },
|
|
126
218
|
);
|
|
127
219
|
|
|
@@ -150,6 +242,7 @@ async function main() {
|
|
|
150
242
|
console.error("[e2e] failed:", error);
|
|
151
243
|
exitCode = 1;
|
|
152
244
|
} finally {
|
|
245
|
+
if (exitCode !== 0) dumpWorkerLogs();
|
|
153
246
|
await stop(server);
|
|
154
247
|
cleanupSandbox();
|
|
155
248
|
}
|
package/scripts/wheel_smoke.py
CHANGED
|
@@ -8,6 +8,10 @@ class of "works only with ``pip install -e .`` from the repo root" failures
|
|
|
8
8
|
(e.g. the v3.x wheels that omitted the root ``setup.py`` wizard module while
|
|
9
9
|
``latticeai.server_app`` imported it).
|
|
10
10
|
|
|
11
|
+
v11.6.0: the app it boots is the AI-Worker (``create_worker_app``), because
|
|
12
|
+
that is the only application this package builds — the product server is the
|
|
13
|
+
``lattice-host`` binary.
|
|
14
|
+
|
|
11
15
|
Usage:
|
|
12
16
|
python scripts/wheel_smoke.py # build + install + import + /health
|
|
13
17
|
python scripts/wheel_smoke.py --wheel dist/ltcai-X.Y.Z-py3-none-any.whl
|
|
@@ -30,39 +34,45 @@ from pathlib import Path
|
|
|
30
34
|
|
|
31
35
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
32
36
|
|
|
33
|
-
# Every importable module the wheel ships (
|
|
37
|
+
# Every importable module the wheel ships. v11.6.0 (WP-P1) reduced the package
|
|
38
|
+
# to the AI-Worker: the product application, the graph store, the agent loop,
|
|
39
|
+
# the telegram bridge and the setup wizard are `lattice-host`'s now, so the
|
|
40
|
+
# names below are the compute surface plus the two entrypoints a bundle starts.
|
|
34
41
|
WHEEL_MODULES = [
|
|
35
42
|
"lattice_brain",
|
|
36
|
-
"lattice_brain.
|
|
37
|
-
"lattice_brain.graph.
|
|
38
|
-
"lattice_brain.runtime",
|
|
39
|
-
"lattice_brain.runtime.agent_runtime",
|
|
40
|
-
"lattice_brain.storage",
|
|
41
|
-
"lattice_brain.archive",
|
|
43
|
+
"lattice_brain.embeddings",
|
|
44
|
+
"lattice_brain.graph._kg_common",
|
|
42
45
|
"lattice_brain.ingestion",
|
|
43
|
-
"lattice_brain.
|
|
44
|
-
"lattice_brain.
|
|
46
|
+
"lattice_brain.multimodal",
|
|
47
|
+
"lattice_brain.runtime",
|
|
45
48
|
"latticeai",
|
|
46
|
-
"latticeai.server_app",
|
|
47
49
|
"latticeai.app_factory",
|
|
50
|
+
"latticeai.worker_app",
|
|
48
51
|
"latticeai.cli.entrypoint",
|
|
49
|
-
"latticeai.
|
|
50
|
-
"latticeai.
|
|
52
|
+
"latticeai.api.worker_compute",
|
|
53
|
+
"latticeai.api.worker_seams",
|
|
51
54
|
"latticeai.models.router",
|
|
52
|
-
"latticeai.
|
|
53
|
-
"latticeai.
|
|
55
|
+
"latticeai.runtime.build_phases.worker_profile",
|
|
56
|
+
"latticeai.services.model_runtime",
|
|
54
57
|
"latticeai.services.p_reinforce",
|
|
55
58
|
"latticeai.tools",
|
|
56
59
|
"latticeai.tools.knowledge",
|
|
57
|
-
"latticeai.setup.auto_setup",
|
|
58
|
-
"latticeai.setup.wizard",
|
|
59
|
-
"latticeai.services.local_knowledge",
|
|
60
|
-
"lattice_brain.graph.schema",
|
|
61
|
-
"server",
|
|
62
60
|
]
|
|
63
61
|
|
|
64
|
-
# Root shims removed in 9.9.1
|
|
62
|
+
# Root shims removed in 9.9.1, plus the product modules WP-P1 deleted: the
|
|
63
|
+
# wheel must NOT ship any of them. ``server`` and ``latticeai.server_app`` are
|
|
64
|
+
# on this list for the same reason the shims are — a bundle that still imports
|
|
65
|
+
# them is a bundle running an application that no longer exists.
|
|
65
66
|
REMOVED_ROOT_MODULES = [
|
|
67
|
+
"server",
|
|
68
|
+
"latticeai.server_app",
|
|
69
|
+
"latticeai.api.chat",
|
|
70
|
+
"latticeai.core.agent",
|
|
71
|
+
"latticeai.integrations.telegram_bot",
|
|
72
|
+
"latticeai.setup.wizard",
|
|
73
|
+
"lattice_brain.graph.store",
|
|
74
|
+
"lattice_brain.storage",
|
|
75
|
+
"lattice_brain.workflow",
|
|
66
76
|
"ltcai_cli",
|
|
67
77
|
"auto_setup",
|
|
68
78
|
"setup_wizard",
|
|
@@ -96,9 +106,9 @@ else:
|
|
|
96
106
|
|
|
97
107
|
HEALTH_CHECK = """
|
|
98
108
|
from fastapi.testclient import TestClient
|
|
99
|
-
from latticeai.
|
|
109
|
+
from latticeai.worker_app import create_worker_app
|
|
100
110
|
|
|
101
|
-
app =
|
|
111
|
+
app = create_worker_app()
|
|
102
112
|
response = TestClient(app).get("/health")
|
|
103
113
|
assert response.status_code == 200, f"/health returned {response.status_code}"
|
|
104
114
|
payload = response.json()
|