ltcai 11.5.2 → 11.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -148
- package/bin/ltcai.js +234 -24
- package/docs/CHANGELOG.md +119 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +8 -6
- package/docs/ENTERPRISE.md +2 -1
- package/docs/MULTI_AGENT_RUNTIME.md +12 -5
- package/docs/ONBOARDING.md +1 -1
- package/docs/OPERATIONS.md +6 -3
- package/docs/REALTIME_COLLABORATION.md +1 -1
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +1 -1
- package/docs/WORKFLOW_DESIGNER.md +3 -2
- package/docs/kg-schema.md +1 -1
- package/docs/v11.6.0_ONE_DOOR_PLAN.md +170 -0
- package/lattice_brain/__init__.py +42 -79
- package/lattice_brain/graph/__init__.py +9 -24
- package/lattice_brain/graph/_kg_common/__init__.py +13 -24
- package/lattice_brain/ingestion/__init__.py +19 -58
- package/lattice_brain/ingestion/pipeline.py +20 -398
- package/lattice_brain/multimodal/__init__.py +7 -18
- package/lattice_brain/multimodal/images.py +6 -264
- package/lattice_brain/multimodal/video.py +8 -247
- package/lattice_brain/runtime/__init__.py +8 -79
- package/lattice_brain/runtime/hooks.py +22 -584
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agent_worker_seam.py +7 -80
- package/latticeai/api/health.py +6 -20
- package/latticeai/api/local_files.py +16 -613
- package/latticeai/api/models.py +12 -87
- package/latticeai/api/search.py +17 -255
- package/latticeai/api/tools.py +69 -750
- package/latticeai/api/voice_capture.py +8 -70
- package/latticeai/api/worker_compute.py +842 -0
- package/latticeai/api/worker_seams.py +216 -0
- package/latticeai/app_factory.py +23 -232
- package/latticeai/cli/entrypoint.py +36 -249
- package/latticeai/core/agent_permission.py +16 -91
- package/latticeai/core/messages.py +89 -531
- package/latticeai/runtime/access_runtime.py +0 -14
- package/latticeai/runtime/bootstrap.py +10 -21
- package/latticeai/runtime/brain_runtime.py +35 -43
- package/latticeai/runtime/build_phases/__init__.py +21 -37
- package/latticeai/runtime/build_phases/features.py +99 -389
- package/latticeai/runtime/build_phases/foundation.py +82 -392
- package/latticeai/runtime/build_phases/web.py +91 -408
- package/latticeai/runtime/build_phases/worker_profile.py +244 -0
- package/latticeai/runtime/lifespan_runtime.py +7 -16
- package/latticeai/runtime/platform_services_runtime.py +1 -15
- package/latticeai/runtime/runtime_context.py +13 -130
- package/latticeai/runtime/security_runtime.py +10 -103
- package/latticeai/services/architecture_readiness.py +82 -43
- package/latticeai/services/model_runtime/__init__.py +2 -11
- package/latticeai/services/model_runtime/service.py +4 -28
- package/latticeai/services/p_reinforce.py +10 -261
- package/latticeai/services/product_readiness.py +31 -38
- package/latticeai/services/search_service.py +37 -795
- package/latticeai/services/tool_dispatch.py +30 -386
- package/latticeai/services/voice_capture.py +13 -107
- package/latticeai/tools/__init__.py +22 -49
- package/latticeai/tools/commands.py +0 -163
- package/latticeai/tools/computer.py +0 -39
- package/latticeai/tools/documents.py +1 -134
- package/latticeai/tools/filesystem.py +1 -247
- package/latticeai/tools/knowledge.py +1 -52
- package/latticeai/tools/local_files.py +0 -20
- package/latticeai/worker_app.py +75 -0
- package/package.json +2 -3
- package/requirements.txt +0 -5
- package/scripts/agent_eval.py +16 -28
- package/scripts/brain_quality_eval.py +20 -183
- package/scripts/bump_version.py +5 -5
- package/scripts/check_current_release_docs.mjs +7 -4
- package/scripts/check_openapi_drift.mjs +10 -0
- package/scripts/check_server_i18n.mjs +2 -18
- package/scripts/compose_openapi.py +377 -0
- package/scripts/export_openapi.py +32 -4
- package/scripts/gen_messages_catalog_fixture.py +302 -0
- package/scripts/gen_openapi_fragments.py +365 -0
- package/scripts/gen_redact_fixture.py +196 -0
- package/scripts/gen_worker_allowlist_fixture.py +115 -0
- package/scripts/generate_agent_parity_fixtures.py +33 -14
- package/scripts/openapi_route_families.json +2161 -0
- package/scripts/release_screen_claims.json +54 -0
- package/scripts/run_integration_tests.mjs +134 -29
- package/scripts/run_sidecar_e2e.mjs +104 -11
- package/scripts/wheel_smoke.py +32 -22
- package/src-tauri/Cargo.lock +375 -9
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/backend.rs +151 -45
- package/src-tauri/src/main.rs +18 -18
- package/src-tauri/src/topology.rs +58 -88
- package/src-tauri/tauri.conf.json +1 -2
- package/static/app/asset-manifest.json +41 -41
- package/static/app/assets/{Act-DcQizkl1.js → Act-BPcVAbOL.js} +1 -1
- package/static/app/assets/AdminConsole-Bw1ATQL0.js +1 -0
- package/static/app/assets/{Brain-3VCSHFcn.js → Brain-CT92Kos0.js} +2 -2
- package/static/app/assets/{BrainHome-Qm8eaztx.js → BrainHome-CFBkt1K_.js} +1 -1
- package/static/app/assets/{BrainSignals-DS9BtKOW.js → BrainSignals-ReLWF2H8.js} +1 -1
- package/static/app/assets/Capture-BsTokYkk.js +1 -0
- package/static/app/assets/{Chronicle-BGvuAchH.js → Chronicle-B6f0T9id.js} +1 -1
- package/static/app/assets/{CommandPalette-Bqhm0Urn.js → CommandPalette-CuvjTv1u.js} +1 -1
- package/static/app/assets/{Library-BV6NnF0a.js → Library-BGJbG9Hd.js} +1 -1
- package/static/app/assets/{LivingBrain-GzenJchP.js → LivingBrain-DGYK_Jsa.js} +1 -1
- package/static/app/assets/{ProductFlow-DEP6-vML.js → ProductFlow-DXBC6brE.js} +1 -1
- package/static/app/assets/{ReviewCard-CNZ7XjWG.js → ReviewCard-HXRle3qq.js} +2 -2
- package/static/app/assets/System-CMHSO9qM.js +1 -0
- package/static/app/assets/arrow-left-BfmkskWx.js +1 -0
- package/static/app/assets/{bot-B_K1Tdmw.js → bot-Cn8bWRuq.js} +1 -1
- package/static/app/assets/{brain-DWyaV1L1.js → brain-CQJberbE.js} +1 -1
- package/static/app/assets/{button-aTn4s84A.js → button-Ct9f2_oT.js} +1 -1
- package/static/app/assets/circle-check-DruOxB-4.js +1 -0
- package/static/app/assets/{circle-pause-xKgeGXkT.js → circle-pause-CmzC_apg.js} +1 -1
- package/static/app/assets/{circle-play-DkT6tYPX.js → circle-play-D8mW2aQ7.js} +1 -1
- package/static/app/assets/{cpu-85xYObUC.js → cpu-DZcdd0PZ.js} +1 -1
- package/static/app/assets/{download-B5Fm7YXo.js → download-bv1KEPGQ.js} +1 -1
- package/static/app/assets/{folder-open-kk2Xa52u.js → folder-open-d-Pip5gr.js} +1 -1
- package/static/app/assets/{hard-drive-DkA3zBW_.js → hard-drive-D20iavUb.js} +1 -1
- package/static/app/assets/index-D9x-kSNy.css +2 -0
- package/static/app/assets/{index-BMPdTmlY.js → index-Do83hDzJ.js} +3 -3
- package/static/app/assets/{input-B0nRf2jO.js → input-BLXVNmj1.js} +1 -1
- package/static/app/assets/{link-2-Dwb4gnTc.js → link-2-BPJOFlAy.js} +1 -1
- package/static/app/assets/{permissionCopy-CQDUBrOZ.js → permissionCopy-ChdJd493.js} +1 -1
- package/static/app/assets/primitives-Cv5tbZBY.js +1 -0
- package/static/app/assets/search-CT9aho2j.js +1 -0
- package/static/app/assets/{share-2-BsrxFglO.js → share-2-YNX_NtMU.js} +1 -1
- package/static/app/assets/{shield-alert-5BStfp2_.js → shield-alert-DuQ3zrVL.js} +1 -1
- package/static/app/assets/{textarea-Cg8IUA-k.js → textarea-DqwLnli4.js} +1 -1
- package/static/app/assets/{useFocusTrap-CYKvE46M.js → useFocusTrap-ZVI98jaW.js} +1 -1
- package/static/app/assets/{useMutation-CSn9t1op.js → useMutation-CVC4qv_D.js} +1 -1
- package/static/app/assets/{useQuery-CY2OI2uy.js → useQuery-C7BeG4HU.js} +1 -1
- package/static/app/assets/{utils-Ddol2RWD.js → utils-CiFtIdZq.js} +1 -1
- package/static/app/assets/{workspace-BqDwOz_p.js → workspace-DQz9vIId.js} +1 -1
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/lattice_brain/archive.py +0 -522
- package/lattice_brain/context.py +0 -325
- package/lattice_brain/conversations.py +0 -382
- package/lattice_brain/core.py +0 -82
- package/lattice_brain/graph/_kg_contract.py +0 -249
- package/lattice_brain/graph/curator.py +0 -676
- package/lattice_brain/graph/discovery.py +0 -595
- package/lattice_brain/graph/discovery_index/__init__.py +0 -35
- package/lattice_brain/graph/discovery_index/cleanup.py +0 -182
- package/lattice_brain/graph/discovery_index/extract.py +0 -137
- package/lattice_brain/graph/discovery_index/scan.py +0 -411
- package/lattice_brain/graph/discovery_index/upsert.py +0 -495
- package/lattice_brain/graph/documents.py +0 -380
- package/lattice_brain/graph/fusion.py +0 -395
- package/lattice_brain/graph/identity.py +0 -175
- package/lattice_brain/graph/image_vectors.py +0 -230
- package/lattice_brain/graph/ingest.py +0 -829
- package/lattice_brain/graph/network.py +0 -205
- package/lattice_brain/graph/proactive.py +0 -724
- package/lattice_brain/graph/projection/__init__.py +0 -42
- package/lattice_brain/graph/projection/curation.py +0 -500
- package/lattice_brain/graph/projection/v2_schema.py +0 -518
- package/lattice_brain/graph/provenance.py +0 -524
- package/lattice_brain/graph/rerank.py +0 -163
- package/lattice_brain/graph/retrieval/__init__.py +0 -54
- package/lattice_brain/graph/retrieval/context.py +0 -197
- package/lattice_brain/graph/retrieval/graph_view.py +0 -319
- package/lattice_brain/graph/retrieval/hybrid.py +0 -488
- package/lattice_brain/graph/retrieval/maintenance.py +0 -121
- package/lattice_brain/graph/retrieval/signals.py +0 -95
- package/lattice_brain/graph/retrieval_docgen.py +0 -253
- package/lattice_brain/graph/retrieval_policy.py +0 -180
- package/lattice_brain/graph/retrieval_reads.py +0 -769
- package/lattice_brain/graph/retrieval_vector/__init__.py +0 -42
- package/lattice_brain/graph/retrieval_vector/fingerprint.py +0 -97
- package/lattice_brain/graph/retrieval_vector/indexing.py +0 -347
- package/lattice_brain/graph/retrieval_vector/search.py +0 -560
- package/lattice_brain/graph/retrieval_vector/status.py +0 -374
- package/lattice_brain/graph/schema.py +0 -792
- package/lattice_brain/graph/store.py +0 -268
- package/lattice_brain/graph/vector_index/__init__.py +0 -85
- package/lattice_brain/graph/vector_index/base.py +0 -167
- package/lattice_brain/graph/vector_index/brute_force.py +0 -110
- package/lattice_brain/graph/vector_index/hnsw.py +0 -290
- package/lattice_brain/graph/vector_index/jobs.py +0 -287
- package/lattice_brain/graph/vector_index/quantized.py +0 -148
- package/lattice_brain/graph/vector_index/selector.py +0 -161
- package/lattice_brain/graph/write_master.py +0 -308
- package/lattice_brain/ingestion/_contract.py +0 -90
- package/lattice_brain/ingestion/folder_scan.py +0 -57
- package/lattice_brain/ingestion/folders.py +0 -258
- package/lattice_brain/ingestion/jobs_api.py +0 -107
- package/lattice_brain/ingestion/routing.py +0 -295
- package/lattice_brain/ingestion_jobs.py +0 -380
- package/lattice_brain/memory.py +0 -75
- package/lattice_brain/portability/__init__.py +0 -90
- package/lattice_brain/portability/_contract.py +0 -42
- package/lattice_brain/portability/backups.py +0 -338
- package/lattice_brain/portability/bundles.py +0 -136
- package/lattice_brain/portability/constants.py +0 -93
- package/lattice_brain/portability/fsops.py +0 -138
- package/lattice_brain/portability/service.py +0 -41
- package/lattice_brain/portability/sharing.py +0 -710
- package/lattice_brain/quality.py +0 -543
- package/lattice_brain/retrieval_benchmark_fixtures.py +0 -92
- package/lattice_brain/runtime/agent_runtime.py +0 -859
- package/lattice_brain/runtime/contracts.py +0 -460
- package/lattice_brain/runtime/multi_agent.py +0 -942
- package/lattice_brain/runtime/statuses.py +0 -10
- package/lattice_brain/sealed_box.py +0 -240
- package/lattice_brain/self_model.py +0 -675
- package/lattice_brain/sensitivity.py +0 -94
- package/lattice_brain/storage/__init__.py +0 -22
- package/lattice_brain/storage/base.py +0 -100
- package/lattice_brain/storage/docker.py +0 -105
- package/lattice_brain/storage/factory.py +0 -31
- package/lattice_brain/storage/migration.py +0 -191
- package/lattice_brain/storage/postgres.py +0 -123
- package/lattice_brain/storage/sqlite.py +0 -143
- package/lattice_brain/synthesis.py +0 -824
- package/lattice_brain/workflow.py +0 -497
- package/latticeai/api/admin.py +0 -471
- package/latticeai/api/agent_registry.py +0 -105
- package/latticeai/api/agents.py +0 -228
- package/latticeai/api/auth.py +0 -383
- package/latticeai/api/automation_intelligence.py +0 -401
- package/latticeai/api/brain_intelligence.py +0 -199
- package/latticeai/api/browser.py +0 -493
- package/latticeai/api/change_proposals.py +0 -89
- package/latticeai/api/chat.py +0 -572
- package/latticeai/api/chat_agent_http.py +0 -892
- package/latticeai/api/chat_contracts.py +0 -73
- package/latticeai/api/chat_documents.py +0 -276
- package/latticeai/api/chat_helpers.py +0 -460
- package/latticeai/api/chat_history.py +0 -101
- package/latticeai/api/chat_hybrid.py +0 -113
- package/latticeai/api/chat_intents.py +0 -646
- package/latticeai/api/chat_stream.py +0 -216
- package/latticeai/api/chronicle.py +0 -63
- package/latticeai/api/command_center.py +0 -51
- package/latticeai/api/computer_use.py +0 -474
- package/latticeai/api/evidence_actions.py +0 -48
- package/latticeai/api/features.py +0 -70
- package/latticeai/api/funnel_metrics.py +0 -31
- package/latticeai/api/garden.py +0 -34
- package/latticeai/api/hooks.py +0 -165
- package/latticeai/api/index_jobs.py +0 -145
- package/latticeai/api/invitations.py +0 -100
- package/latticeai/api/knowledge_graph.py +0 -536
- package/latticeai/api/marketplace.py +0 -105
- package/latticeai/api/mcp.py +0 -482
- package/latticeai/api/memory.py +0 -270
- package/latticeai/api/network.py +0 -81
- package/latticeai/api/network_boundary.py +0 -225
- package/latticeai/api/permission_mode.py +0 -61
- package/latticeai/api/permissions.py +0 -436
- package/latticeai/api/plugins.py +0 -126
- package/latticeai/api/portability.py +0 -391
- package/latticeai/api/project_sessions.py +0 -114
- package/latticeai/api/realtime.py +0 -118
- package/latticeai/api/review_queue.py +0 -364
- package/latticeai/api/security_dashboard.py +0 -604
- package/latticeai/api/setup.py +0 -319
- package/latticeai/api/static_routes.py +0 -354
- package/latticeai/api/ui_redirects.py +0 -26
- package/latticeai/api/workflow_designer.py +0 -394
- package/latticeai/api/workspace.py +0 -856
- package/latticeai/api/workspace_scope.py +0 -125
- package/latticeai/core/agent/__init__.py +0 -93
- package/latticeai/core/agent/_contract.py +0 -79
- package/latticeai/core/agent/context.py +0 -57
- package/latticeai/core/agent/deps.py +0 -125
- package/latticeai/core/agent/execution.py +0 -622
- package/latticeai/core/agent/planning.py +0 -145
- package/latticeai/core/agent/recovery.py +0 -157
- package/latticeai/core/agent/runtime.py +0 -210
- package/latticeai/core/agent/verification.py +0 -231
- package/latticeai/core/agent_eval.py +0 -739
- package/latticeai/core/agent_helpers.py +0 -493
- package/latticeai/core/agent_profiles.py +0 -110
- package/latticeai/core/agent_prompts.py +0 -171
- package/latticeai/core/agent_registry.py +0 -232
- package/latticeai/core/agent_state.py +0 -41
- package/latticeai/core/agent_trace.py +0 -104
- package/latticeai/core/artifact_ledger.py +0 -109
- package/latticeai/core/audit.py +0 -260
- package/latticeai/core/builtin_hooks.py +0 -105
- package/latticeai/core/context_builder.py +0 -394
- package/latticeai/core/document_generator.py +0 -103
- package/latticeai/core/enterprise.py +0 -154
- package/latticeai/core/enterprise_admin.py +0 -158
- package/latticeai/core/file_generation/__init__.py +0 -115
- package/latticeai/core/file_generation/bundles.py +0 -76
- package/latticeai/core/file_generation/extraction.py +0 -154
- package/latticeai/core/file_generation/inference.py +0 -235
- package/latticeai/core/file_generation/orchestration.py +0 -152
- package/latticeai/core/file_generation/prompting.py +0 -117
- package/latticeai/core/file_generation/repair.py +0 -114
- package/latticeai/core/file_generation/sanitize.py +0 -61
- package/latticeai/core/file_generation/validation.py +0 -201
- package/latticeai/core/invitations.py +0 -132
- package/latticeai/core/legacy_compatibility.py +0 -243
- package/latticeai/core/logging_safety.py +0 -46
- package/latticeai/core/marketplace.py +0 -293
- package/latticeai/core/mcp_catalog.py +0 -452
- package/latticeai/core/mcp_registry.py +0 -506
- package/latticeai/core/network_boundary.py +0 -168
- package/latticeai/core/oidc.py +0 -208
- package/latticeai/core/plugins.py +0 -432
- package/latticeai/core/product_hardening.py +0 -218
- package/latticeai/core/project_sessions.py +0 -337
- package/latticeai/core/realtime.py +0 -238
- package/latticeai/core/run_explain.py +0 -426
- package/latticeai/core/run_store.py +0 -252
- package/latticeai/core/timezones.py +0 -80
- package/latticeai/core/workspace_computer_memory.py +0 -84
- package/latticeai/core/workspace_graph_trace.py +0 -155
- package/latticeai/core/workspace_indexing.py +0 -102
- package/latticeai/core/workspace_memory.py +0 -77
- package/latticeai/core/workspace_onboarding.py +0 -104
- package/latticeai/core/workspace_os.py +0 -978
- package/latticeai/core/workspace_os_constants.py +0 -126
- package/latticeai/core/workspace_os_state.py +0 -180
- package/latticeai/core/workspace_os_utils.py +0 -103
- package/latticeai/core/workspace_permissions.py +0 -101
- package/latticeai/core/workspace_plugins.py +0 -97
- package/latticeai/core/workspace_relationships.py +0 -99
- package/latticeai/core/workspace_reorganization.py +0 -335
- package/latticeai/core/workspace_review_items.py +0 -112
- package/latticeai/core/workspace_runs.py +0 -726
- package/latticeai/core/workspace_skills.py +0 -109
- package/latticeai/core/workspace_snapshots.py +0 -198
- package/latticeai/core/workspace_timeline.py +0 -110
- package/latticeai/integrations/__init__.py +0 -0
- package/latticeai/integrations/telegram_bot/__init__.py +0 -123
- package/latticeai/integrations/telegram_bot/__main__.py +0 -17
- package/latticeai/integrations/telegram_bot/config.py +0 -86
- package/latticeai/integrations/telegram_bot/dispatch.py +0 -311
- package/latticeai/integrations/telegram_bot/flows.py +0 -478
- package/latticeai/integrations/telegram_bot/helpers.py +0 -322
- package/latticeai/integrations/telegram_bot/screens.py +0 -394
- package/latticeai/runtime/audit_runtime.py +0 -76
- package/latticeai/runtime/automation_runtime.py +0 -81
- package/latticeai/runtime/chat_wiring.py +0 -141
- package/latticeai/runtime/context_runtime.py +0 -66
- package/latticeai/runtime/feature_toggle_wiring.py +0 -157
- package/latticeai/runtime/history_runtime.py +0 -163
- package/latticeai/runtime/history_writer.py +0 -138
- package/latticeai/runtime/hooks_runtime.py +0 -77
- package/latticeai/runtime/model_wiring.py +0 -68
- package/latticeai/runtime/namespace_runtime.py +0 -163
- package/latticeai/runtime/network_boundary_wiring.py +0 -117
- package/latticeai/runtime/network_config_runtime.py +0 -56
- package/latticeai/runtime/permission_mode_wiring.py +0 -112
- package/latticeai/runtime/persistence_runtime.py +0 -159
- package/latticeai/runtime/platform_runtime_wiring.py +0 -89
- package/latticeai/runtime/review_wiring.py +0 -42
- package/latticeai/runtime/router_registration.py +0 -693
- package/latticeai/runtime/service_singletons.py +0 -55
- package/latticeai/runtime/sso_config_runtime.py +0 -128
- package/latticeai/runtime/user_key_runtime.py +0 -106
- package/latticeai/runtime/web_runtime.py +0 -92
- package/latticeai/server_app.py +0 -51
- package/latticeai/services/app_context.py +0 -130
- package/latticeai/services/automation_execution.py +0 -266
- package/latticeai/services/automation_intelligence.py +0 -614
- package/latticeai/services/brain_automation.py +0 -191
- package/latticeai/services/brain_intelligence/__init__.py +0 -58
- package/latticeai/services/brain_intelligence/_contract.py +0 -71
- package/latticeai/services/brain_intelligence/consistency.py +0 -193
- package/latticeai/services/brain_intelligence/constants.py +0 -47
- package/latticeai/services/brain_intelligence/digest.py +0 -258
- package/latticeai/services/brain_intelligence/health.py +0 -331
- package/latticeai/services/brain_intelligence/proposals.py +0 -259
- package/latticeai/services/brain_intelligence/sampling.py +0 -84
- package/latticeai/services/brain_intelligence/service.py +0 -48
- package/latticeai/services/change_proposals.py +0 -471
- package/latticeai/services/chat_service.py +0 -243
- package/latticeai/services/chronicle.py +0 -555
- package/latticeai/services/cloud_egress_audit.py +0 -85
- package/latticeai/services/cloud_extraction.py +0 -129
- package/latticeai/services/cloud_streaming.py +0 -268
- package/latticeai/services/cloud_token_guard.py +0 -84
- package/latticeai/services/command_center.py +0 -548
- package/latticeai/services/evidence_actions.py +0 -258
- package/latticeai/services/feature_toggles.py +0 -502
- package/latticeai/services/folder_watch.py +0 -520
- package/latticeai/services/funnel_metrics.py +0 -307
- package/latticeai/services/hybrid_chat.py +0 -316
- package/latticeai/services/hybrid_context.py +0 -228
- package/latticeai/services/hybrid_policy.py +0 -129
- package/latticeai/services/interop_bridges.py +0 -978
- package/latticeai/services/local_knowledge.py +0 -465
- package/latticeai/services/memory_service/__init__.py +0 -52
- package/latticeai/services/memory_service/_contract.py +0 -100
- package/latticeai/services/memory_service/brief.py +0 -431
- package/latticeai/services/memory_service/constants.py +0 -57
- package/latticeai/services/memory_service/maintenance.py +0 -138
- package/latticeai/services/memory_service/manager.py +0 -186
- package/latticeai/services/memory_service/proof.py +0 -136
- package/latticeai/services/memory_service/recall.py +0 -225
- package/latticeai/services/memory_service/service.py +0 -48
- package/latticeai/services/memory_service/stores.py +0 -110
- package/latticeai/services/mode_store.py +0 -132
- package/latticeai/services/model_recommendation.py +0 -224
- package/latticeai/services/model_runtime/cloud.py +0 -87
- package/latticeai/services/network_boundary_service.py +0 -117
- package/latticeai/services/obsidian_bridge.py +0 -609
- package/latticeai/services/openai_compatible_adapter.py +0 -101
- package/latticeai/services/permission_mode_service.py +0 -122
- package/latticeai/services/platform_runtime.py +0 -366
- package/latticeai/services/review_queue.py +0 -380
- package/latticeai/services/router_context.py +0 -59
- package/latticeai/services/run_executor.py +0 -387
- package/latticeai/services/self_model_service.py +0 -171
- package/latticeai/services/setup_detection.py +0 -147
- package/latticeai/services/triggers.py +0 -378
- package/latticeai/services/upload_service.py +0 -172
- package/latticeai/services/workspace_service.py +0 -165
- package/latticeai/setup/__init__.py +0 -25
- package/latticeai/setup/auto_setup.py +0 -846
- package/latticeai/setup/demo_corpus.py +0 -98
- package/latticeai/setup/wizard/__init__.py +0 -126
- package/latticeai/setup/wizard/catalog.py +0 -175
- package/latticeai/setup/wizard/detect.py +0 -302
- package/latticeai/setup/wizard/install.py +0 -348
- package/latticeai/setup/wizard/paths.py +0 -165
- package/latticeai/setup/wizard/plans.py +0 -74
- package/latticeai/setup/wizard/recommend.py +0 -320
- package/scripts/bench_agent_smoke.py +0 -409
- package/scripts/bench_models.py +0 -540
- package/scripts/bench_vector_index.py +0 -295
- package/scripts/funnel_soft_gate.py +0 -192
- package/scripts/generate_agent_loop_fixtures.py +0 -994
- package/scripts/generate_rust_parity_fixtures.py +0 -908
- package/scripts/migrate_brain_storage.py +0 -57
- package/scripts/parity_fixture_corpus_context.py +0 -162
- package/scripts/parity_fixture_corpus_docgen.py +0 -341
- package/scripts/profile_kg.py +0 -355
- package/server.py +0 -30
- package/static/app/assets/AdminConsole-cf4npybT.js +0 -1
- package/static/app/assets/Capture-DiQ219jW.js +0 -1
- package/static/app/assets/System-CieofHQa.js +0 -1
- package/static/app/assets/arrow-left-kfsrk0mv.js +0 -1
- package/static/app/assets/circle-check-qqLug9nU.js +0 -1
- package/static/app/assets/index-DxmOfNRi.css +0 -2
- package/static/app/assets/primitives-SNp0LRJz.js +0 -1
- package/static/app/assets/search-BcHqkjoy.js +0 -1
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"""The v11.6.0 worker seams: the two chains a Rust route package delegates.
|
|
2
|
+
|
|
3
|
+
v11.5.1 gave the Rust loop calls back into Python (``/agent/llm``,
|
|
4
|
+
``/agent/tool``). v11.6.0 moved the *product* routes to ``lattice-host`` as
|
|
5
|
+
well, and two of those routes turn out to need something only this process can
|
|
6
|
+
do:
|
|
7
|
+
|
|
8
|
+
``GET /worker/sysinfo``
|
|
9
|
+
The MLX/GPU block of ``/local/sysinfo``. CPU and RAM are ordinary host
|
|
10
|
+
telemetry that Rust can sample itself; unified-memory usage can only be
|
|
11
|
+
read from the process that holds the MLX context, which is this one.
|
|
12
|
+
|
|
13
|
+
``POST /worker/llm/stream``
|
|
14
|
+
Token generation never moves (plan §설계 결정 6). ``/agent/llm`` is
|
|
15
|
+
buffered; chat needs the same ``LLMRouter.stream_generate_as`` path
|
|
16
|
+
framed as SSE so the gateway can pass bytes through. ``mode=document``
|
|
17
|
+
selects ``stream_generate_document_as``.
|
|
18
|
+
|
|
19
|
+
``POST /worker/chat/record-turn`` used to live here as a third seam — the
|
|
20
|
+
redact → audit → store → ingest chain behind ``POST /chat``. WP-W3a moved that
|
|
21
|
+
whole chain into ``lattice-chat`` (``rust/lattice-chat/src/turn.rs``) and its
|
|
22
|
+
own tests assert the seam is requested **zero** times; WP-P1 retires it, along
|
|
23
|
+
with the conversation store, the audit sink and the ingestion write door that
|
|
24
|
+
were its only reason to exist in a worker that owns no state.
|
|
25
|
+
|
|
26
|
+
Both remaining seams are gated by the same switch as ``/agent/tool`` —
|
|
27
|
+
``LATTICEAI_AGENT_TOOL_SEAM=1``, read per request through
|
|
28
|
+
:func:`~latticeai.api.agent_worker_seam._seam_open` so there is one gate, not a
|
|
29
|
+
second one that can drift — and answer 404 with the same message when it is
|
|
30
|
+
off. They are mounted only by the worker profile
|
|
31
|
+
(:func:`latticeai.worker_app.create_worker_app`).
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import asyncio
|
|
37
|
+
import json
|
|
38
|
+
import logging
|
|
39
|
+
import subprocess # noqa: S404 — one fixed sysctl read, no shell, no user input
|
|
40
|
+
from typing import Any, Callable, Dict, Optional, Tuple
|
|
41
|
+
|
|
42
|
+
from fastapi import APIRouter, Request
|
|
43
|
+
from fastapi.responses import StreamingResponse
|
|
44
|
+
from pydantic import BaseModel
|
|
45
|
+
|
|
46
|
+
from latticeai.api.agent_worker_seam import SEAM_RATE_BUCKET
|
|
47
|
+
from latticeai.api.agent_worker_seam import _seam_open as seam_open
|
|
48
|
+
from latticeai.core.messages import http_error, resolve_language
|
|
49
|
+
from latticeai.core.quiet import quiet
|
|
50
|
+
|
|
51
|
+
logger = logging.getLogger(__name__)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ── GPU probe: the MLX half of /local/sysinfo ───────────────────────────────
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _mlx_memory() -> Tuple[int, int]:
|
|
58
|
+
"""Active and cached unified memory held by this process's MLX context."""
|
|
59
|
+
import mlx.core as mx
|
|
60
|
+
|
|
61
|
+
return int(mx.get_active_memory()), int(mx.get_cache_memory())
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _total_memory_bytes() -> int:
|
|
65
|
+
"""Installed physical memory, the denominator ``gpu_mem_pct`` is taken of."""
|
|
66
|
+
completed = subprocess.run( # noqa: S603,S607 — fixed argv, no shell
|
|
67
|
+
["sysctl", "-n", "hw.memsize"],
|
|
68
|
+
capture_output=True,
|
|
69
|
+
text=True,
|
|
70
|
+
timeout=2,
|
|
71
|
+
)
|
|
72
|
+
return int(completed.stdout.strip())
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def probe_gpu_memory() -> Dict[str, Any]:
|
|
76
|
+
"""The GPU block ``/local/sysinfo`` reports, on its own.
|
|
77
|
+
|
|
78
|
+
Blocking (one ``sysctl``), so callers hand it to a worker thread. A machine
|
|
79
|
+
without MLX — every Linux CI box, every Intel Mac — is not an error: it
|
|
80
|
+
answers ``mlx_available: false`` with zeroes and the reason, which is what
|
|
81
|
+
"we could not look" honestly looks like.
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
active, cached = _mlx_memory()
|
|
85
|
+
total = _total_memory_bytes()
|
|
86
|
+
except Exception as exc: # noqa: BLE001 — an absent GPU is not a failure
|
|
87
|
+
quiet("MLX unified-memory probe")
|
|
88
|
+
return {
|
|
89
|
+
"mlx_available": False,
|
|
90
|
+
"gpu_mem_gb": 0.0,
|
|
91
|
+
"gpu_mem_pct": 0.0,
|
|
92
|
+
"total_bytes": 0,
|
|
93
|
+
"detail": str(exc),
|
|
94
|
+
}
|
|
95
|
+
used = active + cached
|
|
96
|
+
return {
|
|
97
|
+
"mlx_available": True,
|
|
98
|
+
"gpu_mem_gb": round(used / (1024 ** 3), 2),
|
|
99
|
+
"gpu_mem_pct": round(used / total * 100, 1) if total else 0.0,
|
|
100
|
+
"total_bytes": total,
|
|
101
|
+
"detail": None,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# ── request bodies ──────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class LlmStreamRequest(BaseModel):
|
|
109
|
+
"""One streaming completion, in the argument shape ``LLMRouter`` already takes."""
|
|
110
|
+
|
|
111
|
+
model_id: Optional[str] = None
|
|
112
|
+
message: str
|
|
113
|
+
context: Optional[str] = None
|
|
114
|
+
max_tokens: int = 4096
|
|
115
|
+
temperature: float = 0.2
|
|
116
|
+
image_data: Optional[str] = None
|
|
117
|
+
mode: str = "chat"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def create_worker_seams_router(
|
|
121
|
+
*,
|
|
122
|
+
require_user: Callable[[Request], Any],
|
|
123
|
+
enforce_rate_limit: Callable[[str, str], None],
|
|
124
|
+
model_router: Any = None,
|
|
125
|
+
) -> APIRouter:
|
|
126
|
+
"""The remaining v11.6.0 delegation seams, wired to what the worker holds.
|
|
127
|
+
|
|
128
|
+
``model_router`` is the in-process
|
|
129
|
+
:class:`~latticeai.models.router.LLMRouter`; absent, the stream seam yields
|
|
130
|
+
the same ``No model.`` marker the router itself would.
|
|
131
|
+
"""
|
|
132
|
+
router = APIRouter()
|
|
133
|
+
|
|
134
|
+
def _require_seam(request: Request) -> None:
|
|
135
|
+
"""404 unless the host opened the seam for this worker."""
|
|
136
|
+
if not seam_open():
|
|
137
|
+
raise http_error(404, "agent_seam.disabled", resolve_language(request))
|
|
138
|
+
|
|
139
|
+
def _admit(request: Request) -> str:
|
|
140
|
+
"""Authenticate and charge this call against the per-step budget."""
|
|
141
|
+
current_user = require_user(request)
|
|
142
|
+
enforce_rate_limit(current_user, SEAM_RATE_BUCKET)
|
|
143
|
+
return str(current_user or "")
|
|
144
|
+
|
|
145
|
+
@router.get("/worker/sysinfo")
|
|
146
|
+
async def worker_sysinfo(request: Request):
|
|
147
|
+
"""The unified-memory reading only this process can take."""
|
|
148
|
+
_require_seam(request)
|
|
149
|
+
_admit(request)
|
|
150
|
+
return await asyncio.to_thread(probe_gpu_memory)
|
|
151
|
+
|
|
152
|
+
@router.post("/worker/llm/stream")
|
|
153
|
+
async def worker_llm_stream(req: LlmStreamRequest, request: Request):
|
|
154
|
+
"""Stream one completion over the same path ``ChatService`` uses.
|
|
155
|
+
|
|
156
|
+
Frames are ``data: {"text": …}`` (or ``{"error": …}``) plus the
|
|
157
|
+
terminating ``data: [DONE]`` sentinel. The gateway never content-
|
|
158
|
+
negotiates on ``Accept``; this seam always answers as an event stream
|
|
159
|
+
so a VS Code client that sent only ``stream: true`` still parses.
|
|
160
|
+
"""
|
|
161
|
+
_require_seam(request)
|
|
162
|
+
_admit(request)
|
|
163
|
+
|
|
164
|
+
async def _frames():
|
|
165
|
+
try:
|
|
166
|
+
if model_router is None:
|
|
167
|
+
yield (
|
|
168
|
+
"data: "
|
|
169
|
+
+ json.dumps({"text": "No model."}, ensure_ascii=False)
|
|
170
|
+
+ "\n\n"
|
|
171
|
+
)
|
|
172
|
+
yield "data: [DONE]\n\n"
|
|
173
|
+
return
|
|
174
|
+
if req.mode == "document":
|
|
175
|
+
agen = model_router.stream_generate_document_as(
|
|
176
|
+
req.model_id,
|
|
177
|
+
req.message,
|
|
178
|
+
req.context or "",
|
|
179
|
+
max_tokens=req.max_tokens,
|
|
180
|
+
temperature=req.temperature,
|
|
181
|
+
)
|
|
182
|
+
else:
|
|
183
|
+
agen = model_router.stream_generate_as(
|
|
184
|
+
req.model_id,
|
|
185
|
+
req.message,
|
|
186
|
+
req.context,
|
|
187
|
+
req.max_tokens,
|
|
188
|
+
req.temperature,
|
|
189
|
+
req.image_data,
|
|
190
|
+
)
|
|
191
|
+
async for chunk in agen:
|
|
192
|
+
text = chunk.text if hasattr(chunk, "text") else chunk
|
|
193
|
+
yield (
|
|
194
|
+
"data: "
|
|
195
|
+
+ json.dumps({"text": str(text)}, ensure_ascii=False)
|
|
196
|
+
+ "\n\n"
|
|
197
|
+
)
|
|
198
|
+
except Exception as exc: # noqa: BLE001 — already streaming a 200
|
|
199
|
+
logger.warning("worker llm stream failed: %s", exc)
|
|
200
|
+
yield (
|
|
201
|
+
"data: "
|
|
202
|
+
+ json.dumps({"error": str(exc)}, ensure_ascii=False)
|
|
203
|
+
+ "\n\n"
|
|
204
|
+
)
|
|
205
|
+
yield "data: [DONE]\n\n"
|
|
206
|
+
|
|
207
|
+
return StreamingResponse(_frames(), media_type="text/event-stream")
|
|
208
|
+
|
|
209
|
+
return router
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
__all__ = [
|
|
213
|
+
"LlmStreamRequest",
|
|
214
|
+
"create_worker_seams_router",
|
|
215
|
+
"probe_gpu_memory",
|
|
216
|
+
]
|
package/latticeai/app_factory.py
CHANGED
|
@@ -1,150 +1,40 @@
|
|
|
1
|
-
"""Lattice AI application factory.
|
|
2
|
-
|
|
3
|
-
``
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
``
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
the RuntimeContext preserves exactly that property while naming the state.
|
|
1
|
+
"""Lattice AI AI-Worker application factory.
|
|
2
|
+
|
|
3
|
+
``build_context`` performs *all* construction the worker process needs: MLX/GPU
|
|
4
|
+
device init, config parsing, the seam gate, the embedder and multi-modal ports,
|
|
5
|
+
the LLM router, and the compute routers. Importing this module has **no side
|
|
6
|
+
effects**: nothing heavy is imported and no file is created until
|
|
7
|
+
``build_context`` is called.
|
|
8
|
+
|
|
9
|
+
The assembly itself lives in :mod:`latticeai.runtime.build_phases` as seven
|
|
10
|
+
ordered phases sharing a
|
|
11
|
+
:class:`~latticeai.runtime.runtime_context.RuntimeContext`. This module is now
|
|
12
|
+
only the *orchestrator*: run the phases and hand back the context.
|
|
13
|
+
|
|
14
|
+
``create_app`` used to live here and built the 464-route product server.
|
|
15
|
+
v11.6.0 moved that whole surface into ``lattice-host`` (plan §설계 결정 1) and
|
|
16
|
+
WP-P1 deleted its Python side, so there is exactly one application in this
|
|
17
|
+
package now — :func:`latticeai.worker_app.create_worker_app`, which is
|
|
18
|
+
``build_context`` plus the worker profile.
|
|
20
19
|
"""
|
|
21
20
|
|
|
22
21
|
from __future__ import annotations
|
|
23
22
|
|
|
24
|
-
import
|
|
25
|
-
from dataclasses import dataclass
|
|
26
|
-
from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
23
|
+
from typing import TYPE_CHECKING, Optional
|
|
27
24
|
|
|
28
25
|
from latticeai.runtime.build_phases import BUILD_PHASES
|
|
29
|
-
from latticeai.runtime.namespace_runtime import RuntimeBundle, build_runtime_namespace
|
|
30
|
-
from latticeai.runtime.router_registration import build_router_bundle
|
|
31
26
|
from latticeai.runtime.runtime_context import RuntimeContext
|
|
32
27
|
|
|
33
28
|
if TYPE_CHECKING: # imports for annotations only — keep module import light
|
|
34
|
-
from fastapi import FastAPI
|
|
35
|
-
|
|
36
29
|
from latticeai.core.config import Config
|
|
37
30
|
|
|
38
31
|
|
|
39
|
-
def _legacy_exports(ctx: RuntimeContext) -> Dict[str, Any]:
|
|
40
|
-
"""The explicit, allowlisted compatibility surface for ``server_app``.
|
|
41
|
-
|
|
42
|
-
Two kinds of name appear here: values the phases produced (read off the
|
|
43
|
-
context) and pass-through re-exports of module functions that historical
|
|
44
|
-
callers reached through ``server_app``. Keeping them in one function makes
|
|
45
|
-
the surface countable — ``namespace_runtime`` rejects anything not on its
|
|
46
|
-
allowlist.
|
|
47
|
-
"""
|
|
48
|
-
from latticeai.api.security_dashboard import (
|
|
49
|
-
create_security_router as _create_security_router,
|
|
50
|
-
)
|
|
51
|
-
from latticeai.api.workspace import _workspace_scope_from_request
|
|
52
|
-
from latticeai.core.audit import (
|
|
53
|
-
build_admin_audit_report as _build_admin_audit_report,
|
|
54
|
-
)
|
|
55
|
-
from latticeai.core.audit import (
|
|
56
|
-
build_sensitivity_report as _build_sensitivity_report,
|
|
57
|
-
)
|
|
58
|
-
from latticeai.core.audit import (
|
|
59
|
-
classify_sensitive_message as _classify_sensitive_message,
|
|
60
|
-
)
|
|
61
|
-
from latticeai.core.audit import get_audit_log as _get_audit_log
|
|
62
|
-
from latticeai.core.mcp_registry import _fetch_skills_marketplace
|
|
63
|
-
from latticeai.core.model_compat import (
|
|
64
|
-
list_cached_profiles as _list_compat_profiles,
|
|
65
|
-
)
|
|
66
|
-
from latticeai.core.security import (
|
|
67
|
-
check_ip_rate_limit as _check_ip_rate_limit,
|
|
68
|
-
)
|
|
69
|
-
from latticeai.core.security import hash_password, verify_password
|
|
70
|
-
from latticeai.core.security import (
|
|
71
|
-
redact_secret_text as _redact_secret_text,
|
|
72
|
-
)
|
|
73
|
-
from latticeai.core.tool_registry import TOOL_CATALOG_BRIEF as _TOOL_CATALOG_BRIEF
|
|
74
|
-
from latticeai.core.users import user_id_for_email as _user_id_for_email
|
|
75
|
-
from latticeai.services.model_runtime import (
|
|
76
|
-
ENGINE_MODEL_CATALOG,
|
|
77
|
-
filter_lower_family_versions,
|
|
78
|
-
normalize_local_model_request,
|
|
79
|
-
)
|
|
80
|
-
from latticeai.services.tool_dispatch import (
|
|
81
|
-
LOCAL_WRITE_BLOCKED_PREFIXES as _LOCAL_WRITE_BLOCKED_PREFIXES,
|
|
82
|
-
)
|
|
83
|
-
from latticeai.services.tool_dispatch import TOOL_GOVERNANCE
|
|
84
|
-
from latticeai.services.tool_dispatch import (
|
|
85
|
-
TOOL_GOVERNANCE_DEFAULT as _TOOL_GOVERNANCE_DEFAULT,
|
|
86
|
-
)
|
|
87
|
-
from latticeai.services.tool_dispatch import agent_risk as _agent_risk
|
|
88
|
-
from latticeai.services.tool_dispatch import check_tool_role as _check_tool_role
|
|
89
|
-
from latticeai.services.tool_dispatch import tool_response as _tool_response
|
|
90
|
-
|
|
91
|
-
return {
|
|
92
|
-
# ── pass-through re-exports ──────────────────────────────────────
|
|
93
|
-
"ENGINE_MODEL_CATALOG": ENGINE_MODEL_CATALOG,
|
|
94
|
-
"TOOL_GOVERNANCE": TOOL_GOVERNANCE,
|
|
95
|
-
"filter_lower_family_versions": filter_lower_family_versions,
|
|
96
|
-
"hash_password": hash_password,
|
|
97
|
-
"normalize_local_model_request": normalize_local_model_request,
|
|
98
|
-
"verify_password": verify_password,
|
|
99
|
-
"_LOCAL_WRITE_BLOCKED_PREFIXES": _LOCAL_WRITE_BLOCKED_PREFIXES,
|
|
100
|
-
"_TOOL_CATALOG_BRIEF": _TOOL_CATALOG_BRIEF,
|
|
101
|
-
"_TOOL_GOVERNANCE_DEFAULT": _TOOL_GOVERNANCE_DEFAULT,
|
|
102
|
-
"_agent_risk": _agent_risk,
|
|
103
|
-
"_build_admin_audit_report": _build_admin_audit_report,
|
|
104
|
-
"_build_sensitivity_report": _build_sensitivity_report,
|
|
105
|
-
"_check_ip_rate_limit": _check_ip_rate_limit,
|
|
106
|
-
"_check_tool_role": _check_tool_role,
|
|
107
|
-
"_classify_sensitive_message": _classify_sensitive_message,
|
|
108
|
-
"_create_security_router": _create_security_router,
|
|
109
|
-
"_fetch_skills_marketplace": _fetch_skills_marketplace,
|
|
110
|
-
"_get_audit_log": _get_audit_log,
|
|
111
|
-
"_list_compat_profiles": _list_compat_profiles,
|
|
112
|
-
"_redact_secret_text": _redact_secret_text,
|
|
113
|
-
"_tool_response": _tool_response,
|
|
114
|
-
"_user_id_for_email": _user_id_for_email,
|
|
115
|
-
"_workspace_scope_from_request": _workspace_scope_from_request,
|
|
116
|
-
# ── values the phases produced ───────────────────────────────────
|
|
117
|
-
"enforce_rate_limit": ctx.enforce_rate_limit,
|
|
118
|
-
"_RATE_LIMIT_ENABLED": ctx._RATE_LIMIT_ENABLED,
|
|
119
|
-
"_SESSION_TTL": ctx._SESSION_TTL,
|
|
120
|
-
"_allowed_workspaces_for": ctx._allowed_workspaces_for,
|
|
121
|
-
"_bytes_match_extension": ctx._bytes_match_extension,
|
|
122
|
-
"_check_rate_limit": ctx._check_rate_limit,
|
|
123
|
-
"_client_ip": ctx._client_ip,
|
|
124
|
-
"_embedding_info": ctx._embedding_info,
|
|
125
|
-
"_get_sso_discovery": ctx._get_sso_discovery,
|
|
126
|
-
"_graph_stats_safe": ctx._graph_stats_safe,
|
|
127
|
-
"_host_is_loopback": ctx._host_is_loopback,
|
|
128
|
-
"_llm_generate_sync": ctx._llm_generate_sync,
|
|
129
|
-
"_product_hardening_status": ctx._product_hardening_status,
|
|
130
|
-
"_recent_chat_context": ctx._recent_chat_context,
|
|
131
|
-
"_require_graph": ctx._require_graph,
|
|
132
|
-
"_scoped_hybrid_search": ctx._scoped_hybrid_search,
|
|
133
|
-
"_security_audit_events_safe": ctx._security_audit_events_safe,
|
|
134
|
-
"_security_list_uploaded_files": ctx._security_list_uploaded_files,
|
|
135
|
-
"_spawn": ctx._spawn,
|
|
136
|
-
"_workspace_graph": ctx._workspace_graph,
|
|
137
|
-
"_workspace_models_payload": ctx._workspace_models_payload,
|
|
138
|
-
"_workspace_settings_payload": ctx._workspace_settings_payload,
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
32
|
def build_context(config: "Optional[Config]" = None) -> RuntimeContext:
|
|
143
33
|
"""Run every build phase in order and return the populated context.
|
|
144
34
|
|
|
145
|
-
Exposed separately from :func:`
|
|
146
|
-
assembly (which phase produced what) without
|
|
147
|
-
|
|
35
|
+
Exposed separately from :func:`latticeai.worker_app.create_worker_app` so
|
|
36
|
+
tests can inspect the assembly (which phase produced what) without building
|
|
37
|
+
an application.
|
|
148
38
|
"""
|
|
149
39
|
ctx = RuntimeContext(config)
|
|
150
40
|
for phase in BUILD_PHASES:
|
|
@@ -152,103 +42,4 @@ def build_context(config: "Optional[Config]" = None) -> RuntimeContext:
|
|
|
152
42
|
return ctx
|
|
153
43
|
|
|
154
44
|
|
|
155
|
-
|
|
156
|
-
"""Assemble the application and return its explicit export namespace."""
|
|
157
|
-
ctx = build_context(config)
|
|
158
|
-
runtime_bundle = RuntimeBundle(
|
|
159
|
-
app=ctx.app,
|
|
160
|
-
CONFIG=ctx.CONFIG,
|
|
161
|
-
KNOWLEDGE_GRAPH=ctx.KNOWLEDGE_GRAPH,
|
|
162
|
-
INGESTION_PIPELINE=ctx.INGESTION_PIPELINE,
|
|
163
|
-
AGENT_RUNTIME=ctx.AGENT_RUNTIME,
|
|
164
|
-
HOOKS_REGISTRY=ctx.HOOKS_REGISTRY,
|
|
165
|
-
REVIEW_QUEUE=ctx.REVIEW_QUEUE,
|
|
166
|
-
AGENT_REGISTRY=ctx.AGENT_REGISTRY,
|
|
167
|
-
model_router=ctx.model_router,
|
|
168
|
-
build_runtime=build_runtime,
|
|
169
|
-
get_shared_runtime=get_shared_runtime,
|
|
170
|
-
create_app=create_app,
|
|
171
|
-
config_runtime=ctx.config_runtime,
|
|
172
|
-
security_runtime=ctx.security_runtime,
|
|
173
|
-
brain_runtime=ctx.brain_runtime,
|
|
174
|
-
model_runtime=ctx.model_runtime,
|
|
175
|
-
router_bundle=build_router_bundle(ctx.app, ctx.app_context),
|
|
176
|
-
)
|
|
177
|
-
return build_runtime_namespace(
|
|
178
|
-
runtime_bundle=runtime_bundle,
|
|
179
|
-
legacy_exports=_legacy_exports(ctx),
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
@dataclass(frozen=True)
|
|
184
|
-
class LegacyRuntimeNamespace:
|
|
185
|
-
"""Compatibility adapter for the historical module-level runtime surface."""
|
|
186
|
-
|
|
187
|
-
namespace: Dict[str, Any]
|
|
188
|
-
|
|
189
|
-
def bind(self, runtime: "AppRuntime") -> None:
|
|
190
|
-
runtime.__dict__.update(self.namespace)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
class AppRuntime:
|
|
194
|
-
"""The constructed application namespace.
|
|
195
|
-
|
|
196
|
-
Exposes every name the legacy import-time ``server_app`` module defined
|
|
197
|
-
(``app``, ``KNOWLEDGE_GRAPH``, ``load_users``, …) as attributes.
|
|
198
|
-
"""
|
|
199
|
-
|
|
200
|
-
# Declared because they are bound dynamically from the namespace dict;
|
|
201
|
-
# these two are the ones this module itself reads back.
|
|
202
|
-
app: Any
|
|
203
|
-
CONFIG: Any
|
|
204
|
-
|
|
205
|
-
def __init__(self, namespace: Dict[str, Any]) -> None:
|
|
206
|
-
self._legacy_namespace = LegacyRuntimeNamespace(namespace)
|
|
207
|
-
self._legacy_namespace.bind(self)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
_runtime_lock = threading.RLock()
|
|
211
|
-
_shared_runtime: "Optional[AppRuntime]" = None
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
def build_runtime(config: "Optional[Config]" = None) -> AppRuntime:
|
|
215
|
-
"""Construct a fresh runtime (all singletons + FastAPI app)."""
|
|
216
|
-
return AppRuntime(_build(config))
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def get_shared_runtime() -> AppRuntime:
|
|
220
|
-
"""The process-wide runtime backing ``latticeai.server_app`` / ``server``.
|
|
221
|
-
|
|
222
|
-
Built once, on first access — never at import time.
|
|
223
|
-
"""
|
|
224
|
-
global _shared_runtime
|
|
225
|
-
if _shared_runtime is None:
|
|
226
|
-
with _runtime_lock:
|
|
227
|
-
if _shared_runtime is None:
|
|
228
|
-
_shared_runtime = build_runtime()
|
|
229
|
-
return _shared_runtime
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
def create_app(config: "Optional[Config]" = None) -> "FastAPI":
|
|
233
|
-
"""Build and return the FastAPI application (the factory entrypoint)."""
|
|
234
|
-
return build_runtime(config).app
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
def main() -> None:
|
|
238
|
-
"""Serve the shared runtime (``python -m latticeai.server_app``).
|
|
239
|
-
|
|
240
|
-
This used to call ``get_shared_runtime().main()``, but ``main`` was a local
|
|
241
|
-
inside the old ``_build`` closure and was never on the export allowlist, so
|
|
242
|
-
the call raised ``AttributeError`` — the module entrypoint was broken.
|
|
243
|
-
Serving from here needs no export at all.
|
|
244
|
-
"""
|
|
245
|
-
import uvicorn
|
|
246
|
-
|
|
247
|
-
runtime = get_shared_runtime()
|
|
248
|
-
config = runtime.CONFIG
|
|
249
|
-
host, port = config.host, config.port
|
|
250
|
-
print(
|
|
251
|
-
f"🧠 Lattice AI Server starting in {config.app_mode} mode "
|
|
252
|
-
f"on http://{host}:{port}"
|
|
253
|
-
)
|
|
254
|
-
uvicorn.run(runtime.app, host=host, port=port, log_level="info")
|
|
45
|
+
__all__ = ["build_context"]
|