ltcai 11.5.2 → 11.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -148
- package/bin/ltcai.js +234 -24
- package/docs/CHANGELOG.md +119 -0
- package/docs/COMMUNITY_AND_PLUGINS.md +1 -1
- package/docs/DEVELOPMENT.md +8 -6
- package/docs/ENTERPRISE.md +2 -1
- package/docs/MULTI_AGENT_RUNTIME.md +12 -5
- package/docs/ONBOARDING.md +1 -1
- package/docs/OPERATIONS.md +6 -3
- package/docs/REALTIME_COLLABORATION.md +1 -1
- package/docs/TRUST_MODEL.md +1 -1
- package/docs/WHY_LATTICE.md +1 -1
- package/docs/WORKFLOW_DESIGNER.md +3 -2
- package/docs/kg-schema.md +1 -1
- package/docs/v11.6.0_ONE_DOOR_PLAN.md +170 -0
- package/lattice_brain/__init__.py +42 -79
- package/lattice_brain/graph/__init__.py +9 -24
- package/lattice_brain/graph/_kg_common/__init__.py +13 -24
- package/lattice_brain/ingestion/__init__.py +19 -58
- package/lattice_brain/ingestion/pipeline.py +20 -398
- package/lattice_brain/multimodal/__init__.py +7 -18
- package/lattice_brain/multimodal/images.py +6 -264
- package/lattice_brain/multimodal/video.py +8 -247
- package/lattice_brain/runtime/__init__.py +8 -79
- package/lattice_brain/runtime/hooks.py +22 -584
- package/latticeai/__init__.py +1 -1
- package/latticeai/api/agent_worker_seam.py +7 -80
- package/latticeai/api/health.py +6 -20
- package/latticeai/api/local_files.py +16 -613
- package/latticeai/api/models.py +12 -87
- package/latticeai/api/search.py +17 -255
- package/latticeai/api/tools.py +69 -750
- package/latticeai/api/voice_capture.py +8 -70
- package/latticeai/api/worker_compute.py +842 -0
- package/latticeai/api/worker_seams.py +216 -0
- package/latticeai/app_factory.py +23 -232
- package/latticeai/cli/entrypoint.py +36 -249
- package/latticeai/core/agent_permission.py +16 -91
- package/latticeai/core/messages.py +89 -531
- package/latticeai/runtime/access_runtime.py +0 -14
- package/latticeai/runtime/bootstrap.py +10 -21
- package/latticeai/runtime/brain_runtime.py +35 -43
- package/latticeai/runtime/build_phases/__init__.py +21 -37
- package/latticeai/runtime/build_phases/features.py +99 -389
- package/latticeai/runtime/build_phases/foundation.py +82 -392
- package/latticeai/runtime/build_phases/web.py +91 -408
- package/latticeai/runtime/build_phases/worker_profile.py +244 -0
- package/latticeai/runtime/lifespan_runtime.py +7 -16
- package/latticeai/runtime/platform_services_runtime.py +1 -15
- package/latticeai/runtime/runtime_context.py +13 -130
- package/latticeai/runtime/security_runtime.py +10 -103
- package/latticeai/services/architecture_readiness.py +82 -43
- package/latticeai/services/model_runtime/__init__.py +2 -11
- package/latticeai/services/model_runtime/service.py +4 -28
- package/latticeai/services/p_reinforce.py +10 -261
- package/latticeai/services/product_readiness.py +31 -38
- package/latticeai/services/search_service.py +37 -795
- package/latticeai/services/tool_dispatch.py +30 -386
- package/latticeai/services/voice_capture.py +13 -107
- package/latticeai/tools/__init__.py +22 -49
- package/latticeai/tools/commands.py +0 -163
- package/latticeai/tools/computer.py +0 -39
- package/latticeai/tools/documents.py +1 -134
- package/latticeai/tools/filesystem.py +1 -247
- package/latticeai/tools/knowledge.py +1 -52
- package/latticeai/tools/local_files.py +0 -20
- package/latticeai/worker_app.py +75 -0
- package/package.json +2 -3
- package/requirements.txt +0 -5
- package/scripts/agent_eval.py +16 -28
- package/scripts/brain_quality_eval.py +20 -183
- package/scripts/bump_version.py +5 -5
- package/scripts/check_current_release_docs.mjs +7 -4
- package/scripts/check_openapi_drift.mjs +10 -0
- package/scripts/check_server_i18n.mjs +2 -18
- package/scripts/compose_openapi.py +377 -0
- package/scripts/export_openapi.py +32 -4
- package/scripts/gen_messages_catalog_fixture.py +302 -0
- package/scripts/gen_openapi_fragments.py +365 -0
- package/scripts/gen_redact_fixture.py +196 -0
- package/scripts/gen_worker_allowlist_fixture.py +115 -0
- package/scripts/generate_agent_parity_fixtures.py +33 -14
- package/scripts/openapi_route_families.json +2161 -0
- package/scripts/release_screen_claims.json +54 -0
- package/scripts/run_integration_tests.mjs +134 -29
- package/scripts/run_sidecar_e2e.mjs +104 -11
- package/scripts/wheel_smoke.py +32 -22
- package/src-tauri/Cargo.lock +375 -9
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/backend.rs +151 -45
- package/src-tauri/src/main.rs +18 -18
- package/src-tauri/src/topology.rs +58 -88
- package/src-tauri/tauri.conf.json +1 -2
- package/static/app/asset-manifest.json +41 -41
- package/static/app/assets/{Act-DcQizkl1.js → Act-BPcVAbOL.js} +1 -1
- package/static/app/assets/AdminConsole-Bw1ATQL0.js +1 -0
- package/static/app/assets/{Brain-3VCSHFcn.js → Brain-CT92Kos0.js} +2 -2
- package/static/app/assets/{BrainHome-Qm8eaztx.js → BrainHome-CFBkt1K_.js} +1 -1
- package/static/app/assets/{BrainSignals-DS9BtKOW.js → BrainSignals-ReLWF2H8.js} +1 -1
- package/static/app/assets/Capture-BsTokYkk.js +1 -0
- package/static/app/assets/{Chronicle-BGvuAchH.js → Chronicle-B6f0T9id.js} +1 -1
- package/static/app/assets/{CommandPalette-Bqhm0Urn.js → CommandPalette-CuvjTv1u.js} +1 -1
- package/static/app/assets/{Library-BV6NnF0a.js → Library-BGJbG9Hd.js} +1 -1
- package/static/app/assets/{LivingBrain-GzenJchP.js → LivingBrain-DGYK_Jsa.js} +1 -1
- package/static/app/assets/{ProductFlow-DEP6-vML.js → ProductFlow-DXBC6brE.js} +1 -1
- package/static/app/assets/{ReviewCard-CNZ7XjWG.js → ReviewCard-HXRle3qq.js} +2 -2
- package/static/app/assets/System-CMHSO9qM.js +1 -0
- package/static/app/assets/arrow-left-BfmkskWx.js +1 -0
- package/static/app/assets/{bot-B_K1Tdmw.js → bot-Cn8bWRuq.js} +1 -1
- package/static/app/assets/{brain-DWyaV1L1.js → brain-CQJberbE.js} +1 -1
- package/static/app/assets/{button-aTn4s84A.js → button-Ct9f2_oT.js} +1 -1
- package/static/app/assets/circle-check-DruOxB-4.js +1 -0
- package/static/app/assets/{circle-pause-xKgeGXkT.js → circle-pause-CmzC_apg.js} +1 -1
- package/static/app/assets/{circle-play-DkT6tYPX.js → circle-play-D8mW2aQ7.js} +1 -1
- package/static/app/assets/{cpu-85xYObUC.js → cpu-DZcdd0PZ.js} +1 -1
- package/static/app/assets/{download-B5Fm7YXo.js → download-bv1KEPGQ.js} +1 -1
- package/static/app/assets/{folder-open-kk2Xa52u.js → folder-open-d-Pip5gr.js} +1 -1
- package/static/app/assets/{hard-drive-DkA3zBW_.js → hard-drive-D20iavUb.js} +1 -1
- package/static/app/assets/index-D9x-kSNy.css +2 -0
- package/static/app/assets/{index-BMPdTmlY.js → index-Do83hDzJ.js} +3 -3
- package/static/app/assets/{input-B0nRf2jO.js → input-BLXVNmj1.js} +1 -1
- package/static/app/assets/{link-2-Dwb4gnTc.js → link-2-BPJOFlAy.js} +1 -1
- package/static/app/assets/{permissionCopy-CQDUBrOZ.js → permissionCopy-ChdJd493.js} +1 -1
- package/static/app/assets/primitives-Cv5tbZBY.js +1 -0
- package/static/app/assets/search-CT9aho2j.js +1 -0
- package/static/app/assets/{share-2-BsrxFglO.js → share-2-YNX_NtMU.js} +1 -1
- package/static/app/assets/{shield-alert-5BStfp2_.js → shield-alert-DuQ3zrVL.js} +1 -1
- package/static/app/assets/{textarea-Cg8IUA-k.js → textarea-DqwLnli4.js} +1 -1
- package/static/app/assets/{useFocusTrap-CYKvE46M.js → useFocusTrap-ZVI98jaW.js} +1 -1
- package/static/app/assets/{useMutation-CSn9t1op.js → useMutation-CVC4qv_D.js} +1 -1
- package/static/app/assets/{useQuery-CY2OI2uy.js → useQuery-C7BeG4HU.js} +1 -1
- package/static/app/assets/{utils-Ddol2RWD.js → utils-CiFtIdZq.js} +1 -1
- package/static/app/assets/{workspace-BqDwOz_p.js → workspace-DQz9vIId.js} +1 -1
- package/static/app/index.html +4 -4
- package/static/sw.js +1 -1
- package/lattice_brain/archive.py +0 -522
- package/lattice_brain/context.py +0 -325
- package/lattice_brain/conversations.py +0 -382
- package/lattice_brain/core.py +0 -82
- package/lattice_brain/graph/_kg_contract.py +0 -249
- package/lattice_brain/graph/curator.py +0 -676
- package/lattice_brain/graph/discovery.py +0 -595
- package/lattice_brain/graph/discovery_index/__init__.py +0 -35
- package/lattice_brain/graph/discovery_index/cleanup.py +0 -182
- package/lattice_brain/graph/discovery_index/extract.py +0 -137
- package/lattice_brain/graph/discovery_index/scan.py +0 -411
- package/lattice_brain/graph/discovery_index/upsert.py +0 -495
- package/lattice_brain/graph/documents.py +0 -380
- package/lattice_brain/graph/fusion.py +0 -395
- package/lattice_brain/graph/identity.py +0 -175
- package/lattice_brain/graph/image_vectors.py +0 -230
- package/lattice_brain/graph/ingest.py +0 -829
- package/lattice_brain/graph/network.py +0 -205
- package/lattice_brain/graph/proactive.py +0 -724
- package/lattice_brain/graph/projection/__init__.py +0 -42
- package/lattice_brain/graph/projection/curation.py +0 -500
- package/lattice_brain/graph/projection/v2_schema.py +0 -518
- package/lattice_brain/graph/provenance.py +0 -524
- package/lattice_brain/graph/rerank.py +0 -163
- package/lattice_brain/graph/retrieval/__init__.py +0 -54
- package/lattice_brain/graph/retrieval/context.py +0 -197
- package/lattice_brain/graph/retrieval/graph_view.py +0 -319
- package/lattice_brain/graph/retrieval/hybrid.py +0 -488
- package/lattice_brain/graph/retrieval/maintenance.py +0 -121
- package/lattice_brain/graph/retrieval/signals.py +0 -95
- package/lattice_brain/graph/retrieval_docgen.py +0 -253
- package/lattice_brain/graph/retrieval_policy.py +0 -180
- package/lattice_brain/graph/retrieval_reads.py +0 -769
- package/lattice_brain/graph/retrieval_vector/__init__.py +0 -42
- package/lattice_brain/graph/retrieval_vector/fingerprint.py +0 -97
- package/lattice_brain/graph/retrieval_vector/indexing.py +0 -347
- package/lattice_brain/graph/retrieval_vector/search.py +0 -560
- package/lattice_brain/graph/retrieval_vector/status.py +0 -374
- package/lattice_brain/graph/schema.py +0 -792
- package/lattice_brain/graph/store.py +0 -268
- package/lattice_brain/graph/vector_index/__init__.py +0 -85
- package/lattice_brain/graph/vector_index/base.py +0 -167
- package/lattice_brain/graph/vector_index/brute_force.py +0 -110
- package/lattice_brain/graph/vector_index/hnsw.py +0 -290
- package/lattice_brain/graph/vector_index/jobs.py +0 -287
- package/lattice_brain/graph/vector_index/quantized.py +0 -148
- package/lattice_brain/graph/vector_index/selector.py +0 -161
- package/lattice_brain/graph/write_master.py +0 -308
- package/lattice_brain/ingestion/_contract.py +0 -90
- package/lattice_brain/ingestion/folder_scan.py +0 -57
- package/lattice_brain/ingestion/folders.py +0 -258
- package/lattice_brain/ingestion/jobs_api.py +0 -107
- package/lattice_brain/ingestion/routing.py +0 -295
- package/lattice_brain/ingestion_jobs.py +0 -380
- package/lattice_brain/memory.py +0 -75
- package/lattice_brain/portability/__init__.py +0 -90
- package/lattice_brain/portability/_contract.py +0 -42
- package/lattice_brain/portability/backups.py +0 -338
- package/lattice_brain/portability/bundles.py +0 -136
- package/lattice_brain/portability/constants.py +0 -93
- package/lattice_brain/portability/fsops.py +0 -138
- package/lattice_brain/portability/service.py +0 -41
- package/lattice_brain/portability/sharing.py +0 -710
- package/lattice_brain/quality.py +0 -543
- package/lattice_brain/retrieval_benchmark_fixtures.py +0 -92
- package/lattice_brain/runtime/agent_runtime.py +0 -859
- package/lattice_brain/runtime/contracts.py +0 -460
- package/lattice_brain/runtime/multi_agent.py +0 -942
- package/lattice_brain/runtime/statuses.py +0 -10
- package/lattice_brain/sealed_box.py +0 -240
- package/lattice_brain/self_model.py +0 -675
- package/lattice_brain/sensitivity.py +0 -94
- package/lattice_brain/storage/__init__.py +0 -22
- package/lattice_brain/storage/base.py +0 -100
- package/lattice_brain/storage/docker.py +0 -105
- package/lattice_brain/storage/factory.py +0 -31
- package/lattice_brain/storage/migration.py +0 -191
- package/lattice_brain/storage/postgres.py +0 -123
- package/lattice_brain/storage/sqlite.py +0 -143
- package/lattice_brain/synthesis.py +0 -824
- package/lattice_brain/workflow.py +0 -497
- package/latticeai/api/admin.py +0 -471
- package/latticeai/api/agent_registry.py +0 -105
- package/latticeai/api/agents.py +0 -228
- package/latticeai/api/auth.py +0 -383
- package/latticeai/api/automation_intelligence.py +0 -401
- package/latticeai/api/brain_intelligence.py +0 -199
- package/latticeai/api/browser.py +0 -493
- package/latticeai/api/change_proposals.py +0 -89
- package/latticeai/api/chat.py +0 -572
- package/latticeai/api/chat_agent_http.py +0 -892
- package/latticeai/api/chat_contracts.py +0 -73
- package/latticeai/api/chat_documents.py +0 -276
- package/latticeai/api/chat_helpers.py +0 -460
- package/latticeai/api/chat_history.py +0 -101
- package/latticeai/api/chat_hybrid.py +0 -113
- package/latticeai/api/chat_intents.py +0 -646
- package/latticeai/api/chat_stream.py +0 -216
- package/latticeai/api/chronicle.py +0 -63
- package/latticeai/api/command_center.py +0 -51
- package/latticeai/api/computer_use.py +0 -474
- package/latticeai/api/evidence_actions.py +0 -48
- package/latticeai/api/features.py +0 -70
- package/latticeai/api/funnel_metrics.py +0 -31
- package/latticeai/api/garden.py +0 -34
- package/latticeai/api/hooks.py +0 -165
- package/latticeai/api/index_jobs.py +0 -145
- package/latticeai/api/invitations.py +0 -100
- package/latticeai/api/knowledge_graph.py +0 -536
- package/latticeai/api/marketplace.py +0 -105
- package/latticeai/api/mcp.py +0 -482
- package/latticeai/api/memory.py +0 -270
- package/latticeai/api/network.py +0 -81
- package/latticeai/api/network_boundary.py +0 -225
- package/latticeai/api/permission_mode.py +0 -61
- package/latticeai/api/permissions.py +0 -436
- package/latticeai/api/plugins.py +0 -126
- package/latticeai/api/portability.py +0 -391
- package/latticeai/api/project_sessions.py +0 -114
- package/latticeai/api/realtime.py +0 -118
- package/latticeai/api/review_queue.py +0 -364
- package/latticeai/api/security_dashboard.py +0 -604
- package/latticeai/api/setup.py +0 -319
- package/latticeai/api/static_routes.py +0 -354
- package/latticeai/api/ui_redirects.py +0 -26
- package/latticeai/api/workflow_designer.py +0 -394
- package/latticeai/api/workspace.py +0 -856
- package/latticeai/api/workspace_scope.py +0 -125
- package/latticeai/core/agent/__init__.py +0 -93
- package/latticeai/core/agent/_contract.py +0 -79
- package/latticeai/core/agent/context.py +0 -57
- package/latticeai/core/agent/deps.py +0 -125
- package/latticeai/core/agent/execution.py +0 -622
- package/latticeai/core/agent/planning.py +0 -145
- package/latticeai/core/agent/recovery.py +0 -157
- package/latticeai/core/agent/runtime.py +0 -210
- package/latticeai/core/agent/verification.py +0 -231
- package/latticeai/core/agent_eval.py +0 -739
- package/latticeai/core/agent_helpers.py +0 -493
- package/latticeai/core/agent_profiles.py +0 -110
- package/latticeai/core/agent_prompts.py +0 -171
- package/latticeai/core/agent_registry.py +0 -232
- package/latticeai/core/agent_state.py +0 -41
- package/latticeai/core/agent_trace.py +0 -104
- package/latticeai/core/artifact_ledger.py +0 -109
- package/latticeai/core/audit.py +0 -260
- package/latticeai/core/builtin_hooks.py +0 -105
- package/latticeai/core/context_builder.py +0 -394
- package/latticeai/core/document_generator.py +0 -103
- package/latticeai/core/enterprise.py +0 -154
- package/latticeai/core/enterprise_admin.py +0 -158
- package/latticeai/core/file_generation/__init__.py +0 -115
- package/latticeai/core/file_generation/bundles.py +0 -76
- package/latticeai/core/file_generation/extraction.py +0 -154
- package/latticeai/core/file_generation/inference.py +0 -235
- package/latticeai/core/file_generation/orchestration.py +0 -152
- package/latticeai/core/file_generation/prompting.py +0 -117
- package/latticeai/core/file_generation/repair.py +0 -114
- package/latticeai/core/file_generation/sanitize.py +0 -61
- package/latticeai/core/file_generation/validation.py +0 -201
- package/latticeai/core/invitations.py +0 -132
- package/latticeai/core/legacy_compatibility.py +0 -243
- package/latticeai/core/logging_safety.py +0 -46
- package/latticeai/core/marketplace.py +0 -293
- package/latticeai/core/mcp_catalog.py +0 -452
- package/latticeai/core/mcp_registry.py +0 -506
- package/latticeai/core/network_boundary.py +0 -168
- package/latticeai/core/oidc.py +0 -208
- package/latticeai/core/plugins.py +0 -432
- package/latticeai/core/product_hardening.py +0 -218
- package/latticeai/core/project_sessions.py +0 -337
- package/latticeai/core/realtime.py +0 -238
- package/latticeai/core/run_explain.py +0 -426
- package/latticeai/core/run_store.py +0 -252
- package/latticeai/core/timezones.py +0 -80
- package/latticeai/core/workspace_computer_memory.py +0 -84
- package/latticeai/core/workspace_graph_trace.py +0 -155
- package/latticeai/core/workspace_indexing.py +0 -102
- package/latticeai/core/workspace_memory.py +0 -77
- package/latticeai/core/workspace_onboarding.py +0 -104
- package/latticeai/core/workspace_os.py +0 -978
- package/latticeai/core/workspace_os_constants.py +0 -126
- package/latticeai/core/workspace_os_state.py +0 -180
- package/latticeai/core/workspace_os_utils.py +0 -103
- package/latticeai/core/workspace_permissions.py +0 -101
- package/latticeai/core/workspace_plugins.py +0 -97
- package/latticeai/core/workspace_relationships.py +0 -99
- package/latticeai/core/workspace_reorganization.py +0 -335
- package/latticeai/core/workspace_review_items.py +0 -112
- package/latticeai/core/workspace_runs.py +0 -726
- package/latticeai/core/workspace_skills.py +0 -109
- package/latticeai/core/workspace_snapshots.py +0 -198
- package/latticeai/core/workspace_timeline.py +0 -110
- package/latticeai/integrations/__init__.py +0 -0
- package/latticeai/integrations/telegram_bot/__init__.py +0 -123
- package/latticeai/integrations/telegram_bot/__main__.py +0 -17
- package/latticeai/integrations/telegram_bot/config.py +0 -86
- package/latticeai/integrations/telegram_bot/dispatch.py +0 -311
- package/latticeai/integrations/telegram_bot/flows.py +0 -478
- package/latticeai/integrations/telegram_bot/helpers.py +0 -322
- package/latticeai/integrations/telegram_bot/screens.py +0 -394
- package/latticeai/runtime/audit_runtime.py +0 -76
- package/latticeai/runtime/automation_runtime.py +0 -81
- package/latticeai/runtime/chat_wiring.py +0 -141
- package/latticeai/runtime/context_runtime.py +0 -66
- package/latticeai/runtime/feature_toggle_wiring.py +0 -157
- package/latticeai/runtime/history_runtime.py +0 -163
- package/latticeai/runtime/history_writer.py +0 -138
- package/latticeai/runtime/hooks_runtime.py +0 -77
- package/latticeai/runtime/model_wiring.py +0 -68
- package/latticeai/runtime/namespace_runtime.py +0 -163
- package/latticeai/runtime/network_boundary_wiring.py +0 -117
- package/latticeai/runtime/network_config_runtime.py +0 -56
- package/latticeai/runtime/permission_mode_wiring.py +0 -112
- package/latticeai/runtime/persistence_runtime.py +0 -159
- package/latticeai/runtime/platform_runtime_wiring.py +0 -89
- package/latticeai/runtime/review_wiring.py +0 -42
- package/latticeai/runtime/router_registration.py +0 -693
- package/latticeai/runtime/service_singletons.py +0 -55
- package/latticeai/runtime/sso_config_runtime.py +0 -128
- package/latticeai/runtime/user_key_runtime.py +0 -106
- package/latticeai/runtime/web_runtime.py +0 -92
- package/latticeai/server_app.py +0 -51
- package/latticeai/services/app_context.py +0 -130
- package/latticeai/services/automation_execution.py +0 -266
- package/latticeai/services/automation_intelligence.py +0 -614
- package/latticeai/services/brain_automation.py +0 -191
- package/latticeai/services/brain_intelligence/__init__.py +0 -58
- package/latticeai/services/brain_intelligence/_contract.py +0 -71
- package/latticeai/services/brain_intelligence/consistency.py +0 -193
- package/latticeai/services/brain_intelligence/constants.py +0 -47
- package/latticeai/services/brain_intelligence/digest.py +0 -258
- package/latticeai/services/brain_intelligence/health.py +0 -331
- package/latticeai/services/brain_intelligence/proposals.py +0 -259
- package/latticeai/services/brain_intelligence/sampling.py +0 -84
- package/latticeai/services/brain_intelligence/service.py +0 -48
- package/latticeai/services/change_proposals.py +0 -471
- package/latticeai/services/chat_service.py +0 -243
- package/latticeai/services/chronicle.py +0 -555
- package/latticeai/services/cloud_egress_audit.py +0 -85
- package/latticeai/services/cloud_extraction.py +0 -129
- package/latticeai/services/cloud_streaming.py +0 -268
- package/latticeai/services/cloud_token_guard.py +0 -84
- package/latticeai/services/command_center.py +0 -548
- package/latticeai/services/evidence_actions.py +0 -258
- package/latticeai/services/feature_toggles.py +0 -502
- package/latticeai/services/folder_watch.py +0 -520
- package/latticeai/services/funnel_metrics.py +0 -307
- package/latticeai/services/hybrid_chat.py +0 -316
- package/latticeai/services/hybrid_context.py +0 -228
- package/latticeai/services/hybrid_policy.py +0 -129
- package/latticeai/services/interop_bridges.py +0 -978
- package/latticeai/services/local_knowledge.py +0 -465
- package/latticeai/services/memory_service/__init__.py +0 -52
- package/latticeai/services/memory_service/_contract.py +0 -100
- package/latticeai/services/memory_service/brief.py +0 -431
- package/latticeai/services/memory_service/constants.py +0 -57
- package/latticeai/services/memory_service/maintenance.py +0 -138
- package/latticeai/services/memory_service/manager.py +0 -186
- package/latticeai/services/memory_service/proof.py +0 -136
- package/latticeai/services/memory_service/recall.py +0 -225
- package/latticeai/services/memory_service/service.py +0 -48
- package/latticeai/services/memory_service/stores.py +0 -110
- package/latticeai/services/mode_store.py +0 -132
- package/latticeai/services/model_recommendation.py +0 -224
- package/latticeai/services/model_runtime/cloud.py +0 -87
- package/latticeai/services/network_boundary_service.py +0 -117
- package/latticeai/services/obsidian_bridge.py +0 -609
- package/latticeai/services/openai_compatible_adapter.py +0 -101
- package/latticeai/services/permission_mode_service.py +0 -122
- package/latticeai/services/platform_runtime.py +0 -366
- package/latticeai/services/review_queue.py +0 -380
- package/latticeai/services/router_context.py +0 -59
- package/latticeai/services/run_executor.py +0 -387
- package/latticeai/services/self_model_service.py +0 -171
- package/latticeai/services/setup_detection.py +0 -147
- package/latticeai/services/triggers.py +0 -378
- package/latticeai/services/upload_service.py +0 -172
- package/latticeai/services/workspace_service.py +0 -165
- package/latticeai/setup/__init__.py +0 -25
- package/latticeai/setup/auto_setup.py +0 -846
- package/latticeai/setup/demo_corpus.py +0 -98
- package/latticeai/setup/wizard/__init__.py +0 -126
- package/latticeai/setup/wizard/catalog.py +0 -175
- package/latticeai/setup/wizard/detect.py +0 -302
- package/latticeai/setup/wizard/install.py +0 -348
- package/latticeai/setup/wizard/paths.py +0 -165
- package/latticeai/setup/wizard/plans.py +0 -74
- package/latticeai/setup/wizard/recommend.py +0 -320
- package/scripts/bench_agent_smoke.py +0 -409
- package/scripts/bench_models.py +0 -540
- package/scripts/bench_vector_index.py +0 -295
- package/scripts/funnel_soft_gate.py +0 -192
- package/scripts/generate_agent_loop_fixtures.py +0 -994
- package/scripts/generate_rust_parity_fixtures.py +0 -908
- package/scripts/migrate_brain_storage.py +0 -57
- package/scripts/parity_fixture_corpus_context.py +0 -162
- package/scripts/parity_fixture_corpus_docgen.py +0 -341
- package/scripts/profile_kg.py +0 -355
- package/server.py +0 -30
- package/static/app/assets/AdminConsole-cf4npybT.js +0 -1
- package/static/app/assets/Capture-DiQ219jW.js +0 -1
- package/static/app/assets/System-CieofHQa.js +0 -1
- package/static/app/assets/arrow-left-kfsrk0mv.js +0 -1
- package/static/app/assets/circle-check-qqLug9nU.js +0 -1
- package/static/app/assets/index-DxmOfNRi.css +0 -2
- package/static/app/assets/primitives-SNp0LRJz.js +0 -1
- package/static/app/assets/search-BcHqkjoy.js +0 -1
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
"""Per-extension structural checks — step 3 of the pipeline.
|
|
2
|
-
|
|
3
|
-
Answers one question about an already-extracted payload: *is this a file of the
|
|
4
|
-
requested type?* HTML document shape, JSON parses, CSS has rule blocks, Python
|
|
5
|
-
parses, braced code is balanced, components close their blocks — and, for prose
|
|
6
|
-
types with no grammar to check, that the reply is not merely talk about the
|
|
7
|
-
file.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
import ast
|
|
13
|
-
import json
|
|
14
|
-
import re
|
|
15
|
-
from typing import List, Tuple
|
|
16
|
-
|
|
17
|
-
from .extraction import _ext
|
|
18
|
-
|
|
19
|
-
_REFUSAL_RE = re.compile(
|
|
20
|
-
r"(i can('|no)?t|i'?m (sorry|unable)|as an ai|cannot assist"
|
|
21
|
-
r"|죄송(하지만|합니다)|할 수 없|불가능합니다|도와드릴 수 없)",
|
|
22
|
-
re.IGNORECASE,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def looks_like_refusal(content: str) -> bool:
|
|
27
|
-
head = content[:300]
|
|
28
|
-
return bool(_REFUSAL_RE.search(head)) and len(content) < 600
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# Braced code types validated structurally (balanced delimiters, no fences).
|
|
32
|
-
_BRACED_CODE_EXTENSIONS = frozenset({".js", ".jsx", ".ts", ".tsx"})
|
|
33
|
-
# Single-file components validated by their block tags being closed.
|
|
34
|
-
_COMPONENT_EXTENSIONS = frozenset({".vue", ".svelte"})
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _strip_code_literals(text: str) -> str:
|
|
38
|
-
"""Remove string literals and comments so delimiter counting stays honest.
|
|
39
|
-
|
|
40
|
-
A cheap single-pass scanner (not a parser): quotes ('', "", ``), line
|
|
41
|
-
comments (//) and block comments (/* */) commonly contain lone braces
|
|
42
|
-
that would otherwise false-flag valid JS/TS as unbalanced.
|
|
43
|
-
"""
|
|
44
|
-
out: List[str] = []
|
|
45
|
-
i, n = 0, len(text)
|
|
46
|
-
while i < n:
|
|
47
|
-
ch = text[i]
|
|
48
|
-
nxt = text[i + 1] if i + 1 < n else ""
|
|
49
|
-
if ch == "\\":
|
|
50
|
-
i += 2 # escaped char (inside or outside a literal — always skip)
|
|
51
|
-
continue
|
|
52
|
-
if ch in ("'", '"', "`"):
|
|
53
|
-
quote = ch
|
|
54
|
-
i += 1
|
|
55
|
-
while i < n:
|
|
56
|
-
if text[i] == "\\":
|
|
57
|
-
i += 2
|
|
58
|
-
continue
|
|
59
|
-
if text[i] == quote:
|
|
60
|
-
i += 1
|
|
61
|
-
break
|
|
62
|
-
i += 1
|
|
63
|
-
continue
|
|
64
|
-
if ch == "/" and nxt == "/":
|
|
65
|
-
while i < n and text[i] != "\n":
|
|
66
|
-
i += 1
|
|
67
|
-
continue
|
|
68
|
-
if ch == "/" and nxt == "*":
|
|
69
|
-
end = text.find("*/", i + 2)
|
|
70
|
-
i = n if end < 0 else end + 2
|
|
71
|
-
continue
|
|
72
|
-
out.append(ch)
|
|
73
|
-
i += 1
|
|
74
|
-
return "".join(out)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def _check_balanced_delimiters(content: str) -> Tuple[bool, str]:
|
|
78
|
-
"""Lenient count-based balance check for braced code (js/ts family).
|
|
79
|
-
|
|
80
|
-
Only *counts* are compared, never ordering, so valid-but-unusual code is
|
|
81
|
-
not rejected; a truncated file with a dangling ``{`` still fails.
|
|
82
|
-
"""
|
|
83
|
-
stripped = _strip_code_literals(content)
|
|
84
|
-
for opener, closer, label in (("{", "}", "braces"), ("(", ")", "parentheses"), ("[", "]", "brackets")):
|
|
85
|
-
if stripped.count(opener) != stripped.count(closer):
|
|
86
|
-
return False, f"unbalanced {label} ({opener}{closer}) — the file looks truncated"
|
|
87
|
-
return True, "ok"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def _check_component_blocks(content: str) -> Tuple[bool, str]:
|
|
91
|
-
"""Vue/Svelte SFC sanity: every opened block tag must be closed."""
|
|
92
|
-
lower = content.lower()
|
|
93
|
-
for tag in ("template", "script", "style"):
|
|
94
|
-
opened = len(re.findall(rf"<{tag}(?:\s[^>]*)?>", lower))
|
|
95
|
-
closed = lower.count(f"</{tag}>")
|
|
96
|
-
if opened != closed:
|
|
97
|
-
return False, f"<{tag}> block is not closed — the component looks truncated"
|
|
98
|
-
return True, "ok"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def validate_file_content(content: str, target_path: str) -> Tuple[bool, str]:
|
|
102
|
-
"""Structural sanity check per file type. Returns (ok, reason)."""
|
|
103
|
-
if not content.strip():
|
|
104
|
-
return False, "empty output"
|
|
105
|
-
if looks_like_refusal(content):
|
|
106
|
-
return False, "the reply was a refusal/chat message, not file content"
|
|
107
|
-
|
|
108
|
-
ext = _ext(target_path)
|
|
109
|
-
if ext in (".html", ".htm"):
|
|
110
|
-
lower = content.lower()
|
|
111
|
-
if "<html" not in lower and "<!doctype" not in lower:
|
|
112
|
-
return False, "not a complete HTML document (missing <!DOCTYPE html>/<html>)"
|
|
113
|
-
if "</html>" not in lower:
|
|
114
|
-
return False, "HTML document is truncated (missing </html>)"
|
|
115
|
-
# A document that merely *contains* html somewhere is not a valid
|
|
116
|
-
# file payload: fenced/chat-wrapped replies must fail here so the
|
|
117
|
-
# extraction pass gets a chance to slice out the real document.
|
|
118
|
-
stripped = content.lstrip()
|
|
119
|
-
if not (stripped.lower().startswith("<!doctype") or stripped.lower().startswith("<html")):
|
|
120
|
-
return False, "HTML document is wrapped in prose or fences"
|
|
121
|
-
if "```" in content:
|
|
122
|
-
return False, "output still contains Markdown fences"
|
|
123
|
-
return True, "ok"
|
|
124
|
-
if ext == ".json":
|
|
125
|
-
try:
|
|
126
|
-
json.loads(content)
|
|
127
|
-
except (ValueError, TypeError) as exc:
|
|
128
|
-
return False, f"invalid JSON: {exc}"
|
|
129
|
-
return True, "ok"
|
|
130
|
-
if ext == ".css":
|
|
131
|
-
if "```" in content:
|
|
132
|
-
return False, "output still contains Markdown fences"
|
|
133
|
-
if "{" not in content or "}" not in content:
|
|
134
|
-
return False, "no CSS rule blocks found"
|
|
135
|
-
return True, "ok"
|
|
136
|
-
if ext == ".py":
|
|
137
|
-
if "```" in content:
|
|
138
|
-
return False, "output still contains Markdown fences"
|
|
139
|
-
try:
|
|
140
|
-
ast.parse(content)
|
|
141
|
-
except SyntaxError as exc:
|
|
142
|
-
return False, f"invalid Python syntax: {exc.msg} (line {exc.lineno})"
|
|
143
|
-
return True, "ok"
|
|
144
|
-
if ext in _BRACED_CODE_EXTENSIONS:
|
|
145
|
-
if "```" in content:
|
|
146
|
-
return False, "output still contains Markdown fences"
|
|
147
|
-
return _check_balanced_delimiters(content)
|
|
148
|
-
if ext in _COMPONENT_EXTENSIONS:
|
|
149
|
-
if "```" in content:
|
|
150
|
-
return False, "output still contains Markdown fences"
|
|
151
|
-
return _check_component_blocks(content)
|
|
152
|
-
if ext in (".sh", ".sql"):
|
|
153
|
-
if "```" in content:
|
|
154
|
-
return False, "output still contains Markdown fences"
|
|
155
|
-
return True, "ok"
|
|
156
|
-
# Prose types (.md, .txt, .csv, …) have no grammar to check, which used to
|
|
157
|
-
# mean *nothing* was checked: a 1–4B model that answered "Sure! Here is the
|
|
158
|
-
# document you asked for:" and stopped had its sentence saved as the file,
|
|
159
|
-
# because the fence stripper only removes conversational lines it can
|
|
160
|
-
# recognise and the length guard on `looks_like_refusal` lets a wordy
|
|
161
|
-
# refusal through. The two checks below are the only ones that generalise
|
|
162
|
-
# without inventing a grammar: it must not still be wearing fences, and it
|
|
163
|
-
# must not be *only* an answer about the file.
|
|
164
|
-
if "```" in content:
|
|
165
|
-
return False, "output still contains Markdown fences"
|
|
166
|
-
if _looks_like_commentary(content):
|
|
167
|
-
return False, "the reply talks about the file instead of being the file"
|
|
168
|
-
return True, "ok"
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
# Openers that mean "I am about to give you the thing" — if the whole reply is
|
|
172
|
-
# one of these, the thing never arrived.
|
|
173
|
-
_COMMENTARY_RE = re.compile(
|
|
174
|
-
r"^\s*("
|
|
175
|
-
r"(sure|of course|certainly|okay|ok|alright|here|below|the following)\b"
|
|
176
|
-
r"|i('ve| have| will|'ll)\b"
|
|
177
|
-
r"|(물론|네[,!. ]|알겠|다음은|아래(는|의)?|요청하신|원하시는)"
|
|
178
|
-
r")",
|
|
179
|
-
re.IGNORECASE,
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def _looks_like_commentary(content: str) -> bool:
|
|
184
|
-
"""True when the reply reads as an answer *about* a file, not the file.
|
|
185
|
-
|
|
186
|
-
Deliberately conservative — a long document that merely opens with "The
|
|
187
|
-
following" is a document. Only a short reply that both opens
|
|
188
|
-
conversationally and never grows into content is rejected, so a real file
|
|
189
|
-
is never thrown away to catch a chat line.
|
|
190
|
-
"""
|
|
191
|
-
stripped = content.strip()
|
|
192
|
-
if len(stripped) > 400:
|
|
193
|
-
return False
|
|
194
|
-
if not _COMMENTARY_RE.match(stripped):
|
|
195
|
-
return False
|
|
196
|
-
# Structure means content arrived after the preamble: a heading, a list, a
|
|
197
|
-
# table row, a delimiter, or simply several lines of body text.
|
|
198
|
-
body = stripped.split("\n", 1)[1].strip() if "\n" in stripped else ""
|
|
199
|
-
if re.search(r"^\s*(#{1,6}\s|[-*+]\s|\d+[.)]\s|\||>)", body, re.MULTILINE):
|
|
200
|
-
return False
|
|
201
|
-
return len(body) < 120
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
"""Local-first invitation tokens for workspace membership."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
import secrets
|
|
7
|
-
from datetime import datetime, timedelta
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any, Dict, List, Optional
|
|
10
|
-
|
|
11
|
-
from latticeai.core.quiet import quiet
|
|
12
|
-
from latticeai.core.security import sha256_hex
|
|
13
|
-
|
|
14
|
-
from .timeutil import local_now as _now
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _iso(dt: datetime) -> str:
|
|
18
|
-
return dt.isoformat(timespec="seconds")
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _hash_token(token: str) -> str:
|
|
22
|
-
"""Strict by design: an invite code is always a string by the time it lands here."""
|
|
23
|
-
return sha256_hex(token)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def _atomic_write(path: Path, data: Dict[str, Any]) -> None:
|
|
27
|
-
path.parent.mkdir(parents=True, exist_ok=True)
|
|
28
|
-
tmp = path.with_suffix(path.suffix + ".tmp")
|
|
29
|
-
tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
30
|
-
tmp.replace(path)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class InvitationStore:
|
|
34
|
-
def __init__(self, path: Path | str):
|
|
35
|
-
self.path = Path(path)
|
|
36
|
-
|
|
37
|
-
def _load(self) -> Dict[str, Any]:
|
|
38
|
-
if not self.path.exists():
|
|
39
|
-
return {"version": 1, "invitations": []}
|
|
40
|
-
try:
|
|
41
|
-
data = json.loads(self.path.read_text(encoding="utf-8"))
|
|
42
|
-
if isinstance(data, dict):
|
|
43
|
-
data.setdefault("invitations", [])
|
|
44
|
-
return data
|
|
45
|
-
except Exception:
|
|
46
|
-
quiet()
|
|
47
|
-
return {"version": 1, "invitations": []}
|
|
48
|
-
|
|
49
|
-
def _save(self, data: Dict[str, Any]) -> None:
|
|
50
|
-
data["version"] = 1
|
|
51
|
-
_atomic_write(self.path, data)
|
|
52
|
-
|
|
53
|
-
def create(
|
|
54
|
-
self,
|
|
55
|
-
*,
|
|
56
|
-
email: Optional[str],
|
|
57
|
-
workspace_id: Optional[str],
|
|
58
|
-
role: str,
|
|
59
|
-
created_by: Optional[str],
|
|
60
|
-
expires_hours: int = 168,
|
|
61
|
-
) -> Dict[str, Any]:
|
|
62
|
-
token = secrets.token_urlsafe(32)
|
|
63
|
-
now = _now()
|
|
64
|
-
record = {
|
|
65
|
-
"id": f"invite-{secrets.token_hex(8)}",
|
|
66
|
-
"token_hash": _hash_token(token),
|
|
67
|
-
"email": (email or "").strip().lower() or None,
|
|
68
|
-
"workspace_id": workspace_id,
|
|
69
|
-
"role": role,
|
|
70
|
-
"created_by": created_by,
|
|
71
|
-
"created_at": _iso(now),
|
|
72
|
-
"expires_at": _iso(now + timedelta(hours=max(1, min(int(expires_hours or 168), 24 * 30)))),
|
|
73
|
-
"status": "pending",
|
|
74
|
-
"accepted_by": None,
|
|
75
|
-
"accepted_at": None,
|
|
76
|
-
}
|
|
77
|
-
data = self._load()
|
|
78
|
-
data.setdefault("invitations", []).append(record)
|
|
79
|
-
self._save(data)
|
|
80
|
-
public = self.public(record)
|
|
81
|
-
public["token"] = token
|
|
82
|
-
return public
|
|
83
|
-
|
|
84
|
-
def list(self) -> List[Dict[str, Any]]:
|
|
85
|
-
data = self._load()
|
|
86
|
-
changed = False
|
|
87
|
-
records = []
|
|
88
|
-
for record in data.get("invitations") or []:
|
|
89
|
-
if self._expire_if_needed(record):
|
|
90
|
-
changed = True
|
|
91
|
-
records.append(self.public(record))
|
|
92
|
-
if changed:
|
|
93
|
-
self._save(data)
|
|
94
|
-
return records
|
|
95
|
-
|
|
96
|
-
def accept(self, token: str, *, accepted_by: str, email: Optional[str]) -> Dict[str, Any]:
|
|
97
|
-
data = self._load()
|
|
98
|
-
token_hash = _hash_token(token)
|
|
99
|
-
record = next((item for item in data.get("invitations") or [] if item.get("token_hash") == token_hash), None)
|
|
100
|
-
if record is None:
|
|
101
|
-
raise FileNotFoundError("invitation not found")
|
|
102
|
-
if self._expire_if_needed(record):
|
|
103
|
-
self._save(data)
|
|
104
|
-
raise PermissionError("invitation expired")
|
|
105
|
-
if record.get("status") != "pending":
|
|
106
|
-
raise PermissionError(f"invitation is {record.get('status')}")
|
|
107
|
-
invited_email = (record.get("email") or "").lower()
|
|
108
|
-
if invited_email and (not email or invited_email != email.lower()):
|
|
109
|
-
raise PermissionError("invitation was issued for a different email")
|
|
110
|
-
record["status"] = "accepted"
|
|
111
|
-
record["accepted_by"] = accepted_by
|
|
112
|
-
record["accepted_at"] = _iso(_now())
|
|
113
|
-
self._save(data)
|
|
114
|
-
return self.public(record)
|
|
115
|
-
|
|
116
|
-
@staticmethod
|
|
117
|
-
def _expire_if_needed(record: Dict[str, Any]) -> bool:
|
|
118
|
-
if record.get("status") != "pending":
|
|
119
|
-
return False
|
|
120
|
-
try:
|
|
121
|
-
expires_at = datetime.fromisoformat(str(record.get("expires_at")))
|
|
122
|
-
except Exception:
|
|
123
|
-
expires_at = _now() - timedelta(seconds=1)
|
|
124
|
-
if expires_at >= _now():
|
|
125
|
-
return False
|
|
126
|
-
record["status"] = "expired"
|
|
127
|
-
record["expired_at"] = _iso(_now())
|
|
128
|
-
return True
|
|
129
|
-
|
|
130
|
-
@staticmethod
|
|
131
|
-
def public(record: Dict[str, Any]) -> Dict[str, Any]:
|
|
132
|
-
return {k: v for k, v in record.items() if k != "token_hash"}
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
"""Managed legacy compatibility surface for legacy import shims.
|
|
2
|
-
|
|
3
|
-
Compatibility modules are intentionally still present for old scripts, VS Code
|
|
4
|
-
extension paths, historical integrations, and pre-graph-package imports. 8.4.0
|
|
5
|
-
stops treating them as vague technical debt: every tracked shim has an owner,
|
|
6
|
-
migration target, removal phase, and replacement import that can be surfaced in
|
|
7
|
-
docs and tests.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
from dataclasses import dataclass
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
from typing import Any, Dict, List
|
|
15
|
-
|
|
16
|
-
LEGACY_COMPATIBILITY_VERSION = "11.5.2"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@dataclass(frozen=True)
|
|
20
|
-
class LegacyShim:
|
|
21
|
-
path: str
|
|
22
|
-
owner: str
|
|
23
|
-
replacement: str
|
|
24
|
-
reason: str
|
|
25
|
-
removal_phase: str
|
|
26
|
-
layer: str = "root"
|
|
27
|
-
status: str = "managed"
|
|
28
|
-
|
|
29
|
-
def as_dict(self) -> Dict[str, str]:
|
|
30
|
-
return {
|
|
31
|
-
"path": self.path,
|
|
32
|
-
"owner": self.owner,
|
|
33
|
-
"replacement": self.replacement,
|
|
34
|
-
"reason": self.reason,
|
|
35
|
-
"removal_phase": self.removal_phase,
|
|
36
|
-
"layer": self.layer,
|
|
37
|
-
"status": self.status,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
LEGACY_SHIMS: List[LegacyShim] = [
|
|
42
|
-
LegacyShim(
|
|
43
|
-
path="server.py",
|
|
44
|
-
owner="latticeai.server_app",
|
|
45
|
-
replacement="from latticeai.server_app import app, main",
|
|
46
|
-
reason="Deployment docs, Docker CMD, start scripts, and uvicorn targets still use server:app.",
|
|
47
|
-
removal_phase="major-release-after-9.x",
|
|
48
|
-
),
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
# Shim layers that have completed their compatibility window and were
|
|
52
|
-
# physically deleted. Kept in the report so consumers (docs, tests, release
|
|
53
|
-
# notes) can tell "removed on purpose" apart from "missing by accident".
|
|
54
|
-
# Removing the internal-only layers is the first step of extracting
|
|
55
|
-
# ``lattice_brain`` as a standalone Brain Core package: the package now has
|
|
56
|
-
# exactly one import surface (``lattice_brain.*`` physical paths).
|
|
57
|
-
REMOVED_SHIMS: List[LegacyShim] = [
|
|
58
|
-
LegacyShim(
|
|
59
|
-
path="knowledge_graph.py",
|
|
60
|
-
owner="lattice_brain.graph.store",
|
|
61
|
-
replacement="from lattice_brain.graph.store import KnowledgeGraphStore",
|
|
62
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
63
|
-
removal_phase="removed-9.9.1",
|
|
64
|
-
layer="root",
|
|
65
|
-
status="removed",
|
|
66
|
-
),
|
|
67
|
-
LegacyShim(
|
|
68
|
-
path="knowledge_graph_api.py",
|
|
69
|
-
owner="latticeai.api.knowledge_graph",
|
|
70
|
-
replacement="from latticeai.api.knowledge_graph import create_knowledge_graph_router",
|
|
71
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
72
|
-
removal_phase="removed-9.9.1",
|
|
73
|
-
layer="root",
|
|
74
|
-
status="removed",
|
|
75
|
-
),
|
|
76
|
-
LegacyShim(
|
|
77
|
-
path="kg_schema.py",
|
|
78
|
-
owner="lattice_brain.graph.schema",
|
|
79
|
-
replacement="from lattice_brain.graph.schema import ...",
|
|
80
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
81
|
-
removal_phase="removed-9.9.1",
|
|
82
|
-
layer="root",
|
|
83
|
-
status="removed",
|
|
84
|
-
),
|
|
85
|
-
LegacyShim(
|
|
86
|
-
path="ltcai_cli.py",
|
|
87
|
-
owner="latticeai.cli.entrypoint",
|
|
88
|
-
replacement="from latticeai.cli.entrypoint import main",
|
|
89
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
90
|
-
removal_phase="removed-9.9.1",
|
|
91
|
-
layer="root",
|
|
92
|
-
status="removed",
|
|
93
|
-
),
|
|
94
|
-
LegacyShim(
|
|
95
|
-
path="telegram_bot.py",
|
|
96
|
-
owner="latticeai.integrations.telegram_bot",
|
|
97
|
-
replacement="from latticeai.integrations.telegram_bot import run_bot",
|
|
98
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
99
|
-
removal_phase="removed-9.9.1",
|
|
100
|
-
layer="root",
|
|
101
|
-
status="removed",
|
|
102
|
-
),
|
|
103
|
-
LegacyShim(
|
|
104
|
-
path="p_reinforce.py",
|
|
105
|
-
owner="latticeai.services.p_reinforce",
|
|
106
|
-
replacement="from latticeai.services.p_reinforce import PReinforceGardener",
|
|
107
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
108
|
-
removal_phase="removed-9.9.1",
|
|
109
|
-
layer="root",
|
|
110
|
-
status="removed",
|
|
111
|
-
),
|
|
112
|
-
LegacyShim(
|
|
113
|
-
path="mcp_registry.py",
|
|
114
|
-
owner="latticeai.core.mcp_registry",
|
|
115
|
-
replacement="import latticeai.core.mcp_registry",
|
|
116
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
117
|
-
removal_phase="removed-9.9.1",
|
|
118
|
-
layer="root",
|
|
119
|
-
status="removed",
|
|
120
|
-
),
|
|
121
|
-
LegacyShim(
|
|
122
|
-
path="llm_router.py",
|
|
123
|
-
owner="latticeai.models.router",
|
|
124
|
-
replacement="import latticeai.models.router",
|
|
125
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
126
|
-
removal_phase="removed-9.9.1",
|
|
127
|
-
layer="root",
|
|
128
|
-
status="removed",
|
|
129
|
-
),
|
|
130
|
-
LegacyShim(
|
|
131
|
-
path="local_knowledge_api.py",
|
|
132
|
-
owner="latticeai.services.local_knowledge",
|
|
133
|
-
replacement="from latticeai.services.local_knowledge import create_local_knowledge_router",
|
|
134
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
135
|
-
removal_phase="removed-9.9.1",
|
|
136
|
-
layer="root",
|
|
137
|
-
status="removed",
|
|
138
|
-
),
|
|
139
|
-
LegacyShim(
|
|
140
|
-
path="auto_setup.py",
|
|
141
|
-
owner="latticeai.setup.auto_setup",
|
|
142
|
-
replacement="from latticeai.setup.auto_setup import probe, recommend",
|
|
143
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
144
|
-
removal_phase="removed-9.9.1",
|
|
145
|
-
layer="root",
|
|
146
|
-
status="removed",
|
|
147
|
-
),
|
|
148
|
-
LegacyShim(
|
|
149
|
-
path="setup_wizard.py",
|
|
150
|
-
owner="latticeai.setup.wizard",
|
|
151
|
-
replacement="from latticeai.setup.wizard import scan_environment",
|
|
152
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
153
|
-
removal_phase="removed-9.9.1",
|
|
154
|
-
layer="root",
|
|
155
|
-
status="removed",
|
|
156
|
-
),
|
|
157
|
-
LegacyShim(
|
|
158
|
-
path="tools/",
|
|
159
|
-
owner="latticeai.tools",
|
|
160
|
-
replacement="from latticeai.tools import execute_tool",
|
|
161
|
-
reason="Root compatibility shims completed their window; removed in 9.9.1.",
|
|
162
|
-
removal_phase="removed-9.9.1",
|
|
163
|
-
layer="root",
|
|
164
|
-
status="removed",
|
|
165
|
-
),
|
|
166
|
-
LegacyShim(
|
|
167
|
-
path="lattice_brain/store.py",
|
|
168
|
-
owner="lattice_brain.graph.store",
|
|
169
|
-
replacement="from lattice_brain.graph.store import KnowledgeGraphStore",
|
|
170
|
-
reason="Pre-graph-package flat modules were internal-only; removed in 8.8.0.",
|
|
171
|
-
removal_phase="removed-8.8.0",
|
|
172
|
-
layer="brain-flat",
|
|
173
|
-
status="removed",
|
|
174
|
-
),
|
|
175
|
-
LegacyShim(
|
|
176
|
-
path="lattice_brain/ingest.py",
|
|
177
|
-
owner="lattice_brain.graph.ingest",
|
|
178
|
-
replacement="from lattice_brain.graph.ingest import KnowledgeGraphIngestMixin",
|
|
179
|
-
reason="Pre-graph-package flat modules were internal-only; removed in 8.8.0.",
|
|
180
|
-
removal_phase="removed-8.8.0",
|
|
181
|
-
layer="brain-flat",
|
|
182
|
-
status="removed",
|
|
183
|
-
),
|
|
184
|
-
LegacyShim(
|
|
185
|
-
path="lattice_brain/retrieval.py",
|
|
186
|
-
owner="lattice_brain.graph.retrieval",
|
|
187
|
-
replacement="from lattice_brain.graph.retrieval import KnowledgeGraphRetrievalMixin",
|
|
188
|
-
reason="Pre-graph-package flat modules were internal-only; removed in 8.8.0.",
|
|
189
|
-
removal_phase="removed-8.8.0",
|
|
190
|
-
layer="brain-flat",
|
|
191
|
-
status="removed",
|
|
192
|
-
),
|
|
193
|
-
LegacyShim(
|
|
194
|
-
path="latticeai/brain/",
|
|
195
|
-
owner="lattice_brain",
|
|
196
|
-
replacement="import lattice_brain",
|
|
197
|
-
reason="The deprecated latticeai.brain namespace completed its window; removed in 8.8.0.",
|
|
198
|
-
removal_phase="removed-8.8.0",
|
|
199
|
-
layer="deprecated-namespace",
|
|
200
|
-
status="removed",
|
|
201
|
-
),
|
|
202
|
-
LegacyShim(
|
|
203
|
-
path="latticeai/services/agent_runtime.py",
|
|
204
|
-
owner="lattice_brain.runtime.agent_runtime",
|
|
205
|
-
replacement="from lattice_brain.runtime.agent_runtime import AgentRuntime",
|
|
206
|
-
reason="The service-layer alias completed its window; removed in 8.8.0.",
|
|
207
|
-
removal_phase="removed-8.8.0",
|
|
208
|
-
layer="service-alias",
|
|
209
|
-
status="removed",
|
|
210
|
-
),
|
|
211
|
-
]
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
def legacy_shim_report(root: Path | None = None) -> Dict[str, Any]:
|
|
215
|
-
if root is None:
|
|
216
|
-
root = Path(__file__).resolve().parents[2]
|
|
217
|
-
entries = [shim.as_dict() for shim in LEGACY_SHIMS]
|
|
218
|
-
missing = [shim.path for shim in LEGACY_SHIMS if not (root / shim.path).exists()]
|
|
219
|
-
lingering = [shim.path for shim in REMOVED_SHIMS if (root / shim.path).exists()]
|
|
220
|
-
phases = sorted({shim.removal_phase for shim in LEGACY_SHIMS})
|
|
221
|
-
layers = sorted({shim.layer for shim in LEGACY_SHIMS})
|
|
222
|
-
return {
|
|
223
|
-
"schema_version": "legacy-compatibility/v1",
|
|
224
|
-
"version_target": LEGACY_COMPATIBILITY_VERSION,
|
|
225
|
-
"status": "managed" if not missing and not lingering else "incomplete",
|
|
226
|
-
"remaining_count": len(LEGACY_SHIMS),
|
|
227
|
-
"removed_count": len(REMOVED_SHIMS),
|
|
228
|
-
"missing": missing,
|
|
229
|
-
"lingering": lingering,
|
|
230
|
-
"removal_phases": phases,
|
|
231
|
-
"layers": layers,
|
|
232
|
-
"shims": entries,
|
|
233
|
-
"removed": [shim.as_dict() for shim in REMOVED_SHIMS],
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
__all__ = [
|
|
238
|
-
"LEGACY_COMPATIBILITY_VERSION",
|
|
239
|
-
"LEGACY_SHIMS",
|
|
240
|
-
"REMOVED_SHIMS",
|
|
241
|
-
"LegacyShim",
|
|
242
|
-
"legacy_shim_report",
|
|
243
|
-
]
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"""Helpers for keeping sensitive values out of logs."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import logging
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
from latticeai.core.security import redact_secret_text, redact_secrets
|
|
9
|
-
|
|
10
|
-
_LOG_FILTER_INSTALLED = False
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def mask_telegram_bot_token(value: Any) -> str:
|
|
14
|
-
"""Return ``value`` as text with Telegram bot token and other secrets redacted."""
|
|
15
|
-
|
|
16
|
-
return redact_secret_text(str(value))
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def safe_log_text(value: Any) -> str:
|
|
20
|
-
"""Sanitize text before it is sent to application logs."""
|
|
21
|
-
|
|
22
|
-
return mask_telegram_bot_token(value)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _safe_log_arg(value: Any) -> Any:
|
|
26
|
-
return redact_secrets(value)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def install_sensitive_log_filter() -> None:
|
|
30
|
-
"""Install a process-wide log-record sanitizer for known secret shapes."""
|
|
31
|
-
|
|
32
|
-
global _LOG_FILTER_INSTALLED
|
|
33
|
-
if _LOG_FILTER_INSTALLED:
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
original_factory = logging.getLogRecordFactory()
|
|
37
|
-
|
|
38
|
-
def factory(*args: Any, **kwargs: Any) -> logging.LogRecord:
|
|
39
|
-
record = original_factory(*args, **kwargs)
|
|
40
|
-
record.msg = _safe_log_arg(record.msg)
|
|
41
|
-
if record.args:
|
|
42
|
-
record.args = _safe_log_arg(record.args)
|
|
43
|
-
return record
|
|
44
|
-
|
|
45
|
-
logging.setLogRecordFactory(factory)
|
|
46
|
-
_LOG_FILTER_INSTALLED = True
|