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,172 +0,0 @@
|
|
|
1
|
-
"""Document upload parsing, safety checks, and knowledge-graph ingestion."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import logging
|
|
6
|
-
import tempfile
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
|
|
10
|
-
from fastapi import HTTPException, Request, UploadFile
|
|
11
|
-
|
|
12
|
-
from lattice_brain.ingestion import IngestionItem
|
|
13
|
-
from latticeai.api.workspace_scope import resolve_workspace_scope
|
|
14
|
-
from latticeai.core.quiet import quiet
|
|
15
|
-
from latticeai.tools import ToolError, read_document
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
async def process_uploaded_document(
|
|
19
|
-
*,
|
|
20
|
-
request: Request,
|
|
21
|
-
file: UploadFile,
|
|
22
|
-
current_user: str,
|
|
23
|
-
enable_graph: bool,
|
|
24
|
-
knowledge_graph,
|
|
25
|
-
ingestion_pipeline=None,
|
|
26
|
-
bytes_match_extension,
|
|
27
|
-
classify_sensitive_message,
|
|
28
|
-
append_audit_event,
|
|
29
|
-
enforce_rate_limit,
|
|
30
|
-
hooks=None,
|
|
31
|
-
workspace_service=None,
|
|
32
|
-
) -> dict:
|
|
33
|
-
enforce_rate_limit(current_user, "upload")
|
|
34
|
-
workspace_id = resolve_workspace_scope(
|
|
35
|
-
request,
|
|
36
|
-
user=current_user,
|
|
37
|
-
workspace_service=workspace_service,
|
|
38
|
-
write=True,
|
|
39
|
-
)
|
|
40
|
-
suffix = Path(file.filename or "upload").suffix.lower()
|
|
41
|
-
allowed = {".pdf", ".docx", ".xlsx", ".pptx", ".txt", ".md", ".csv"}
|
|
42
|
-
if suffix not in allowed:
|
|
43
|
-
raise HTTPException(status_code=400, detail=f"지원하지 않는 형식: {suffix}")
|
|
44
|
-
|
|
45
|
-
contents = await file.read()
|
|
46
|
-
if len(contents) > 10 * 1024 * 1024:
|
|
47
|
-
raise HTTPException(status_code=400, detail="파일이 너무 큽니다. 최대 10MB.")
|
|
48
|
-
if not bytes_match_extension(contents, suffix):
|
|
49
|
-
raise HTTPException(status_code=400, detail=f"파일 내용이 확장자({suffix})와 일치하지 않습니다.")
|
|
50
|
-
|
|
51
|
-
# ── pre_upload hook ── may gate the upload before any work happens.
|
|
52
|
-
if hooks is not None:
|
|
53
|
-
pre_up = hooks.fire_hook(
|
|
54
|
-
"pre_upload", "document.upload",
|
|
55
|
-
payload={"filename": file.filename, "ext": suffix, "bytes": len(contents)},
|
|
56
|
-
user_email=current_user,
|
|
57
|
-
)
|
|
58
|
-
if pre_up.get("blocked"):
|
|
59
|
-
raise HTTPException(status_code=403, detail=pre_up.get("block_reason") or "Upload blocked by a pre_upload hook.")
|
|
60
|
-
|
|
61
|
-
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
|
|
62
|
-
tmp.write(contents)
|
|
63
|
-
tmp_path = tmp.name
|
|
64
|
-
|
|
65
|
-
try:
|
|
66
|
-
result = read_document(tmp_path)
|
|
67
|
-
sensitive = classify_sensitive_message(
|
|
68
|
-
{
|
|
69
|
-
"role": "document",
|
|
70
|
-
"content": result.get("content") or result.get("preview") or "",
|
|
71
|
-
"user_email": current_user,
|
|
72
|
-
"timestamp": datetime.now().isoformat(),
|
|
73
|
-
},
|
|
74
|
-
-1,
|
|
75
|
-
)
|
|
76
|
-
# ── pre_index / post_index hooks bracket the KG ingest (chunk → embed →
|
|
77
|
-
# graph-build), the actual indexing step.
|
|
78
|
-
if hooks is not None:
|
|
79
|
-
hooks.fire_hook("pre_index", "document.index",
|
|
80
|
-
payload={"filename": file.filename, "chars": result.get("chars")},
|
|
81
|
-
user_email=current_user)
|
|
82
|
-
try:
|
|
83
|
-
if not (enable_graph and knowledge_graph):
|
|
84
|
-
raise RuntimeError("graph disabled")
|
|
85
|
-
if ingestion_pipeline is not None:
|
|
86
|
-
# v4: uploads enter the brain through the unified ingestion
|
|
87
|
-
# pipeline (provenance + kg_ingest hook lifecycle).
|
|
88
|
-
ingest = ingestion_pipeline.ingest(
|
|
89
|
-
IngestionItem(
|
|
90
|
-
source_type="upload",
|
|
91
|
-
title=file.filename,
|
|
92
|
-
path=tmp_path,
|
|
93
|
-
mime_type=file.content_type,
|
|
94
|
-
owner=current_user,
|
|
95
|
-
workspace_id=workspace_id,
|
|
96
|
-
conversation_id=request.query_params.get("conversation_id"),
|
|
97
|
-
metadata={"extracted": result},
|
|
98
|
-
),
|
|
99
|
-
user_email=current_user,
|
|
100
|
-
)
|
|
101
|
-
if ingest.status != "ok":
|
|
102
|
-
raise RuntimeError(ingest.detail or f"ingestion {ingest.status}")
|
|
103
|
-
result["knowledge_graph"] = {
|
|
104
|
-
"node_id": ingest.node_id,
|
|
105
|
-
"sha256": ingest.content_hash,
|
|
106
|
-
"provenance_id": ingest.provenance_id,
|
|
107
|
-
}
|
|
108
|
-
else:
|
|
109
|
-
graph_result = knowledge_graph.ingest_document(
|
|
110
|
-
Path(tmp_path),
|
|
111
|
-
original_filename=file.filename,
|
|
112
|
-
mime_type=file.content_type,
|
|
113
|
-
uploader=current_user,
|
|
114
|
-
workspace_id=workspace_id,
|
|
115
|
-
conversation_id=request.query_params.get("conversation_id"),
|
|
116
|
-
extracted=result,
|
|
117
|
-
)
|
|
118
|
-
result["knowledge_graph"] = {
|
|
119
|
-
"node_id": graph_result["node_id"],
|
|
120
|
-
"sha256": graph_result["sha256"],
|
|
121
|
-
}
|
|
122
|
-
except Exception as graph_error:
|
|
123
|
-
logging.warning("knowledge graph document ingest failed: %s", graph_error)
|
|
124
|
-
result["knowledge_graph"] = {"error": str(graph_error)}
|
|
125
|
-
if hooks is not None:
|
|
126
|
-
_kg = result.get("knowledge_graph") or {}
|
|
127
|
-
hooks.fire_hook("post_index", "document.index",
|
|
128
|
-
payload={"filename": file.filename, "graph_node": _kg.get("node_id"),
|
|
129
|
-
"indexed": bool(_kg.get("node_id")), "error": _kg.get("error")},
|
|
130
|
-
user_email=current_user)
|
|
131
|
-
|
|
132
|
-
append_audit_event(
|
|
133
|
-
"document_upload",
|
|
134
|
-
user_email=current_user,
|
|
135
|
-
conversation_id=request.query_params.get("conversation_id"),
|
|
136
|
-
filename=file.filename,
|
|
137
|
-
mime_type=file.content_type,
|
|
138
|
-
ext=suffix,
|
|
139
|
-
bytes=len(contents),
|
|
140
|
-
extracted_chars=result.get("chars"),
|
|
141
|
-
graph_node=(result.get("knowledge_graph") or {}).get("node_id"),
|
|
142
|
-
content_preview=sensitive.get("preview"),
|
|
143
|
-
sensitivity=sensitive.get("sensitivity"),
|
|
144
|
-
sensitive_labels=sensitive.get("labels") or [],
|
|
145
|
-
)
|
|
146
|
-
except ToolError as exc:
|
|
147
|
-
raise HTTPException(status_code=400, detail=str(exc))
|
|
148
|
-
finally:
|
|
149
|
-
try:
|
|
150
|
-
Path(tmp_path).unlink()
|
|
151
|
-
except OSError:
|
|
152
|
-
quiet()
|
|
153
|
-
|
|
154
|
-
# ── post_upload hook ── the whole upload → parse → index pipeline finished.
|
|
155
|
-
if hooks is not None:
|
|
156
|
-
kg = result.get("knowledge_graph") or {}
|
|
157
|
-
hooks.fire_hook(
|
|
158
|
-
"post_upload", "document.uploaded",
|
|
159
|
-
payload={
|
|
160
|
-
"filename": file.filename,
|
|
161
|
-
"chars": result.get("chars"),
|
|
162
|
-
"graph_node": kg.get("node_id"),
|
|
163
|
-
"indexed": bool(kg.get("node_id")),
|
|
164
|
-
},
|
|
165
|
-
user_email=current_user,
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
result["original_filename"] = file.filename
|
|
169
|
-
return result
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
__all__ = ["process_uploaded_document"]
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"""Workspace service layer: scope resolution, permission guardrails, and a
|
|
2
|
-
single seam in front of :class:`WorkspaceOSStore`.
|
|
3
|
-
|
|
4
|
-
This module centralizes the workspace_id resolution and role/permission checks
|
|
5
|
-
that were previously scattered across the FastAPI handlers. It depends only on
|
|
6
|
-
``workspace_os`` (and indirectly ``enterprise``), never on the FastAPI app, so
|
|
7
|
-
both the app assembly and the API routers can import it freely.
|
|
8
|
-
|
|
9
|
-
Guardrail summary (v1.2.0):
|
|
10
|
-
|
|
11
|
-
* **Explicit workspace targeting is gated.** When a caller names a workspace
|
|
12
|
-
(``X-Workspace-Id`` header / ``workspace_id``), reads require ``read`` and
|
|
13
|
-
writes require ``write`` on that workspace; non-members are rejected.
|
|
14
|
-
* **Backward compatible default.** With no workspace named, the scope resolves
|
|
15
|
-
to the *active* workspace (Personal by default). Pre-1.1 clients that never
|
|
16
|
-
send a header keep operating on Personal data exactly as before.
|
|
17
|
-
* **Personal workspace** always grants its single local user owner rights.
|
|
18
|
-
* **No-auth local mode** keeps the owner fallback for *ownerless* org
|
|
19
|
-
workspaces (the anonymous local user owns what they create), but a *named*
|
|
20
|
-
stranger never bypasses membership.
|
|
21
|
-
* **Graph and installed Skills are intentionally machine-global shared state**
|
|
22
|
-
(the local knowledge graph and on-disk skills are not partitioned per
|
|
23
|
-
workspace). Skill enable/disable and other actions still record
|
|
24
|
-
workspace-scoped timeline events via the active workspace.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
from __future__ import annotations
|
|
28
|
-
|
|
29
|
-
from typing import Any, Callable, Dict, Optional
|
|
30
|
-
|
|
31
|
-
from latticeai.core.workspace_os import WorkspaceOSStore
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class WorkspaceService:
|
|
35
|
-
"""Permission-aware façade over :class:`WorkspaceOSStore`."""
|
|
36
|
-
|
|
37
|
-
# Graph / installed-skill state that is shared machine-wide rather than
|
|
38
|
-
# partitioned per workspace. Surfaced so the UI / docs can be explicit.
|
|
39
|
-
SHARED_GLOBAL_AREAS = ("graph", "skills")
|
|
40
|
-
|
|
41
|
-
def __init__(self, store: WorkspaceOSStore, *, resolve_user_id: Optional[Callable[[Optional[str]], Optional[str]]] = None):
|
|
42
|
-
self.store = store
|
|
43
|
-
self._resolve_user_id = resolve_user_id or (lambda user_id: user_id)
|
|
44
|
-
|
|
45
|
-
def _identity(self, user_id: Optional[str]) -> Optional[str]:
|
|
46
|
-
if isinstance(user_id, str) and user_id.startswith("user:"):
|
|
47
|
-
return user_id
|
|
48
|
-
return self._resolve_user_id(user_id)
|
|
49
|
-
|
|
50
|
-
# ── scope resolution + gating ────────────────────────────────────────
|
|
51
|
-
|
|
52
|
-
def _ensure_permission(self, workspace_id: str, user_id: Optional[str], permission: str) -> None:
|
|
53
|
-
resolved_user = self._identity(user_id)
|
|
54
|
-
if not self.store.has_permission(workspace_id, resolved_user, permission):
|
|
55
|
-
raise PermissionError(
|
|
56
|
-
f"'{user_id or 'anonymous'}' lacks '{permission}' on workspace '{workspace_id}'"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
def resolve_read_scope(self, requested: Optional[str], user_id: Optional[str]) -> str:
|
|
60
|
-
"""Resolve + authorize the workspace a read should target.
|
|
61
|
-
|
|
62
|
-
``None`` falls back to the active workspace (Personal by default), which
|
|
63
|
-
preserves pre-1.1 behaviour. An explicitly named workspace is gated on
|
|
64
|
-
``read`` so non-members cannot read organization data.
|
|
65
|
-
"""
|
|
66
|
-
workspace_id = requested or self.store._active_workspace_id()
|
|
67
|
-
self._ensure_permission(workspace_id, user_id, "read")
|
|
68
|
-
return workspace_id
|
|
69
|
-
|
|
70
|
-
def resolve_write_scope(self, requested: Optional[str], user_id: Optional[str]) -> str:
|
|
71
|
-
"""Resolve + authorize the workspace a write should target (gated on ``write``)."""
|
|
72
|
-
workspace_id = requested or self.store._active_workspace_id()
|
|
73
|
-
self._ensure_permission(workspace_id, user_id, "write")
|
|
74
|
-
return workspace_id
|
|
75
|
-
|
|
76
|
-
def readable_workspaces(self, user_id: Optional[str]) -> list[str]:
|
|
77
|
-
"""Return workspace ids the caller can read.
|
|
78
|
-
|
|
79
|
-
This keeps scoped read APIs from each reconstructing membership logic
|
|
80
|
-
from raw workspace state. The personal workspace remains readable via
|
|
81
|
-
the store's normal permission rules.
|
|
82
|
-
"""
|
|
83
|
-
resolved_user = self._identity(user_id)
|
|
84
|
-
workspaces = (self.store.load_state().get("workspaces") or {})
|
|
85
|
-
return [
|
|
86
|
-
str(workspace_id)
|
|
87
|
-
for workspace_id in workspaces
|
|
88
|
-
if self.store.has_permission(str(workspace_id), resolved_user, "read")
|
|
89
|
-
]
|
|
90
|
-
|
|
91
|
-
# ── record-level authorization (by-id access must not bypass gating) ──
|
|
92
|
-
|
|
93
|
-
def authorize_record_read(self, record: Dict[str, Any], user_id: Optional[str]) -> None:
|
|
94
|
-
"""Authorize reading a record against ITS OWN workspace.
|
|
95
|
-
|
|
96
|
-
Records predating workspace scoping carry no workspace_id and remain
|
|
97
|
-
readable (legacy-global compatibility); a scoped record requires read
|
|
98
|
-
permission on its workspace regardless of any caller-supplied header.
|
|
99
|
-
"""
|
|
100
|
-
workspace_id = (record or {}).get("workspace_id")
|
|
101
|
-
if workspace_id:
|
|
102
|
-
self._ensure_permission(workspace_id, user_id, "read")
|
|
103
|
-
|
|
104
|
-
def authorize_memory_delete(self, record: Dict[str, Any], user_id: Optional[str]) -> None:
|
|
105
|
-
"""Delete requires owning the memory or write access to its workspace.
|
|
106
|
-
|
|
107
|
-
Ownerless records with no workspace keep their pre-v4 behaviour
|
|
108
|
-
(deletable by any authenticated local user).
|
|
109
|
-
"""
|
|
110
|
-
owner = (record or {}).get("user_email")
|
|
111
|
-
workspace_id = (record or {}).get("workspace_id")
|
|
112
|
-
resolved_user = self._identity(user_id)
|
|
113
|
-
if owner and owner in {user_id, resolved_user}:
|
|
114
|
-
return
|
|
115
|
-
if workspace_id:
|
|
116
|
-
self._ensure_permission(workspace_id, resolved_user, "write")
|
|
117
|
-
return
|
|
118
|
-
if owner and owner not in {user_id, resolved_user}:
|
|
119
|
-
raise PermissionError(
|
|
120
|
-
f"'{user_id or 'anonymous'}' is not the owner of memory '{record.get('id')}'"
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
# ── workspace registry / summary ─────────────────────────────────────
|
|
124
|
-
|
|
125
|
-
def summary(self, user_id: Optional[str]) -> Dict[str, Any]:
|
|
126
|
-
data = self.store.summary()
|
|
127
|
-
data["workspace_registry"] = self.store.list_workspaces(user_id=self._identity(user_id))
|
|
128
|
-
data["shared_global_areas"] = list(self.SHARED_GLOBAL_AREAS)
|
|
129
|
-
return data
|
|
130
|
-
|
|
131
|
-
def list_workspaces(self, user_id: Optional[str]) -> Dict[str, Any]:
|
|
132
|
-
return self.store.list_workspaces(user_id=self._identity(user_id))
|
|
133
|
-
|
|
134
|
-
def get_workspace(self, workspace_id: str, user_id: Optional[str]) -> Dict[str, Any]:
|
|
135
|
-
# Reading workspace metadata requires read access to that workspace.
|
|
136
|
-
self._ensure_permission(workspace_id, user_id, "read")
|
|
137
|
-
return self.store.get_workspace(workspace_id, user_id=self._identity(user_id))
|
|
138
|
-
|
|
139
|
-
def workspace_summary(self, workspace_id: str, user_id: Optional[str]) -> Dict[str, Any]:
|
|
140
|
-
self._ensure_permission(workspace_id, user_id, "read")
|
|
141
|
-
return self.store.workspace_summary(workspace_id, user_id=self._identity(user_id))
|
|
142
|
-
|
|
143
|
-
# ── organization workspace management (delegates with actor) ─────────
|
|
144
|
-
|
|
145
|
-
def create_organization_workspace(self, *, name: str, owner_user_id: Optional[str], settings: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
146
|
-
return self.store.create_organization_workspace(name=name, owner_user_id=self._identity(owner_user_id), settings=settings)
|
|
147
|
-
|
|
148
|
-
def update_workspace(self, workspace_id: str, *, name=None, settings=None, actor=None) -> Dict[str, Any]:
|
|
149
|
-
return self.store.update_workspace(workspace_id, name=name, settings=settings, actor=self._identity(actor))
|
|
150
|
-
|
|
151
|
-
def archive_workspace(self, workspace_id: str, *, actor=None) -> Dict[str, Any]:
|
|
152
|
-
return self.store.archive_workspace(workspace_id, actor=self._identity(actor))
|
|
153
|
-
|
|
154
|
-
def add_member(self, workspace_id: str, *, user_id: str, role: str = "member", actor=None) -> Dict[str, Any]:
|
|
155
|
-
return self.store.add_member(workspace_id, user_id=self._identity(user_id) or user_id, role=role, actor=self._identity(actor))
|
|
156
|
-
|
|
157
|
-
def update_member_role(self, workspace_id: str, *, user_id: str, role: str, actor=None) -> Dict[str, Any]:
|
|
158
|
-
return self.store.update_member_role(workspace_id, user_id=self._identity(user_id) or user_id, role=role, actor=self._identity(actor))
|
|
159
|
-
|
|
160
|
-
def remove_member(self, workspace_id: str, *, user_id: str, actor=None) -> Dict[str, Any]:
|
|
161
|
-
return self.store.remove_member(workspace_id, user_id=self._identity(user_id) or user_id, actor=self._identity(actor))
|
|
162
|
-
|
|
163
|
-
def set_active_workspace(self, workspace_id: str, user_id: Optional[str]) -> Dict[str, Any]:
|
|
164
|
-
# Membership is enforced inside the store for organization workspaces.
|
|
165
|
-
return self.store.set_active_workspace(workspace_id, user_id=self._identity(user_id))
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""Setup services owned by the :mod:`latticeai` package."""
|
|
2
|
-
|
|
3
|
-
from .auto_setup import (
|
|
4
|
-
InstallPlan,
|
|
5
|
-
Recommendation,
|
|
6
|
-
SystemProfile,
|
|
7
|
-
plan,
|
|
8
|
-
preset,
|
|
9
|
-
probe,
|
|
10
|
-
recommend,
|
|
11
|
-
run_all,
|
|
12
|
-
verify,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
__all__ = [
|
|
16
|
-
"InstallPlan",
|
|
17
|
-
"Recommendation",
|
|
18
|
-
"SystemProfile",
|
|
19
|
-
"plan",
|
|
20
|
-
"preset",
|
|
21
|
-
"probe",
|
|
22
|
-
"recommend",
|
|
23
|
-
"run_all",
|
|
24
|
-
"verify",
|
|
25
|
-
]
|