agentengine-sdk-python 0.8.4__py3-none-any.whl → 0.8.5__py3-none-any.whl
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.
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/METADATA +6 -3
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/RECORD +591 -365
- ksadk/_build_provenance.json +1 -1
- ksadk/_process.py +83 -0
- ksadk/_str_enum.py +17 -0
- ksadk/a2ui/core.py +3 -3
- ksadk/api/client.py +6 -0
- ksadk/builders/code_builder.py +38 -12
- ksadk/builders/framework_requirements.py +20 -2
- ksadk/cli/__init__.py +36 -0
- ksadk/cli/cmd_config.py +4 -4
- ksadk/cli/cmd_create.py +12 -12
- ksadk/cli/cmd_hermes.py +24 -2
- ksadk/cli/cmd_invoke.py +28 -5
- ksadk/cli/cmd_openclaw.py +26 -1
- ksadk/cli/cmd_plugin.py +70 -12
- ksadk/cli/cmd_studio.py +64 -16
- ksadk/cli/openclaw_env.py +1 -1
- ksadk/cli/resource_common.py +26 -0
- ksadk/codex/client.py +3 -2
- ksadk/configs/__init__.py +1 -1
- ksadk/configs/env_registry.py +125 -31
- ksadk/configs/env_registry_studio.py +86 -0
- ksadk/configs/global_config.py +1 -1
- ksadk/configs/settings.py +3 -3
- ksadk/connector/__init__.py +17 -0
- ksadk/connector/channel.py +477 -0
- ksadk/context_engine/capabilities.py +52 -4
- ksadk/conversations/attachment_storage.py +10 -3
- ksadk/conversations/attachments.py +16 -5
- ksadk/conversations/message_projection.py +23 -32
- ksadk/conversations/normalize.py +28 -10
- ksadk/conversations/runtime_baseline.py +37 -0
- ksadk/conversations/runtime_invocation.py +17 -4
- ksadk/conversations/runtime_observability.py +39 -10
- ksadk/conversations/runtime_payloads.py +8 -0
- ksadk/conversations/runtime_persistence.py +105 -9
- ksadk/conversations/runtime_preparation.py +13 -7
- ksadk/conversations/runtime_stream_events.py +29 -35
- ksadk/conversations/runtime_streaming.py +8 -0
- ksadk/events/adapters/_codex_items.py +16 -8
- ksadk/events/adapters/_langgraph_support.py +34 -0
- ksadk/events/session_event.py +2 -2
- ksadk/harness/__init__.py +14 -0
- ksadk/harness/app.py +11 -0
- ksadk/harness/artifact_store.py +213 -0
- ksadk/harness/capabilities.py +115 -0
- ksadk/harness/capability_runtime.py +237 -0
- ksadk/harness/closure_contract.py +92 -0
- ksadk/harness/compaction_record.py +122 -0
- ksadk/harness/compiler.py +284 -0
- ksadk/harness/conformance/__init__.py +33 -0
- ksadk/harness/conformance/contract.py +506 -0
- ksadk/harness/conformance/fixtures.py +102 -0
- ksadk/harness/context_engine.py +403 -0
- ksadk/harness/context_maintenance.py +259 -0
- ksadk/harness/context_manifest.py +188 -0
- ksadk/harness/context_tuning.py +168 -0
- ksadk/harness/draft_runtime.py +322 -0
- ksadk/harness/engine/__init__.py +40 -0
- ksadk/harness/engine/base.py +122 -0
- ksadk/harness/engine/budgets.py +108 -0
- ksadk/harness/engine/capability_declarations.py +59 -0
- ksadk/harness/engine/completion_guard.py +42 -0
- ksadk/harness/engine/context_pipeline.py +579 -0
- ksadk/harness/engine/graph_builder.py +859 -0
- ksadk/harness/engine/langgraph.py +931 -0
- ksadk/harness/engine/mcp_disclosure.py +750 -0
- ksadk/harness/engine/policy_runtime.py +70 -0
- ksadk/harness/engine/postgres_checkpointer.py +63 -0
- ksadk/harness/engine/run_control_bridge.py +80 -0
- ksadk/harness/engine/run_types.py +88 -0
- ksadk/harness/engine/skill_disclosure.py +189 -0
- ksadk/harness/engine/spans.py +41 -0
- ksadk/harness/engine/subagents.py +343 -0
- ksadk/harness/engine/thread_ids.py +112 -0
- ksadk/harness/engine/tool_dispatch.py +144 -0
- ksadk/harness/event_tree.py +212 -0
- ksadk/harness/events.py +461 -0
- ksadk/harness/execution_policy.py +94 -0
- ksadk/harness/insights.py +210 -0
- ksadk/harness/lifecycle.py +578 -0
- ksadk/harness/lifecycle_conformance.py +233 -0
- ksadk/harness/lifecycle_local_plane.py +104 -0
- ksadk/harness/loop/__init__.py +44 -0
- ksadk/harness/loop/reason.py +454 -0
- ksadk/harness/loop/tools.py +762 -0
- ksadk/harness/managed_runtime.py +884 -0
- ksadk/harness/mcp_matrix.py +474 -0
- ksadk/harness/mcp_runtime.py +471 -0
- ksadk/harness/memory_consolidation.py +157 -0
- ksadk/harness/memory_loop.py +156 -0
- ksadk/harness/memory_runtime.py +541 -0
- ksadk/harness/metrics.py +90 -0
- ksadk/harness/model_capability.py +253 -0
- ksadk/harness/model_provider.py +220 -0
- ksadk/harness/observability/__init__.py +29 -0
- ksadk/harness/observability/inspection.py +528 -0
- ksadk/harness/observability/metrics.py +167 -0
- ksadk/harness/observability/otel_exporter.py +218 -0
- ksadk/harness/prompt_cache.py +70 -0
- ksadk/harness/public_activity.py +154 -0
- ksadk/harness/readiness.py +249 -0
- ksadk/harness/reasoner.py +466 -13
- ksadk/harness/release_readiness.py +140 -0
- ksadk/harness/resource_ref.py +69 -0
- ksadk/harness/run_control.py +668 -0
- ksadk/harness/runtime.py +146 -111
- ksadk/harness/runtime_capabilities.py +158 -0
- ksadk/harness/runtime_server.py +514 -0
- ksadk/harness/sandbox_adapters.py +739 -0
- ksadk/harness/sandbox_backend.py +530 -0
- ksadk/harness/sandbox_conformance.py +288 -0
- ksadk/harness/sandbox_lease.py +77 -0
- ksadk/harness/sandbox_lease_conformance.py +259 -0
- ksadk/harness/sandbox_matrix.py +170 -0
- ksadk/harness/sandbox_reconciliation.py +140 -0
- ksadk/harness/sandbox_recovery.py +586 -0
- ksadk/harness/sandbox_recovery_conformance.py +246 -0
- ksadk/harness/session_store.py +243 -0
- ksadk/harness/skill_composition.py +212 -0
- ksadk/harness/skill_feedback.py +123 -0
- ksadk/harness/skill_matrix.py +233 -0
- ksadk/harness/skill_runtime.py +259 -0
- ksadk/harness/spec.py +332 -0
- ksadk/harness/state.py +153 -0
- ksadk/harness/strategies.py +149 -0
- ksadk/harness/subagent.py +253 -0
- ksadk/harness/tool_policy.py +131 -0
- ksadk/harness/tool_receipts.py +96 -0
- ksadk/harness/tool_reliability.py +81 -0
- ksadk/harness/user_errors.py +69 -0
- ksadk/harness/working_context.py +81 -0
- ksadk/harness/working_context_patch.py +99 -0
- ksadk/identity/resolver.py +18 -0
- ksadk/interaction/__init__.py +1 -1
- ksadk/interaction/ledger.py +1 -1
- ksadk/interaction/provider.py +1 -1
- ksadk/interaction/providers/__init__.py +3 -1
- ksadk/interaction/providers/adk.py +1 -1
- ksadk/interaction/providers/codex.py +1 -1
- ksadk/interaction/providers/harness.py +50 -0
- ksadk/interaction/providers/langgraph.py +1 -1
- ksadk/kernel/__init__.py +10 -0
- ksadk/kernel/approval_presentation.py +91 -0
- ksadk/kernel/authorization.py +1 -1
- ksadk/kernel/bootstrap.py +86 -102
- ksadk/kernel/contract_fingerprints.py +1 -1
- ksadk/kernel/contracts.py +5 -0
- ksadk/kernel/control.py +32 -1
- ksadk/kernel/execution_grants.py +221 -0
- ksadk/kernel/execution_grants_memory.py +133 -0
- ksadk/kernel/execution_grants_postgres.py +217 -0
- ksadk/kernel/execution_grants_sqlite.py +209 -0
- ksadk/kernel/ingress.py +27 -27
- ksadk/kernel/mapping.py +1 -1
- ksadk/kernel/memory_store.py +24 -11
- ksadk/kernel/postgres_store.py +63 -33
- ksadk/kernel/recovery.py +78 -14
- ksadk/kernel/sql/001_agent_kernel.sql +23 -0
- ksadk/kernel/sqlite_store.py +304 -25
- ksadk/kernel/state.py +2 -3
- ksadk/kernel/store.py +69 -2
- ksadk/kernel/worker.py +79 -41
- ksadk/kernel/worker_history.py +72 -0
- ksadk/kernel/worker_identity.py +47 -0
- ksadk/memory/coordinator.py +22 -6
- ksadk/memory/extraction.py +40 -1
- ksadk/memory/models.py +77 -1
- ksadk/memory/provider_resolver.py +5 -0
- ksadk/memory/providers/local_postgres.py +200 -0
- ksadk/memory/providers/local_sqlite.py +42 -3
- ksadk/memory/retrieval.py +189 -0
- ksadk/memory/store_adapter.py +150 -0
- ksadk/model_policy.py +2 -2
- ksadk/model_proxy/detect.py +254 -0
- ksadk/model_proxy/server.py +4 -2
- ksadk/model_proxy/transform.py +40 -2
- ksadk/plugins/__init__.py +1 -1
- ksadk/plugins/bridges/dsh.py +11 -0
- ksadk/plugins/builtins.py +40 -2
- ksadk/plugins/companion_artifacts.py +83 -0
- ksadk/plugins/companions.py +368 -0
- ksadk/plugins/contracts.py +1 -1
- ksadk/plugins/dsh_channels.py +156 -0
- ksadk/plugins/dsh_home.py +140 -0
- ksadk/plugins/dsh_teams.py +105 -0
- ksadk/plugins/dsh_toolchain.py +101 -19
- ksadk/plugins/execution_host.py +99 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/client.js +19 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/index.mjs +7 -0
- ksadk/plugins/providers/bundles/dsh-channels-client/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-memory/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +1 -1
- ksadk/plugins/providers/bundles/dsh-teams-client/client.js +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/index.mjs +11 -0
- ksadk/plugins/providers/bundles/dsh-teams-client/package.json +35 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/index.mjs +13 -0
- ksadk/plugins/providers/bundles/dsh-teams-leader-policy/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/index.mjs +12 -0
- ksadk/plugins/providers/bundles/dsh-teams-profile/package.json +26 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-router/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/index.mjs +16 -0
- ksadk/plugins/providers/bundles/dsh-teams-tasks/package.json +27 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/index.mjs +25 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/package.json +29 -0
- ksadk/plugins/providers/bundles/dsh-teams-tools/tools.json +235 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +1 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +51 -1
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +2 -2
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/client.mjs +133 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-companion-host/index.mjs +14 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +27 -4
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +9 -5
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +1 -1
- ksadk/plugins/providers/codex.py +10 -2
- ksadk/plugins/providers/dsh_capabilities.py +61 -0
- ksadk/plugins/providers/harness.py +181 -33
- ksadk/plugins/providers/harness_delegation.py +593 -0
- ksadk/plugins/providers/harness_managed.py +456 -0
- ksadk/plugins/providers/harness_tools.py +326 -0
- ksadk/plugins/providers/shipped_dsh.py +4 -1
- ksadk/plugins/subagent_providers/codex.py +28 -6
- ksadk/plugins/teams/__init__.py +5 -0
- ksadk/plugins/teams/api.py +405 -0
- ksadk/plugins/teams/application.py +680 -0
- ksadk/plugins/teams/artifacts.py +60 -0
- ksadk/plugins/teams/context.py +96 -0
- ksadk/plugins/teams/contracts.py +136 -0
- ksadk/plugins/teams/domain.py +1427 -0
- ksadk/plugins/teams/domain_values.py +24 -0
- ksadk/plugins/teams/errors.py +13 -0
- ksadk/plugins/teams/migration.py +311 -0
- ksadk/plugins/teams/migration_cli.py +322 -0
- ksadk/plugins/teams/postgres_store.py +138 -0
- ksadk/plugins/teams/runtime.py +777 -0
- ksadk/plugins/teams/source_projection.py +84 -0
- ksadk/plugins/teams/store.py +311 -0
- ksadk/plugins/teams/task_decisions.py +423 -0
- ksadk/plugins/teams/transport.py +91 -0
- ksadk/plugins/teams/workspaces.py +255 -0
- ksadk/runners/_langgraph_runner_streams.py +121 -45
- ksadk/runners/_langgraph_state_reader.py +106 -0
- ksadk/runners/_session_identity.py +285 -0
- ksadk/runners/adk_runner.py +25 -60
- ksadk/runners/langgraph_runner.py +128 -111
- ksadk/runners/patch_langchain.py +47 -0
- ksadk/runners/usage_accumulator.py +11 -3
- ksadk/runtime/_runner_adapter/stream_mapping.py +52 -2
- ksadk/runtime/conversation_execution.py +25 -1
- ksadk/runtime/executor.py +9 -1
- ksadk/runtime/factory.py +36 -1
- ksadk/runtime/preprocessing.py +11 -3
- ksadk/runtime/runner_adapter.py +38 -9
- ksadk/runtime/skill_eval_result.py +36 -0
- ksadk/runtime/timing.py +46 -0
- ksadk/runtime/usage.py +49 -18
- ksadk/runtime_context.py +103 -1
- ksadk/sandbox/backends/e2b.py +245 -23
- ksadk/sandbox/backends/local_process.py +63 -39
- ksadk/sandbox/base.py +62 -1
- ksadk/sandbox/diagnostics.py +82 -0
- ksadk/sandbox/local_controls.py +746 -0
- ksadk/sandbox/local_launcher.py +90 -0
- ksadk/scheduler/dispatcher.py +1 -1
- ksadk/server/invocation_identity.py +118 -0
- ksadk/server/routes/common.py +32 -3
- ksadk/server/routes/control.py +64 -9
- ksadk/server/routes/dependencies.py +2 -1
- ksadk/server/routes/kernel_ingress.py +9 -1
- ksadk/server/routes/misc.py +233 -25
- ksadk/server/routes/models.py +3 -3
- ksadk/server/routes/openai_compat.py +76 -13
- ksadk/server/routes/run.py +106 -35
- ksadk/server/routes/sessions.py +244 -68
- ksadk/server/routes/workspace.py +130 -21
- ksadk/server/static/assets/{ArtifactsPanel-CGbWlMNh.js → ArtifactsPanel-C1YoaKhx.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-b4C7upmO.js → CodeBlock-DHuAWfr5.js} +10 -7
- ksadk/server/static/assets/MathMessageMarkdown-cvdrBwYr.js +8 -0
- ksadk/server/static/assets/{MermaidBlock-BEBN4Ksz.js → MermaidBlock-DeBkbJvI.js} +9 -9
- ksadk/server/static/assets/{NativeTerminalPanel-zvL-WpAn.js → NativeTerminalPanel-oJj44_sV.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-BYafW7Za.js → abnfDiagram-VCTEODGH-Dhfv25o2.js} +1 -1
- ksadk/server/static/assets/{arc-bTohInsS.js → arc-C35w-pn1.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BCsa26zi.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-Ch5Lbzsi.js → architectureDiagram-5GKGNRK7-FoMY_u6D.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-kqF4MDOG.js → blockDiagram-NRAW4CY4-zD4Rt7oE.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-8uSRIODv.js → c4Diagram-UCG6FXSJ-BCtGGkhN.js} +1 -1
- ksadk/server/static/assets/channel-_KDifNys.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-HdVkJ9F0.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-DkhehZDr.js → chunk-5VM5RSS4-C2Ms13_k.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-BdXhtPe9.js → chunk-F27PBJKO-BoTj-qgx.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-DPTpvpwi.js → chunk-G27WJ6UU-DOMyyjHH.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-Pqoh38el.js → chunk-JWPE2WC7-DbJJqDli.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-DeU00qC-.js → chunk-LCL6LL3I-CLuRCt_W.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CzxScFkr.js → chunk-POPQ4Y6H-D0Dz847e.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-DpqMx-ux.js → chunk-RHFEMEQ7-BWSRzEcd.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-C6t0SypQ.js → chunk-SVP7TREG-CPoHqkCY.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-DVaeafZk.js → chunk-XXDRQBXY-Bx1jS-X-.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-BVCW3ZqZ.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-BVCW3ZqZ.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-Bf9D3tzJ.js → cose-bilkent-JH36ORCC-LzyWm4m0.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-CNXjFctL.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-B9cY3iTz.js → cynefinDiagram-5FMLGOSQ-BlW_bHED.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-CSwlx3CB.js → dagre-3AP2YEHR-Bu_S86_i.js} +1 -1
- ksadk/server/static/assets/{dagre-UBpgon5q.js → dagre-B7nCawed.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-C9akhN9a.js → diagram-S7CK7UJ4-W_Zow2Km.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-CgedhTPI.js → diagram-UQ7AKVKN-CLIKAHON.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-Cjucz5BY.js → diagram-VSXAHHWV-Dv6_QAlN.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-Dd4Vleyn.js → diagram-VX7I27RA-BWAWRDtZ.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-CZ2jGtYW.js → diagram-Z3DM3KII-XA_rWMss.js} +1 -1
- ksadk/server/static/assets/dist-0X_j2Rcc.js +1 -0
- ksadk/server/static/assets/{dist-DiixqL0J.js → dist-1nXCdsej.js} +1 -1
- ksadk/server/static/assets/{dist-BIr4DSRq.js → dist-2vL2sAdF.js} +1 -1
- ksadk/server/static/assets/{dist-D_ctSS2i.js → dist-B3bA05-e.js} +1 -1
- ksadk/server/static/assets/{dist-ClYUxfeK.js → dist-BLpRy_Yx.js} +1 -1
- ksadk/server/static/assets/{dist-QfkEHOlb.js → dist-BO_UwatH.js} +1 -1
- ksadk/server/static/assets/{dist-B3FR1SKK.js → dist-BdNFAney.js} +1 -1
- ksadk/server/static/assets/{dist-BnaTiyzN.js → dist-C0J5_3qM.js} +1 -1
- ksadk/server/static/assets/{dist-Bj730Ib4.js → dist-CGt_UGeO.js} +1 -1
- ksadk/server/static/assets/{dist-CFzsn6BG.js → dist-CIRMvUM4.js} +1 -1
- ksadk/server/static/assets/{dist-BgV_owcB.js → dist-CIpWk_5f.js} +1 -1
- ksadk/server/static/assets/{dist-C5_ZAZsG.js → dist-CPyieXEf.js} +1 -1
- ksadk/server/static/assets/{dist-btbmmX5O.js → dist-D-92S-Fd.js} +1 -1
- ksadk/server/static/assets/{dist-fBO2v5Kt.js → dist-DNKuMzWc.js} +1 -1
- ksadk/server/static/assets/{dist-ufY3F5p6.js → dist-DWfdmz9s.js} +2 -2
- ksadk/server/static/assets/{dist-DVCOWtha.js → dist-DppE_r-D.js} +1 -1
- ksadk/server/static/assets/{dist-C1NMAY5a.js → dist-DyG6Ya-z.js} +1 -1
- ksadk/server/static/assets/{dist-CB9iJrvg.js → dist-M-SrdhhZ.js} +1 -1
- ksadk/server/static/assets/{dist-DvFK7p5S.js → dist-mqD5TZup.js} +1 -1
- ksadk/server/static/assets/{dist-Cf125P_m.js → dist-n3n6t_FO.js} +1 -1
- ksadk/server/static/assets/{dist-DFD6Qa6T.js → dist-qe8xjesy.js} +1 -1
- ksadk/server/static/assets/{dist-DoVSwoDb.js → dist-t6MzE0jU.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Ci8NqqZu.js → ebnfDiagram-PWID7BFC-BfCzF1Xi.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CCIOhLZG.js → erDiagram-SSCWMZ5O-Dpz9_0zn.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-B5-8RH9c.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BppFxEKw.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js → ganttDiagram-EL5Y4UJY-DDaG1f4_.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-B-AhYj4C.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js → gitGraphDiagram-WWUBYQGX-DcxzRwYC.js} +1 -1
- ksadk/server/static/assets/index-BMd2mucF.css +2 -0
- ksadk/server/static/assets/index-D5qyyhTH.js +244 -0
- ksadk/server/static/assets/info-A6RAGUB7-0uiKrC35.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-CO0rRTRA.js → infoDiagram-RXCK75RN-CYMdn6lQ.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CHiaedSS.js → ishikawaDiagram-5VMMS53U-CLHFAD6c.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-CHcCIB09.js → journeyDiagram-EYS64GPL-BHSKQGAl.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CJ_ebBZf.js → kanban-definition-3QL26DDD-D5W3tjTT.js} +1 -1
- ksadk/server/static/assets/{katex-B4weu383.js → katex-mtjOi4KM.js} +1 -1
- ksadk/server/static/assets/{linear-V-MgYHW1.js → linear-BETqsxE_.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-CBijEX_c.js → mermaid-parser.core-DPWrvs90.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-Bc-pQvpp.js → mindmap-definition-FBJOCRG2-CJG2mfBP.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BVTmZ_cw.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-D7genGLl.js → pegDiagram-XKGWAZYB-GjAPNaqn.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-DyfxBU7V.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-Bxj32zwD.js → pieDiagram-E7YTZNPT-ToIewrqr.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BURv2mGh.js → quadrantDiagram-AXDQQJYC-4d78KiEY.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-FFontjL2.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-D0Uidzen.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BOo_9T2h.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-D6-BjW7Z.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CXx__yMm.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-CCsh3avW.js → railroadDiagram-O6MQD6OU-DKzx4xfv.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-_FRRBKEd.js → requirementDiagram-EFPCY7ZU-CJYljxQS.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-C-gr2o9M.js → sankeyDiagram-P5KCCOFB-DLU2fV1w.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-D97NmfKg.js → sequenceDiagram-WJ2MYXX4-CVqysrA9.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DjrPC5FX.js → sizeCapture-X5ZJPWSS-BUxfmTHc.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DzMNg1hh.js → stateDiagram-HBIQ2CUA-CNFgYI9E.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BXAFScz8.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-Cssf_CsU.js → swimlanes-XN3QIQJK-B6qCMe8N.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uIQ2lJKH.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-BWTHzyS1.js → timeline-definition-24CTP7MA-CMD3x_U_.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5GgucZ.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-Bq1u1SpG.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-BSKgJsmR.js → vennDiagram-4TSXK5OY-BqtUqvXM.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-QAt06uEz.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-eflHNoaZ.js → wardleyDiagram-VM6X3IG4-B5KfDjI-.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-eYqrQ-v4.js → xychartDiagram-S5SC5T6Z-BaUlSZrn.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/server/terminal_sessions.py +34 -2
- ksadk/sessions/invocation_identity.py +235 -0
- ksadk/skills/__init__.py +26 -0
- ksadk/skills/events.py +464 -0
- ksadk/skills/manifest_cache.py +263 -0
- ksadk/skills/mcp_server/__init__.py +0 -0
- ksadk/skills/mcp_server/_registry.py +33 -0
- ksadk/skills/mcp_server/_routing.py +26 -0
- ksadk/skills/mcp_server/_workspace_files.py +160 -0
- ksadk/skills/mcp_server/register.py +415 -0
- ksadk/skills/mcp_server/server.py +218 -0
- ksadk/skills/models.py +11 -0
- ksadk/skills/observability.py +132 -0
- ksadk/skills/package_store.py +75 -2
- ksadk/skills/runtime/agent.py +38 -5
- ksadk/skills/runtime/artifacts.py +87 -0
- ksadk/skills/runtime/backends/e2b.py +393 -52
- ksadk/skills/runtime/backends/local.py +621 -119
- ksadk/skills/runtime/base.py +78 -7
- ksadk/skills/runtime/executor.py +266 -1
- ksadk/skills/runtime/loader.py +108 -3
- ksadk/skills/runtime/request.py +18 -0
- ksadk/skills/tool_defs.py +108 -3
- ksadk/studio/api.py +592 -57
- ksadk/studio/api_contracts.py +8 -2
- ksadk/studio/api_plugin_routes.py +39 -12
- ksadk/studio/api_resource_connections.py +79 -41
- ksadk/studio/authoring.py +12 -6
- ksadk/studio/authoring_coordinator.py +4 -2
- ksadk/studio/builder.py +12 -0
- ksadk/studio/capabilities.py +23 -6
- ksadk/studio/channel_connections.py +333 -0
- ksadk/studio/cloud.py +30 -10
- ksadk/studio/cloud_shared_web.py +75 -2
- ksadk/studio/codex_agent_service.py +2 -2
- ksadk/studio/codex_builder.py +1 -1
- ksadk/studio/codex_run.py +6 -1
- ksadk/studio/compiler.py +10 -0
- ksadk/studio/configuration.py +182 -0
- ksadk/studio/contracts.py +33 -5
- ksadk/studio/dsh_application.py +135 -25
- ksadk/studio/dsh_capability_service.py +287 -20
- ksadk/studio/dsh_lifecycle.py +58 -0
- ksadk/studio/dsh_provider_registration.py +55 -16
- ksadk/studio/entry.py +53 -0
- ksadk/studio/event_store.py +36 -5
- ksadk/studio/execution_host.py +525 -0
- ksadk/studio/framework_run.py +32 -10
- ksadk/studio/hosted_kernel.py +1 -1
- ksadk/studio/kernel_registry.py +418 -0
- ksadk/studio/kernel_sqlite_migration.py +181 -0
- ksadk/studio/model_client.py +1178 -64
- ksadk/studio/model_profile_service.py +26 -11
- ksadk/studio/native_documents.py +172 -0
- ksadk/studio/plugin_composition.py +13 -2
- ksadk/studio/plugin_kernel_adapter.py +15 -0
- ksadk/studio/plugin_lifecycle.py +80 -0
- ksadk/studio/plugin_runtime.py +230 -17
- ksadk/studio/provider_recovery.py +59 -0
- ksadk/studio/recovery_page.py +70 -0
- ksadk/studio/resource_authority.py +59 -32
- ksadk/studio/resource_catalog.py +6 -0
- ksadk/studio/run_activity.py +895 -0
- ksadk/studio/run_documents.py +127 -0
- ksadk/studio/run_service.py +329 -33
- ksadk/studio/runtime_catalog.py +53 -10
- ksadk/studio/runtime_source.py +1 -1
- ksadk/studio/scheduler_runtime.py +32 -289
- ksadk/studio/service.py +398 -103
- ksadk/studio/shared_web.py +149 -36
- ksadk/studio/static/assets/ChannelsPage-D_PGmKVq.js +8 -0
- ksadk/studio/static/assets/CodeBlock-DMIf4h33-UIqo-BPW.js +44 -0
- ksadk/studio/static/assets/ExecutionTree-v3HexvPo-Bk8wzGSy.js +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-BesSeCYl-OhNwH4K9.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-H_0qzQDf-BdXtxug_.js +11 -0
- ksadk/studio/static/assets/MessageMarkdown-CwMTvgFj-g0I-I4dD.js +59 -0
- ksadk/studio/static/assets/PrismRenderer-5pK6tUdb.js +3 -0
- ksadk/studio/static/assets/TeamsPage-DqX4HWKQ.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-Bnb1O3tA.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-5Zn1gqJv.js +36 -0
- ksadk/studio/static/assets/{blockDiagram-I7D4REHJ-CFmPl1de.js → blockDiagram-I7D4REHJ-CLB4L11u.js} +6 -6
- ksadk/studio/static/assets/{c4Diagram-7LVT6UL2-BRrGu8qt.js → c4Diagram-7LVT6UL2-BOma_Z_F.js} +7 -7
- ksadk/studio/static/assets/channel-r8itPEik.js +1 -0
- ksadk/studio/static/assets/chunk-2E4U76K2-BFf_huql.js +2 -0
- ksadk/studio/static/assets/chunk-2ZTRR5NV-C2qZJila.js +2 -0
- ksadk/studio/static/assets/chunk-3Z5EZCMW-DMniOlPd.js +1 -0
- ksadk/studio/static/assets/{chunk-4HAMMTFA-D220vUtq.js → chunk-4HAMMTFA-DVtDP4rm.js} +7 -7
- ksadk/studio/static/assets/chunk-5V3GS4D5-i-ZDOEnP.js +1 -0
- ksadk/studio/static/assets/chunk-6AZGARVD-BB6FqMl-.js +1 -0
- ksadk/studio/static/assets/chunk-6EIED4P4-DdUJkP0f.js +1 -0
- ksadk/studio/static/assets/chunk-6K3QC6MW-CqVsVn-y.js +1 -0
- ksadk/studio/static/assets/chunk-6TQVIW2G-DKlLbNIP.js +1 -0
- ksadk/studio/static/assets/chunk-747NJXEK-BFkZPlab.js +2 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-BZNhM4vB.js +2 -0
- ksadk/studio/static/assets/chunk-CLGD4ZFX-D-GTtyKs.js +1 -0
- ksadk/studio/static/assets/{chunk-DU6HZSFF-C4DtVpCu.js → chunk-DU6HZSFF-CpEZCUgg.js} +1 -1
- ksadk/studio/static/assets/chunk-F27PBJKO-D7pvKf0C.js +1 -0
- ksadk/studio/static/assets/{chunk-GMAD6QVW-DiQA-u2N.js → chunk-GMAD6QVW-DE_8H717.js} +6 -6
- ksadk/studio/static/assets/chunk-GVQU2GXP-BfEB0lNv.js +1 -0
- ksadk/studio/static/assets/chunk-I5DQTOEV-Hm2LfiYI.js +1 -0
- ksadk/studio/static/assets/chunk-ICYGCRZG-749o-pGJ.js +1 -0
- ksadk/studio/static/assets/chunk-IH6LHLGP-CC6I9F3i.js +1 -0
- ksadk/studio/static/assets/{chunk-IMKFNOWR-BSlbjT_b.js → chunk-IMKFNOWR-D38axYOR.js} +5 -5
- ksadk/studio/static/assets/chunk-KI3K4JFJ-Rma-0k_M.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Dq5xn7aL.js +1 -0
- ksadk/studio/static/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
- ksadk/studio/static/assets/{chunk-OSK3NFVY-M2m6G3j4.js → chunk-OSK3NFVY-DiCQjx9b.js} +5 -5
- ksadk/studio/static/assets/chunk-OUJLGHUK-D0j2JRSg.js +2 -0
- ksadk/studio/static/assets/{chunk-P2QGCYS3-DezaQxiK.js → chunk-P2QGCYS3-VdhKmfYq.js} +1 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-C1_rzO5M.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-B45HvflI.js +1 -0
- ksadk/studio/static/assets/{chunk-SHT3W25Y-DAyIVp5H.js → chunk-SHT3W25Y-DsCFnRVE.js} +9 -9
- ksadk/studio/static/assets/{chunk-SVP7TREG-DulomOrS.js → chunk-SVP7TREG-DljApgRX.js} +1 -1
- ksadk/studio/static/assets/{chunk-TICWLB2K-bHJYoflj.js → chunk-TICWLB2K-DWqRtyqa.js} +6 -6
- ksadk/studio/static/assets/chunk-TLUHSLCS-DUeGgnD5.js +2 -0
- ksadk/studio/static/assets/chunk-UY3FDG6J-CnmaAkG5.js +1 -0
- ksadk/studio/static/assets/chunk-XHIXRSVI-BFQ6B8BE.js +1 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-DqAYeljN.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-DjeMNJmu.js +1 -0
- ksadk/studio/static/assets/clsx-DB0hHKMi.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-om8AY0Mc.js +1 -0
- ksadk/studio/static/assets/createLucideIcon-DR0LGTP5.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-6BrmK52S.js +62 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-buZBRlwz.js +4 -0
- ksadk/studio/static/assets/{diagram-S7CK7UJ4-0BZ98mya.js → diagram-S7CK7UJ4-C6aH78c4.js} +3 -3
- ksadk/studio/static/assets/diagram-UQ7AKVKN-DY_tQ6C_.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-DX9p5cQT.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-DB2WSH8X.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-Ce1BJwHE.js +24 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-Daukxwqf.js +1 -0
- ksadk/studio/static/assets/{erDiagram-RLTQ6QDP-DLGry2Ap.js → erDiagram-RLTQ6QDP-CGthTMmJ.js} +6 -6
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-CZ1tEenp.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BfoAZW9X.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-S985OIJF.js +106 -0
- ksadk/studio/static/assets/iconfont-4HN3C9Pg.woff2 +0 -0
- ksadk/studio/static/assets/index-CfEnms6Y.css +2 -0
- ksadk/studio/static/assets/index-Dp61rOWZ.js +0 -0
- ksadk/studio/static/assets/index.dom-BQenBtFm.js +1 -0
- ksadk/studio/static/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-CO3W8tFn.js +2 -0
- ksadk/studio/static/assets/{ishikawaDiagram-5VMMS53U-CljI2wyf.js → ishikawaDiagram-5VMMS53U-BUGEl8cO.js} +2 -2
- ksadk/studio/static/assets/{journeyDiagram-3NMN7TZE-D50Fo2sL.js → journeyDiagram-3NMN7TZE-Ch2ZYxvr.js} +6 -6
- ksadk/studio/static/assets/{kanban-definition-UXKFOSKX-DimfOTam.js → kanban-definition-UXKFOSKX-Da-Fp4vC.js} +3 -3
- ksadk/studio/static/assets/kingsoft-cloud-BOcLiQ3e.ico +0 -0
- ksadk/studio/static/assets/{line-CX5BOOUP.js → line-BDaeq300.js} +1 -1
- ksadk/studio/static/assets/linear-DmucvK78.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-Cj5mYdBi.js +4 -0
- ksadk/studio/static/assets/{mindmap-definition-YA3MSWOX-Bizzqy5R.js → mindmap-definition-YA3MSWOX-CvlsVQ38.js} +1 -1
- ksadk/studio/static/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-BuHuNgT5.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
- ksadk/studio/static/assets/{pieDiagram-E7YTZNPT-B9mrFSDF.js → pieDiagram-E7YTZNPT-DlrWiSOv.js} +1 -1
- ksadk/studio/static/assets/preload-helper-CO68xz6u.js +1 -0
- ksadk/studio/static/assets/presentation-yYw7xK60-BmcZriri.js +1 -0
- ksadk/studio/static/assets/{quadrantDiagram-AXDQQJYC-NzUfCbMR.js → quadrantDiagram-AXDQQJYC-BA3hpUZM.js} +6 -6
- ksadk/studio/static/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-BxpAazym.js +1 -0
- ksadk/studio/static/assets/{requirementDiagram-BXWQKSXE-BF3d103U.js → requirementDiagram-BXWQKSXE-E-Ge0FcV.js} +1 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-CA6YKhQ3.js +40 -0
- ksadk/studio/static/assets/{sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js → sequenceDiagram-WJ2MYXX4-CcElXGg4.js} +9 -9
- ksadk/studio/static/assets/src-B6xuSHsQ.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DdXZOFqY.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-CJbOM-QK.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-NtgEEHLY.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-D-AVlW8B.js +8 -0
- ksadk/studio/static/assets/{timeline-definition-24CTP7MA-DxmSSjRB.js → timeline-definition-24CTP7MA-CIuYhNy3.js} +7 -7
- ksadk/studio/static/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-7HbApbrv.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
- ksadk/studio/static/assets/{wardleyDiagram-VM6X3IG4-Ba1AOWoe.js → wardleyDiagram-VM6X3IG4-CMJiaedy.js} +1 -1
- ksadk/studio/static/assets/{xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js → xychartDiagram-S5SC5T6Z-BdgtMvW2.js} +6 -6
- ksadk/studio/static/index.html +8 -2
- ksadk/studio/teams_catalog.py +133 -0
- ksadk/studio/teams_installation.py +214 -0
- ksadk/studio/teams_node.py +545 -0
- ksadk/studio/teams_node_runner.py +69 -0
- ksadk/studio/teams_remote.py +274 -0
- ksadk/studio/templates.py +40 -19
- ksadk/studio/validator.py +13 -0
- ksadk/studio/workspace.py +19 -4
- ksadk/studio/workspace_plugins.py +136 -0
- ksadk/studio/workspace_registry.py +286 -0
- ksadk/toolsets/__init__.py +11 -0
- ksadk/toolsets/skills.py +446 -378
- ksadk/toolsets/workspace.py +3 -3
- ksadk/toolsets/workspace_identity.py +15 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/memory_backend/providers/lancedb.py +56 -2
- ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -148
- ksadk_runtime_common/workspace_files/router.py +26 -13
- ksadk/server/static/assets/MathMessageMarkdown-DbdW5A4_.js +0 -8
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +0 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +0 -1
- ksadk/server/static/assets/dist-B2_CVgKv.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +0 -1
- ksadk/server/static/assets/index-DcTML1Up.css +0 -2
- ksadk/server/static/assets/index-Dh2XHqPK.js +0 -244
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +0 -1
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +0 -41
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +0 -8
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +0 -44
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +0 -3
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +0 -1
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +0 -1
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +0 -36
- ksadk/studio/static/assets/channel-BqO-gtEw.js +0 -1
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +0 -2
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +0 -1
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +0 -1
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +0 -1
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +0 -1
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +0 -1
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +0 -1
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +0 -1
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +0 -1
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +0 -1
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +0 -62
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +0 -4
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +0 -41
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +0 -3
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +0 -24
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +0 -24
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +0 -1
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +0 -1
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +0 -1
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +0 -292
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +0 -1
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +0 -106
- ksadk/studio/static/assets/index-CeHL9ARV.css +0 -2
- ksadk/studio/static/assets/index-D9QEcVpL.js +0 -320
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +0 -1
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +0 -2
- ksadk/studio/static/assets/linear-BCxN9JLv.js +0 -1
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +0 -7
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +0 -1
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +0 -1
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +0 -1
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +0 -1
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +0 -1
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +0 -1
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +0 -1
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +0 -1
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +0 -1
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +0 -40
- ksadk/studio/static/assets/src-SFn9St9H.js +0 -1
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +0 -1
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +0 -1
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +0 -1
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +0 -8
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +0 -1
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +0 -1
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +0 -34
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +0 -1
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.4.dist-info → agentengine_sdk_python-0.8.5.dist-info}/top_level.txt +0 -0
- /ksadk/studio/static/assets/{MathMessageMarkdown-CBcDrAw--BEOyPC3w.css → MathMessageMarkdown-BesSeCYl-BEOyPC3w.css} +0 -0
|
@@ -0,0 +1,931 @@
|
|
|
1
|
+
"""ManagedLangGraphEngine —— 默认执行引擎(plan §7 / Kernel)。
|
|
2
|
+
|
|
3
|
+
实现 §7.1 默认 Agent Loop 的 Kernel 子集:prepare_context -> reason ->
|
|
4
|
+
tool_calls -> final,reason 自环。LangGraph 类型不越出本模块
|
|
5
|
+
(tests/architecture/test_harness_contract.py 守卫)。
|
|
6
|
+
|
|
7
|
+
Kernel 能力范围(诚实声明):
|
|
8
|
+
- Cancel:支持(终止语义,不伪装 Pause);
|
|
9
|
+
- Interrupt/Resume:支持(approval 通道,resume 携带 payload 重放);
|
|
10
|
+
- Checkpoint:LangGraph Checkpointer 注入(内存/SQLite),thread_id 走
|
|
11
|
+
租户复合编码(plan §6.2.2);
|
|
12
|
+
- Context 压缩:Release 交付,本引擎留 policy 读取口。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import asyncio
|
|
18
|
+
import time
|
|
19
|
+
import uuid
|
|
20
|
+
from typing import Any, AsyncIterator, Callable
|
|
21
|
+
|
|
22
|
+
from langgraph.checkpoint.base import BaseCheckpointSaver
|
|
23
|
+
from langgraph.errors import GraphInterrupt
|
|
24
|
+
from langgraph.types import Command
|
|
25
|
+
|
|
26
|
+
from ksadk.harness.engine import budgets
|
|
27
|
+
from ksadk.harness.engine.base import (
|
|
28
|
+
CompiledHarness,
|
|
29
|
+
EngineCapability,
|
|
30
|
+
EngineCapabilityMatrix,
|
|
31
|
+
ExecutionEngineError,
|
|
32
|
+
)
|
|
33
|
+
from ksadk.harness.engine.context_pipeline import EngineContextPipeline
|
|
34
|
+
from ksadk.harness.engine.mcp_disclosure import (
|
|
35
|
+
McpDisclosureBridge,
|
|
36
|
+
McpDisclosureCursors,
|
|
37
|
+
)
|
|
38
|
+
from ksadk.harness.engine.policy_runtime import configure_run, revalidate_policy
|
|
39
|
+
from ksadk.harness.engine.run_types import _EngineRun, _GraphState
|
|
40
|
+
from ksadk.harness.engine.skill_disclosure import SkillDisclosureBridge
|
|
41
|
+
from ksadk.harness.engine.thread_ids import encode_thread_id
|
|
42
|
+
from ksadk.harness.events import EventType, RuntimeEvent
|
|
43
|
+
from ksadk.harness.execution_policy import execution_policy_scope
|
|
44
|
+
from ksadk.harness.mcp_runtime import McpCapabilityRuntime
|
|
45
|
+
from ksadk.harness.prompt_cache import PromptCacheTracker
|
|
46
|
+
from ksadk.harness.reasoner import HarnessReasoner, LiteLLMHarnessReasoner
|
|
47
|
+
from ksadk.harness.run_control import (
|
|
48
|
+
RunController,
|
|
49
|
+
RunControlStop,
|
|
50
|
+
run_control_spec_from_config,
|
|
51
|
+
)
|
|
52
|
+
from ksadk.harness.skill_runtime import SkillRuntime
|
|
53
|
+
from ksadk.harness.spec import HarnessSpec
|
|
54
|
+
from ksadk.harness.state import HarnessState, Message, MessageRole, RunStatus
|
|
55
|
+
from ksadk.harness.strategies import ExecutionStrategyRegistry
|
|
56
|
+
from ksadk.runtime import (
|
|
57
|
+
CancelResult,
|
|
58
|
+
PauseResult,
|
|
59
|
+
ResumePayload,
|
|
60
|
+
ResumeTarget,
|
|
61
|
+
RunHandle,
|
|
62
|
+
StartRequest,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
_MAX_REASONING_TURNS = 8
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ManagedLangGraphEngine:
|
|
69
|
+
"""默认执行引擎:Revision 编译产物在 LangGraph 上运行。"""
|
|
70
|
+
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
*,
|
|
74
|
+
reasoner: HarnessReasoner | None = None,
|
|
75
|
+
checkpointer: BaseCheckpointSaver | None = None,
|
|
76
|
+
tenant_id: str = "default",
|
|
77
|
+
tools: dict[str, Any] | None = None,
|
|
78
|
+
approval_required: set[str] | None = None,
|
|
79
|
+
context_engine: Any | None = None,
|
|
80
|
+
strategy_registry: ExecutionStrategyRegistry | None = None,
|
|
81
|
+
capability_runtime: Any | None = None,
|
|
82
|
+
sub_agents: dict[str, Any] | None = None,
|
|
83
|
+
memory_runtime: Any | None = None,
|
|
84
|
+
skill_runtime: SkillRuntime | None = None,
|
|
85
|
+
mcp_runtime: McpCapabilityRuntime | None = None,
|
|
86
|
+
artifact_store: Any | None = None,
|
|
87
|
+
mcp_offload_policy: Any | None = None,
|
|
88
|
+
delegation_runtime: Any | None = None,
|
|
89
|
+
event_sink: Callable[[str, str, RuntimeEvent], None] | None = None,
|
|
90
|
+
max_reasoning_turns: int = _MAX_REASONING_TURNS,
|
|
91
|
+
) -> None:
|
|
92
|
+
self._reasoner = reasoner or LiteLLMHarnessReasoner()
|
|
93
|
+
self._checkpointer = checkpointer
|
|
94
|
+
# 集成项 4:Strategy Registry 真正参与 compile()——拓扑来自注册表。
|
|
95
|
+
self._strategy_registry = strategy_registry or ExecutionStrategyRegistry()
|
|
96
|
+
self._tenant_id = tenant_id
|
|
97
|
+
self._tools = tools or {}
|
|
98
|
+
self._approval_required = approval_required or set()
|
|
99
|
+
self._context_engine = context_engine
|
|
100
|
+
# 收口 2:统一 CapabilityRuntime(Policy 决策 + Receipt 幂等)。
|
|
101
|
+
# 为 None 时 tool_calls 节点回退静态 approval_required 集合。
|
|
102
|
+
self._capability_runtime = capability_runtime
|
|
103
|
+
# 收口 6:子 Agent(名称 → SubAgentSpec);多 Agent 作为可选能力。
|
|
104
|
+
self._sub_agents = sub_agents or {}
|
|
105
|
+
if max_reasoning_turns < 1:
|
|
106
|
+
raise ValueError("max_reasoning_turns 必须为正整数")
|
|
107
|
+
self._max_reasoning_turns = max_reasoning_turns
|
|
108
|
+
# 长任务方案 §6.4:压缩前受控 Memory Flush 用的 Memory Runtime(可选)。
|
|
109
|
+
self._memory_runtime = memory_runtime
|
|
110
|
+
self._prompt_cache_tracker = PromptCacheTracker()
|
|
111
|
+
# SkillRuntime 只消费已绑定、已校验的 Skill 内容;L0 摘要常驻动态
|
|
112
|
+
# Context,L1/L2/L3 由默认 Agent Loop 的受限工具渐进披露。
|
|
113
|
+
self._skill_runtime = skill_runtime
|
|
114
|
+
self._skill_disclosure = SkillDisclosureBridge(skill_runtime)
|
|
115
|
+
# P0 MCP Deferred Tool Loading:McpCapabilityRuntime 复用健康缓存/
|
|
116
|
+
# 熔断/tools 缓存,披露层级(L0 目录/L1 列表/L2 Schema/L3 调用)
|
|
117
|
+
# 由 McpDisclosureBridge 接入默认 Loop。
|
|
118
|
+
self._mcp_runtime = mcp_runtime
|
|
119
|
+
# P1 大结果 Offload:L3 结果超阈值/命中敏感策略 → Artifact Store 外置。
|
|
120
|
+
self._mcp_disclosure = McpDisclosureBridge(
|
|
121
|
+
mcp_runtime,
|
|
122
|
+
artifact_store=artifact_store,
|
|
123
|
+
offload_policy=mcp_offload_policy,
|
|
124
|
+
)
|
|
125
|
+
# Provider-owned dynamic delegation. The engine only knows the stable
|
|
126
|
+
# tool/runtime seam; provider selection remains outside the LangGraph
|
|
127
|
+
# execution kernel.
|
|
128
|
+
self._delegation_runtime = delegation_runtime
|
|
129
|
+
# P3 补强:事件出口回调(session_id, run_id, event)——洞察登记处
|
|
130
|
+
# (ksadk.harness.insights)由此拿到完整事件流,供 Studio API 消费。
|
|
131
|
+
self._event_sink = event_sink
|
|
132
|
+
# Context 构建管线(规划/压缩/组装/Manifest 投影,见 context_pipeline)。
|
|
133
|
+
self._context_pipeline = (
|
|
134
|
+
EngineContextPipeline(
|
|
135
|
+
context_engine=self._context_engine,
|
|
136
|
+
reasoner=self._reasoner,
|
|
137
|
+
event_fn=self._event,
|
|
138
|
+
memory_runtime=self._memory_runtime,
|
|
139
|
+
prompt_cache_tracker=self._prompt_cache_tracker,
|
|
140
|
+
)
|
|
141
|
+
if self._context_engine is not None
|
|
142
|
+
else None
|
|
143
|
+
)
|
|
144
|
+
# 最近 compile 的 Spec(子 Agent 派生 child spec 用)。
|
|
145
|
+
self._current_spec: HarnessSpec | None = None
|
|
146
|
+
# 收口 6:子 Agent 事件缓冲(run_id → 待并入父流的子事件)。
|
|
147
|
+
# 子 Agent 在 tool_calls 节点内联执行,但事件必须等本节点自身的
|
|
148
|
+
# tool.call.begin/end 落定后统一重排并入,保证 seq 单调。
|
|
149
|
+
self._pending_child_events: dict[str, list[RuntimeEvent]] = {}
|
|
150
|
+
# 并行子 Agent 按 call_id 单独缓冲,节点结束时再按模型原始调用顺序
|
|
151
|
+
# 合并,避免墙钟完成顺序造成 Trace/重放结果不确定。
|
|
152
|
+
self._pending_subagent_events: dict[str, dict[str, list[RuntimeEvent]]] = {}
|
|
153
|
+
# parent_run_id -> call_id -> (child_engine, child_handle)。父取消必须先
|
|
154
|
+
# 显式传播到所有活动子 Run,不能只依赖 asyncio 任务树的隐式取消。
|
|
155
|
+
self._active_subagent_runs: dict[str, dict[str, tuple[Any, RunHandle]]] = {}
|
|
156
|
+
self._runs: dict[str, _EngineRun] = {}
|
|
157
|
+
|
|
158
|
+
# ------------------------------------------------------------- compile
|
|
159
|
+
|
|
160
|
+
async def compile(self, spec: HarnessSpec) -> CompiledHarness:
|
|
161
|
+
# 集成项 4:拓扑由 Strategy Registry 按 spec.execution_strategy 编译,
|
|
162
|
+
# 引擎不再硬编码 single_agent_plan。
|
|
163
|
+
plan = self._strategy_registry.compile(spec, strategy=spec.execution_strategy.kind.value)
|
|
164
|
+
if spec.execution_strategy.kind.value == self._strategy_registry.default():
|
|
165
|
+
ExecutionStrategyRegistry.assert_single_agent_purity(plan)
|
|
166
|
+
max_parallel = spec.execution_strategy.config.get("max_parallel_subagents", 4)
|
|
167
|
+
if isinstance(max_parallel, bool) or not isinstance(max_parallel, int):
|
|
168
|
+
raise ExecutionEngineError("max_parallel_subagents 必须是整数")
|
|
169
|
+
if not 1 <= max_parallel <= 32:
|
|
170
|
+
raise ExecutionEngineError("max_parallel_subagents 必须在 1..32 之间")
|
|
171
|
+
failure_mode = spec.execution_strategy.config.get("subagent_failure_mode", "partial")
|
|
172
|
+
if failure_mode not in {"partial", "fail_fast"}:
|
|
173
|
+
raise ExecutionEngineError("subagent_failure_mode 必须是 partial 或 fail_fast")
|
|
174
|
+
try:
|
|
175
|
+
run_control_spec_from_config(spec.execution_strategy.config)
|
|
176
|
+
except ValueError as exc:
|
|
177
|
+
raise ExecutionEngineError(f"run_control 配置无效: {exc}") from exc
|
|
178
|
+
declared_sub_agents = {binding.name for binding in spec.sub_agents}
|
|
179
|
+
self._skill_disclosure.validate_bindings(
|
|
180
|
+
spec,
|
|
181
|
+
tool_names=set(self._tools),
|
|
182
|
+
sub_agent_names=set(self._sub_agents) | declared_sub_agents,
|
|
183
|
+
)
|
|
184
|
+
self._mcp_disclosure.validate_bindings(
|
|
185
|
+
spec,
|
|
186
|
+
tool_names=set(self._tools),
|
|
187
|
+
sub_agent_names=set(self._sub_agents) | declared_sub_agents,
|
|
188
|
+
)
|
|
189
|
+
self._current_spec = spec
|
|
190
|
+
return CompiledHarness(
|
|
191
|
+
spec=spec,
|
|
192
|
+
plan=plan,
|
|
193
|
+
engine_kind="managed-langgraph",
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# --------------------------------------------------------------- start
|
|
197
|
+
|
|
198
|
+
async def start(
|
|
199
|
+
self, request: StartRequest, compiled: CompiledHarness, *,
|
|
200
|
+
execution_policy=None, execution_policy_resolver=None, execution_policy_request=None,
|
|
201
|
+
) -> RunHandle:
|
|
202
|
+
run_id = str(request.metadata.get("invocation_id") or f"mle_{uuid.uuid4().hex[:16]}")
|
|
203
|
+
if run_id in self._runs:
|
|
204
|
+
raise ValueError(f"duplicate engine run: {run_id}")
|
|
205
|
+
state = HarnessState(
|
|
206
|
+
tenant_id=self._tenant_id,
|
|
207
|
+
user_id=request.user_id,
|
|
208
|
+
agent_id=str(request.agent_id or compiled.spec.agent_revision_ref),
|
|
209
|
+
session_id=request.session_id,
|
|
210
|
+
run_id=run_id,
|
|
211
|
+
status=RunStatus.PENDING,
|
|
212
|
+
)
|
|
213
|
+
checkpoint_session_id = str(
|
|
214
|
+
request.metadata.get("checkpoint_session_id") or request.session_id
|
|
215
|
+
)
|
|
216
|
+
thread_id = encode_thread_id(
|
|
217
|
+
tenant_id=self._tenant_id,
|
|
218
|
+
user_id=request.user_id,
|
|
219
|
+
agent_id=state.agent_id,
|
|
220
|
+
session_id=checkpoint_session_id,
|
|
221
|
+
run_id=run_id,
|
|
222
|
+
)
|
|
223
|
+
handle = RunHandle(
|
|
224
|
+
run_id=run_id,
|
|
225
|
+
session_id=request.session_id,
|
|
226
|
+
runtime_type="managed-langgraph",
|
|
227
|
+
native_ref={
|
|
228
|
+
"thread_id": thread_id,
|
|
229
|
+
"user_id": request.user_id,
|
|
230
|
+
"agent_id": state.agent_id,
|
|
231
|
+
**({"execution_policy_ref": request.metadata["execution_policy_ref"]}
|
|
232
|
+
if "execution_policy_ref" in request.metadata else {}),
|
|
233
|
+
**({"parent_run_id": request.metadata["parent_run_id"]}
|
|
234
|
+
if "parent_run_id" in request.metadata else {}),
|
|
235
|
+
},
|
|
236
|
+
)
|
|
237
|
+
from ksadk.harness.subagent import SubAgentSpec
|
|
238
|
+
|
|
239
|
+
revision_sub_agents = {
|
|
240
|
+
binding.name: SubAgentSpec.from_binding(binding)
|
|
241
|
+
for binding in compiled.spec.sub_agents
|
|
242
|
+
}
|
|
243
|
+
# Revision 是事实源;宿主同名配置只作为未编译旧路径的兼容兜底。
|
|
244
|
+
effective_sub_agents = {**self._sub_agents, **revision_sub_agents}
|
|
245
|
+
self._runs[run_id] = _EngineRun(
|
|
246
|
+
handle=handle,
|
|
247
|
+
request=request,
|
|
248
|
+
compiled=compiled,
|
|
249
|
+
state=state,
|
|
250
|
+
thread_id=thread_id,
|
|
251
|
+
skill_catalog=self._skill_disclosure.catalog(
|
|
252
|
+
compiled.spec, query=str(request.input or "")
|
|
253
|
+
),
|
|
254
|
+
mcp_catalog=self._mcp_disclosure.catalog(compiled.spec),
|
|
255
|
+
sub_agents=effective_sub_agents,
|
|
256
|
+
controller=self._new_run_controller(compiled),
|
|
257
|
+
)
|
|
258
|
+
configure_run(
|
|
259
|
+
self, self._runs[run_id], policy=execution_policy,
|
|
260
|
+
resolver=execution_policy_resolver, request=execution_policy_request,
|
|
261
|
+
)
|
|
262
|
+
return handle
|
|
263
|
+
|
|
264
|
+
# -------------------------------------------------------------- attach
|
|
265
|
+
|
|
266
|
+
def is_handle_attached(self, handle: RunHandle) -> bool:
|
|
267
|
+
"""Return whether this engine process already owns the live Run state."""
|
|
268
|
+
return handle.run_id in self._runs
|
|
269
|
+
|
|
270
|
+
async def attach(
|
|
271
|
+
self, handle: RunHandle, compiled: CompiledHarness, *, allow_completed: bool = False,
|
|
272
|
+
execution_policy=None, execution_policy_resolver=None, execution_policy_request=None,
|
|
273
|
+
) -> RunHandle:
|
|
274
|
+
"""跨进程恢复(收口 3):从持久 Checkpoint 重建 _EngineRun。
|
|
275
|
+
|
|
276
|
+
状态从 durable Checkpointer 的 graph snapshot 推断:存在未决 interrupt
|
|
277
|
+
→ awaiting_approval;存在 pending 节点 → paused;无 Checkpoint → 诚实报错。
|
|
278
|
+
事件队列从空开始(历史事件已由平台 EventStore 持久化)。
|
|
279
|
+
"""
|
|
280
|
+
if handle.run_id in self._runs:
|
|
281
|
+
return handle
|
|
282
|
+
if self._checkpointer is None:
|
|
283
|
+
raise ExecutionEngineError(
|
|
284
|
+
"attach 需要 durable Checkpointer:跨进程恢复依赖持久 Checkpoint"
|
|
285
|
+
)
|
|
286
|
+
thread_id = str(handle.native_ref.get("thread_id") or "")
|
|
287
|
+
if not thread_id:
|
|
288
|
+
raise ExecutionEngineError(
|
|
289
|
+
f"attach 失败:handle.native_ref 缺少 thread_id(run {handle.run_id!r})"
|
|
290
|
+
)
|
|
291
|
+
# 持久 handle 可能不带 user_id(旧版本句柄):用占位值,事件锚点以
|
|
292
|
+
# Checkpoint 内的图状态为准,跨进程身份由 thread_id 保证。
|
|
293
|
+
user_id = str(handle.native_ref.get("user_id") or "unknown")
|
|
294
|
+
agent_id = str(handle.native_ref.get("agent_id") or compiled.spec.agent_revision_ref)
|
|
295
|
+
state = HarnessState(
|
|
296
|
+
tenant_id=self._tenant_id,
|
|
297
|
+
user_id=user_id,
|
|
298
|
+
agent_id=agent_id,
|
|
299
|
+
session_id=handle.session_id,
|
|
300
|
+
run_id=handle.run_id,
|
|
301
|
+
status=RunStatus.PAUSED,
|
|
302
|
+
)
|
|
303
|
+
run = _EngineRun(
|
|
304
|
+
handle=handle,
|
|
305
|
+
request=StartRequest(
|
|
306
|
+
agent_id=agent_id,
|
|
307
|
+
user_id=user_id,
|
|
308
|
+
session_id=handle.session_id,
|
|
309
|
+
input="",
|
|
310
|
+
runtime_type="managed-langgraph",
|
|
311
|
+
metadata={
|
|
312
|
+
"invocation_id": handle.run_id,
|
|
313
|
+
**{key: handle.native_ref[key] for key in
|
|
314
|
+
("parent_run_id", "execution_policy_ref") if key in handle.native_ref},
|
|
315
|
+
},
|
|
316
|
+
),
|
|
317
|
+
compiled=compiled,
|
|
318
|
+
state=state,
|
|
319
|
+
thread_id=thread_id,
|
|
320
|
+
skill_catalog=self._skill_disclosure.catalog(compiled.spec),
|
|
321
|
+
mcp_catalog=self._mcp_disclosure.catalog(compiled.spec),
|
|
322
|
+
controller=self._new_run_controller(compiled),
|
|
323
|
+
)
|
|
324
|
+
run.started_emitted = True # run.started 已在首个进程发出
|
|
325
|
+
run.done = False
|
|
326
|
+
configure_run(
|
|
327
|
+
self, run, policy=execution_policy,
|
|
328
|
+
resolver=execution_policy_resolver, request=execution_policy_request,
|
|
329
|
+
)
|
|
330
|
+
# 从 Checkpoint snapshot 推断挂起状态。
|
|
331
|
+
graph = self._build_graph(run)
|
|
332
|
+
snapshot = await graph.aget_state({"configurable": {"thread_id": thread_id}})
|
|
333
|
+
if snapshot is None or not snapshot.values or (not snapshot.next and not allow_completed):
|
|
334
|
+
raise ExecutionEngineError(f"attach 失败:thread {thread_id!r} 无未决 Checkpoint")
|
|
335
|
+
tasks = getattr(snapshot, "tasks", None) or ()
|
|
336
|
+
if isinstance(tasks, dict):
|
|
337
|
+
tasks = tuple(tasks.values())
|
|
338
|
+
has_interrupt = any(getattr(task, "interrupts", None) for task in tasks)
|
|
339
|
+
for task in tasks:
|
|
340
|
+
for pending in getattr(task, "interrupts", ()):
|
|
341
|
+
value = getattr(pending, "value", {})
|
|
342
|
+
if isinstance(value, dict) and value.get("call_id"):
|
|
343
|
+
run.pending_approval_call_id = str(value["call_id"])
|
|
344
|
+
run.pending_approval = dict(value)
|
|
345
|
+
break
|
|
346
|
+
if run.controller is not None:
|
|
347
|
+
values = getattr(snapshot, "values", None) or {}
|
|
348
|
+
control_snapshot = values.get("run_control") if isinstance(values, dict) else None
|
|
349
|
+
if control_snapshot:
|
|
350
|
+
run.controller.restore(control_snapshot)
|
|
351
|
+
run.state.status = RunStatus.AWAITING_APPROVAL if has_interrupt else RunStatus.PAUSED
|
|
352
|
+
values = snapshot.values
|
|
353
|
+
budgets.restore(run, values.get("budget") or {})
|
|
354
|
+
run.seq = int(values.get("event_seq") or 0)
|
|
355
|
+
run.state.messages = self._messages(values.get("messages", []))
|
|
356
|
+
if not snapshot.next:
|
|
357
|
+
terminal = values.get("execution_terminal") or "completed"
|
|
358
|
+
run.state.status = RunStatus(terminal)
|
|
359
|
+
run.done = True
|
|
360
|
+
self._runs[handle.run_id] = run
|
|
361
|
+
from ksadk.harness.engine.subagents import restore_pending_child
|
|
362
|
+
|
|
363
|
+
await restore_pending_child(self, run)
|
|
364
|
+
return handle
|
|
365
|
+
|
|
366
|
+
# -------------------------------------------------------------- stream
|
|
367
|
+
|
|
368
|
+
def stream(self, handle: RunHandle) -> AsyncIterator[RuntimeEvent]:
|
|
369
|
+
return self._stream(handle)
|
|
370
|
+
|
|
371
|
+
async def _stream(self, handle: RunHandle) -> AsyncIterator[RuntimeEvent]:
|
|
372
|
+
run = self._require_run(handle)
|
|
373
|
+
task_finished = run.task is None or run.task.done()
|
|
374
|
+
if run.state.status in (RunStatus.AWAITING_APPROVAL, RunStatus.PAUSED) and task_finished:
|
|
375
|
+
# 挂起中:只回放未消费事件,不重启图(恢复必须走 resume)。
|
|
376
|
+
while run.events:
|
|
377
|
+
yield run.events.pop(0)
|
|
378
|
+
return
|
|
379
|
+
if run.done and task_finished:
|
|
380
|
+
while run.events:
|
|
381
|
+
yield run.events.pop(0)
|
|
382
|
+
return
|
|
383
|
+
if run.task is None or task_finished:
|
|
384
|
+
run.task = asyncio.create_task(self._execute(run))
|
|
385
|
+
try:
|
|
386
|
+
while True:
|
|
387
|
+
while run.events:
|
|
388
|
+
event = run.events.pop(0)
|
|
389
|
+
self._emit_insight(run, event)
|
|
390
|
+
yield event
|
|
391
|
+
if run.task.done():
|
|
392
|
+
break
|
|
393
|
+
await asyncio.sleep(0)
|
|
394
|
+
remaining = await run.task
|
|
395
|
+
for event in remaining:
|
|
396
|
+
self._emit_insight(run, event)
|
|
397
|
+
yield event
|
|
398
|
+
except asyncio.CancelledError:
|
|
399
|
+
# A subscriber timeout must cancel and await the executing graph,
|
|
400
|
+
# not just mark its output stream finished while tools keep running.
|
|
401
|
+
await self.cancel(handle)
|
|
402
|
+
raise
|
|
403
|
+
|
|
404
|
+
def _emit_insight(self, run: _EngineRun, event: RuntimeEvent) -> None:
|
|
405
|
+
"""事件出口统一回调(洞察登记处 / 审计侧消费;异常不阻断主流程)。"""
|
|
406
|
+
if self._event_sink is None:
|
|
407
|
+
return
|
|
408
|
+
try:
|
|
409
|
+
self._event_sink(run.state.session_id, run.handle.run_id, event)
|
|
410
|
+
except Exception: # noqa: BLE001 - 登记失败不阻断对话主流程
|
|
411
|
+
pass
|
|
412
|
+
|
|
413
|
+
def harness_capabilities(self):
|
|
414
|
+
"""返回运行时真实治理声明;该声明也随每个 Run 的首批事件保存。"""
|
|
415
|
+
from ksadk.harness.runtime_capabilities import managed_langgraph_capabilities
|
|
416
|
+
|
|
417
|
+
return managed_langgraph_capabilities()
|
|
418
|
+
|
|
419
|
+
async def _execute(
|
|
420
|
+
self,
|
|
421
|
+
run: _EngineRun,
|
|
422
|
+
resume_command: Command | None = None,
|
|
423
|
+
*,
|
|
424
|
+
resume_from_checkpoint: bool = False,
|
|
425
|
+
) -> list[RuntimeEvent]:
|
|
426
|
+
run.execution_started_at = time.monotonic()
|
|
427
|
+
spec = run.compiled.spec
|
|
428
|
+
run.state.status = RunStatus.RUNNING
|
|
429
|
+
if not run.started_emitted:
|
|
430
|
+
run.started_emitted = True
|
|
431
|
+
run.events.append(self._event(run, EventType.RUN_STARTED, {"status": "in_progress"}))
|
|
432
|
+
# 收口 5:事件树根——Agent 生命周期(主 Agent 与未来子 Agent 同构)。
|
|
433
|
+
run.events.append(
|
|
434
|
+
self._event(run, EventType.AGENT_STARTED, {"agent_id": run.state.agent_id})
|
|
435
|
+
)
|
|
436
|
+
from ksadk.harness.engine.capability_declarations import (
|
|
437
|
+
capability_declarations,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
run.events.extend(capability_declarations(self, run))
|
|
441
|
+
try:
|
|
442
|
+
if run.cancel_requested:
|
|
443
|
+
raise asyncio.CancelledError
|
|
444
|
+
await revalidate_policy(self, run)
|
|
445
|
+
graph = self._build_graph(run)
|
|
446
|
+
instructions = spec.prompt.instructions or ""
|
|
447
|
+
config = {
|
|
448
|
+
"configurable": {"thread_id": run.thread_id},
|
|
449
|
+
# Sequential tool checkpoints are graph steps too. The model
|
|
450
|
+
# turn/tool budgets, not LangGraph's default 25, govern a Run.
|
|
451
|
+
"recursion_limit": max(64, self._max_reasoning_turns * 128),
|
|
452
|
+
}
|
|
453
|
+
invoke_input: _GraphState | Command | None
|
|
454
|
+
if resume_command is not None:
|
|
455
|
+
invoke_input = resume_command
|
|
456
|
+
elif resume_from_checkpoint:
|
|
457
|
+
# 通用 pause 恢复:None → LangGraph 从最近 Checkpoint 续跑。
|
|
458
|
+
invoke_input = None
|
|
459
|
+
else:
|
|
460
|
+
# 收口 1:ContextEngine 真正控制首次模型输入(规划 + 主动/紧急压缩
|
|
461
|
+
# + 组装);未注入时回退旧的 history 拼接路径。
|
|
462
|
+
planned = await self._prepare_context(run, instructions)
|
|
463
|
+
if planned is not None:
|
|
464
|
+
conversation = planned
|
|
465
|
+
else:
|
|
466
|
+
history = run.request.metadata.get("conversation_history") or []
|
|
467
|
+
conversation = [{"role": "system", "content": instructions}]
|
|
468
|
+
skill_catalog_message = self._skill_disclosure.catalog_message(
|
|
469
|
+
run.skill_catalog
|
|
470
|
+
)
|
|
471
|
+
if skill_catalog_message:
|
|
472
|
+
conversation.append(skill_catalog_message)
|
|
473
|
+
mcp_catalog_message = self._mcp_disclosure.catalog_message(
|
|
474
|
+
run.mcp_catalog
|
|
475
|
+
)
|
|
476
|
+
if mcp_catalog_message:
|
|
477
|
+
conversation.append(mcp_catalog_message)
|
|
478
|
+
if isinstance(history, list) and history:
|
|
479
|
+
# 宿主(如 Studio Playground)注入的会话历史已含当前输入。
|
|
480
|
+
conversation.extend(dict(m) for m in history if isinstance(m, dict))
|
|
481
|
+
else:
|
|
482
|
+
conversation.append(
|
|
483
|
+
{"role": "user", "content": str(run.request.input or "")}
|
|
484
|
+
)
|
|
485
|
+
invoke_input = {
|
|
486
|
+
"messages": conversation,
|
|
487
|
+
"pending_tool_calls": [],
|
|
488
|
+
"turn_count": 0,
|
|
489
|
+
"route": "reason",
|
|
490
|
+
"mcp_listed": [],
|
|
491
|
+
"mcp_schema_read": [],
|
|
492
|
+
"finalization_retries": 0,
|
|
493
|
+
"delegation_synthesis_pending": False,
|
|
494
|
+
"run_control": (
|
|
495
|
+
run.controller.snapshot() if run.controller is not None else {}
|
|
496
|
+
),
|
|
497
|
+
}
|
|
498
|
+
from ksadk.harness.engine.run_control_bridge import invoke_graph_with_control
|
|
499
|
+
|
|
500
|
+
with execution_policy_scope(run.execution_policy):
|
|
501
|
+
final_state = await invoke_graph_with_control(
|
|
502
|
+
graph, invoke_input, config, run.controller
|
|
503
|
+
)
|
|
504
|
+
interrupts = final_state.get("__interrupt__") if isinstance(final_state, dict) else None
|
|
505
|
+
if interrupts:
|
|
506
|
+
# Approval 挂起:图状态已由 Checkpointer 持久化,等待 resume。
|
|
507
|
+
run.state.status = RunStatus.AWAITING_APPROVAL
|
|
508
|
+
run.done = False
|
|
509
|
+
info = getattr(interrupts[0], "value", {}) or {}
|
|
510
|
+
run.pending_approval_call_id = str(info.get("call_id") or "")
|
|
511
|
+
run.pending_approval = dict(info)
|
|
512
|
+
approval_id = f"ap-{run.handle.run_id}-{info.get('call_id', '')}"
|
|
513
|
+
run.events.append(
|
|
514
|
+
self._event(
|
|
515
|
+
run,
|
|
516
|
+
EventType.APPROVAL_REQUESTED,
|
|
517
|
+
{
|
|
518
|
+
"approval_id": approval_id,
|
|
519
|
+
"call_id": str(info.get("call_id", "")),
|
|
520
|
+
"kind": "tool",
|
|
521
|
+
"detail": info,
|
|
522
|
+
},
|
|
523
|
+
)
|
|
524
|
+
)
|
|
525
|
+
run.events.append(
|
|
526
|
+
self._event(
|
|
527
|
+
run,
|
|
528
|
+
EventType.RUN_INTERRUPTED,
|
|
529
|
+
{"status": "awaiting_approval", "reason": "tool_approval",
|
|
530
|
+
"approval_id": approval_id},
|
|
531
|
+
)
|
|
532
|
+
)
|
|
533
|
+
return []
|
|
534
|
+
# 影子状态消息(§6.2.1):完整对话消息投影,供 Transcript 持久化。
|
|
535
|
+
final_messages = final_state.get("messages", [])
|
|
536
|
+
run.state.messages = self._messages(final_messages)
|
|
537
|
+
# 最终答案事件由 reason 节点统一产生。这里仅投影 Transcript;若再从
|
|
538
|
+
# final_state 补发,stream 已消费 reason 事件时会造成同一答案重复展示。
|
|
539
|
+
if run.cancel_requested:
|
|
540
|
+
raise asyncio.CancelledError
|
|
541
|
+
from ksadk.harness.engine.completion_guard import unfinished_delegations
|
|
542
|
+
|
|
543
|
+
unfinished = unfinished_delegations(run.events)
|
|
544
|
+
if unfinished:
|
|
545
|
+
labels = ", ".join(unfinished.values())
|
|
546
|
+
raise ExecutionEngineError(
|
|
547
|
+
"parent run cannot complete while delegated children lack terminal "
|
|
548
|
+
f"evidence: {labels}"
|
|
549
|
+
)
|
|
550
|
+
run.state.status = RunStatus.COMPLETED
|
|
551
|
+
run.events.append(
|
|
552
|
+
self._event(
|
|
553
|
+
run,
|
|
554
|
+
EventType.AGENT_COMPLETED,
|
|
555
|
+
{"agent_id": run.state.agent_id, "status": "completed"},
|
|
556
|
+
)
|
|
557
|
+
)
|
|
558
|
+
from ksadk.harness.engine.run_control_bridge import completion_payload
|
|
559
|
+
|
|
560
|
+
payload = completion_payload(run)
|
|
561
|
+
run.events.append(self._event(run, EventType.RUN_COMPLETED, payload))
|
|
562
|
+
run.done = True
|
|
563
|
+
return []
|
|
564
|
+
except asyncio.CancelledError:
|
|
565
|
+
if run.pause_requested:
|
|
566
|
+
# 通用 pause:非终止性挂起,Checkpoint 持久化后可 resume。
|
|
567
|
+
run.pause_requested = False
|
|
568
|
+
run.state.status = RunStatus.PAUSED
|
|
569
|
+
run.done = False
|
|
570
|
+
run.events.append(
|
|
571
|
+
self._event(
|
|
572
|
+
run,
|
|
573
|
+
EventType.RUN_INTERRUPTED,
|
|
574
|
+
{"status": "paused", "reason": "pause_requested"},
|
|
575
|
+
)
|
|
576
|
+
)
|
|
577
|
+
return []
|
|
578
|
+
run.state.status = RunStatus.CANCELED
|
|
579
|
+
run.done = True
|
|
580
|
+
run.events.append(self._event(run, EventType.RUN_CANCELED, {"status": "cancelled"}))
|
|
581
|
+
return []
|
|
582
|
+
except GraphInterrupt as exc:
|
|
583
|
+
# checkpoint=False 路径(无 Checkpointer 时 interrupt 直接抛出)。
|
|
584
|
+
run.state.status = RunStatus.AWAITING_APPROVAL
|
|
585
|
+
run.done = False
|
|
586
|
+
run.events.append(
|
|
587
|
+
self._event(
|
|
588
|
+
run,
|
|
589
|
+
EventType.RUN_INTERRUPTED,
|
|
590
|
+
{"status": "awaiting_approval", "reason": f"graph_interrupt: {exc}"},
|
|
591
|
+
)
|
|
592
|
+
)
|
|
593
|
+
return []
|
|
594
|
+
except RunControlStop as exc:
|
|
595
|
+
from ksadk.harness.engine.run_control_bridge import append_controlled_stop
|
|
596
|
+
|
|
597
|
+
append_controlled_stop(self, run, exc.reason)
|
|
598
|
+
return []
|
|
599
|
+
except Exception as exc: # noqa: BLE001
|
|
600
|
+
run.state.status = RunStatus.FAILED
|
|
601
|
+
run.done = True
|
|
602
|
+
run.events.append(
|
|
603
|
+
self._event(
|
|
604
|
+
run,
|
|
605
|
+
EventType.AGENT_COMPLETED,
|
|
606
|
+
{"agent_id": run.state.agent_id, "status": "failed"},
|
|
607
|
+
)
|
|
608
|
+
)
|
|
609
|
+
run.events.append(
|
|
610
|
+
self._event(
|
|
611
|
+
run,
|
|
612
|
+
EventType.RUN_FAILED,
|
|
613
|
+
{
|
|
614
|
+
"status": "failed",
|
|
615
|
+
"error": str(exc),
|
|
616
|
+
**(
|
|
617
|
+
{"error_category": str(exc.category)}
|
|
618
|
+
if getattr(exc, "category", None)
|
|
619
|
+
else {}
|
|
620
|
+
),
|
|
621
|
+
},
|
|
622
|
+
)
|
|
623
|
+
)
|
|
624
|
+
return []
|
|
625
|
+
|
|
626
|
+
finally:
|
|
627
|
+
budgets.account_elapsed(run)
|
|
628
|
+
run.execution_started_at = None
|
|
629
|
+
|
|
630
|
+
# ---------------------------------------------------------------- graph
|
|
631
|
+
|
|
632
|
+
def _build_graph(self, run: _EngineRun):
|
|
633
|
+
# 图组装(节点实现/边/条件路由)拆至 graph_builder 模块,保持本模块
|
|
634
|
+
# <1000 行的仓库合同;节点闭包仍经 engine 访问运行时状态。
|
|
635
|
+
from ksadk.harness.engine.graph_builder import build_graph
|
|
636
|
+
|
|
637
|
+
return build_graph(self, run)
|
|
638
|
+
|
|
639
|
+
async def _invoke_tool(
|
|
640
|
+
self,
|
|
641
|
+
name: str,
|
|
642
|
+
arguments: dict[str, Any],
|
|
643
|
+
*,
|
|
644
|
+
run: Any = None,
|
|
645
|
+
mcp_cursors: McpDisclosureCursors | None = None,
|
|
646
|
+
call_id: str = "",
|
|
647
|
+
) -> Any:
|
|
648
|
+
from ksadk.harness.engine.tool_dispatch import invoke_tool
|
|
649
|
+
|
|
650
|
+
if run is not None:
|
|
651
|
+
await revalidate_policy(self, run)
|
|
652
|
+
with execution_policy_scope(run.execution_policy if run is not None else None):
|
|
653
|
+
return await invoke_tool(
|
|
654
|
+
self, name, arguments, run=run, mcp_cursors=mcp_cursors, call_id=call_id
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
# --------------------------------------------------------------- cancel
|
|
658
|
+
|
|
659
|
+
async def cancel(self, handle: RunHandle) -> CancelResult:
|
|
660
|
+
run = self._runs.get(handle.run_id)
|
|
661
|
+
if run is None or run.done:
|
|
662
|
+
return CancelResult.NOT_RUNNING
|
|
663
|
+
run.cancel_requested = True
|
|
664
|
+
active_children = list(self._active_subagent_runs.get(handle.run_id, {}).values())
|
|
665
|
+
active_task = run.task if run.task is not None and not run.task.done() else None
|
|
666
|
+
if active_task is not None:
|
|
667
|
+
active_task.cancel()
|
|
668
|
+
await asyncio.gather(active_task, return_exceptions=True)
|
|
669
|
+
else:
|
|
670
|
+
from ksadk.harness.engine.subagents import cancel_and_drain
|
|
671
|
+
from ksadk.harness.subagent import resequence_child_events
|
|
672
|
+
|
|
673
|
+
for child_engine, child_handle in active_children:
|
|
674
|
+
await cancel_and_drain(
|
|
675
|
+
child_engine, child_handle,
|
|
676
|
+
lambda event: resequence_child_events(run, [event], observe=True),
|
|
677
|
+
)
|
|
678
|
+
self._active_subagent_runs.pop(handle.run_id, None)
|
|
679
|
+
if self._delegation_runtime is not None:
|
|
680
|
+
await self._delegation_runtime.cancel_parent(handle.run_id)
|
|
681
|
+
if run.task is None and run.state.status is RunStatus.PENDING:
|
|
682
|
+
return CancelResult.PENDING_CANCEL_RECORDED
|
|
683
|
+
if active_task is None:
|
|
684
|
+
run.done = True
|
|
685
|
+
run.state.status = RunStatus.CANCELED
|
|
686
|
+
run.events.append(self._event(run, EventType.RUN_CANCELED, {"status": "cancelled"}))
|
|
687
|
+
return CancelResult.INTERRUPTED_ACTIVE_TURN
|
|
688
|
+
return CancelResult.INTERRUPTED_ACTIVE_TURN
|
|
689
|
+
|
|
690
|
+
# --------------------------------------------------------------- pause
|
|
691
|
+
|
|
692
|
+
async def pause(self, handle: RunHandle) -> PauseResult:
|
|
693
|
+
"""通用 pause:取消当前回合但保留状态,Checkpointer 持久化后可 resume。"""
|
|
694
|
+
run = self._runs.get(handle.run_id)
|
|
695
|
+
if run is None or run.done:
|
|
696
|
+
return PauseResult.NOT_RUNNING
|
|
697
|
+
if run.state.status not in (RunStatus.RUNNING, RunStatus.PENDING):
|
|
698
|
+
return PauseResult.NOT_RUNNING
|
|
699
|
+
if self._checkpointer is None:
|
|
700
|
+
return PauseResult.NOT_SUPPORTED
|
|
701
|
+
if run.task is None or run.task.done():
|
|
702
|
+
# 尚未启动流式执行:直接置 PAUSED,start 后由 stream/resume 驱动。
|
|
703
|
+
run.state.status = RunStatus.PAUSED
|
|
704
|
+
run.events.append(
|
|
705
|
+
self._event(
|
|
706
|
+
run,
|
|
707
|
+
EventType.RUN_INTERRUPTED,
|
|
708
|
+
{"status": "paused", "reason": "pause_requested"},
|
|
709
|
+
)
|
|
710
|
+
)
|
|
711
|
+
return PauseResult.PAUSED_ACTIVE_TURN
|
|
712
|
+
run.pause_requested = True
|
|
713
|
+
run.task.cancel()
|
|
714
|
+
return PauseResult.PAUSED_ACTIVE_TURN
|
|
715
|
+
|
|
716
|
+
# --------------------------------------------------------------- resume
|
|
717
|
+
|
|
718
|
+
async def resume(
|
|
719
|
+
self,
|
|
720
|
+
handle: RunHandle,
|
|
721
|
+
target: ResumeTarget,
|
|
722
|
+
payload: ResumePayload | None,
|
|
723
|
+
) -> RunHandle:
|
|
724
|
+
run = self._require_run(handle)
|
|
725
|
+
await revalidate_policy(self, run)
|
|
726
|
+
if run.state.status is RunStatus.PAUSED:
|
|
727
|
+
if self._checkpointer is None:
|
|
728
|
+
raise ExecutionEngineError(
|
|
729
|
+
"resume 需要 Checkpointer:pause 状态由 Checkpoint 持久化"
|
|
730
|
+
)
|
|
731
|
+
# 通用恢复:从最近 Checkpoint 续跑(非审批通道)。
|
|
732
|
+
run.state.status = RunStatus.RUNNING
|
|
733
|
+
run.events.append(
|
|
734
|
+
self._event(
|
|
735
|
+
run,
|
|
736
|
+
EventType.RUN_RESUMED,
|
|
737
|
+
{"target": target.id, "resume_kind": "checkpoint"},
|
|
738
|
+
)
|
|
739
|
+
)
|
|
740
|
+
run.task = asyncio.create_task(self._execute(run, resume_from_checkpoint=True))
|
|
741
|
+
return handle
|
|
742
|
+
if run.state.status is not RunStatus.AWAITING_APPROVAL:
|
|
743
|
+
raise ExecutionEngineError(
|
|
744
|
+
f"resume 仅支持 awaiting_approval 状态,当前 {run.state.status.value}"
|
|
745
|
+
)
|
|
746
|
+
if self._checkpointer is None:
|
|
747
|
+
raise ExecutionEngineError(
|
|
748
|
+
"resume 需要 Checkpointer:interrupt 状态由 Checkpoint 持久化"
|
|
749
|
+
)
|
|
750
|
+
if (
|
|
751
|
+
payload is None or payload.kind != "approval_decision"
|
|
752
|
+
or not run.pending_approval_call_id
|
|
753
|
+
or payload.call_id != run.pending_approval_call_id
|
|
754
|
+
or payload.data not in ("approved", "denied", "rejected")
|
|
755
|
+
):
|
|
756
|
+
raise ExecutionEngineError(
|
|
757
|
+
"approval resume requires an explicit decision for the pending call_id"
|
|
758
|
+
)
|
|
759
|
+
decision = "denied"
|
|
760
|
+
if payload is not None:
|
|
761
|
+
decision = str(payload.data) if payload.data is not None else "approved"
|
|
762
|
+
run.events.append(
|
|
763
|
+
self._event(
|
|
764
|
+
run,
|
|
765
|
+
EventType.APPROVAL_RESOLVED,
|
|
766
|
+
{
|
|
767
|
+
"approval_id": f"ap-{run.handle.run_id}-{payload.call_id or ''}",
|
|
768
|
+
"call_id": payload.call_id or "",
|
|
769
|
+
"decision": decision,
|
|
770
|
+
},
|
|
771
|
+
)
|
|
772
|
+
)
|
|
773
|
+
run.state.status = RunStatus.RUNNING
|
|
774
|
+
run.events.append(
|
|
775
|
+
self._event(
|
|
776
|
+
run,
|
|
777
|
+
EventType.RUN_RESUMED,
|
|
778
|
+
{"target": target.id, "resume_kind": "approval_decision"},
|
|
779
|
+
)
|
|
780
|
+
)
|
|
781
|
+
run.task = asyncio.create_task(self._execute(run, resume_command=Command(resume=decision)))
|
|
782
|
+
return handle
|
|
783
|
+
|
|
784
|
+
# ------------------------------------------------------------- snapshot
|
|
785
|
+
|
|
786
|
+
async def snapshot_state(self, handle: RunHandle) -> HarnessState | None:
|
|
787
|
+
run = self._runs.get(handle.run_id)
|
|
788
|
+
return run.state if run else None
|
|
789
|
+
|
|
790
|
+
def capabilities(self) -> EngineCapabilityMatrix:
|
|
791
|
+
return EngineCapabilityMatrix(
|
|
792
|
+
cancel=EngineCapability(supported=True),
|
|
793
|
+
resume=EngineCapability(
|
|
794
|
+
supported=True, reason="approval + checkpoint (paused) channels"
|
|
795
|
+
),
|
|
796
|
+
checkpoint=EngineCapability(
|
|
797
|
+
supported=self._checkpointer is not None,
|
|
798
|
+
reason=None if self._checkpointer else "no checkpointer injected",
|
|
799
|
+
),
|
|
800
|
+
interrupt=EngineCapability(supported=True, reason="approval channel only"),
|
|
801
|
+
durable_across_process=EngineCapability(
|
|
802
|
+
supported=self._checkpointer is not None and _is_durable(self._checkpointer),
|
|
803
|
+
reason=None,
|
|
804
|
+
),
|
|
805
|
+
streaming=EngineCapability(supported=True),
|
|
806
|
+
)
|
|
807
|
+
|
|
808
|
+
async def close(self, handle: RunHandle) -> None:
|
|
809
|
+
if handle.run_id in self._runs and not self._runs[handle.run_id].done:
|
|
810
|
+
await self.cancel(handle)
|
|
811
|
+
run = self._runs.pop(handle.run_id, None)
|
|
812
|
+
if run and run.task and not run.task.done():
|
|
813
|
+
run.task.cancel()
|
|
814
|
+
await asyncio.gather(run.task, return_exceptions=True)
|
|
815
|
+
if run is not None:
|
|
816
|
+
self._skill_disclosure.clear_run(run.handle.run_id)
|
|
817
|
+
self._mcp_disclosure.clear_run(run.handle.run_id)
|
|
818
|
+
self._pending_child_events.pop(run.handle.run_id, None)
|
|
819
|
+
self._pending_subagent_events.pop(run.handle.run_id, None)
|
|
820
|
+
self._active_subagent_runs.pop(run.handle.run_id, None)
|
|
821
|
+
if self._delegation_runtime is not None:
|
|
822
|
+
self._delegation_runtime.clear_run(run.handle.run_id)
|
|
823
|
+
|
|
824
|
+
# ------------------------------------------------------------- helpers
|
|
825
|
+
|
|
826
|
+
async def _prepare_context(
|
|
827
|
+
self, run: _EngineRun, instructions: str
|
|
828
|
+
) -> list[dict[str, Any]] | None:
|
|
829
|
+
"""Context 构建管线委托(长任务方案 §6/§8,实现见 context_pipeline)。"""
|
|
830
|
+
if self._context_engine is None:
|
|
831
|
+
return None
|
|
832
|
+
return await self._context_pipeline.prepare_context(run, instructions)
|
|
833
|
+
|
|
834
|
+
def _require_run(self, handle: RunHandle) -> _EngineRun:
|
|
835
|
+
try:
|
|
836
|
+
return self._runs[handle.run_id]
|
|
837
|
+
except KeyError:
|
|
838
|
+
raise KeyError(f"unknown engine run: {handle.run_id}") from None
|
|
839
|
+
|
|
840
|
+
async def _invoke_mcp_tool(
|
|
841
|
+
self,
|
|
842
|
+
name: str,
|
|
843
|
+
arguments: dict[str, Any],
|
|
844
|
+
*,
|
|
845
|
+
run: _EngineRun | None,
|
|
846
|
+
cursors: McpDisclosureCursors,
|
|
847
|
+
call_id: str = "",
|
|
848
|
+
) -> dict[str, Any]:
|
|
849
|
+
return await self._mcp_disclosure.invoke(
|
|
850
|
+
name,
|
|
851
|
+
arguments,
|
|
852
|
+
run=run,
|
|
853
|
+
cursors=cursors,
|
|
854
|
+
pending_events=self._pending_child_events,
|
|
855
|
+
call_id=call_id,
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
def _invoke_skill_tool(
|
|
859
|
+
self, name: str, arguments: dict[str, Any], *, run: _EngineRun | None
|
|
860
|
+
) -> dict[str, Any]:
|
|
861
|
+
return self._skill_disclosure.invoke(
|
|
862
|
+
name,
|
|
863
|
+
arguments,
|
|
864
|
+
run=run,
|
|
865
|
+
pending_events=self._pending_child_events,
|
|
866
|
+
)
|
|
867
|
+
|
|
868
|
+
def _event(
|
|
869
|
+
self, run: _EngineRun, event_type: str, payload: dict[str, Any], *, phase: str | None = None
|
|
870
|
+
) -> RuntimeEvent:
|
|
871
|
+
run.seq += 1
|
|
872
|
+
event = RuntimeEvent.create(
|
|
873
|
+
event_type,
|
|
874
|
+
agent_id=run.state.agent_id,
|
|
875
|
+
user_id=run.state.user_id,
|
|
876
|
+
session_id=run.state.session_id,
|
|
877
|
+
invocation_id=run.handle.run_id,
|
|
878
|
+
seq_id=run.seq,
|
|
879
|
+
payload=payload,
|
|
880
|
+
phase=phase,
|
|
881
|
+
)
|
|
882
|
+
if run.controller is not None:
|
|
883
|
+
run.control_events.append(event)
|
|
884
|
+
run.controller.observe(event)
|
|
885
|
+
run.observed_event_ids.add(event.event_id)
|
|
886
|
+
return event
|
|
887
|
+
|
|
888
|
+
@staticmethod
|
|
889
|
+
def _messages(messages):
|
|
890
|
+
return [
|
|
891
|
+
Message(
|
|
892
|
+
role=MessageRole(m.get("role", "user")), content=str(m.get("content") or ""),
|
|
893
|
+
tool_call_id=str(m["tool_call_id"]) if m.get("tool_call_id") else None,
|
|
894
|
+
name=str(m["name"]) if m.get("name") else None,
|
|
895
|
+
)
|
|
896
|
+
for m in messages if isinstance(m, dict)
|
|
897
|
+
]
|
|
898
|
+
|
|
899
|
+
@staticmethod
|
|
900
|
+
def _new_run_controller(compiled: CompiledHarness) -> RunController | None:
|
|
901
|
+
from ksadk.harness.engine.run_control_bridge import new_run_controller
|
|
902
|
+
|
|
903
|
+
return new_run_controller(compiled)
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
def _is_durable(checkpointer: BaseCheckpointSaver) -> bool:
|
|
907
|
+
"""SQLite/Postgres Checkpointer 视为跨进程持久;MemorySaver 不是。"""
|
|
908
|
+
from langgraph.checkpoint.memory import InMemorySaver, MemorySaver
|
|
909
|
+
|
|
910
|
+
return not isinstance(checkpointer, (MemorySaver, InMemorySaver))
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
def memory_checkpointer() -> BaseCheckpointSaver:
|
|
914
|
+
"""进程内 Checkpointer(langgraph 类型不越出本模块的架构合同)。"""
|
|
915
|
+
from langgraph.checkpoint.memory import InMemorySaver
|
|
916
|
+
|
|
917
|
+
return InMemorySaver()
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
def sqlite_checkpointer(db_path: str) -> Any:
|
|
921
|
+
"""SQLite 异步 Checkpointer 的上下文管理器(调用方负责 __aenter__)。
|
|
922
|
+
|
|
923
|
+
经由本工厂获取,避免 langgraph import 越出引擎模块
|
|
924
|
+
(tests/architecture/test_harness_contract.py 守卫)。
|
|
925
|
+
"""
|
|
926
|
+
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
|
|
927
|
+
|
|
928
|
+
return AsyncSqliteSaver.from_conn_string(db_path)
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
__all__ = ["ManagedLangGraphEngine", "memory_checkpointer", "sqlite_checkpointer"]
|