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,180 @@
|
|
|
1
|
+
"""Credential-free resource snapshots consumed by Build activation and workers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import json
|
|
7
|
+
from typing import Literal
|
|
8
|
+
from urllib.parse import urlsplit, urlunsplit
|
|
9
|
+
|
|
10
|
+
from pydantic import Field, field_validator, model_validator
|
|
11
|
+
|
|
12
|
+
from ksadk.plugins.bridges.dsh import DshProfileBuildSnapshot
|
|
13
|
+
from ksadk.plugins.contracts import PluginContractModel
|
|
14
|
+
from ksadk.resource_runtime.contracts import (
|
|
15
|
+
Digest,
|
|
16
|
+
Identifier,
|
|
17
|
+
ResourceConfig,
|
|
18
|
+
validate_resource_bindings,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ConnectionTarget(PluginContractModel):
|
|
23
|
+
connection_ref: Identifier
|
|
24
|
+
tenant_ref: Identifier
|
|
25
|
+
principal_ref: Identifier
|
|
26
|
+
endpoint: str
|
|
27
|
+
auth_mode: Literal["signed", "sts", "token"]
|
|
28
|
+
|
|
29
|
+
@field_validator("endpoint")
|
|
30
|
+
@classmethod
|
|
31
|
+
def canonical_endpoint(cls, value: str) -> str:
|
|
32
|
+
if any(char.isspace() for char in value) or "\\" in value:
|
|
33
|
+
raise ValueError("Invalid resource endpoint")
|
|
34
|
+
url = urlsplit(value)
|
|
35
|
+
if (
|
|
36
|
+
url.scheme not in {"http", "https"}
|
|
37
|
+
or not url.hostname
|
|
38
|
+
or url.username is not None
|
|
39
|
+
or url.password is not None
|
|
40
|
+
or url.query
|
|
41
|
+
or url.fragment
|
|
42
|
+
or "%" in url.hostname
|
|
43
|
+
):
|
|
44
|
+
raise ValueError("Resource endpoint must be an explicit HTTP service URL")
|
|
45
|
+
port = url.port # validates port range and syntax
|
|
46
|
+
host = url.hostname.encode("idna").decode("ascii").lower()
|
|
47
|
+
if ":" in host:
|
|
48
|
+
host = f"[{host}]"
|
|
49
|
+
if port is not None and (url.scheme, port) not in {("http", 80), ("https", 443)}:
|
|
50
|
+
host += f":{port}"
|
|
51
|
+
return urlunsplit((url.scheme, host, url.path.rstrip("/"), "", ""))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class SkillExecutionTarget(PluginContractModel):
|
|
55
|
+
backend: Literal["e2b"] = "e2b"
|
|
56
|
+
connection: ConnectionTarget
|
|
57
|
+
domain: str = Field(strict=True, pattern=r"^[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9-]+)*$")
|
|
58
|
+
template_id: Identifier
|
|
59
|
+
timeout: int = Field(default=900, strict=True, ge=1, le=900)
|
|
60
|
+
allow_internet_access: bool = Field(default=False, strict=True)
|
|
61
|
+
|
|
62
|
+
@model_validator(mode="after")
|
|
63
|
+
def explicit_target(self):
|
|
64
|
+
url = urlsplit(self.connection.endpoint)
|
|
65
|
+
if self.connection.auth_mode != "token" or url.scheme != "https" or url.path:
|
|
66
|
+
raise ValueError("Skill execution requires an explicit HTTPS token connection")
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class MemoryRecallPolicy(PluginContractModel):
|
|
71
|
+
"""Frozen projection of Agent memory recall limits, never a second draft config."""
|
|
72
|
+
|
|
73
|
+
top_k: int = Field(default=8, strict=True, ge=1, le=64)
|
|
74
|
+
max_tokens: int = Field(default=1600, strict=True, ge=0, le=100000)
|
|
75
|
+
min_score: float = Field(default=0, strict=True, ge=0, le=1)
|
|
76
|
+
|
|
77
|
+
@model_validator(mode="after")
|
|
78
|
+
def supported_score(self):
|
|
79
|
+
if self.min_score != 0:
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"MEMORY_SEARCH_POLICY_UNSUPPORTED: AICP score threshold is unavailable"
|
|
82
|
+
)
|
|
83
|
+
return self
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class FrozenResourceBinding(PluginContractModel):
|
|
87
|
+
config: ResourceConfig
|
|
88
|
+
connection: ConnectionTarget
|
|
89
|
+
# The connection target deliberately contains no credential references.
|
|
90
|
+
# Freeze the repository revision separately so rotating those references
|
|
91
|
+
# cannot make an old Build silently consume a different credential set.
|
|
92
|
+
connection_revision: int = Field(default=1, strict=True, ge=1)
|
|
93
|
+
skill_execution: SkillExecutionTarget | None = None
|
|
94
|
+
memory_recall: MemoryRecallPolicy | None = None
|
|
95
|
+
|
|
96
|
+
@model_validator(mode="after")
|
|
97
|
+
def matching_connection(self) -> FrozenResourceBinding:
|
|
98
|
+
if self.config.binding.connection_ref != self.connection.connection_ref:
|
|
99
|
+
raise ValueError("Resource binding and connection reference do not match")
|
|
100
|
+
if (
|
|
101
|
+
self.memory_recall is not None
|
|
102
|
+
and self.config.binding.resource.kind != "memory-instance"
|
|
103
|
+
):
|
|
104
|
+
raise ValueError("Memory recall policy requires a memory binding")
|
|
105
|
+
if self.skill_execution is not None and (
|
|
106
|
+
self.config.binding.resource.kind != "skill-space"
|
|
107
|
+
or self.config.execution_mode != "isolated"
|
|
108
|
+
or self.skill_execution.connection.tenant_ref != self.connection.tenant_ref
|
|
109
|
+
):
|
|
110
|
+
raise ValueError("Skill execution target requires an isolated Skill in the same tenant")
|
|
111
|
+
return self
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ResourceSnapshot(PluginContractModel):
|
|
115
|
+
schema_version: Literal[1] = 1
|
|
116
|
+
plugin_lock_digest: Digest
|
|
117
|
+
bindings: tuple[FrozenResourceBinding, ...]
|
|
118
|
+
# Older standalone Worker fixtures may omit this. Studio Build/activation
|
|
119
|
+
# requires the actual host snapshot, bound into the resource digest below.
|
|
120
|
+
dsh_profile: DshProfileBuildSnapshot | None = None
|
|
121
|
+
|
|
122
|
+
@field_validator("schema_version", mode="before")
|
|
123
|
+
@classmethod
|
|
124
|
+
def strict_version(cls, value: object) -> object:
|
|
125
|
+
if type(value) is not int:
|
|
126
|
+
raise ValueError("Resource snapshot version must be an integer")
|
|
127
|
+
return value
|
|
128
|
+
|
|
129
|
+
@model_validator(mode="after")
|
|
130
|
+
def unique_bindings(self) -> ResourceSnapshot:
|
|
131
|
+
validate_resource_bindings(tuple(binding.config for binding in self.bindings))
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def digest(self) -> str:
|
|
136
|
+
payload = {
|
|
137
|
+
"schemaVersion": self.schema_version,
|
|
138
|
+
"pluginLockDigest": self.plugin_lock_digest,
|
|
139
|
+
**({"dshProfileDigest": self.dsh_profile.digest} if self.dsh_profile else {}),
|
|
140
|
+
"bindings": [
|
|
141
|
+
{
|
|
142
|
+
"config": json.loads(binding.config.canonical_bytes()),
|
|
143
|
+
"connection": binding.connection.model_dump(by_alias=True, mode="json"),
|
|
144
|
+
"connectionRevision": binding.connection_revision,
|
|
145
|
+
**(
|
|
146
|
+
{
|
|
147
|
+
"memoryRecall": binding.memory_recall.model_dump(
|
|
148
|
+
by_alias=True, mode="json"
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
if binding.memory_recall is not None
|
|
152
|
+
else {}
|
|
153
|
+
),
|
|
154
|
+
**(
|
|
155
|
+
{
|
|
156
|
+
"skillExecution": binding.skill_execution.model_dump(
|
|
157
|
+
by_alias=True, mode="json"
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
if binding.skill_execution is not None
|
|
161
|
+
else {}
|
|
162
|
+
),
|
|
163
|
+
}
|
|
164
|
+
for binding in sorted(self.bindings, key=lambda item: item.config.binding.id)
|
|
165
|
+
],
|
|
166
|
+
}
|
|
167
|
+
raw = json.dumps(
|
|
168
|
+
payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False
|
|
169
|
+
).encode("utf-8")
|
|
170
|
+
return "sha256:" + hashlib.sha256(raw).hexdigest()
|
|
171
|
+
|
|
172
|
+
def binding(self, binding_id: str) -> FrozenResourceBinding:
|
|
173
|
+
for binding in self.bindings:
|
|
174
|
+
if binding.config.binding.id == binding_id:
|
|
175
|
+
return binding
|
|
176
|
+
raise ValueError("RESOURCE_BINDING_NOT_IN_BUILD")
|
|
177
|
+
|
|
178
|
+
def verify_connection(self, binding_id: str, current: ConnectionTarget) -> None:
|
|
179
|
+
if self.binding(binding_id).connection != current:
|
|
180
|
+
raise ValueError("RESOURCE_CONNECTION_CHANGED")
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Private Unix socket ingress for the existing host's resource broker."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import os
|
|
7
|
+
import struct
|
|
8
|
+
import tempfile
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from ksadk.resource_runtime.broker import ResourceBroker
|
|
12
|
+
from ksadk.resource_runtime.ipc import MAX_FRAME_BYTES, FrameError, decode_body, encode_frame
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ResourceSocketServer:
|
|
16
|
+
def __init__(self, broker: ResourceBroker, *, max_connections: int = 64):
|
|
17
|
+
if type(max_connections) is not int or not 1 <= max_connections <= 1024:
|
|
18
|
+
raise ValueError("Socket connection limit must be 1..1024")
|
|
19
|
+
self._broker = broker
|
|
20
|
+
self._max_connections = max_connections
|
|
21
|
+
self._directory: tempfile.TemporaryDirectory | None = None
|
|
22
|
+
self._server: asyncio.AbstractServer | None = None
|
|
23
|
+
self._clients: set[asyncio.Task] = set()
|
|
24
|
+
self._closing = False
|
|
25
|
+
self.path: Path | None = None
|
|
26
|
+
|
|
27
|
+
async def start(self) -> Path:
|
|
28
|
+
if os.name != "posix":
|
|
29
|
+
raise RuntimeError("RESOURCE_IPC_UNSUPPORTED")
|
|
30
|
+
if self._directory is not None or self._closing:
|
|
31
|
+
raise RuntimeError("Resource socket server cannot be restarted")
|
|
32
|
+
directory = tempfile.TemporaryDirectory(prefix="ksr-")
|
|
33
|
+
self._directory = directory
|
|
34
|
+
self.path = Path(directory.name) / "broker.sock"
|
|
35
|
+
try:
|
|
36
|
+
os.chmod(directory.name, 0o700)
|
|
37
|
+
# Private parent directory prevents access during the bind/chmod gap.
|
|
38
|
+
self._server = await asyncio.start_unix_server(self._accept, path=str(self.path))
|
|
39
|
+
os.chmod(self.path, 0o600)
|
|
40
|
+
return self.path
|
|
41
|
+
except BaseException:
|
|
42
|
+
await self.aclose()
|
|
43
|
+
raise
|
|
44
|
+
|
|
45
|
+
async def _accept(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
|
|
46
|
+
task = asyncio.current_task()
|
|
47
|
+
assert task is not None
|
|
48
|
+
if self._closing or len(self._clients) >= self._max_connections:
|
|
49
|
+
writer.close()
|
|
50
|
+
await writer.wait_closed()
|
|
51
|
+
return
|
|
52
|
+
self._clients.add(task)
|
|
53
|
+
try:
|
|
54
|
+
while not self._closing:
|
|
55
|
+
payload = await asyncio.wait_for(self._read(reader), 15)
|
|
56
|
+
if payload is None:
|
|
57
|
+
return
|
|
58
|
+
response = await self._broker.dispatch(payload)
|
|
59
|
+
writer.write(encode_frame(response))
|
|
60
|
+
await asyncio.wait_for(writer.drain(), 5)
|
|
61
|
+
except (
|
|
62
|
+
FrameError,
|
|
63
|
+
asyncio.TimeoutError,
|
|
64
|
+
asyncio.IncompleteReadError,
|
|
65
|
+
ConnectionError,
|
|
66
|
+
OSError,
|
|
67
|
+
):
|
|
68
|
+
# Closing rejects malformed/slow ingress; never echo raw input.
|
|
69
|
+
pass
|
|
70
|
+
finally:
|
|
71
|
+
self._clients.discard(task)
|
|
72
|
+
writer.close()
|
|
73
|
+
try:
|
|
74
|
+
await writer.wait_closed()
|
|
75
|
+
except (ConnectionError, OSError):
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
async def _read(reader: asyncio.StreamReader) -> dict | None:
|
|
80
|
+
try:
|
|
81
|
+
prefix = await reader.readexactly(4)
|
|
82
|
+
except asyncio.IncompleteReadError as exc:
|
|
83
|
+
if not exc.partial:
|
|
84
|
+
return None
|
|
85
|
+
raise
|
|
86
|
+
(size,) = struct.unpack("!I", prefix)
|
|
87
|
+
if not 0 < size <= MAX_FRAME_BYTES:
|
|
88
|
+
raise FrameError("Invalid IPC frame length")
|
|
89
|
+
return decode_body(await reader.readexactly(size))
|
|
90
|
+
|
|
91
|
+
async def aclose(self) -> None:
|
|
92
|
+
self._closing = True
|
|
93
|
+
if self._server is not None:
|
|
94
|
+
self._server.close()
|
|
95
|
+
await self._server.wait_closed()
|
|
96
|
+
self._broker.revoke_generation()
|
|
97
|
+
clients = tuple(self._clients)
|
|
98
|
+
for task in clients:
|
|
99
|
+
task.cancel()
|
|
100
|
+
if clients:
|
|
101
|
+
await asyncio.gather(*clients, return_exceptions=True)
|
|
102
|
+
if self._directory is not None:
|
|
103
|
+
self._directory.cleanup()
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"""Generation-owned resource lifecycle for trusted Studio/runtime adapters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from collections.abc import Awaitable, Callable
|
|
7
|
+
from dataclasses import dataclass, field
|
|
8
|
+
from datetime import datetime, timezone
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from ksadk.resource_runtime.broker import ResourceBroker, ResourceWriteAuthorizer
|
|
12
|
+
from ksadk.resource_runtime.discovery_receipts import (
|
|
13
|
+
DiscoverySelectionReceipts,
|
|
14
|
+
discovery_scope_key,
|
|
15
|
+
)
|
|
16
|
+
from ksadk.resource_runtime.ipc import ResourceRequest
|
|
17
|
+
from ksadk.resource_runtime.leases import (
|
|
18
|
+
LeaseRejected,
|
|
19
|
+
ResourceLease,
|
|
20
|
+
ResourceLeaseRegistry,
|
|
21
|
+
ResourceScope,
|
|
22
|
+
)
|
|
23
|
+
from ksadk.resource_runtime.operation_ledger import OperationLedger
|
|
24
|
+
from ksadk.resource_runtime.process import ResourceWorkerProcess
|
|
25
|
+
from ksadk.resource_runtime.socket_server import ResourceSocketServer
|
|
26
|
+
from ksadk.resource_runtime.worker import DiscoverySkillWorkerBinding, WorkerInitialization
|
|
27
|
+
|
|
28
|
+
ResourceRevalidator = Callable[[tuple[ResourceScope, ...]], Awaitable[bool]]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class ActiveResources:
|
|
33
|
+
activation_id: str
|
|
34
|
+
socket_path: Path
|
|
35
|
+
leases: tuple[ResourceLease, ...] = field(repr=False)
|
|
36
|
+
worker_pid: int
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class _Running:
|
|
41
|
+
worker: ResourceWorkerProcess
|
|
42
|
+
resources: ActiveResources
|
|
43
|
+
lease_changed: asyncio.Event = field(default_factory=asyncio.Event)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _ActivationApprovals:
|
|
47
|
+
"""Dispatch only to the approval owner admitted for this exact activation."""
|
|
48
|
+
|
|
49
|
+
def __init__(self):
|
|
50
|
+
self.owners: dict[str, tuple[tuple[ResourceScope, ...], ResourceWriteAuthorizer]] = {}
|
|
51
|
+
|
|
52
|
+
def register(self, scopes: tuple[ResourceScope, ...], owner: ResourceWriteAuthorizer) -> None:
|
|
53
|
+
activation_id = scopes[0].activation_id
|
|
54
|
+
if activation_id in self.owners:
|
|
55
|
+
raise ValueError("RESOURCE_APPROVAL_OWNER_IMMUTABLE")
|
|
56
|
+
self.owners[activation_id] = (scopes, owner)
|
|
57
|
+
|
|
58
|
+
def revoke(self, activation_id: str) -> None:
|
|
59
|
+
self.owners.pop(activation_id, None)
|
|
60
|
+
|
|
61
|
+
async def authorize(self, request: ResourceRequest, scope: ResourceScope) -> str | None:
|
|
62
|
+
admitted = self.owners.get(scope.activation_id)
|
|
63
|
+
if admitted is None or scope not in admitted[0]:
|
|
64
|
+
return None
|
|
65
|
+
event_id = await admitted[1].authorize(request, scope)
|
|
66
|
+
# An approval may finish after the run was stopped. Do not revive it.
|
|
67
|
+
return event_id if self.owners.get(scope.activation_id) is admitted else None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ResourceSupervisor:
|
|
71
|
+
"""One owner per Core generation, with one worker per activation.
|
|
72
|
+
|
|
73
|
+
Admission and real credential/principal verification precede activate().
|
|
74
|
+
This class never derives user identity from tool arguments, reads credential
|
|
75
|
+
environment variables, restarts failed activations or replays requests.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
generation_id: str,
|
|
81
|
+
*,
|
|
82
|
+
max_workers: int = 32,
|
|
83
|
+
write_authorizer: ResourceWriteAuthorizer | None = None,
|
|
84
|
+
operation_ledger: OperationLedger | None = None,
|
|
85
|
+
):
|
|
86
|
+
if type(max_workers) is not int or not 1 <= max_workers <= 128:
|
|
87
|
+
raise ValueError("Resource worker limit must be 1..128")
|
|
88
|
+
self.generation_id = generation_id
|
|
89
|
+
self._max_workers = max_workers
|
|
90
|
+
if write_authorizer is not None and operation_ledger is None:
|
|
91
|
+
raise ValueError("Write approval requires a durable operation ledger")
|
|
92
|
+
self._default_write_authorizer = write_authorizer
|
|
93
|
+
self._has_operation_ledger = operation_ledger is not None
|
|
94
|
+
self._discovery_receipts = (
|
|
95
|
+
DiscoverySelectionReceipts(operation_ledger) if operation_ledger is not None else None
|
|
96
|
+
)
|
|
97
|
+
self._approvals = _ActivationApprovals()
|
|
98
|
+
self._registry = ResourceLeaseRegistry()
|
|
99
|
+
self._broker = ResourceBroker(
|
|
100
|
+
self._registry,
|
|
101
|
+
generation_id,
|
|
102
|
+
write_authorizer=self._approvals if operation_ledger is not None else None,
|
|
103
|
+
operation_ledger=operation_ledger,
|
|
104
|
+
)
|
|
105
|
+
self._socket = ResourceSocketServer(self._broker)
|
|
106
|
+
self._lock = asyncio.Lock()
|
|
107
|
+
self._running: dict[str, _Running] = {}
|
|
108
|
+
self._used: set[str] = set()
|
|
109
|
+
self._monitors: set[asyncio.Task] = set()
|
|
110
|
+
self._closed = False
|
|
111
|
+
|
|
112
|
+
async def start_broker(self) -> Path:
|
|
113
|
+
"""Prepare private ingress before Core startup, without workers or grants."""
|
|
114
|
+
async with self._lock:
|
|
115
|
+
return await self._start_broker_locked()
|
|
116
|
+
|
|
117
|
+
async def _start_broker_locked(self) -> Path:
|
|
118
|
+
if self._closed:
|
|
119
|
+
raise RuntimeError("RESOURCE_SUPERVISOR_CLOSED")
|
|
120
|
+
if self._socket.path is None:
|
|
121
|
+
try:
|
|
122
|
+
await self._socket.start()
|
|
123
|
+
except BaseException:
|
|
124
|
+
self._closed = True
|
|
125
|
+
raise
|
|
126
|
+
assert self._socket.path is not None
|
|
127
|
+
return self._socket.path
|
|
128
|
+
|
|
129
|
+
async def activate(
|
|
130
|
+
self,
|
|
131
|
+
initialization: WorkerInitialization,
|
|
132
|
+
*,
|
|
133
|
+
write_authorizer: ResourceWriteAuthorizer | None = None,
|
|
134
|
+
) -> ActiveResources:
|
|
135
|
+
# Revalidate even models assembled via unchecked model_copy/model_construct.
|
|
136
|
+
initialization = WorkerInitialization.model_validate(initialization.pipe_payload())
|
|
137
|
+
discovery_keys = {}
|
|
138
|
+
restored_bindings = list(initialization.bindings)
|
|
139
|
+
for index, binding in enumerate(initialization.bindings):
|
|
140
|
+
if isinstance(binding, DiscoverySkillWorkerBinding):
|
|
141
|
+
if self._discovery_receipts is None:
|
|
142
|
+
raise ValueError("RESOURCE_DISCOVERY_RECEIPTS_REQUIRED")
|
|
143
|
+
binding_scope = next(
|
|
144
|
+
item for item in initialization.scopes
|
|
145
|
+
if item.binding_id == binding.config.binding.id
|
|
146
|
+
)
|
|
147
|
+
key = discovery_scope_key(binding_scope, binding.selection_run_ref)
|
|
148
|
+
discovery_keys[binding_scope.binding_id] = key
|
|
149
|
+
restored = await asyncio.to_thread(self._discovery_receipts.read, key)
|
|
150
|
+
# Only host ledger contents may restore selections. Ignore caller
|
|
151
|
+
# supplied preloads at this public lifecycle entry.
|
|
152
|
+
restored_bindings[index] = binding.model_copy(
|
|
153
|
+
update={"restored_selections": restored}
|
|
154
|
+
)
|
|
155
|
+
initialization = initialization.model_copy(update={"bindings": tuple(restored_bindings)})
|
|
156
|
+
scope = initialization.scopes[0]
|
|
157
|
+
owner = write_authorizer if write_authorizer is not None else self._default_write_authorizer
|
|
158
|
+
if owner is not None and not self._has_operation_ledger:
|
|
159
|
+
raise ValueError("Write approval requires a durable operation ledger")
|
|
160
|
+
if scope.generation_id != self.generation_id:
|
|
161
|
+
raise ValueError("Resource activation belongs to another generation")
|
|
162
|
+
async with self._lock:
|
|
163
|
+
if self._closed:
|
|
164
|
+
raise RuntimeError("RESOURCE_SUPERVISOR_CLOSED")
|
|
165
|
+
if scope.activation_id in self._used:
|
|
166
|
+
raise ValueError("RESOURCE_ACTIVATION_ALREADY_USED")
|
|
167
|
+
if len(self._used) >= 4096:
|
|
168
|
+
raise RuntimeError("RESOURCE_GENERATION_CAPACITY")
|
|
169
|
+
if len(self._running) >= self._max_workers:
|
|
170
|
+
raise RuntimeError("RESOURCE_WORKER_CAPACITY")
|
|
171
|
+
await self._start_broker_locked()
|
|
172
|
+
self._used.add(scope.activation_id)
|
|
173
|
+
worker = None
|
|
174
|
+
try:
|
|
175
|
+
if owner is not None:
|
|
176
|
+
self._approvals.register(initialization.scopes, owner)
|
|
177
|
+
worker = await ResourceWorkerProcess.start(initialization)
|
|
178
|
+
leases = []
|
|
179
|
+
for binding_scope in initialization.scopes:
|
|
180
|
+
binding = next(
|
|
181
|
+
item
|
|
182
|
+
for item in initialization.bindings
|
|
183
|
+
if item.config.binding.id == binding_scope.binding_id
|
|
184
|
+
)
|
|
185
|
+
self._broker.register(
|
|
186
|
+
binding_scope,
|
|
187
|
+
worker,
|
|
188
|
+
artifact_root=getattr(binding, "artifact_directory", None),
|
|
189
|
+
discovery_key=discovery_keys.get(binding_scope.binding_id),
|
|
190
|
+
)
|
|
191
|
+
leases.append(self._registry.issue(binding_scope))
|
|
192
|
+
assert self._socket.path is not None
|
|
193
|
+
resources = ActiveResources(
|
|
194
|
+
scope.activation_id, self._socket.path, tuple(leases), worker.pid
|
|
195
|
+
)
|
|
196
|
+
self._running[scope.activation_id] = _Running(worker, resources)
|
|
197
|
+
monitor = asyncio.create_task(self._monitor(scope.activation_id, worker))
|
|
198
|
+
self._monitors.add(monitor)
|
|
199
|
+
monitor.add_done_callback(self._monitors.discard)
|
|
200
|
+
return resources
|
|
201
|
+
except BaseException:
|
|
202
|
+
self._approvals.revoke(scope.activation_id)
|
|
203
|
+
self._broker.revoke_activation(scope.activation_id)
|
|
204
|
+
if worker is not None:
|
|
205
|
+
await worker.aclose()
|
|
206
|
+
await self._broker.retire_activation(scope.activation_id)
|
|
207
|
+
raise
|
|
208
|
+
|
|
209
|
+
async def deactivate(self, activation_id: str) -> None:
|
|
210
|
+
async with self._lock:
|
|
211
|
+
await self._deactivate_locked(activation_id)
|
|
212
|
+
|
|
213
|
+
async def owns(self, current: ActiveResources) -> bool:
|
|
214
|
+
"""Confirm an opaque activation handle still names this live generation."""
|
|
215
|
+
|
|
216
|
+
async with self._lock:
|
|
217
|
+
running = self._running.get(current.activation_id)
|
|
218
|
+
return (
|
|
219
|
+
not self._closed
|
|
220
|
+
and running is not None
|
|
221
|
+
and running.resources is current
|
|
222
|
+
and running.worker.is_running
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
async def renew(
|
|
226
|
+
self,
|
|
227
|
+
current: ActiveResources,
|
|
228
|
+
*,
|
|
229
|
+
revalidate: ResourceRevalidator,
|
|
230
|
+
lifetime: int = 600,
|
|
231
|
+
) -> ActiveResources:
|
|
232
|
+
"""Host-only renewal after fresh upstream permission checks.
|
|
233
|
+
|
|
234
|
+
The caller replaces its connector with the returned handles at a safe
|
|
235
|
+
turn boundary. No model operation, automatic timer, or default grant is
|
|
236
|
+
installed here. The verifier must check every supplied binding scope.
|
|
237
|
+
"""
|
|
238
|
+
if type(lifetime) is not int or not 1 <= lifetime <= 600:
|
|
239
|
+
raise ValueError("Resource lease lifetime must be 1..600 seconds")
|
|
240
|
+
async with self._lock:
|
|
241
|
+
running = self._running.get(current.activation_id)
|
|
242
|
+
if (
|
|
243
|
+
self._closed
|
|
244
|
+
or running is None
|
|
245
|
+
or running.resources is not current
|
|
246
|
+
or not running.worker.is_running
|
|
247
|
+
):
|
|
248
|
+
raise ValueError("RESOURCE_RENEWAL_STALE")
|
|
249
|
+
scopes = tuple(
|
|
250
|
+
ResourceScope.model_validate(lease.scope.model_dump()) for lease in current.leases
|
|
251
|
+
)
|
|
252
|
+
# Do not block immediate deactivation while checking the platform.
|
|
253
|
+
try:
|
|
254
|
+
if await asyncio.wait_for(revalidate(scopes), timeout=15) is not True:
|
|
255
|
+
raise PermissionError("RESOURCE_RENEWAL_DENIED")
|
|
256
|
+
except BaseException:
|
|
257
|
+
async with self._lock:
|
|
258
|
+
latest = self._running.get(current.activation_id)
|
|
259
|
+
if latest is running and latest.resources is current:
|
|
260
|
+
await self._deactivate_locked(current.activation_id)
|
|
261
|
+
raise
|
|
262
|
+
async with self._lock:
|
|
263
|
+
if (
|
|
264
|
+
self._closed
|
|
265
|
+
or self._running.get(current.activation_id) is not running
|
|
266
|
+
or running.resources is not current
|
|
267
|
+
or not running.worker.is_running
|
|
268
|
+
):
|
|
269
|
+
raise ValueError("RESOURCE_RENEWAL_STALE")
|
|
270
|
+
try:
|
|
271
|
+
leases = self._registry.renew_many(
|
|
272
|
+
tuple(lease.handle for lease in current.leases),
|
|
273
|
+
lifetime=lifetime,
|
|
274
|
+
)
|
|
275
|
+
except BaseException:
|
|
276
|
+
await self._deactivate_locked(current.activation_id)
|
|
277
|
+
raise
|
|
278
|
+
renewed = ActiveResources(
|
|
279
|
+
current.activation_id, current.socket_path, leases, current.worker_pid
|
|
280
|
+
)
|
|
281
|
+
running.resources = renewed
|
|
282
|
+
running.lease_changed.set()
|
|
283
|
+
return renewed
|
|
284
|
+
|
|
285
|
+
async def runtime_status(self, *, agent_id: str, activation_id: str) -> dict | None:
|
|
286
|
+
"""Observe this live activation without issuing leases or probing upstream.
|
|
287
|
+
|
|
288
|
+
Unknown and differently owned activations are indistinguishable. This is
|
|
289
|
+
transport availability, not proof that current upstream grants are valid.
|
|
290
|
+
"""
|
|
291
|
+
async with self._lock:
|
|
292
|
+
running = self._running.get(activation_id)
|
|
293
|
+
if running is None:
|
|
294
|
+
return None
|
|
295
|
+
scopes = [lease.scope for lease in running.resources.leases]
|
|
296
|
+
if any(scope.identity.agent_id != agent_id for scope in scopes):
|
|
297
|
+
return None
|
|
298
|
+
items = []
|
|
299
|
+
for lease in running.resources.leases:
|
|
300
|
+
available = running.worker.is_running and not self._closed
|
|
301
|
+
try:
|
|
302
|
+
self._registry.authorize(
|
|
303
|
+
lease.handle,
|
|
304
|
+
operation=lease.scope.allowed_operations[0],
|
|
305
|
+
generation_id=self.generation_id,
|
|
306
|
+
activation_id=activation_id,
|
|
307
|
+
)
|
|
308
|
+
except LeaseRejected:
|
|
309
|
+
available = False
|
|
310
|
+
items.append(
|
|
311
|
+
{
|
|
312
|
+
"bindingId": lease.scope.binding_id,
|
|
313
|
+
"runtimeState": "available" if available else "unavailable",
|
|
314
|
+
"allowedOperations": list(lease.scope.allowed_operations)
|
|
315
|
+
if available
|
|
316
|
+
else [],
|
|
317
|
+
}
|
|
318
|
+
)
|
|
319
|
+
first = scopes[0]
|
|
320
|
+
return {
|
|
321
|
+
"agentId": agent_id,
|
|
322
|
+
"activationId": activation_id,
|
|
323
|
+
"generationId": self.generation_id,
|
|
324
|
+
"buildDigest": first.build_digest,
|
|
325
|
+
"bindingSnapshotDigest": first.binding_snapshot_digest,
|
|
326
|
+
"observedAt": datetime.now(timezone.utc).isoformat(),
|
|
327
|
+
"upstreamVerification": "not-observed",
|
|
328
|
+
"items": items,
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async def _deactivate_locked(self, activation_id: str) -> None:
|
|
332
|
+
self._approvals.revoke(activation_id)
|
|
333
|
+
self._broker.revoke_activation(activation_id)
|
|
334
|
+
running = self._running.pop(activation_id, None)
|
|
335
|
+
if running is not None:
|
|
336
|
+
await running.worker.aclose()
|
|
337
|
+
await self._broker.retire_activation(activation_id)
|
|
338
|
+
|
|
339
|
+
async def _monitor(self, activation_id: str, worker: ResourceWorkerProcess) -> None:
|
|
340
|
+
stopped = asyncio.create_task(worker.wait_stopped())
|
|
341
|
+
try:
|
|
342
|
+
while True:
|
|
343
|
+
async with self._lock:
|
|
344
|
+
running = self._running.get(activation_id)
|
|
345
|
+
if running is None or running.worker is not worker:
|
|
346
|
+
return
|
|
347
|
+
remaining = self._registry.remaining_lifetime(
|
|
348
|
+
tuple(lease.handle for lease in running.resources.leases)
|
|
349
|
+
)
|
|
350
|
+
if stopped.done() or remaining <= 0:
|
|
351
|
+
await self._deactivate_locked(activation_id)
|
|
352
|
+
return
|
|
353
|
+
# Read current leases and clear under the same lock as renew.
|
|
354
|
+
# An old expiry wakeup never revokes a successfully renewed run.
|
|
355
|
+
running.lease_changed.clear()
|
|
356
|
+
changed = asyncio.create_task(running.lease_changed.wait())
|
|
357
|
+
try:
|
|
358
|
+
# Also notice complete binding revocation without another model
|
|
359
|
+
# request. This timer cannot refresh credentials or issue leases.
|
|
360
|
+
await asyncio.wait(
|
|
361
|
+
(stopped, changed), timeout=min(remaining, 30.0),
|
|
362
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
363
|
+
)
|
|
364
|
+
finally:
|
|
365
|
+
changed.cancel()
|
|
366
|
+
await asyncio.gather(changed, return_exceptions=True)
|
|
367
|
+
finally:
|
|
368
|
+
if not stopped.done():
|
|
369
|
+
stopped.cancel()
|
|
370
|
+
await asyncio.gather(stopped, return_exceptions=True)
|
|
371
|
+
|
|
372
|
+
async def aclose(self) -> None:
|
|
373
|
+
async with self._lock:
|
|
374
|
+
self._closed = True
|
|
375
|
+
await self._socket.aclose()
|
|
376
|
+
for activation_id in tuple(self._running):
|
|
377
|
+
await self._deactivate_locked(activation_id)
|
|
378
|
+
# Monitors may be waiting on the supervisor lock, so join after releasing it.
|
|
379
|
+
if self._monitors:
|
|
380
|
+
await asyncio.gather(*tuple(self._monitors), return_exceptions=True)
|