agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.4__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.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
- agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
- ksadk/_build_provenance.json +1 -0
- ksadk/agui/_agent_helpers.py +4 -0
- ksadk/api/client.py +108 -91
- ksadk/builders/code_builder.py +36 -9
- ksadk/builders/framework_requirements.py +2 -1
- ksadk/builders/ks3_uploader.py +36 -7
- ksadk/builders/managed_runtime_builder.py +4 -0
- ksadk/cli/__init__.py +38 -3
- ksadk/cli/cmd_managed_runtime.py +13 -1
- ksadk/cli/cmd_plugin.py +662 -0
- ksadk/cli/cmd_web.py +2 -5
- ksadk/cli/runtime_bootstrap.py +23 -1
- ksadk/codex/client.py +424 -96
- ksadk/codex/projection.py +24 -0
- ksadk/codex/runtime.py +83 -283
- ksadk/common/auth.py +16 -10
- ksadk/configs/env_registry.py +59 -3
- ksadk/configs/settings.py +9 -0
- ksadk/context_engine/contributors.py +73 -8
- ksadk/conversations/__init__.py +19 -0
- ksadk/conversations/context.py +104 -24
- ksadk/conversations/contracts.py +266 -0
- ksadk/conversations/message_projection.py +154 -15
- ksadk/conversations/projector.py +614 -0
- ksadk/conversations/reducer.py +98 -0
- ksadk/conversations/runtime_invocation.py +5 -0
- ksadk/conversations/runtime_payloads.py +1 -0
- ksadk/conversations/runtime_preparation.py +30 -27
- ksadk/conversations/runtime_resume.py +50 -2
- ksadk/conversations/runtime_stream_events.py +5 -0
- ksadk/conversations/runtime_streaming.py +25 -7
- ksadk/deployment/env_forward.py +2 -2
- ksadk/deployment/providers/serverless.py +1 -1
- ksadk/events/_v1_compat/projection.py +2 -0
- ksadk/events/adapters/_codex_validators.py +18 -7
- ksadk/events/adapters/codex.py +190 -0
- ksadk/events/adapters/langgraph.py +15 -1
- ksadk/events/canonical_store.py +3 -1
- ksadk/events/projections.py +1 -1
- ksadk/harness/__init__.py +45 -35
- ksadk/harness/config.py +2 -2
- ksadk/harness/runtime.py +75 -16
- ksadk/harness/tools.py +38 -13
- ksadk/interaction/provider.py +1 -0
- ksadk/interaction/providers/langgraph.py +1 -0
- ksadk/kernel/bootstrap.py +28 -4
- ksadk/kernel/contract_fingerprints.py +5 -4
- ksadk/kernel/contracts.py +8 -0
- ksadk/kernel/control.py +1 -0
- ksadk/kernel/ingress.py +36 -2
- ksadk/kernel/memory_store.py +1 -0
- ksadk/kernel/postgres_store.py +1 -0
- ksadk/kernel/sqlite_store.py +28 -0
- ksadk/kernel/store.py +3 -0
- ksadk/kernel/worker.py +76 -10
- ksadk/knowledge_base/client.py +57 -27
- ksadk/mcp_runtime/__init__.py +12 -4
- ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
- ksadk/memory/adk/resilient_session_service.py +25 -17
- ksadk/memory/adk/short_term_memory.py +26 -9
- ksadk/memory/models.py +7 -4
- ksadk/memory/provider_resolver.py +3 -0
- ksadk/memory/providers/local_sqlite.py +7 -0
- ksadk/model_proxy/server.py +10 -5
- ksadk/plugins/__init__.py +171 -0
- ksadk/plugins/artifacts.py +275 -0
- ksadk/plugins/bridges/__init__.py +47 -0
- ksadk/plugins/bridges/codex.py +659 -0
- ksadk/plugins/bridges/dsh.py +1300 -0
- ksadk/plugins/builtins.py +746 -0
- ksadk/plugins/bundle.py +246 -0
- ksadk/plugins/bundle_security.py +191 -0
- ksadk/plugins/codex_manifest.py +983 -0
- ksadk/plugins/composition.py +537 -0
- ksadk/plugins/context_contributor.py +437 -0
- ksadk/plugins/contracts.py +569 -0
- ksadk/plugins/delivery.py +153 -0
- ksadk/plugins/dsh_installation_digest.py +71 -0
- ksadk/plugins/dsh_toolchain.py +1024 -0
- ksadk/plugins/ecosystem_bridge.py +1105 -0
- ksadk/plugins/ecosystem_probe.py +191 -0
- ksadk/plugins/host.py +787 -0
- ksadk/plugins/kernel_adapter.py +205 -0
- ksadk/plugins/providers/__init__.py +108 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
- ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
- ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
- ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
- ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
- ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
- ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
- ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
- ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
- ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
- ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
- ksadk/plugins/providers/codex.py +988 -0
- ksadk/plugins/providers/codex_dsh.py +83 -0
- ksadk/plugins/providers/codex_native.py +368 -0
- ksadk/plugins/providers/codex_turn.py +301 -0
- ksadk/plugins/providers/dsh.py +951 -0
- ksadk/plugins/providers/dsh_capabilities.py +1389 -0
- ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
- ksadk/plugins/providers/dsh_mcp.py +467 -0
- ksadk/plugins/providers/harness.py +632 -0
- ksadk/plugins/providers/harness_dsh.py +91 -0
- ksadk/plugins/providers/legacy.py +215 -0
- ksadk/plugins/providers/legacy_catalog.py +100 -0
- ksadk/plugins/providers/mcp_projection.py +150 -0
- ksadk/plugins/providers/platform_resources.py +657 -0
- ksadk/plugins/providers/shipped_dsh.py +370 -0
- ksadk/plugins/resolver.py +338 -0
- ksadk/plugins/subagent_providers/__init__.py +12 -0
- ksadk/plugins/subagent_providers/codex.py +443 -0
- ksadk/plugins/subagents.py +333 -0
- ksadk/resource_runtime/__init__.py +4 -0
- ksadk/resource_runtime/broker.py +616 -0
- ksadk/resource_runtime/build_artifacts.py +165 -0
- ksadk/resource_runtime/contracts.py +138 -0
- ksadk/resource_runtime/discovery_receipts.py +100 -0
- ksadk/resource_runtime/discovery_skills.py +172 -0
- ksadk/resource_runtime/errors.py +6 -0
- ksadk/resource_runtime/ipc.py +142 -0
- ksadk/resource_runtime/kernel_approval.py +165 -0
- ksadk/resource_runtime/knowledge.py +114 -0
- ksadk/resource_runtime/langgraph.py +94 -0
- ksadk/resource_runtime/leases.py +191 -0
- ksadk/resource_runtime/managed_projection.py +186 -0
- ksadk/resource_runtime/mcp_server.py +138 -0
- ksadk/resource_runtime/memory_provider.py +318 -0
- ksadk/resource_runtime/memory_receipts.py +34 -0
- ksadk/resource_runtime/operation_ledger.py +211 -0
- ksadk/resource_runtime/plugin_config.py +48 -0
- ksadk/resource_runtime/policy_authorization.py +54 -0
- ksadk/resource_runtime/process.py +110 -0
- ksadk/resource_runtime/skill_artifacts.py +153 -0
- ksadk/resource_runtime/skill_runtime.py +42 -0
- ksadk/resource_runtime/skill_workspace.py +118 -0
- ksadk/resource_runtime/skills.py +215 -0
- ksadk/resource_runtime/snapshots.py +180 -0
- ksadk/resource_runtime/socket_server.py +103 -0
- ksadk/resource_runtime/supervisor.py +380 -0
- ksadk/resource_runtime/worker.py +504 -0
- ksadk/runners/_langgraph_runner_streams.py +74 -6
- ksadk/runners/adk_runner.py +149 -11
- ksadk/runners/base_runner.py +29 -1
- ksadk/runners/langgraph_runner.py +475 -145
- ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
- ksadk/runtime/adapter.py +3 -0
- ksadk/runtime/conversation_execution.py +92 -16
- ksadk/runtime/executor.py +78 -2
- ksadk/runtime/factory.py +30 -200
- ksadk/runtime/framework_adapters.py +41 -0
- ksadk/runtime/preprocessing.py +10 -2
- ksadk/runtime/runner_adapter.py +78 -14
- ksadk/runtime_context.py +40 -2
- ksadk/sandbox/__init__.py +2 -1
- ksadk/sandbox/backends/e2b.py +52 -11
- ksadk/sandbox/backends/local_process.py +9 -0
- ksadk/sandbox/base.py +2 -0
- ksadk/sandbox/e2b_connection.py +66 -0
- ksadk/sandbox/factory.py +72 -0
- ksadk/scheduler/__init__.py +18 -0
- ksadk/scheduler/calendar.py +102 -0
- ksadk/scheduler/contracts.py +254 -0
- ksadk/scheduler/dispatcher.py +129 -0
- ksadk/scheduler/engine.py +416 -0
- ksadk/scheduler/sqlite_store.py +581 -0
- ksadk/server/composition.py +2 -0
- ksadk/server/factory.py +5 -0
- ksadk/server/persistence_capability.py +516 -0
- ksadk/server/routes/control.py +210 -46
- ksadk/server/routes/dependencies.py +15 -0
- ksadk/server/routes/models.py +47 -4
- ksadk/server/routes/projection.py +252 -12
- ksadk/server/routes/sessions.py +284 -107
- ksadk/server/routes/streaming.py +43 -9
- ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
- ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
- ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
- ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
- ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
- ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
- ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
- ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
- ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
- ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
- ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
- ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
- ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
- ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
- ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
- ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
- ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
- ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
- ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
- ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
- ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
- ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
- ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
- ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
- ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
- ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
- ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
- ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
- ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
- ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
- ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
- ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
- ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
- ksadk/server/static/assets/index-DcTML1Up.css +2 -0
- ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
- ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
- ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
- ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
- ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
- ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
- ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
- ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
- ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
- ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
- ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
- ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
- ksadk/server/static/index.html +2 -2
- ksadk/session_context.py +66 -0
- ksadk/sessions/__init__.py +11 -21
- ksadk/sessions/_local_service_sync.py +263 -1
- ksadk/sessions/base.py +176 -0
- ksadk/sessions/errors.py +4 -0
- ksadk/sessions/in_memory.py +309 -19
- ksadk/sessions/local_service.py +83 -1
- ksadk/sessions/persistence.py +275 -0
- ksadk/sessions/postgres_service.py +358 -0
- ksadk/sessions/resilience.py +8 -0
- ksadk/sessions/resilient.py +362 -4
- ksadk/sessions/topology.py +135 -0
- ksadk/skills/models.py +26 -4
- ksadk/skills/package_store.py +186 -38
- ksadk/skills/runtime/agent.py +31 -6
- ksadk/skills/runtime/artifact_delivery.py +139 -0
- ksadk/skills/runtime/backends/e2b.py +98 -6
- ksadk/skills/runtime/backends/local.py +73 -8
- ksadk/skills/runtime/base.py +3 -0
- ksadk/skills/runtime/executor.py +2 -0
- ksadk/skills/runtime/loader.py +10 -2
- ksadk/skills/runtime/pinned.py +114 -0
- ksadk/skills/runtime/request.py +31 -0
- ksadk/skills/service_client.py +211 -24
- ksadk/studio/agent_lifecycle.py +26 -20
- ksadk/studio/api.py +714 -90
- ksadk/studio/api_catalog_routes.py +23 -0
- ksadk/studio/api_contracts.py +34 -1
- ksadk/studio/api_plugin_routes.py +911 -0
- ksadk/studio/api_resource_connections.py +183 -0
- ksadk/studio/attachment_store.py +187 -0
- ksadk/studio/authoring.py +10 -4
- ksadk/studio/authoring_coordinator.py +31 -16
- ksadk/studio/builder.py +199 -43
- ksadk/studio/cloud.py +346 -104
- ksadk/studio/cloud_shared_web.py +565 -0
- ksadk/studio/codex_agent_service.py +140 -27
- ksadk/studio/codex_builder.py +294 -16
- ksadk/studio/codex_credentials.py +90 -0
- ksadk/studio/codex_manifest.py +51 -4
- ksadk/studio/codex_plugin_store.py +746 -0
- ksadk/studio/codex_provider_build.py +231 -0
- ksadk/studio/codex_run.py +200 -29
- ksadk/studio/compatibility_report.py +456 -0
- ksadk/studio/compiler.py +84 -15
- ksadk/studio/contracts.py +249 -4
- ksadk/studio/dsh_application.py +137 -0
- ksadk/studio/dsh_capability_service.py +1107 -0
- ksadk/studio/dsh_models.py +59 -0
- ksadk/studio/dsh_provider_registration.py +1075 -0
- ksadk/studio/event_store.py +54 -6
- ksadk/studio/framework_run.py +37 -4
- ksadk/studio/hosted_kernel.py +89 -14
- ksadk/studio/mcp_runtime.py +11 -3
- ksadk/studio/model_client.py +2 -2
- ksadk/studio/operations.py +12 -2
- ksadk/studio/plugin_composition.py +468 -0
- ksadk/studio/plugin_kernel_adapter.py +28 -0
- ksadk/studio/plugin_runtime.py +831 -0
- ksadk/studio/resource_authority.py +637 -0
- ksadk/studio/resource_binding_validation.py +77 -0
- ksadk/studio/resource_build_admission.py +196 -0
- ksadk/studio/resource_build_materializer.py +149 -0
- ksadk/studio/resource_catalog.py +149 -3
- ksadk/studio/resource_connections.py +220 -0
- ksadk/studio/run_service.py +1144 -96
- ksadk/studio/runtime_source.py +24 -8
- ksadk/studio/scheduler_assistant.py +317 -0
- ksadk/studio/scheduler_runtime.py +383 -0
- ksadk/studio/scheduler_service.py +214 -0
- ksadk/studio/service.py +1131 -95
- ksadk/studio/shared_web.py +610 -87
- ksadk/studio/soul.py +52 -0
- ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
- ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
- ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
- ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
- ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
- ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
- ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
- ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
- ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
- ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
- ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
- ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
- ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
- ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
- ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
- ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
- ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
- ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
- ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
- ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
- ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
- ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
- ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
- ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
- ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
- ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
- ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
- ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
- ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
- ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
- ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
- ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
- ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
- ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
- ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
- ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
- ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
- ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
- ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
- ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
- ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
- ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
- ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
- ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
- ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
- ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
- ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
- ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
- ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
- ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
- ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
- ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
- ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
- ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
- ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
- ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
- ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
- ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
- ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
- ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
- ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
- ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
- ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
- ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
- ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
- ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
- ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
- ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
- ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
- ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
- ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
- ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
- ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
- ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
- ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
- ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
- ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
- ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
- ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
- ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
- ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
- ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
- ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
- ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
- ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
- ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
- ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
- ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
- ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
- ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
- ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
- ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
- ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
- ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
- ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
- ksadk/studio/static/index.html +2 -2
- ksadk/studio/validator.py +1 -1
- ksadk/studio/workspace.py +1 -0
- ksadk/version.py +1 -1
- ksadk_runtime_common/workspace_files/path_utils.py +41 -0
- agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
- ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
- ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
- ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
- ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
- ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
- ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
- ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
"""Resource dispatch admission; transport and subprocess ownership stay separate."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import hashlib
|
|
7
|
+
import json
|
|
8
|
+
import time
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Protocol
|
|
13
|
+
|
|
14
|
+
from pydantic import ValidationError
|
|
15
|
+
|
|
16
|
+
from ksadk.resource_runtime.discovery_receipts import (
|
|
17
|
+
DiscoverySelectionReceipts,
|
|
18
|
+
DiscoverySkillReceipt,
|
|
19
|
+
)
|
|
20
|
+
from ksadk.resource_runtime.ipc import FrameError, ResourceRequest, encode_frame
|
|
21
|
+
from ksadk.resource_runtime.knowledge import KnowledgeQuery
|
|
22
|
+
from ksadk.resource_runtime.leases import LeaseRejected, ResourceLeaseRegistry, ResourceScope
|
|
23
|
+
from ksadk.resource_runtime.memory_provider import (
|
|
24
|
+
MemoryQuery,
|
|
25
|
+
MemoryRecordSelector,
|
|
26
|
+
MemoryStatusQuery,
|
|
27
|
+
MemoryUpdate,
|
|
28
|
+
MemoryWrite,
|
|
29
|
+
)
|
|
30
|
+
from ksadk.resource_runtime.memory_receipts import MemoryMutationReceipt
|
|
31
|
+
from ksadk.resource_runtime.operation_ledger import OperationConflict, OperationLedger
|
|
32
|
+
from ksadk.resource_runtime.skill_artifacts import SkillArtifactQuery, SkillArtifactReceipts
|
|
33
|
+
from ksadk.resource_runtime.skills import SkillExecutionQuery
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ResourceWorkerPort(Protocol):
|
|
37
|
+
async def invoke(self, request: ResourceRequest, scope: ResourceScope) -> dict: ...
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ResourceWriteAuthorizer(Protocol):
|
|
41
|
+
async def authorize(self, request: ResourceRequest, scope: ResourceScope) -> str | None:
|
|
42
|
+
"""Resolve a host approval bound to exact arguments and return its stable event ID.
|
|
43
|
+
|
|
44
|
+
The implementation must validate the request schema and host minimum policy,
|
|
45
|
+
and look up approval in trusted state. IPC arguments are never approval.
|
|
46
|
+
Return None to deny. The event ID must survive activation/checkpoint recovery.
|
|
47
|
+
"""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class _Activation:
|
|
53
|
+
worker: ResourceWorkerPort
|
|
54
|
+
scopes: dict[str, ResourceScope]
|
|
55
|
+
tasks: set[asyncio.Task] = field(default_factory=set)
|
|
56
|
+
closed: bool = False
|
|
57
|
+
execution_lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
|
58
|
+
artifact_roots: dict[str, Path] = field(default_factory=dict)
|
|
59
|
+
discovery_keys: dict[str, str] = field(default_factory=dict)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_WRITES = frozenset({"save_memory", "update_memory", "delete_memory", "execute_skills"})
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ResourceBroker:
|
|
66
|
+
"""One event-loop-owned dispatcher for a Core generation.
|
|
67
|
+
|
|
68
|
+
Registration is host-only. The worker receives identity resolved by the
|
|
69
|
+
registry; IPC callers cannot register workers, set identity or mint handles.
|
|
70
|
+
Write dispatch remains closed until the Kernel approval/receipt adapter is
|
|
71
|
+
installed; a scope alone is never approval for side effects.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
def __init__(
|
|
75
|
+
self,
|
|
76
|
+
registry: ResourceLeaseRegistry,
|
|
77
|
+
generation_id: str,
|
|
78
|
+
*,
|
|
79
|
+
clock: Callable[[], float] = time.time,
|
|
80
|
+
max_inflight: int = 8,
|
|
81
|
+
write_authorizer: ResourceWriteAuthorizer | None = None,
|
|
82
|
+
operation_ledger: OperationLedger | None = None,
|
|
83
|
+
):
|
|
84
|
+
if type(max_inflight) is not int or not 1 <= max_inflight <= 8:
|
|
85
|
+
raise ValueError("Resource concurrency must be 1..8")
|
|
86
|
+
self._registry = registry
|
|
87
|
+
self._generation_id = generation_id
|
|
88
|
+
self._clock = clock
|
|
89
|
+
self._max_inflight = max_inflight
|
|
90
|
+
if (write_authorizer is None) != (operation_ledger is None):
|
|
91
|
+
raise ValueError("Write authorization and durable ledger must be configured together")
|
|
92
|
+
self._write_authorizer = write_authorizer
|
|
93
|
+
self._operation_ledger = operation_ledger
|
|
94
|
+
self._discovery_receipts = (
|
|
95
|
+
DiscoverySelectionReceipts(operation_ledger) if operation_ledger is not None else None
|
|
96
|
+
)
|
|
97
|
+
self._skill_artifacts = (
|
|
98
|
+
SkillArtifactReceipts(operation_ledger) if operation_ledger is not None else None
|
|
99
|
+
)
|
|
100
|
+
self._activations: dict[str, _Activation] = {}
|
|
101
|
+
|
|
102
|
+
def register(
|
|
103
|
+
self,
|
|
104
|
+
scope: ResourceScope,
|
|
105
|
+
worker: ResourceWorkerPort,
|
|
106
|
+
*,
|
|
107
|
+
artifact_root: Path | None = None,
|
|
108
|
+
discovery_key: str | None = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
if discovery_key is not None:
|
|
111
|
+
if self._discovery_receipts is None:
|
|
112
|
+
raise ValueError("RESOURCE_DISCOVERY_RECEIPTS_REQUIRED")
|
|
113
|
+
DiscoverySelectionReceipts._key(discovery_key)
|
|
114
|
+
if artifact_root is not None:
|
|
115
|
+
if not artifact_root.is_absolute():
|
|
116
|
+
raise ValueError("Artifact publication requires an absolute host root")
|
|
117
|
+
artifact_root = artifact_root.resolve()
|
|
118
|
+
if scope.generation_id != self._generation_id:
|
|
119
|
+
raise ValueError("Worker generation does not match broker")
|
|
120
|
+
existing = self._activations.get(scope.activation_id)
|
|
121
|
+
if existing is None:
|
|
122
|
+
if any(item.worker is worker for item in self._activations.values()):
|
|
123
|
+
raise ValueError("A resource worker cannot serve multiple activations")
|
|
124
|
+
self._activations[scope.activation_id] = _Activation(worker, {scope.binding_id: scope})
|
|
125
|
+
if artifact_root is not None:
|
|
126
|
+
self._activations[scope.activation_id].artifact_roots[scope.binding_id] = (
|
|
127
|
+
artifact_root
|
|
128
|
+
)
|
|
129
|
+
if discovery_key is not None:
|
|
130
|
+
self._activations[scope.activation_id].discovery_keys[scope.binding_id] = (
|
|
131
|
+
discovery_key
|
|
132
|
+
)
|
|
133
|
+
return
|
|
134
|
+
first = next(iter(existing.scopes.values()))
|
|
135
|
+
if (
|
|
136
|
+
existing.closed
|
|
137
|
+
or existing.worker is not worker
|
|
138
|
+
or first.identity != scope.identity
|
|
139
|
+
or first.build_digest != scope.build_digest
|
|
140
|
+
or first.profile_digest != scope.profile_digest
|
|
141
|
+
or first.binding_snapshot_digest != scope.binding_snapshot_digest
|
|
142
|
+
):
|
|
143
|
+
raise ValueError("Worker activation identity and Build are immutable")
|
|
144
|
+
if scope.binding_id in existing.scopes and existing.scopes[scope.binding_id] != scope:
|
|
145
|
+
raise ValueError("Worker binding registration is immutable")
|
|
146
|
+
if scope.binding_id in existing.scopes and existing.discovery_keys.get(
|
|
147
|
+
scope.binding_id
|
|
148
|
+
) != discovery_key:
|
|
149
|
+
raise ValueError("Worker discovery run is immutable")
|
|
150
|
+
if (
|
|
151
|
+
scope.binding_id in existing.scopes
|
|
152
|
+
and existing.artifact_roots.get(scope.binding_id) != artifact_root
|
|
153
|
+
):
|
|
154
|
+
raise ValueError("Worker artifact publication root is immutable")
|
|
155
|
+
existing.scopes[scope.binding_id] = scope
|
|
156
|
+
if artifact_root is not None:
|
|
157
|
+
existing.artifact_roots[scope.binding_id] = artifact_root
|
|
158
|
+
if discovery_key is not None:
|
|
159
|
+
existing.discovery_keys[scope.binding_id] = discovery_key
|
|
160
|
+
|
|
161
|
+
async def dispatch(self, payload: dict) -> dict:
|
|
162
|
+
try:
|
|
163
|
+
frame = encode_frame(payload)
|
|
164
|
+
request = ResourceRequest.model_validate_json(frame[4:])
|
|
165
|
+
except (ValidationError, FrameError):
|
|
166
|
+
return self._error("RESOURCE_REQUEST_INVALID")
|
|
167
|
+
try:
|
|
168
|
+
scope = self._registry.resolve(
|
|
169
|
+
request.handle, operation=request.operation, generation_id=self._generation_id
|
|
170
|
+
)
|
|
171
|
+
except LeaseRejected:
|
|
172
|
+
return self._error("RESOURCE_SCOPE_INVALID", request.request_id)
|
|
173
|
+
activation = self._activations.get(scope.activation_id)
|
|
174
|
+
if (
|
|
175
|
+
activation is None
|
|
176
|
+
or activation.closed
|
|
177
|
+
or activation.scopes.get(scope.binding_id) != scope
|
|
178
|
+
):
|
|
179
|
+
return self._error("RESOURCE_ACTIVATION_UNAVAILABLE", request.request_id)
|
|
180
|
+
remaining = request.deadline / 1000 - self._clock()
|
|
181
|
+
if remaining <= 0:
|
|
182
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
183
|
+
if request.check_only:
|
|
184
|
+
if request.arguments:
|
|
185
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
186
|
+
if getattr(activation.worker, "is_running", True) is False:
|
|
187
|
+
return self._error("RESOURCE_ACTIVATION_UNAVAILABLE", request.request_id)
|
|
188
|
+
# Inventory checks prove local lease admission only. They neither
|
|
189
|
+
# call upstream nor claim a write, authorize approval, or renew leases.
|
|
190
|
+
return {"v": 1, "requestId": request.request_id, "result": {"available": True}}
|
|
191
|
+
if request.operation in _WRITES and self._write_authorizer is None:
|
|
192
|
+
return self._error("RESOURCE_APPROVAL_REQUIRED", request.request_id)
|
|
193
|
+
if request.operation == "search_knowledge_base":
|
|
194
|
+
try:
|
|
195
|
+
KnowledgeQuery.model_validate(request.arguments)
|
|
196
|
+
except ValidationError:
|
|
197
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
198
|
+
if request.operation == "load_memory":
|
|
199
|
+
try:
|
|
200
|
+
MemoryQuery.model_validate(request.arguments)
|
|
201
|
+
except ValidationError:
|
|
202
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
203
|
+
if request.operation == "save_memory":
|
|
204
|
+
try:
|
|
205
|
+
parsed = MemoryWrite.model_validate(request.arguments)
|
|
206
|
+
if not parsed.content.strip():
|
|
207
|
+
raise ValueError("Empty memory content")
|
|
208
|
+
except ValueError:
|
|
209
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
210
|
+
if request.operation == "memory_status":
|
|
211
|
+
try:
|
|
212
|
+
MemoryStatusQuery.model_validate(request.arguments)
|
|
213
|
+
except ValueError:
|
|
214
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
215
|
+
if request.operation in {"update_memory", "delete_memory"}:
|
|
216
|
+
try:
|
|
217
|
+
if request.operation == "update_memory":
|
|
218
|
+
if not MemoryUpdate.model_validate(request.arguments).content.strip():
|
|
219
|
+
raise ValueError("Empty memory content")
|
|
220
|
+
else:
|
|
221
|
+
MemoryRecordSelector.model_validate(request.arguments)
|
|
222
|
+
except ValueError:
|
|
223
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
224
|
+
if request.operation == "execute_skills":
|
|
225
|
+
try:
|
|
226
|
+
query = SkillExecutionQuery.model_validate(request.arguments)
|
|
227
|
+
if not query.workflow_prompt.strip():
|
|
228
|
+
raise ValueError("Empty workflow")
|
|
229
|
+
except ValueError:
|
|
230
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
231
|
+
if scope.binding_id not in activation.artifact_roots:
|
|
232
|
+
return self._error("RESOURCE_ARTIFACT_DELIVERY_REQUIRED", request.request_id)
|
|
233
|
+
if request.operation == "read_skill_artifact":
|
|
234
|
+
try:
|
|
235
|
+
SkillArtifactQuery.model_validate(request.arguments)
|
|
236
|
+
except ValueError:
|
|
237
|
+
return self._error("RESOURCE_ARGUMENTS_INVALID", request.request_id)
|
|
238
|
+
if self._skill_artifacts is None:
|
|
239
|
+
return self._error("RESOURCE_OPERATION_NOT_FOUND", request.request_id)
|
|
240
|
+
# The ingress cannot extend worker execution indefinitely with a distant
|
|
241
|
+
# deadline. Bound both the wait and the deadline sent into the subprocess.
|
|
242
|
+
remaining = min(remaining, 900.0 if request.operation == "execute_skills" else 60.0)
|
|
243
|
+
request = request.model_copy(
|
|
244
|
+
update={"deadline": min(request.deadline, int((self._clock() + remaining) * 1000))}
|
|
245
|
+
)
|
|
246
|
+
if len(activation.tasks) >= self._max_inflight:
|
|
247
|
+
return self._error("RESOURCE_BUSY", request.request_id)
|
|
248
|
+
# No await between admission and recording the task. Recheck immediately
|
|
249
|
+
# before the worker call so a queued task cannot bypass revocation.
|
|
250
|
+
task = asyncio.create_task(self._invoke(activation, request, scope))
|
|
251
|
+
activation.tasks.add(task)
|
|
252
|
+
task.add_done_callback(activation.tasks.discard)
|
|
253
|
+
# A timeout or disconnected caller must not cancel a possibly sent write.
|
|
254
|
+
# Only the lifecycle owner cancels these tasks after revocation and Worker
|
|
255
|
+
# shutdown. wait() distinguishes that child cancellation from cancellation
|
|
256
|
+
# of this caller, which must still propagate to the transport/engine.
|
|
257
|
+
done, _ = await asyncio.wait((task,), timeout=remaining)
|
|
258
|
+
if not done:
|
|
259
|
+
if request.operation in _WRITES:
|
|
260
|
+
return self._error("RESOURCE_WRITE_UNKNOWN", request.request_id)
|
|
261
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
262
|
+
if task.cancelled():
|
|
263
|
+
if not activation.closed:
|
|
264
|
+
raise asyncio.CancelledError
|
|
265
|
+
code = (
|
|
266
|
+
"RESOURCE_WRITE_UNKNOWN" if request.operation in _WRITES
|
|
267
|
+
else "RESOURCE_ACTIVATION_UNAVAILABLE"
|
|
268
|
+
)
|
|
269
|
+
return self._error(code, request.request_id)
|
|
270
|
+
return task.result()
|
|
271
|
+
|
|
272
|
+
async def _invoke(
|
|
273
|
+
self, activation: _Activation, request: ResourceRequest, scope: ResourceScope
|
|
274
|
+
) -> dict:
|
|
275
|
+
# Keep the serial SDK queue here so admission is checked after waiting,
|
|
276
|
+
# immediately before handing the request to the worker transport.
|
|
277
|
+
async with activation.execution_lock:
|
|
278
|
+
return await self._invoke_admitted(activation, request, scope)
|
|
279
|
+
|
|
280
|
+
async def _invoke_admitted(
|
|
281
|
+
self, activation: _Activation, request: ResourceRequest, scope: ResourceScope
|
|
282
|
+
) -> dict:
|
|
283
|
+
try:
|
|
284
|
+
self._registry.authorize(
|
|
285
|
+
request.handle,
|
|
286
|
+
operation=request.operation,
|
|
287
|
+
generation_id=self._generation_id,
|
|
288
|
+
activation_id=scope.activation_id,
|
|
289
|
+
)
|
|
290
|
+
if activation.closed or request.deadline / 1000 <= self._clock():
|
|
291
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
292
|
+
if request.operation == "read_skill_artifact":
|
|
293
|
+
try:
|
|
294
|
+
result = await asyncio.to_thread(
|
|
295
|
+
self._skill_artifacts.read,
|
|
296
|
+
request.arguments,
|
|
297
|
+
authority_digest=self._authority(scope),
|
|
298
|
+
)
|
|
299
|
+
except Exception:
|
|
300
|
+
return self._error("RESOURCE_ARTIFACT_NOT_FOUND", request.request_id)
|
|
301
|
+
self._registry.authorize(
|
|
302
|
+
request.handle,
|
|
303
|
+
operation=request.operation,
|
|
304
|
+
generation_id=self._generation_id,
|
|
305
|
+
activation_id=scope.activation_id,
|
|
306
|
+
)
|
|
307
|
+
if request.deadline / 1000 <= self._clock():
|
|
308
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
309
|
+
return {"v": 1, "requestId": request.request_id, "result": result}
|
|
310
|
+
receipt = None
|
|
311
|
+
status_receipt = None
|
|
312
|
+
execution_selections = None
|
|
313
|
+
if (
|
|
314
|
+
request.operation == "execute_skills"
|
|
315
|
+
and scope.binding_id in activation.discovery_keys
|
|
316
|
+
):
|
|
317
|
+
selections = await asyncio.to_thread(
|
|
318
|
+
self._discovery_receipts.read, activation.discovery_keys[scope.binding_id]
|
|
319
|
+
)
|
|
320
|
+
self._registry.authorize(
|
|
321
|
+
request.handle, operation=request.operation,
|
|
322
|
+
generation_id=self._generation_id, activation_id=scope.activation_id,
|
|
323
|
+
)
|
|
324
|
+
selected = {item.skill_id: item for item in selections}
|
|
325
|
+
query = SkillExecutionQuery.model_validate(request.arguments)
|
|
326
|
+
if any(skill_id not in selected for skill_id in query.skill_ids):
|
|
327
|
+
return self._error("RESOURCE_SKILL_SELECTION_REQUIRED", request.request_id)
|
|
328
|
+
execution_selections = [
|
|
329
|
+
selected[skill_id].model_dump(by_alias=True, mode="json")
|
|
330
|
+
for skill_id in query.skill_ids
|
|
331
|
+
]
|
|
332
|
+
if request.operation == "memory_status":
|
|
333
|
+
if self._operation_ledger is None:
|
|
334
|
+
return self._error("RESOURCE_OPERATION_NOT_FOUND", request.request_id)
|
|
335
|
+
query = MemoryStatusQuery.model_validate(request.arguments)
|
|
336
|
+
status_receipt = await asyncio.to_thread(
|
|
337
|
+
self._operation_ledger.lookup,
|
|
338
|
+
query.operation_id,
|
|
339
|
+
authority_digest=self._authority(scope),
|
|
340
|
+
operation="save_memory",
|
|
341
|
+
)
|
|
342
|
+
if status_receipt is None:
|
|
343
|
+
return self._error("RESOURCE_OPERATION_NOT_FOUND", request.request_id)
|
|
344
|
+
self._registry.authorize(
|
|
345
|
+
request.handle,
|
|
346
|
+
operation=request.operation,
|
|
347
|
+
generation_id=self._generation_id,
|
|
348
|
+
activation_id=scope.activation_id,
|
|
349
|
+
)
|
|
350
|
+
if activation.closed or request.deadline / 1000 <= self._clock():
|
|
351
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
352
|
+
if request.operation in _WRITES:
|
|
353
|
+
assert self._write_authorizer is not None and self._operation_ledger is not None
|
|
354
|
+
event_id = await self._write_authorizer.authorize(request, scope)
|
|
355
|
+
if not event_id:
|
|
356
|
+
return self._error("RESOURCE_APPROVAL_REQUIRED", request.request_id)
|
|
357
|
+
authority = self._authority(scope)
|
|
358
|
+
receipt = await asyncio.to_thread(
|
|
359
|
+
self._operation_ledger.claim,
|
|
360
|
+
authority_digest=authority,
|
|
361
|
+
event_id=event_id,
|
|
362
|
+
operation=request.operation,
|
|
363
|
+
arguments=(
|
|
364
|
+
{**request.arguments, "_hostSelections": execution_selections}
|
|
365
|
+
if execution_selections is not None else request.arguments
|
|
366
|
+
),
|
|
367
|
+
)
|
|
368
|
+
# Authorization may have changed while awaiting approval or disk.
|
|
369
|
+
self._registry.authorize(
|
|
370
|
+
request.handle,
|
|
371
|
+
operation=request.operation,
|
|
372
|
+
generation_id=self._generation_id,
|
|
373
|
+
activation_id=scope.activation_id,
|
|
374
|
+
)
|
|
375
|
+
if activation.closed or request.deadline / 1000 <= self._clock():
|
|
376
|
+
return self._error("RESOURCE_WRITE_UNKNOWN", request.request_id)
|
|
377
|
+
if not receipt.claimed:
|
|
378
|
+
previous = None
|
|
379
|
+
if request.operation == "execute_skills" and self._skill_artifacts is not None:
|
|
380
|
+
previous = await asyncio.to_thread(
|
|
381
|
+
self._skill_artifacts.result,
|
|
382
|
+
receipt.operation_id,
|
|
383
|
+
authority_digest=authority,
|
|
384
|
+
)
|
|
385
|
+
self._registry.authorize(
|
|
386
|
+
request.handle,
|
|
387
|
+
operation=request.operation,
|
|
388
|
+
generation_id=self._generation_id,
|
|
389
|
+
activation_id=scope.activation_id,
|
|
390
|
+
)
|
|
391
|
+
elif request.operation in {"update_memory", "delete_memory"}:
|
|
392
|
+
previous = await asyncio.to_thread(
|
|
393
|
+
self._operation_ledger.memory_mutation_result,
|
|
394
|
+
receipt.operation_id,
|
|
395
|
+
authority_digest=authority,
|
|
396
|
+
operation=request.operation,
|
|
397
|
+
)
|
|
398
|
+
self._registry.authorize(
|
|
399
|
+
request.handle,
|
|
400
|
+
operation=request.operation,
|
|
401
|
+
generation_id=self._generation_id,
|
|
402
|
+
activation_id=scope.activation_id,
|
|
403
|
+
)
|
|
404
|
+
if activation.closed or request.deadline / 1000 <= self._clock():
|
|
405
|
+
return self._error("RESOURCE_DEADLINE_EXCEEDED", request.request_id)
|
|
406
|
+
if previous is not None:
|
|
407
|
+
return {
|
|
408
|
+
"v": 1,
|
|
409
|
+
"requestId": request.request_id,
|
|
410
|
+
"result": {**previous, "replayed": False},
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
"v": 1,
|
|
414
|
+
"requestId": request.request_id,
|
|
415
|
+
"result": {
|
|
416
|
+
"status": receipt.state,
|
|
417
|
+
"operationId": receipt.operation_id,
|
|
418
|
+
"replayed": False,
|
|
419
|
+
},
|
|
420
|
+
}
|
|
421
|
+
worker_request = (
|
|
422
|
+
request
|
|
423
|
+
if receipt is None
|
|
424
|
+
else request.model_copy(update={"request_id": receipt.operation_id})
|
|
425
|
+
)
|
|
426
|
+
if execution_selections is not None:
|
|
427
|
+
worker_request = worker_request.model_copy(update={"arguments": {
|
|
428
|
+
**request.arguments, "_hostSelections": execution_selections,
|
|
429
|
+
}})
|
|
430
|
+
result = await activation.worker.invoke(worker_request, scope)
|
|
431
|
+
selection = result.pop("_discoverySelection", None)
|
|
432
|
+
if selection is not None:
|
|
433
|
+
key = activation.discovery_keys.get(scope.binding_id)
|
|
434
|
+
if (
|
|
435
|
+
key is None or self._discovery_receipts is None
|
|
436
|
+
or request.operation not in {"load_skill", "read_skill_resource"}
|
|
437
|
+
or result.get("status") != "ok"
|
|
438
|
+
):
|
|
439
|
+
raise ValueError("Unexpected discovery selection")
|
|
440
|
+
selected = DiscoverySkillReceipt.model_validate(selection)
|
|
441
|
+
if (
|
|
442
|
+
selected.skill_id != result.get("skillId")
|
|
443
|
+
or selected.version_id != result.get("versionId")
|
|
444
|
+
or selected.content_hash != result.get("contentHash")
|
|
445
|
+
or selected.skill_id != request.arguments.get(
|
|
446
|
+
"skillId", request.arguments.get("skill_id")
|
|
447
|
+
)
|
|
448
|
+
):
|
|
449
|
+
raise ValueError("Discovery selection does not match request/result")
|
|
450
|
+
self._registry.authorize(
|
|
451
|
+
request.handle, operation=request.operation,
|
|
452
|
+
generation_id=self._generation_id, activation_id=scope.activation_id,
|
|
453
|
+
)
|
|
454
|
+
await asyncio.to_thread(self._discovery_receipts.record, key, selected)
|
|
455
|
+
elif (
|
|
456
|
+
scope.binding_id in activation.discovery_keys
|
|
457
|
+
and request.operation in {"load_skill", "read_skill_resource"}
|
|
458
|
+
and result.get("status") == "ok"
|
|
459
|
+
):
|
|
460
|
+
raise ValueError("Discovery selection receipt is missing")
|
|
461
|
+
if (
|
|
462
|
+
result.get("status") in {"failed", "unauthorized"}
|
|
463
|
+
and result.get("errorCode", result.get("error_code")) == "RESOURCE_FORBIDDEN"
|
|
464
|
+
):
|
|
465
|
+
self._registry.revoke_binding(scope.activation_id, scope.binding_id)
|
|
466
|
+
denied = self._error("RESOURCE_FORBIDDEN", request.request_id)
|
|
467
|
+
if receipt is not None:
|
|
468
|
+
# Authentication failure is not a confirmed business write
|
|
469
|
+
# receipt. Preserve the claimed operation for reconciliation.
|
|
470
|
+
denied["operationReceipt"] = {
|
|
471
|
+
"operationId": receipt.operation_id, "state": receipt.state,
|
|
472
|
+
}
|
|
473
|
+
return denied
|
|
474
|
+
if receipt is not None and request.operation in {"update_memory", "delete_memory"}:
|
|
475
|
+
mutation = MemoryMutationReceipt.model_validate(result)
|
|
476
|
+
if (
|
|
477
|
+
mutation.operation_id != receipt.operation_id
|
|
478
|
+
or mutation.memory_id
|
|
479
|
+
!= request.arguments.get("memoryId", request.arguments.get("memory_id"))
|
|
480
|
+
):
|
|
481
|
+
raise ValueError("Invalid memory mutation receipt")
|
|
482
|
+
result = mutation.model_dump(by_alias=True, mode="json")
|
|
483
|
+
if mutation.status in {"succeeded", "failed"}:
|
|
484
|
+
receipt = await asyncio.to_thread(
|
|
485
|
+
self._operation_ledger.record_memory_mutation,
|
|
486
|
+
mutation,
|
|
487
|
+
authority_digest=self._authority(scope),
|
|
488
|
+
operation=request.operation,
|
|
489
|
+
)
|
|
490
|
+
if receipt is not None and request.operation == "execute_skills":
|
|
491
|
+
# Never forward the private Worker result, including on malformed
|
|
492
|
+
# receipts. Only host-published metadata can reach the tool caller.
|
|
493
|
+
if (
|
|
494
|
+
set(result) != {"operationId", "status", "outputFiles"}
|
|
495
|
+
or result["operationId"] != receipt.operation_id
|
|
496
|
+
or result["status"] not in {"succeeded", "failed", "unknown"}
|
|
497
|
+
or not isinstance(result["outputFiles"], list)
|
|
498
|
+
or any(not isinstance(path, str) for path in result["outputFiles"])
|
|
499
|
+
):
|
|
500
|
+
raise ValueError("Invalid Skill execution receipt")
|
|
501
|
+
if result["status"] in {"succeeded", "failed"}:
|
|
502
|
+
assert self._skill_artifacts is not None
|
|
503
|
+
result = await asyncio.to_thread(
|
|
504
|
+
self._skill_artifacts.publish,
|
|
505
|
+
receipt.operation_id,
|
|
506
|
+
authority_digest=self._authority(scope),
|
|
507
|
+
root=activation.artifact_roots[scope.binding_id],
|
|
508
|
+
paths=result["outputFiles"],
|
|
509
|
+
status=result["status"],
|
|
510
|
+
)
|
|
511
|
+
receipt = await asyncio.to_thread(
|
|
512
|
+
self._operation_ledger.lookup,
|
|
513
|
+
receipt.operation_id,
|
|
514
|
+
authority_digest=self._authority(scope),
|
|
515
|
+
operation="execute_skills",
|
|
516
|
+
)
|
|
517
|
+
else:
|
|
518
|
+
result = {
|
|
519
|
+
"status": "unknown",
|
|
520
|
+
"operationId": receipt.operation_id,
|
|
521
|
+
"artifacts": [],
|
|
522
|
+
}
|
|
523
|
+
if status_receipt is not None:
|
|
524
|
+
if result == {
|
|
525
|
+
"operationId": status_receipt.operation_id,
|
|
526
|
+
"extractionStatus": "failed",
|
|
527
|
+
"searchable": False,
|
|
528
|
+
"errorCode": None,
|
|
529
|
+
} and status_receipt.state in {"unknown", "accepted_pending", "failed"}:
|
|
530
|
+
status_receipt = await asyncio.to_thread(
|
|
531
|
+
self._operation_ledger.record, status_receipt.operation_id, "failed"
|
|
532
|
+
)
|
|
533
|
+
result = {**result, "status": status_receipt.state}
|
|
534
|
+
if (
|
|
535
|
+
receipt is not None
|
|
536
|
+
and request.operation == "save_memory"
|
|
537
|
+
and result
|
|
538
|
+
== {
|
|
539
|
+
"status": "accepted_pending",
|
|
540
|
+
"operationId": receipt.operation_id,
|
|
541
|
+
"searchable": False,
|
|
542
|
+
"errorCode": None,
|
|
543
|
+
}
|
|
544
|
+
):
|
|
545
|
+
# Fixed memory submission receipt from our initialized Worker;
|
|
546
|
+
# acceptance is not a searchable/succeeded terminal state.
|
|
547
|
+
receipt = await asyncio.to_thread(
|
|
548
|
+
self._operation_ledger.record, receipt.operation_id, "accepted_pending"
|
|
549
|
+
)
|
|
550
|
+
self._registry.authorize(
|
|
551
|
+
request.handle,
|
|
552
|
+
operation=request.operation,
|
|
553
|
+
generation_id=self._generation_id,
|
|
554
|
+
activation_id=scope.activation_id,
|
|
555
|
+
)
|
|
556
|
+
reply = {"v": 1, "requestId": request.request_id, "result": result}
|
|
557
|
+
if receipt is not None:
|
|
558
|
+
# The trusted business adapter must reconcile authoritative status;
|
|
559
|
+
# arbitrary Worker text cannot mark a durable operation successful.
|
|
560
|
+
reply["operationReceipt"] = {
|
|
561
|
+
"operationId": receipt.operation_id,
|
|
562
|
+
"state": receipt.state,
|
|
563
|
+
}
|
|
564
|
+
encode_frame(reply)
|
|
565
|
+
return reply
|
|
566
|
+
except LeaseRejected:
|
|
567
|
+
return self._error("RESOURCE_SCOPE_INVALID", request.request_id)
|
|
568
|
+
except OperationConflict:
|
|
569
|
+
return self._error("RESOURCE_OPERATION_CONFLICT", request.request_id)
|
|
570
|
+
except Exception:
|
|
571
|
+
if request.operation in _WRITES:
|
|
572
|
+
return self._error("RESOURCE_WRITE_UNKNOWN", request.request_id)
|
|
573
|
+
return self._error("RESOURCE_WORKER_FAILED", request.request_id)
|
|
574
|
+
|
|
575
|
+
@staticmethod
|
|
576
|
+
def _authority(scope: ResourceScope) -> str:
|
|
577
|
+
identity = scope.identity.model_dump(mode="json", exclude={"session_ref"})
|
|
578
|
+
return hashlib.sha256(
|
|
579
|
+
json.dumps(
|
|
580
|
+
[identity, scope.binding_id, scope.binding_snapshot_digest],
|
|
581
|
+
sort_keys=True,
|
|
582
|
+
separators=(",", ":"),
|
|
583
|
+
).encode()
|
|
584
|
+
).hexdigest()
|
|
585
|
+
|
|
586
|
+
def revoke_activation(self, activation_id: str) -> None:
|
|
587
|
+
self._registry.revoke_activation(activation_id)
|
|
588
|
+
activation = self._activations.get(activation_id)
|
|
589
|
+
if activation is not None:
|
|
590
|
+
activation.closed = True
|
|
591
|
+
|
|
592
|
+
def revoke_generation(self) -> None:
|
|
593
|
+
self._registry.revoke_generation(self._generation_id)
|
|
594
|
+
for activation in self._activations.values():
|
|
595
|
+
activation.closed = True
|
|
596
|
+
|
|
597
|
+
async def retire_activation(self, activation_id: str) -> None:
|
|
598
|
+
"""Owner closes the worker first, then drains and removes broker state."""
|
|
599
|
+
self.revoke_activation(activation_id)
|
|
600
|
+
activation = self._activations.get(activation_id)
|
|
601
|
+
if activation is None:
|
|
602
|
+
return
|
|
603
|
+
tasks = tuple(activation.tasks)
|
|
604
|
+
if tasks:
|
|
605
|
+
# The owner has closed the Worker. Approval waiters and queued calls
|
|
606
|
+
# must not retain the supervisor lock until a UI response or deadline.
|
|
607
|
+
# Existing ledger claims remain unknown; cancellation is not rollback.
|
|
608
|
+
for task in tasks:
|
|
609
|
+
task.cancel()
|
|
610
|
+
await asyncio.gather(*tasks, return_exceptions=True)
|
|
611
|
+
if self._activations.get(activation_id) is activation:
|
|
612
|
+
del self._activations[activation_id]
|
|
613
|
+
|
|
614
|
+
@staticmethod
|
|
615
|
+
def _error(code: str, request_id: str = "") -> dict:
|
|
616
|
+
return {"v": 1, "requestId": request_id, "error": {"code": code}}
|