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,460 +0,0 @@
|
|
|
1
|
-
"""Shared runtime contracts for agent execution surfaces.
|
|
2
|
-
|
|
3
|
-
These contracts are deliberately small and serializable. The single-agent
|
|
4
|
-
state machine and the multi-agent facade can evolve independently, but callers
|
|
5
|
-
should see the same run identity, mode, status, role, timeline and artifact
|
|
6
|
-
shape across both paths.
|
|
7
|
-
|
|
8
|
-
Contract family (7.4.0)
|
|
9
|
-
-----------------------
|
|
10
|
-
Four observability surfaces — agent runs, workflow runs, audit events, and
|
|
11
|
-
realtime events — now share one **contract family**, ``agent-run-contract/v1``.
|
|
12
|
-
Every record emitted by any of these surfaces carries the same envelope keys so
|
|
13
|
-
a single consumer (timeline UI, exporter, replay tooling) can treat them
|
|
14
|
-
uniformly:
|
|
15
|
-
|
|
16
|
-
* ``family`` — always :data:`CONTRACT_FAMILY` (``agent-run-contract/v1``).
|
|
17
|
-
* ``schema_version`` — the per-surface schema string (see ``*_SCHEMA`` below).
|
|
18
|
-
* ``kind`` — one of :data:`CONTRACT_KINDS`.
|
|
19
|
-
* ``id`` — the record identity (run id / event id), may be ``None``.
|
|
20
|
-
* ``status`` — a normalized lifecycle status string.
|
|
21
|
-
* ``timestamp`` — ISO-8601 second-precision emit/observe time.
|
|
22
|
-
|
|
23
|
-
Each surface keeps its own rich, surface-specific keys *in addition* to the
|
|
24
|
-
envelope — the envelope is purely additive, so existing consumers are never
|
|
25
|
-
broken. :func:`stamp_contract` is the single place that writes the envelope;
|
|
26
|
-
:func:`is_contract_member` validates membership for tests and importers.
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
from __future__ import annotations
|
|
30
|
-
|
|
31
|
-
from dataclasses import dataclass, field
|
|
32
|
-
from datetime import datetime
|
|
33
|
-
from typing import Any, Dict, Iterable, List, Optional, Protocol, runtime_checkable
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def runtime_timestamp() -> str:
|
|
37
|
-
return datetime.now().isoformat(timespec="seconds")
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# ── Contract family identity ────────────────────────────────────────────────
|
|
41
|
-
# A single family string ties every observability surface together. Per-surface
|
|
42
|
-
# schema versions live *under* the family so each surface can rev independently
|
|
43
|
-
# without forking the family contract consumers depend on.
|
|
44
|
-
CONTRACT_FAMILY = "agent-run-contract/v1"
|
|
45
|
-
|
|
46
|
-
AGENT_RUN_SCHEMA = "agent-run-contract/v1"
|
|
47
|
-
WORKFLOW_RUN_SCHEMA = "workflow-run-contract/v1"
|
|
48
|
-
AUDIT_EVENT_SCHEMA = "audit-event-contract/v1"
|
|
49
|
-
REALTIME_EVENT_SCHEMA = "realtime-event-contract/v1"
|
|
50
|
-
|
|
51
|
-
CONTRACT_KINDS = ("agent_run", "workflow_run", "audit_event", "realtime_event")
|
|
52
|
-
|
|
53
|
-
# The envelope keys every family member is guaranteed to expose.
|
|
54
|
-
CONTRACT_ENVELOPE_KEYS = ("family", "schema_version", "kind", "id", "status", "timestamp")
|
|
55
|
-
CONTRACT_VIEW_KEYS = (
|
|
56
|
-
"family",
|
|
57
|
-
"schema_version",
|
|
58
|
-
"kind",
|
|
59
|
-
"id",
|
|
60
|
-
"run_id",
|
|
61
|
-
"agent_id",
|
|
62
|
-
"runtime",
|
|
63
|
-
"mode",
|
|
64
|
-
"status",
|
|
65
|
-
"goal",
|
|
66
|
-
"current_role",
|
|
67
|
-
"timestamp",
|
|
68
|
-
"is_terminal",
|
|
69
|
-
"blocking_reasons",
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
RUNTIME_BOUNDARY_SCHEMA = "runtime-boundary/v1"
|
|
73
|
-
|
|
74
|
-
_SCHEMA_FOR_KIND = {
|
|
75
|
-
"agent_run": AGENT_RUN_SCHEMA,
|
|
76
|
-
"workflow_run": WORKFLOW_RUN_SCHEMA,
|
|
77
|
-
"audit_event": AUDIT_EVENT_SCHEMA,
|
|
78
|
-
"realtime_event": REALTIME_EVENT_SCHEMA,
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def stamp_contract(
|
|
83
|
-
body: Dict[str, Any],
|
|
84
|
-
*,
|
|
85
|
-
kind: str,
|
|
86
|
-
identity: Optional[str],
|
|
87
|
-
status: str,
|
|
88
|
-
timestamp: Optional[str] = None,
|
|
89
|
-
) -> Dict[str, Any]:
|
|
90
|
-
"""Return ``body`` with the ``agent-run-contract/v1`` envelope merged in.
|
|
91
|
-
|
|
92
|
-
Additive and idempotent: existing keys in ``body`` win for everything except
|
|
93
|
-
the six envelope keys, which are authoritative. ``kind`` must be one of
|
|
94
|
-
:data:`CONTRACT_KINDS`; the schema version is derived from it so callers
|
|
95
|
-
cannot mismatch ``kind`` and ``schema_version``.
|
|
96
|
-
"""
|
|
97
|
-
if kind not in _SCHEMA_FOR_KIND:
|
|
98
|
-
raise ValueError(f"unknown contract kind: {kind!r}")
|
|
99
|
-
enveloped = dict(body)
|
|
100
|
-
enveloped["family"] = CONTRACT_FAMILY
|
|
101
|
-
enveloped["schema_version"] = _SCHEMA_FOR_KIND[kind]
|
|
102
|
-
enveloped["kind"] = kind
|
|
103
|
-
enveloped["id"] = identity
|
|
104
|
-
enveloped["status"] = status
|
|
105
|
-
enveloped["timestamp"] = timestamp or body.get("timestamp") or runtime_timestamp()
|
|
106
|
-
return enveloped
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def is_contract_member(record: Any) -> bool:
|
|
110
|
-
"""True if ``record`` carries a valid ``agent-run-contract/v1`` envelope."""
|
|
111
|
-
if not isinstance(record, dict):
|
|
112
|
-
return False
|
|
113
|
-
if record.get("family") != CONTRACT_FAMILY:
|
|
114
|
-
return False
|
|
115
|
-
kind = record.get("kind")
|
|
116
|
-
if kind not in _SCHEMA_FOR_KIND:
|
|
117
|
-
return False
|
|
118
|
-
if record.get("schema_version") != _SCHEMA_FOR_KIND[kind]:
|
|
119
|
-
return False
|
|
120
|
-
return all(key in record for key in CONTRACT_ENVELOPE_KEYS)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def extract_contract(record: Any) -> Optional[Dict[str, Any]]:
|
|
124
|
-
"""Return the normalized family contract carried by ``record``.
|
|
125
|
-
|
|
126
|
-
Consumers should call this instead of branching on whether they received an
|
|
127
|
-
agent run, workflow run, audit row, or realtime event. The function accepts
|
|
128
|
-
either a raw contract dict or a surface record with a nested ``contract``.
|
|
129
|
-
"""
|
|
130
|
-
if is_contract_member(record):
|
|
131
|
-
return dict(record)
|
|
132
|
-
if isinstance(record, dict) and is_contract_member(record.get("contract")):
|
|
133
|
-
return dict(record["contract"])
|
|
134
|
-
return None
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
def require_contract(record: Any) -> Dict[str, Any]:
|
|
138
|
-
"""Return a valid family contract or raise a precise error."""
|
|
139
|
-
contract = extract_contract(record)
|
|
140
|
-
if contract is None:
|
|
141
|
-
raise ValueError("record is missing an agent-run-contract/v1 family contract")
|
|
142
|
-
return contract
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def contract_view(record: Any) -> Dict[str, Any]:
|
|
146
|
-
"""Return a compact, surface-agnostic view for API and UI consumers."""
|
|
147
|
-
contract = require_contract(record)
|
|
148
|
-
return {key: contract.get(key) for key in CONTRACT_VIEW_KEYS if key in contract}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def contract_views(records: Iterable[Any]) -> List[Dict[str, Any]]:
|
|
152
|
-
"""Return compact views for every valid contract in ``records``."""
|
|
153
|
-
views: List[Dict[str, Any]] = []
|
|
154
|
-
for record in records:
|
|
155
|
-
contract = extract_contract(record)
|
|
156
|
-
if contract is not None:
|
|
157
|
-
views.append({key: contract.get(key) for key in CONTRACT_VIEW_KEYS if key in contract})
|
|
158
|
-
return views
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@dataclass(frozen=True)
|
|
162
|
-
class AgentRunContract:
|
|
163
|
-
run_id: Optional[str]
|
|
164
|
-
agent_id: str
|
|
165
|
-
runtime: str
|
|
166
|
-
mode: str
|
|
167
|
-
status: str
|
|
168
|
-
goal: str
|
|
169
|
-
roles: List[str] = field(default_factory=list)
|
|
170
|
-
current_role: Optional[str] = None
|
|
171
|
-
retries: int = 0
|
|
172
|
-
timeline: List[Dict[str, Any]] = field(default_factory=list)
|
|
173
|
-
artifacts: List[Dict[str, Any]] = field(default_factory=list)
|
|
174
|
-
blocking_reasons: List[str] = field(default_factory=list)
|
|
175
|
-
schema_version: str = "agent-run-contract/v1"
|
|
176
|
-
|
|
177
|
-
@property
|
|
178
|
-
def is_terminal(self) -> bool:
|
|
179
|
-
return self.status in {"ok", "retried_ok", "failed", "rejected", "cancelled", "interrupted", "partial", "done"}
|
|
180
|
-
|
|
181
|
-
def as_dict(self) -> Dict[str, Any]:
|
|
182
|
-
body = {
|
|
183
|
-
"run_id": self.run_id,
|
|
184
|
-
"agent_id": self.agent_id,
|
|
185
|
-
"runtime": self.runtime,
|
|
186
|
-
"mode": self.mode,
|
|
187
|
-
"goal": self.goal,
|
|
188
|
-
"roles": list(self.roles),
|
|
189
|
-
"current_role": self.current_role,
|
|
190
|
-
"retries": self.retries,
|
|
191
|
-
"timeline": list(self.timeline),
|
|
192
|
-
"artifacts": list(self.artifacts),
|
|
193
|
-
"blocking_reasons": list(self.blocking_reasons),
|
|
194
|
-
"is_terminal": self.is_terminal,
|
|
195
|
-
}
|
|
196
|
-
return stamp_contract(
|
|
197
|
-
body,
|
|
198
|
-
kind="agent_run",
|
|
199
|
-
identity=self.run_id,
|
|
200
|
-
status=self.status,
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def multi_agent_contract(
|
|
205
|
-
*,
|
|
206
|
-
result: Any,
|
|
207
|
-
goal: str,
|
|
208
|
-
run_id: Optional[str] = None,
|
|
209
|
-
current_role: Optional[str] = None,
|
|
210
|
-
blocking_reasons: Optional[List[str]] = None,
|
|
211
|
-
) -> Dict[str, Any]:
|
|
212
|
-
return AgentRunContract(
|
|
213
|
-
run_id=run_id,
|
|
214
|
-
agent_id=getattr(result, "agent_id", "agent:executor"),
|
|
215
|
-
runtime="multi_agent",
|
|
216
|
-
mode=getattr(result, "mode", "simulation"),
|
|
217
|
-
status=getattr(result, "status", "unknown"),
|
|
218
|
-
goal=goal,
|
|
219
|
-
roles=list(getattr(result, "roles_run", []) or []),
|
|
220
|
-
current_role=current_role,
|
|
221
|
-
retries=int(getattr(result, "retries", 0) or 0),
|
|
222
|
-
timeline=list(getattr(result, "timeline", []) or []),
|
|
223
|
-
artifacts=[],
|
|
224
|
-
blocking_reasons=list(blocking_reasons or []),
|
|
225
|
-
).as_dict()
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
@dataclass(frozen=True)
|
|
229
|
-
class RuntimeBoundaryContract:
|
|
230
|
-
"""Machine-readable descriptor for an execution runtime boundary.
|
|
231
|
-
|
|
232
|
-
This is intentionally separate from run records: it lets tests, routers, and
|
|
233
|
-
docs assert which class owns which execution surface without importing the
|
|
234
|
-
wrong runtime by name.
|
|
235
|
-
"""
|
|
236
|
-
|
|
237
|
-
name: str
|
|
238
|
-
runtime: str
|
|
239
|
-
entrypoint: str
|
|
240
|
-
surface: str
|
|
241
|
-
owns: str
|
|
242
|
-
compatibility_aliases: List[str] = field(default_factory=list)
|
|
243
|
-
|
|
244
|
-
def as_dict(self) -> Dict[str, Any]:
|
|
245
|
-
return {
|
|
246
|
-
"schema_version": RUNTIME_BOUNDARY_SCHEMA,
|
|
247
|
-
"name": self.name,
|
|
248
|
-
"runtime": self.runtime,
|
|
249
|
-
"entrypoint": self.entrypoint,
|
|
250
|
-
"surface": self.surface,
|
|
251
|
-
"owns": self.owns,
|
|
252
|
-
"compatibility_aliases": list(self.compatibility_aliases),
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def runtime_boundary_contract(
|
|
257
|
-
*,
|
|
258
|
-
name: str,
|
|
259
|
-
runtime: str,
|
|
260
|
-
entrypoint: str,
|
|
261
|
-
surface: str,
|
|
262
|
-
owns: str,
|
|
263
|
-
compatibility_aliases: Optional[List[str]] = None,
|
|
264
|
-
) -> Dict[str, Any]:
|
|
265
|
-
return RuntimeBoundaryContract(
|
|
266
|
-
name=name,
|
|
267
|
-
runtime=runtime,
|
|
268
|
-
entrypoint=entrypoint,
|
|
269
|
-
surface=surface,
|
|
270
|
-
owns=owns,
|
|
271
|
-
compatibility_aliases=list(compatibility_aliases or []),
|
|
272
|
-
).as_dict()
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
@runtime_checkable
|
|
276
|
-
class RuntimeBoundaryProtocol(Protocol):
|
|
277
|
-
"""Minimal shared surface for runtime boundary discovery.
|
|
278
|
-
|
|
279
|
-
Product ``AgentRuntime`` and core ``SingleAgentRuntime`` intentionally keep
|
|
280
|
-
different execution methods. This protocol only fixes the common inspection
|
|
281
|
-
surface that DI, readiness gates, and tests can depend on safely.
|
|
282
|
-
"""
|
|
283
|
-
|
|
284
|
-
def boundary(self) -> Dict[str, Any]: ... # pragma: no branch — class-body arc CPython never emits: the def shares its line with its own body
|
|
285
|
-
|
|
286
|
-
def config(self) -> Dict[str, Any]: ...
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
def run_record_contract(run: Dict[str, Any], *, runtime: str = "multi_agent") -> Dict[str, Any]:
|
|
290
|
-
"""Build the family contract from a persisted agent run row."""
|
|
291
|
-
run = dict(run or {})
|
|
292
|
-
timeline = list(run.get("timeline") or [])
|
|
293
|
-
retry_history = list(run.get("retry_history") or [])
|
|
294
|
-
roles = list(run.get("roles_run") or run.get("requested_roles") or [])
|
|
295
|
-
if not roles:
|
|
296
|
-
roles = [
|
|
297
|
-
str(item.get("role"))
|
|
298
|
-
for item in timeline
|
|
299
|
-
if isinstance(item, dict) and item.get("role")
|
|
300
|
-
]
|
|
301
|
-
return AgentRunContract(
|
|
302
|
-
run_id=run.get("id") or run.get("run_id"),
|
|
303
|
-
agent_id=str(run.get("agent_id") or "agent:executor"),
|
|
304
|
-
runtime=runtime,
|
|
305
|
-
mode=str(run.get("mode") or "simulation"),
|
|
306
|
-
status=str(run.get("status") or "unknown"),
|
|
307
|
-
goal=str(run.get("input") or run.get("goal") or ""),
|
|
308
|
-
roles=roles,
|
|
309
|
-
current_role=run.get("current_role"),
|
|
310
|
-
retries=len(retry_history),
|
|
311
|
-
timeline=timeline,
|
|
312
|
-
artifacts=[
|
|
313
|
-
{
|
|
314
|
-
"type": "run_record",
|
|
315
|
-
"workspace_id": run.get("workspace_id"),
|
|
316
|
-
"graph_node_id": run.get("graph_node_id"),
|
|
317
|
-
"execution_mode": run.get("execution_mode"),
|
|
318
|
-
}
|
|
319
|
-
],
|
|
320
|
-
blocking_reasons=[str(run.get("error"))] if run.get("error") else [],
|
|
321
|
-
).as_dict()
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
def single_agent_contract(
|
|
325
|
-
*,
|
|
326
|
-
ctx: Any,
|
|
327
|
-
goal: str,
|
|
328
|
-
run_id: Optional[str] = None,
|
|
329
|
-
agent_id: str = "agent:single",
|
|
330
|
-
mode: str = "llm",
|
|
331
|
-
blocking_reasons: Optional[List[str]] = None,
|
|
332
|
-
) -> Dict[str, Any]:
|
|
333
|
-
state = getattr(getattr(ctx, "state", None), "value", getattr(ctx, "state", "unknown"))
|
|
334
|
-
status = "done" if state == "DONE" else "failed" if state == "FAILED" else str(state or "unknown").lower()
|
|
335
|
-
return AgentRunContract(
|
|
336
|
-
run_id=run_id,
|
|
337
|
-
agent_id=agent_id,
|
|
338
|
-
runtime="single_agent",
|
|
339
|
-
mode=mode,
|
|
340
|
-
status=status,
|
|
341
|
-
goal=goal,
|
|
342
|
-
roles=["planner", "executor", "critic"],
|
|
343
|
-
current_role=str(state or ""),
|
|
344
|
-
retries=int(getattr(ctx, "retry_count", 0) or 0),
|
|
345
|
-
timeline=list(getattr(ctx, "transcript", []) or []),
|
|
346
|
-
artifacts=[],
|
|
347
|
-
blocking_reasons=list(blocking_reasons or []),
|
|
348
|
-
).as_dict()
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
# ── Sibling-surface contract builders ───────────────────────────────────────
|
|
352
|
-
# These wrap the other three observability surfaces into the same family so a
|
|
353
|
-
# consumer can iterate agent runs, workflow runs, audit events and realtime
|
|
354
|
-
# events through one envelope.
|
|
355
|
-
|
|
356
|
-
def workflow_run_contract(run: Any) -> Dict[str, Any]:
|
|
357
|
-
"""Wrap a workflow run dict (``WorkflowRun.as_dict()``) in the family envelope.
|
|
358
|
-
|
|
359
|
-
Accepts either a ``WorkflowRun`` instance or its serialized dict so the
|
|
360
|
-
engine can stamp without importing the dataclass here (avoids a cycle).
|
|
361
|
-
"""
|
|
362
|
-
body = run.as_dict() if hasattr(run, "as_dict") else dict(run or {})
|
|
363
|
-
run_id = body.get("id") or body.get("run_id") or body.get("workflow_id")
|
|
364
|
-
workflow_id = body.get("workflow_id")
|
|
365
|
-
contract_body = {
|
|
366
|
-
"run_id": run_id,
|
|
367
|
-
"agent_id": f"workflow:{workflow_id or body.get('name') or 'workflow'}",
|
|
368
|
-
"runtime": "workflow",
|
|
369
|
-
"mode": body.get("mode") or "live",
|
|
370
|
-
"goal": body.get("name") or "workflow",
|
|
371
|
-
"roles": ["workflow"],
|
|
372
|
-
"current_role": body.get("current_node") or body.get("paused_node"),
|
|
373
|
-
"retries": 0,
|
|
374
|
-
"timeline": list(body.get("timeline") or []),
|
|
375
|
-
"artifacts": [
|
|
376
|
-
{
|
|
377
|
-
"type": "workflow_outputs",
|
|
378
|
-
"workflow_id": workflow_id,
|
|
379
|
-
"outputs": body.get("outputs") or {},
|
|
380
|
-
"pause": body.get("pause") or body.get("pending_approval"),
|
|
381
|
-
}
|
|
382
|
-
],
|
|
383
|
-
"blocking_reasons": [str((body.get("outputs") or {}).get("error"))] if (body.get("outputs") or {}).get("error") else [],
|
|
384
|
-
"is_terminal": str(body.get("status") or "") in {"ok", "failed", "cancelled", "interrupted", "partial", "rejected"},
|
|
385
|
-
}
|
|
386
|
-
return stamp_contract(
|
|
387
|
-
contract_body,
|
|
388
|
-
kind="workflow_run",
|
|
389
|
-
identity=run_id,
|
|
390
|
-
status=str(body.get("status") or "unknown"),
|
|
391
|
-
timestamp=body.get("started_at") or body.get("created_at"),
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
def audit_event_contract(event: Dict[str, Any]) -> Dict[str, Any]:
|
|
396
|
-
"""Wrap a single audit-log event in the family envelope.
|
|
397
|
-
|
|
398
|
-
Audit events have no lifecycle ``status``; we expose the event type as the
|
|
399
|
-
status so the envelope stays uniform and filterable. Identity is a stable
|
|
400
|
-
``event_type@timestamp`` key (audit events are append-only, not addressable).
|
|
401
|
-
"""
|
|
402
|
-
body = dict(event or {})
|
|
403
|
-
event_type = str(body.get("event_type") or "event")
|
|
404
|
-
ts = body.get("timestamp")
|
|
405
|
-
identity = body.get("event_id") or (f"{event_type}@{ts}" if ts else event_type)
|
|
406
|
-
contract_body = {
|
|
407
|
-
"run_id": body.get("run_id"),
|
|
408
|
-
"agent_id": str(body.get("agent_id") or body.get("workflow_id") or f"audit:{event_type}"),
|
|
409
|
-
"runtime": "audit",
|
|
410
|
-
"mode": "event",
|
|
411
|
-
"goal": event_type,
|
|
412
|
-
"roles": [],
|
|
413
|
-
"current_role": None,
|
|
414
|
-
"retries": int(body.get("retries") or 0),
|
|
415
|
-
"timeline": [{"event": event_type, "timestamp": ts, "status": body.get("status") or event_type}],
|
|
416
|
-
"artifacts": [{"type": "audit_payload", "payload": body}],
|
|
417
|
-
"blocking_reasons": [],
|
|
418
|
-
"is_terminal": True,
|
|
419
|
-
}
|
|
420
|
-
return stamp_contract(
|
|
421
|
-
contract_body,
|
|
422
|
-
kind="audit_event",
|
|
423
|
-
identity=identity,
|
|
424
|
-
status=event_type,
|
|
425
|
-
timestamp=ts,
|
|
426
|
-
)
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
def realtime_event_contract(event: Dict[str, Any]) -> Dict[str, Any]:
|
|
430
|
-
"""Wrap a realtime bus event in the family envelope.
|
|
431
|
-
|
|
432
|
-
The bus already assigns a monotonic ``seq`` and ``received_at``; we reuse
|
|
433
|
-
those as identity and timestamp so the envelope is consistent with the
|
|
434
|
-
feed's own ordering guarantees.
|
|
435
|
-
"""
|
|
436
|
-
body = dict(event or {})
|
|
437
|
-
seq = body.get("seq")
|
|
438
|
-
raw_payload = body.get("payload")
|
|
439
|
-
payload: Dict[str, Any] = raw_payload if isinstance(raw_payload, dict) else {}
|
|
440
|
-
contract_body = {
|
|
441
|
-
"run_id": payload.get("run_id") or body.get("run_id"),
|
|
442
|
-
"agent_id": str(payload.get("agent_id") or payload.get("workflow_id") or f"realtime:{body.get('area') or 'workspace'}"),
|
|
443
|
-
"runtime": "realtime",
|
|
444
|
-
"mode": "event",
|
|
445
|
-
"goal": str(body.get("event_type") or "event"),
|
|
446
|
-
"roles": [],
|
|
447
|
-
"current_role": payload.get("current_role"),
|
|
448
|
-
"retries": int(payload.get("retries") or 0),
|
|
449
|
-
"timeline": [{"event": body.get("event_type") or "event", "timestamp": body.get("received_at"), "payload": payload}],
|
|
450
|
-
"artifacts": [{"type": "realtime_payload", "payload": payload}],
|
|
451
|
-
"blocking_reasons": [str(payload.get("error"))] if payload.get("error") else [],
|
|
452
|
-
"is_terminal": str(payload.get("status") or "") in {"ok", "failed", "cancelled", "interrupted", "partial", "rejected"},
|
|
453
|
-
}
|
|
454
|
-
return stamp_contract(
|
|
455
|
-
contract_body,
|
|
456
|
-
kind="realtime_event",
|
|
457
|
-
identity=f"rt:{seq}" if seq is not None else None,
|
|
458
|
-
status=str(body.get("event_type") or "event"),
|
|
459
|
-
timestamp=body.get("received_at"),
|
|
460
|
-
)
|