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,158 +0,0 @@
|
|
|
1
|
-
"""Enterprise PoC surfaces (admin policies, audit export, SIEM stub, org settings).
|
|
2
|
-
|
|
3
|
-
This module is **structure only** — it prepares concrete, discoverable shapes for
|
|
4
|
-
Enterprise governance features while keeping the open-source Community edition
|
|
5
|
-
fully functional and ungated. Every capability here is consulted through
|
|
6
|
-
:data:`latticeai.core.enterprise.capability_registry`; in the Community build
|
|
7
|
-
each is reported ``enabled=False`` and the Community behaviour (local audit
|
|
8
|
-
export, the four base roles, single-tenant local storage) is always available.
|
|
9
|
-
|
|
10
|
-
Nothing in this module restricts a Community feature. It answers "what *would*
|
|
11
|
-
an Enterprise provider light up, and is it active?" so the admin UI can show an
|
|
12
|
-
honest edition/capability matrix and a SIEM export *preview envelope* without
|
|
13
|
-
shipping any Enterprise implementation.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
from typing import Any, Dict, List, Optional
|
|
19
|
-
|
|
20
|
-
from latticeai.core.enterprise import (
|
|
21
|
-
EnterpriseCapability,
|
|
22
|
-
capability_registry,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
COMMUNITY_NOTICE = (
|
|
26
|
-
"Community edition: this is an Enterprise extension point and is not "
|
|
27
|
-
"enforced. Local-first behaviour is always available. See "
|
|
28
|
-
"docs/ENTERPRISE.md and docs/EDITION_STRATEGY.md."
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def _cap(capability: EnterpriseCapability) -> bool:
|
|
33
|
-
return capability_registry.is_capability_enabled(capability)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def admin_policies() -> Dict[str, Any]:
|
|
37
|
-
"""Admin policy-pack status + the effective (open) Community policy."""
|
|
38
|
-
enabled = _cap(EnterpriseCapability.ADMIN_POLICY_PACKS)
|
|
39
|
-
return {
|
|
40
|
-
"capability": EnterpriseCapability.ADMIN_POLICY_PACKS.value,
|
|
41
|
-
"enabled": enabled,
|
|
42
|
-
"enforced": enabled,
|
|
43
|
-
"effective_policy": {
|
|
44
|
-
# Community defaults — descriptive, not enforced by a policy engine.
|
|
45
|
-
"base_roles": ["owner", "admin", "member", "viewer"],
|
|
46
|
-
"local_file_access": "approval-token gated (per path/user/action)",
|
|
47
|
-
"package_install": "admin-only with audit trail",
|
|
48
|
-
"network_binding": "127.0.0.1 by default",
|
|
49
|
-
"managed_policy_packs": [] if not enabled else "provided-by-enterprise",
|
|
50
|
-
},
|
|
51
|
-
"note": COMMUNITY_NOTICE,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def audit_export_descriptor() -> Dict[str, Any]:
|
|
56
|
-
"""What audit export is available locally vs. via Enterprise SIEM streaming."""
|
|
57
|
-
siem_enabled = _cap(EnterpriseCapability.SIEM_EXPORT)
|
|
58
|
-
retention_enabled = _cap(EnterpriseCapability.COMPLIANCE_RETENTION)
|
|
59
|
-
return {
|
|
60
|
-
"local_export": {
|
|
61
|
-
"available": True,
|
|
62
|
-
"endpoint": "/admin/security/export",
|
|
63
|
-
"formats": ["json", "csv", "xlsx", "txt", "pdf"],
|
|
64
|
-
"note": "Community local audit export is always available to admins.",
|
|
65
|
-
},
|
|
66
|
-
"siem_streaming": {
|
|
67
|
-
"capability": EnterpriseCapability.SIEM_EXPORT.value,
|
|
68
|
-
"enabled": siem_enabled,
|
|
69
|
-
"note": COMMUNITY_NOTICE,
|
|
70
|
-
},
|
|
71
|
-
"compliance_retention": {
|
|
72
|
-
"capability": EnterpriseCapability.COMPLIANCE_RETENTION.value,
|
|
73
|
-
"enabled": retention_enabled,
|
|
74
|
-
"note": COMMUNITY_NOTICE,
|
|
75
|
-
},
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
def siem_export_stub(events: Optional[List[Dict[str, Any]]] = None) -> Dict[str, Any]:
|
|
80
|
-
"""A preview of the envelope an Enterprise SIEM exporter would emit.
|
|
81
|
-
|
|
82
|
-
In the Community build this is a *stub*: it returns the envelope *shape*
|
|
83
|
-
(so integrators can see the contract) but ``streamed=False`` and no events
|
|
84
|
-
are actually pushed to an external SIEM.
|
|
85
|
-
"""
|
|
86
|
-
enabled = _cap(EnterpriseCapability.SIEM_EXPORT)
|
|
87
|
-
sample = events or [
|
|
88
|
-
{
|
|
89
|
-
"id": "evt_sample",
|
|
90
|
-
"type": "audit_event",
|
|
91
|
-
"timestamp": "1970-01-01T00:00:00Z",
|
|
92
|
-
"actor": "admin@example.com",
|
|
93
|
-
"action": "model_load",
|
|
94
|
-
"severity": "informational",
|
|
95
|
-
}
|
|
96
|
-
]
|
|
97
|
-
envelope = {
|
|
98
|
-
"format": "ltcai.siem.v1",
|
|
99
|
-
"encoding": "ndjson",
|
|
100
|
-
"vendor": "LatticeAI",
|
|
101
|
-
"product": "Workspace OS",
|
|
102
|
-
"records": [
|
|
103
|
-
{
|
|
104
|
-
"ts": e.get("timestamp"),
|
|
105
|
-
"actor": e.get("actor"),
|
|
106
|
-
"act": e.get("action"),
|
|
107
|
-
"sev": e.get("severity", "informational"),
|
|
108
|
-
"kind": e.get("type"),
|
|
109
|
-
"id": e.get("id"),
|
|
110
|
-
}
|
|
111
|
-
for e in sample
|
|
112
|
-
],
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
"capability": EnterpriseCapability.SIEM_EXPORT.value,
|
|
116
|
-
"enabled": enabled,
|
|
117
|
-
"streamed": False if not enabled else True,
|
|
118
|
-
"destination": None if not enabled else "configured-by-enterprise",
|
|
119
|
-
"preview_envelope": envelope,
|
|
120
|
-
"note": COMMUNITY_NOTICE,
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
def organization_settings() -> Dict[str, Any]:
|
|
125
|
-
"""Org-scale governance capabilities and their (Community=off) state."""
|
|
126
|
-
governance_caps = [
|
|
127
|
-
EnterpriseCapability.TENANT_ISOLATION,
|
|
128
|
-
EnterpriseCapability.RBAC_ABAC_ADVANCED,
|
|
129
|
-
EnterpriseCapability.SCIM,
|
|
130
|
-
EnterpriseCapability.IDP_PROVISIONING,
|
|
131
|
-
EnterpriseCapability.SSO_ADVANCED,
|
|
132
|
-
EnterpriseCapability.DLP_POLICY,
|
|
133
|
-
EnterpriseCapability.EDISCOVERY,
|
|
134
|
-
EnterpriseCapability.PRIVATE_VPC,
|
|
135
|
-
EnterpriseCapability.AIR_GAPPED_DEPLOYMENT,
|
|
136
|
-
]
|
|
137
|
-
return {
|
|
138
|
-
"community_baseline": {
|
|
139
|
-
"workspaces": ["personal", "organization"],
|
|
140
|
-
"roles": ["owner", "admin", "member", "viewer"],
|
|
141
|
-
"data_isolation": "single-tenant local storage (~/.ltcai)",
|
|
142
|
-
},
|
|
143
|
-
"governance_capabilities": {
|
|
144
|
-
cap.value: _cap(cap) for cap in governance_caps
|
|
145
|
-
},
|
|
146
|
-
"note": COMMUNITY_NOTICE,
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def poc_overview() -> Dict[str, Any]:
|
|
151
|
-
"""Combined Enterprise PoC surface for the admin dashboard."""
|
|
152
|
-
return {
|
|
153
|
-
"edition": capability_registry.describe(),
|
|
154
|
-
"admin_policies": admin_policies(),
|
|
155
|
-
"audit_export": audit_export_descriptor(),
|
|
156
|
-
"siem_export": siem_export_stub(),
|
|
157
|
-
"organization_settings": organization_settings(),
|
|
158
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"""Model-agnostic file content generation pipeline.
|
|
2
|
-
|
|
3
|
-
Small local models (gemma/qwen/llama 7B class) asked to "generate an HTML
|
|
4
|
-
file" commonly wrap the payload in chat noise: leading commentary ("Sure!
|
|
5
|
-
Here is your page:"), Markdown fences, ``<think>`` reasoning blocks,
|
|
6
|
-
trailing explanations, or an incomplete document. The previous direct-write
|
|
7
|
-
path saved that reply nearly verbatim, so weak models produced broken files.
|
|
8
|
-
|
|
9
|
-
This package makes the file-creation flow robust regardless of which LLM is
|
|
10
|
-
loaded, by treating the model as an untrusted content source:
|
|
11
|
-
|
|
12
|
-
1. Prompt — extension-aware instructions anchored with the exact first
|
|
13
|
-
line the reply must start with (small models follow examples, not rules).
|
|
14
|
-
→ :mod:`.prompting`
|
|
15
|
-
2. Extract — strip reasoning blocks and conversational framing, pick the
|
|
16
|
-
best fenced block, slice known document boundaries. → :mod:`.extraction`
|
|
17
|
-
3. Validate — per-extension structural checks (HTML document shape, JSON
|
|
18
|
-
parses, CSS has rule blocks, refusal/chat detection). → :mod:`.validation`
|
|
19
|
-
4. Retry — one corrective attempt that tells the model what was wrong.
|
|
20
|
-
→ :mod:`.orchestration`
|
|
21
|
-
5. Repair — deterministic scaffolds guarantee the user still gets a valid
|
|
22
|
-
file even when the model never produces usable output. → :mod:`.repair`
|
|
23
|
-
|
|
24
|
-
Alongside the five steps: :mod:`.sanitize` is the single write-side door every
|
|
25
|
-
entry point runs untrusted content through, :mod:`.inference` guesses a
|
|
26
|
-
filename or a whole project manifest when the user named neither, and
|
|
27
|
-
:mod:`.bundles` checks that a multi-file project's links hold together.
|
|
28
|
-
|
|
29
|
-
The pipeline is pure (no I/O, no FastAPI); the chat layer injects an async
|
|
30
|
-
``generate(context) -> str`` callable.
|
|
31
|
-
|
|
32
|
-
Split into these submodules in v11.3.0 with no behaviour change. Every name
|
|
33
|
-
the single module exposed still resolves from ``latticeai.core.file_generation``.
|
|
34
|
-
|
|
35
|
-
Stubbing note: a name rebound *here* changes only this module's binding — the
|
|
36
|
-
submodule that calls it holds its own. A test standing in for one of the
|
|
37
|
-
regex/helper seams patches the submodule that reads it (for example
|
|
38
|
-
``latticeai.core.file_generation.inference._PKG_NAME_RE``).
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
from __future__ import annotations
|
|
42
|
-
|
|
43
|
-
# The single module bound this for its own use, which made it part of the
|
|
44
|
-
# surface callers could reach. Re-exported in the redundant-alias form so it
|
|
45
|
-
# reads as deliberate rather than as a leftover import.
|
|
46
|
-
from latticeai.core.quiet import quiet as quiet
|
|
47
|
-
|
|
48
|
-
from .bundles import _EXTERNAL_REF_PREFIXES as _EXTERNAL_REF_PREFIXES
|
|
49
|
-
from .bundles import _HTML_LOCAL_REF_RE as _HTML_LOCAL_REF_RE
|
|
50
|
-
from .bundles import _local_bundle_refs as _local_bundle_refs
|
|
51
|
-
from .bundles import repair_bundle_references as repair_bundle_references
|
|
52
|
-
from .bundles import validate_project_bundle as validate_project_bundle
|
|
53
|
-
from .extraction import _CHAT_LINE_RE as _CHAT_LINE_RE
|
|
54
|
-
from .extraction import _EXT_FENCE_LANGS as _EXT_FENCE_LANGS
|
|
55
|
-
from .extraction import _FENCE_RE as _FENCE_RE
|
|
56
|
-
from .extraction import _THINK_BLOCK_RE as _THINK_BLOCK_RE
|
|
57
|
-
from .extraction import _THINK_OPEN_RE as _THINK_OPEN_RE
|
|
58
|
-
from .extraction import _ext as _ext
|
|
59
|
-
from .extraction import _slice_html_document as _slice_html_document
|
|
60
|
-
from .extraction import _slice_json_document as _slice_json_document
|
|
61
|
-
from .extraction import _strip_chat_lines as _strip_chat_lines
|
|
62
|
-
from .extraction import extract_file_content as extract_file_content
|
|
63
|
-
from .inference import _CREATE_VERB_RE as _CREATE_VERB_RE
|
|
64
|
-
from .inference import _CSS_HINT_RE as _CSS_HINT_RE
|
|
65
|
-
from .inference import _EXPLICIT_FILENAME_RE as _EXPLICIT_FILENAME_RE
|
|
66
|
-
from .inference import _HTML_HINT_RE as _HTML_HINT_RE
|
|
67
|
-
from .inference import _JS_HINT_RE as _JS_HINT_RE
|
|
68
|
-
from .inference import _PACKAGE_HINT_RE as _PACKAGE_HINT_RE
|
|
69
|
-
from .inference import _PKG_NAME_RE as _PKG_NAME_RE
|
|
70
|
-
from .inference import _PROJECT_NAME_RE as _PROJECT_NAME_RE
|
|
71
|
-
from .inference import _PYTHON_HINT_RE as _PYTHON_HINT_RE
|
|
72
|
-
from .inference import _REACT_HINT_RE as _REACT_HINT_RE
|
|
73
|
-
from .inference import _TYPE_KEYWORDS as _TYPE_KEYWORDS
|
|
74
|
-
from .inference import _VITE_HINT_RE as _VITE_HINT_RE
|
|
75
|
-
from .inference import _python_package_manifest as _python_package_manifest
|
|
76
|
-
from .inference import _react_manifest as _react_manifest
|
|
77
|
-
from .inference import infer_file_target as infer_file_target
|
|
78
|
-
from .inference import infer_project_manifest as infer_project_manifest
|
|
79
|
-
from .orchestration import _salvage_score as _salvage_score
|
|
80
|
-
from .orchestration import generate_file_content as generate_file_content
|
|
81
|
-
from .prompting import _BUNDLE_HTML_MODULE_RULE as _BUNDLE_HTML_MODULE_RULE
|
|
82
|
-
from .prompting import _BUNDLE_HTML_RULE as _BUNDLE_HTML_RULE
|
|
83
|
-
from .prompting import _FIRST_LINE_HINTS as _FIRST_LINE_HINTS
|
|
84
|
-
from .prompting import _TYPE_RULES as _TYPE_RULES
|
|
85
|
-
from .prompting import _bundle_html_rule as _bundle_html_rule
|
|
86
|
-
from .prompting import build_file_generation_context as build_file_generation_context
|
|
87
|
-
from .repair import _repair_html as _repair_html
|
|
88
|
-
from .repair import repair_file_content as repair_file_content
|
|
89
|
-
from .sanitize import PREVIEWABLE_EXTENSIONS as PREVIEWABLE_EXTENSIONS
|
|
90
|
-
from .sanitize import sanitize_write_content as sanitize_write_content
|
|
91
|
-
from .validation import _BRACED_CODE_EXTENSIONS as _BRACED_CODE_EXTENSIONS
|
|
92
|
-
from .validation import _COMMENTARY_RE as _COMMENTARY_RE
|
|
93
|
-
from .validation import _COMPONENT_EXTENSIONS as _COMPONENT_EXTENSIONS
|
|
94
|
-
from .validation import _REFUSAL_RE as _REFUSAL_RE
|
|
95
|
-
from .validation import _check_balanced_delimiters as _check_balanced_delimiters
|
|
96
|
-
from .validation import _check_component_blocks as _check_component_blocks
|
|
97
|
-
from .validation import _looks_like_commentary as _looks_like_commentary
|
|
98
|
-
from .validation import _strip_code_literals as _strip_code_literals
|
|
99
|
-
from .validation import looks_like_refusal as looks_like_refusal
|
|
100
|
-
from .validation import validate_file_content as validate_file_content
|
|
101
|
-
|
|
102
|
-
__all__ = [
|
|
103
|
-
"PREVIEWABLE_EXTENSIONS",
|
|
104
|
-
"build_file_generation_context",
|
|
105
|
-
"extract_file_content",
|
|
106
|
-
"generate_file_content",
|
|
107
|
-
"infer_file_target",
|
|
108
|
-
"infer_project_manifest",
|
|
109
|
-
"looks_like_refusal",
|
|
110
|
-
"repair_bundle_references",
|
|
111
|
-
"repair_file_content",
|
|
112
|
-
"sanitize_write_content",
|
|
113
|
-
"validate_file_content",
|
|
114
|
-
"validate_project_bundle",
|
|
115
|
-
]
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"""Bundle-level checks: does this set of files hold together?
|
|
2
|
-
|
|
3
|
-
A multi-file project is only as valid as its links. These helpers find the
|
|
4
|
-
local references an HTML document makes, repoint the ones a weak model got
|
|
5
|
-
almost right, and report every file that is invalid or dangling.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import re
|
|
11
|
-
from typing import Any, Dict, List, Tuple
|
|
12
|
-
|
|
13
|
-
from .extraction import _ext
|
|
14
|
-
from .validation import validate_file_content
|
|
15
|
-
|
|
16
|
-
_HTML_LOCAL_REF_RE = re.compile(
|
|
17
|
-
r"(?:href|src)\s*=\s*[\"']([^\"'#?]+)[\"']", re.IGNORECASE
|
|
18
|
-
)
|
|
19
|
-
_EXTERNAL_REF_PREFIXES = ("http://", "https://", "//", "data:", "mailto:", "tel:", "javascript:")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def _local_bundle_refs(html: str) -> List[str]:
|
|
23
|
-
"""File references inside an HTML document that must exist in the bundle."""
|
|
24
|
-
refs: List[str] = []
|
|
25
|
-
for ref in _HTML_LOCAL_REF_RE.findall(html or ""):
|
|
26
|
-
candidate = ref.strip()
|
|
27
|
-
if not candidate or candidate.startswith(_EXTERNAL_REF_PREFIXES):
|
|
28
|
-
continue
|
|
29
|
-
if "." not in candidate.rsplit("/", 1)[-1]:
|
|
30
|
-
continue # anchors / routes, not files
|
|
31
|
-
refs.append(candidate)
|
|
32
|
-
return refs
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def repair_bundle_references(files: Dict[str, str]) -> Tuple[Dict[str, str], List[str]]:
|
|
36
|
-
"""Deterministically point dangling HTML refs at real bundle files.
|
|
37
|
-
|
|
38
|
-
A weak model asked for ``style.css`` sometimes links ``styles.css``. When
|
|
39
|
-
a referenced file is missing but the bundle contains exactly one file of
|
|
40
|
-
the same extension, the reference is rewritten. Returns ``(files, fixes)``.
|
|
41
|
-
"""
|
|
42
|
-
names = {p.rsplit("/", 1)[-1] for p in files}
|
|
43
|
-
fixes: List[str] = []
|
|
44
|
-
repaired = dict(files)
|
|
45
|
-
for path, content in files.items():
|
|
46
|
-
if _ext(path) not in (".html", ".htm"):
|
|
47
|
-
continue
|
|
48
|
-
updated = content
|
|
49
|
-
for ref in _local_bundle_refs(content):
|
|
50
|
-
base = ref.rsplit("/", 1)[-1]
|
|
51
|
-
if base in names:
|
|
52
|
-
continue
|
|
53
|
-
same_ext = [n for n in names if _ext(n) == _ext(base)]
|
|
54
|
-
if len(same_ext) == 1:
|
|
55
|
-
updated = updated.replace(ref, same_ext[0])
|
|
56
|
-
fixes.append(f"{path}: '{ref}' -> '{same_ext[0]}'")
|
|
57
|
-
if updated != content:
|
|
58
|
-
repaired[path] = updated
|
|
59
|
-
return repaired, fixes
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def validate_project_bundle(files: Dict[str, str]) -> Dict[str, Any]:
|
|
63
|
-
"""Bundle-level verification: every file valid, every HTML ref resolvable."""
|
|
64
|
-
issues: List[str] = []
|
|
65
|
-
per_file: Dict[str, Dict[str, Any]] = {}
|
|
66
|
-
names = {p.rsplit("/", 1)[-1] for p in files}
|
|
67
|
-
for path, content in files.items():
|
|
68
|
-
ok, reason = validate_file_content(content, path)
|
|
69
|
-
per_file[path] = {"valid": ok, "reason": reason}
|
|
70
|
-
if not ok:
|
|
71
|
-
issues.append(f"{path}: {reason}")
|
|
72
|
-
if _ext(path) in (".html", ".htm"):
|
|
73
|
-
for ref in _local_bundle_refs(content):
|
|
74
|
-
if ref.rsplit("/", 1)[-1] not in names:
|
|
75
|
-
issues.append(f"{path}: references missing file '{ref}'")
|
|
76
|
-
return {"ok": not issues, "issues": issues, "files": per_file}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
"""Recover the intended file payload from an arbitrary model reply.
|
|
2
|
-
|
|
3
|
-
Step 2 of the pipeline described in the package docstring: strip reasoning
|
|
4
|
-
blocks and conversational framing, pick the best fenced block, and slice known
|
|
5
|
-
document boundaries. Pure string work — nothing here decides whether the result
|
|
6
|
-
is *good*, only what the model most plausibly meant to hand over.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from __future__ import annotations
|
|
10
|
-
|
|
11
|
-
import json
|
|
12
|
-
import re
|
|
13
|
-
from typing import Dict, List, Optional, Tuple
|
|
14
|
-
|
|
15
|
-
from latticeai.core.quiet import quiet
|
|
16
|
-
|
|
17
|
-
_THINK_BLOCK_RE = re.compile(
|
|
18
|
-
r"<(think|thinking|reasoning|reflection)>.*?</\1>",
|
|
19
|
-
re.DOTALL | re.IGNORECASE,
|
|
20
|
-
)
|
|
21
|
-
# Unclosed think block (model hit the token limit mid-reasoning).
|
|
22
|
-
_THINK_OPEN_RE = re.compile(r"<(think|thinking|reasoning)>.*\Z", re.DOTALL | re.IGNORECASE)
|
|
23
|
-
|
|
24
|
-
_FENCE_RE = re.compile(r"```([\w.+-]*)[ \t]*\n(.*?)```", re.DOTALL)
|
|
25
|
-
|
|
26
|
-
# Conversational lines that small models prepend/append around the payload.
|
|
27
|
-
_CHAT_LINE_RE = re.compile(
|
|
28
|
-
r"^\s*("
|
|
29
|
-
r"(sure|of course|certainly|okay|ok|alright|great|absolutely)\b[^\n]*"
|
|
30
|
-
r"|here('s| is| are)\b[^\n]*"
|
|
31
|
-
r"|i('ve| have) (created|written|generated|made)\b[^\n]*"
|
|
32
|
-
r"|(below|following) is\b[^\n]*"
|
|
33
|
-
r"|let me know\b[^\n]*"
|
|
34
|
-
r"|hope (this|that) helps[^\n]*"
|
|
35
|
-
r"|feel free\b[^\n]*"
|
|
36
|
-
r"|물론(입니다|이죠|이에요)?[!., ]*[^\n]*"
|
|
37
|
-
r"|네[,!. ][^\n]*"
|
|
38
|
-
r"|알겠습니다[^\n]*"
|
|
39
|
-
r"|다음은[^\n]*(입니다|합니다)[:.]?[^\n]*"
|
|
40
|
-
r"|아래는?[^\n]*(입니다|내용)[^\n]*"
|
|
41
|
-
r"|(요청하신|원하시는)[^\n]*(입니다|만들었습니다|작성했습니다)[^\n]*"
|
|
42
|
-
r"|(파일|내용|코드)[을를]?\s*(생성|작성|만들)[^\n]*"
|
|
43
|
-
r"|도움이 (필요하|되)[^\n]*"
|
|
44
|
-
r"|추가로[^\n]*(말씀|요청)[^\n]*"
|
|
45
|
-
r")\s*$",
|
|
46
|
-
re.IGNORECASE,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# Language tags that identify a fenced block as the payload for an extension.
|
|
51
|
-
_EXT_FENCE_LANGS: Dict[str, Tuple[str, ...]] = {
|
|
52
|
-
".html": ("html", "htm", "xhtml"),
|
|
53
|
-
".htm": ("html", "htm", "xhtml"),
|
|
54
|
-
".css": ("css",),
|
|
55
|
-
".js": ("js", "javascript"),
|
|
56
|
-
".jsx": ("jsx", "javascript"),
|
|
57
|
-
".ts": ("ts", "typescript"),
|
|
58
|
-
".tsx": ("tsx", "typescript"),
|
|
59
|
-
".py": ("py", "python"),
|
|
60
|
-
".json": ("json",),
|
|
61
|
-
".yaml": ("yaml", "yml"),
|
|
62
|
-
".yml": ("yaml", "yml"),
|
|
63
|
-
".toml": ("toml",),
|
|
64
|
-
".md": ("md", "markdown"),
|
|
65
|
-
".markdown": ("md", "markdown"),
|
|
66
|
-
".sql": ("sql",),
|
|
67
|
-
".sh": ("sh", "bash", "shell", "zsh"),
|
|
68
|
-
".xml": ("xml", "svg"),
|
|
69
|
-
".csv": ("csv",),
|
|
70
|
-
".txt": ("txt", "text", "plaintext"),
|
|
71
|
-
".vue": ("vue", "html"),
|
|
72
|
-
".svelte": ("svelte", "html"),
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _ext(path: str) -> str:
|
|
77
|
-
dot = path.rfind(".")
|
|
78
|
-
return path[dot:].lower() if dot >= 0 else ""
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def _strip_chat_lines(text: str) -> str:
|
|
82
|
-
"""Drop leading/trailing conversational lines around the payload."""
|
|
83
|
-
lines = text.split("\n")
|
|
84
|
-
start, end = 0, len(lines)
|
|
85
|
-
while start < end and (not lines[start].strip() or _CHAT_LINE_RE.match(lines[start])):
|
|
86
|
-
start += 1
|
|
87
|
-
while end > start and (not lines[end - 1].strip() or _CHAT_LINE_RE.match(lines[end - 1])):
|
|
88
|
-
end -= 1
|
|
89
|
-
stripped = "\n".join(lines[start:end]).strip()
|
|
90
|
-
return stripped if stripped else text.strip()
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def extract_file_content(raw: str, target_path: str) -> str:
|
|
94
|
-
"""Recover the intended file payload from an arbitrary model reply."""
|
|
95
|
-
text = (raw or "").strip()
|
|
96
|
-
if not text:
|
|
97
|
-
return ""
|
|
98
|
-
text = _THINK_BLOCK_RE.sub("", text)
|
|
99
|
-
text = _THINK_OPEN_RE.sub("", text).strip()
|
|
100
|
-
|
|
101
|
-
ext = _ext(target_path)
|
|
102
|
-
fences = _FENCE_RE.findall(text + ("\n```" if text.count("```") % 2 else ""))
|
|
103
|
-
if fences:
|
|
104
|
-
wanted = _EXT_FENCE_LANGS.get(ext, ())
|
|
105
|
-
matching = [body for lang, body in fences if lang.lower() in wanted]
|
|
106
|
-
candidates = matching if matching else [body for _, body in fences]
|
|
107
|
-
# The payload is the largest block; short blocks are usually usage
|
|
108
|
-
# snippets ("run it with: python app.py").
|
|
109
|
-
content = max(candidates, key=len).strip()
|
|
110
|
-
else:
|
|
111
|
-
content = _strip_chat_lines(text)
|
|
112
|
-
|
|
113
|
-
if ext in (".html", ".htm"):
|
|
114
|
-
content = _slice_html_document(content)
|
|
115
|
-
elif ext == ".json":
|
|
116
|
-
sliced = _slice_json_document(content)
|
|
117
|
-
if sliced is not None:
|
|
118
|
-
content = sliced
|
|
119
|
-
return content.strip()
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def _slice_html_document(content: str) -> str:
|
|
123
|
-
"""Cut a complete HTML document out of surrounding prose when present."""
|
|
124
|
-
lower = content.lower()
|
|
125
|
-
start = lower.find("<!doctype")
|
|
126
|
-
if start < 0:
|
|
127
|
-
start = lower.find("<html")
|
|
128
|
-
if start > 0:
|
|
129
|
-
content = content[start:]
|
|
130
|
-
lower = lower[start:]
|
|
131
|
-
end = lower.rfind("</html>")
|
|
132
|
-
if end >= 0:
|
|
133
|
-
content = content[: end + len("</html>")]
|
|
134
|
-
return content
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def _slice_json_document(content: str) -> Optional[str]:
|
|
138
|
-
"""Return the largest parseable JSON value inside ``content``, if any."""
|
|
139
|
-
candidates: List[str] = [content]
|
|
140
|
-
for opener, closer in (("{", "}"), ("[", "]")):
|
|
141
|
-
start = content.find(opener)
|
|
142
|
-
end = content.rfind(closer)
|
|
143
|
-
if start >= 0 and end > start:
|
|
144
|
-
candidates.append(content[start : end + 1])
|
|
145
|
-
best: Optional[str] = None
|
|
146
|
-
for candidate in candidates:
|
|
147
|
-
try:
|
|
148
|
-
json.loads(candidate)
|
|
149
|
-
except (ValueError, TypeError):
|
|
150
|
-
quiet()
|
|
151
|
-
continue
|
|
152
|
-
if best is None or len(candidate) > len(best):
|
|
153
|
-
best = candidate
|
|
154
|
-
return best
|