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
ksadk/skills/package_store.py
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import hashlib
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
4
6
|
import shutil
|
|
7
|
+
import stat
|
|
8
|
+
import tempfile
|
|
9
|
+
import threading
|
|
5
10
|
import zipfile
|
|
11
|
+
from contextlib import contextmanager
|
|
6
12
|
from dataclasses import dataclass
|
|
7
|
-
from pathlib import Path
|
|
13
|
+
from pathlib import Path, PurePosixPath
|
|
14
|
+
|
|
15
|
+
try:
|
|
16
|
+
import fcntl
|
|
17
|
+
except ImportError: # Windows legacy callers retain in-process synchronization.
|
|
18
|
+
fcntl = None
|
|
8
19
|
|
|
9
20
|
from ksadk.skills.models import SkillRef
|
|
10
21
|
|
|
@@ -23,60 +34,128 @@ class SkillPackage:
|
|
|
23
34
|
|
|
24
35
|
|
|
25
36
|
class PackageStore:
|
|
26
|
-
def __init__(
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
cache_dir: str | Path,
|
|
40
|
+
*,
|
|
41
|
+
namespace: str = "",
|
|
42
|
+
require_hash: bool = False,
|
|
43
|
+
max_archive_bytes: int = 20 * 1024 * 1024,
|
|
44
|
+
max_extracted_bytes: int = 100 * 1024 * 1024,
|
|
45
|
+
max_files: int = 2000,
|
|
46
|
+
):
|
|
47
|
+
if any(
|
|
48
|
+
type(value) is not int or value < 1
|
|
49
|
+
for value in (max_archive_bytes, max_extracted_bytes, max_files)
|
|
50
|
+
):
|
|
51
|
+
raise ValueError("Skill package limits must be positive integers")
|
|
52
|
+
if require_hash and (not namespace or fcntl is None):
|
|
53
|
+
raise ValueError("Verified package stores require a namespace and process locking")
|
|
27
54
|
self.cache_dir = Path(cache_dir)
|
|
28
|
-
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
|
55
|
+
self.cache_dir.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
56
|
+
self.namespace = namespace
|
|
57
|
+
self.require_hash = require_hash
|
|
58
|
+
self.max_archive_bytes = max_archive_bytes
|
|
59
|
+
self.max_extracted_bytes = max_extracted_bytes
|
|
60
|
+
self.max_files = max_files
|
|
61
|
+
self._thread_lock = threading.RLock()
|
|
29
62
|
|
|
30
63
|
def store_archive(self, ref: SkillRef, content: bytes) -> SkillPackage:
|
|
31
64
|
self._verify_hash(ref, content)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
extract_dir = skill_dir / "extracted"
|
|
35
|
-
|
|
36
|
-
if archive_path.exists() and extract_dir.exists():
|
|
37
|
-
cached = self.get_cached(ref)
|
|
65
|
+
with self._locked(ref):
|
|
66
|
+
cached = self._get_cached(ref)
|
|
38
67
|
if cached is not None:
|
|
39
68
|
return cached
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
69
|
+
skill_dir = self._skill_dir(ref)
|
|
70
|
+
stage = Path(tempfile.mkdtemp(prefix=".stage-", dir=self.cache_dir))
|
|
71
|
+
try:
|
|
72
|
+
(stage / "archive.zip").write_bytes(content)
|
|
73
|
+
os.chmod(stage / "archive.zip", 0o600)
|
|
74
|
+
extracted = stage / "extracted"
|
|
75
|
+
extracted.mkdir(mode=0o700)
|
|
76
|
+
self._safe_extract(stage / "archive.zip", extracted)
|
|
77
|
+
self._find_skill_root(extracted)
|
|
78
|
+
# Publish only a complete validated tree, under the per-key lock.
|
|
79
|
+
if skill_dir.is_symlink() or skill_dir.is_file():
|
|
80
|
+
skill_dir.unlink()
|
|
81
|
+
elif skill_dir.exists():
|
|
82
|
+
shutil.rmtree(skill_dir)
|
|
83
|
+
os.replace(stage, skill_dir)
|
|
84
|
+
except (OSError, zipfile.BadZipFile, RuntimeError, ValueError) as error:
|
|
85
|
+
raise SkillPackageError("Skill archive could not be safely materialized") from error
|
|
86
|
+
finally:
|
|
87
|
+
if stage.exists():
|
|
88
|
+
shutil.rmtree(stage)
|
|
89
|
+
return self._package(ref, skill_dir, cache_hit=False)
|
|
55
90
|
|
|
56
91
|
def get_cached(self, ref: SkillRef) -> SkillPackage | None:
|
|
92
|
+
with self._locked(ref):
|
|
93
|
+
return self._get_cached(ref)
|
|
94
|
+
|
|
95
|
+
def _get_cached(self, ref: SkillRef) -> SkillPackage | None:
|
|
57
96
|
skill_dir = self._skill_dir(ref)
|
|
58
97
|
archive_path = skill_dir / "archive.zip"
|
|
59
98
|
extract_dir = skill_dir / "extracted"
|
|
60
|
-
if
|
|
99
|
+
if (
|
|
100
|
+
skill_dir.is_symlink()
|
|
101
|
+
or archive_path.is_symlink()
|
|
102
|
+
or extract_dir.is_symlink()
|
|
103
|
+
or not archive_path.is_file()
|
|
104
|
+
or not extract_dir.is_dir()
|
|
105
|
+
):
|
|
61
106
|
return None
|
|
62
|
-
content = archive_path.read_bytes()
|
|
63
107
|
try:
|
|
108
|
+
if archive_path.stat().st_size > self.max_archive_bytes:
|
|
109
|
+
return None
|
|
110
|
+
content = archive_path.read_bytes()
|
|
64
111
|
self._verify_hash(ref, content)
|
|
65
|
-
|
|
112
|
+
self._verify_tree(archive_path, extract_dir)
|
|
113
|
+
return self._package(ref, skill_dir, cache_hit=True)
|
|
114
|
+
except (RuntimeError, OSError, zipfile.BadZipFile, ValueError):
|
|
66
115
|
return None
|
|
116
|
+
|
|
117
|
+
def _package(self, ref: SkillRef, skill_dir: Path, *, cache_hit: bool) -> SkillPackage:
|
|
67
118
|
return SkillPackage(
|
|
68
119
|
ref=ref,
|
|
69
|
-
archive_path=
|
|
70
|
-
extract_dir=
|
|
71
|
-
root_dir=self._find_skill_root(
|
|
72
|
-
cache_hit=
|
|
120
|
+
archive_path=skill_dir / "archive.zip",
|
|
121
|
+
extract_dir=skill_dir / "extracted",
|
|
122
|
+
root_dir=self._find_skill_root(skill_dir / "extracted"),
|
|
123
|
+
cache_hit=cache_hit,
|
|
73
124
|
)
|
|
74
125
|
|
|
75
126
|
def _skill_dir(self, ref: SkillRef) -> Path:
|
|
76
|
-
|
|
127
|
+
identity = [
|
|
128
|
+
self.namespace,
|
|
129
|
+
ref.skill_id,
|
|
130
|
+
ref.version_id,
|
|
131
|
+
ref.version,
|
|
132
|
+
ref.name,
|
|
133
|
+
ref.content_hash.render() if ref.content_hash else "",
|
|
134
|
+
]
|
|
135
|
+
key = hashlib.sha256(json.dumps(identity, ensure_ascii=False).encode()).hexdigest()
|
|
136
|
+
return self.cache_dir / key
|
|
137
|
+
|
|
138
|
+
@contextmanager
|
|
139
|
+
def _locked(self, ref: SkillRef):
|
|
140
|
+
with self._thread_lock:
|
|
141
|
+
if fcntl is None:
|
|
142
|
+
yield
|
|
143
|
+
return
|
|
144
|
+
path = self._skill_dir(ref).with_suffix(".lock")
|
|
145
|
+
fd = os.open(path, os.O_CREAT | os.O_RDWR | os.O_NOFOLLOW, 0o600)
|
|
146
|
+
with os.fdopen(fd, "rb") as lock:
|
|
147
|
+
fcntl.flock(lock, fcntl.LOCK_EX)
|
|
148
|
+
try:
|
|
149
|
+
yield
|
|
150
|
+
finally:
|
|
151
|
+
fcntl.flock(lock, fcntl.LOCK_UN)
|
|
77
152
|
|
|
78
153
|
def _verify_hash(self, ref: SkillRef, content: bytes) -> None:
|
|
154
|
+
if len(content) > self.max_archive_bytes:
|
|
155
|
+
raise SkillPackageError("Skill archive exceeds size limit")
|
|
79
156
|
if not ref.content_hash:
|
|
157
|
+
if self.require_hash:
|
|
158
|
+
raise SkillPackageError("Verified Skill packages require ContentHash")
|
|
80
159
|
return
|
|
81
160
|
if ref.content_hash.algorithm != "sha256":
|
|
82
161
|
raise SkillPackageError(
|
|
@@ -90,13 +169,82 @@ class PackageStore:
|
|
|
90
169
|
)
|
|
91
170
|
|
|
92
171
|
def _safe_extract(self, archive_path: Path, extract_dir: Path) -> None:
|
|
93
|
-
|
|
172
|
+
expanded = 0
|
|
173
|
+
with zipfile.ZipFile(archive_path) as archive:
|
|
174
|
+
for member, relative in self._members(archive):
|
|
175
|
+
target = extract_dir / relative
|
|
176
|
+
target.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
177
|
+
if member.is_dir():
|
|
178
|
+
target.mkdir(exist_ok=True, mode=0o700)
|
|
179
|
+
continue
|
|
180
|
+
with archive.open(member) as source, target.open("xb") as destination:
|
|
181
|
+
written = 0
|
|
182
|
+
while chunk := source.read(64 * 1024):
|
|
183
|
+
written += len(chunk)
|
|
184
|
+
expanded += len(chunk)
|
|
185
|
+
if written > member.file_size or expanded > self.max_extracted_bytes:
|
|
186
|
+
raise SkillPackageError("Expanded Skill package exceeds limits")
|
|
187
|
+
destination.write(chunk)
|
|
188
|
+
os.chmod(target, 0o700 if (member.external_attr >> 16) & 0o111 else 0o600)
|
|
189
|
+
|
|
190
|
+
def _members(self, archive: zipfile.ZipFile):
|
|
191
|
+
members = archive.infolist()
|
|
192
|
+
if (
|
|
193
|
+
len(members) > self.max_files
|
|
194
|
+
or sum(item.file_size for item in members) > self.max_extracted_bytes
|
|
195
|
+
):
|
|
196
|
+
raise SkillPackageError("Expanded Skill package exceeds limits")
|
|
197
|
+
seen = set()
|
|
198
|
+
result = []
|
|
199
|
+
for member in members:
|
|
200
|
+
relative = PurePosixPath(member.filename)
|
|
201
|
+
kind = stat.S_IFMT(member.external_attr >> 16)
|
|
202
|
+
if (
|
|
203
|
+
not relative.parts
|
|
204
|
+
or relative.is_absolute()
|
|
205
|
+
or ".." in relative.parts
|
|
206
|
+
or "\\" in member.filename
|
|
207
|
+
or ":" in member.filename
|
|
208
|
+
or "\x00" in member.orig_filename
|
|
209
|
+
or kind not in (0, stat.S_IFREG, stat.S_IFDIR)
|
|
210
|
+
or relative in seen
|
|
211
|
+
or member.flag_bits & 1
|
|
212
|
+
):
|
|
213
|
+
raise SkillPackageError("Unsafe Skill archive member")
|
|
214
|
+
seen.add(relative)
|
|
215
|
+
result.append((member, relative))
|
|
216
|
+
return result
|
|
217
|
+
|
|
218
|
+
def _verify_tree(self, archive_path: Path, extract_dir: Path) -> None:
|
|
219
|
+
expected = set()
|
|
94
220
|
with zipfile.ZipFile(archive_path) as archive:
|
|
95
|
-
for member in
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
221
|
+
for member, relative in self._members(archive):
|
|
222
|
+
expected.update(
|
|
223
|
+
parent for parent in relative.parents if parent != PurePosixPath(".")
|
|
224
|
+
)
|
|
225
|
+
expected.add(relative)
|
|
226
|
+
target = extract_dir / relative
|
|
227
|
+
if any((extract_dir / parent).is_symlink() for parent in relative.parents):
|
|
228
|
+
raise SkillPackageError("Skill cache contains a linked parent")
|
|
229
|
+
if target.is_symlink():
|
|
230
|
+
raise SkillPackageError("Skill cache contains a link")
|
|
231
|
+
if member.is_dir():
|
|
232
|
+
if not target.is_dir():
|
|
233
|
+
raise SkillPackageError("Skill cache directory missing")
|
|
234
|
+
continue
|
|
235
|
+
if not target.is_file() or target.stat().st_size != member.file_size:
|
|
236
|
+
raise SkillPackageError("Skill cache file changed")
|
|
237
|
+
with archive.open(member) as source, target.open("rb") as current:
|
|
238
|
+
while chunk := source.read(64 * 1024):
|
|
239
|
+
if chunk != current.read(len(chunk)):
|
|
240
|
+
raise SkillPackageError("Skill cache content changed")
|
|
241
|
+
actual = set()
|
|
242
|
+
for path in extract_dir.rglob("*"):
|
|
243
|
+
if path.is_symlink():
|
|
244
|
+
raise SkillPackageError("Skill cache contains a link")
|
|
245
|
+
actual.add(PurePosixPath(path.relative_to(extract_dir).as_posix()))
|
|
246
|
+
if actual != expected:
|
|
247
|
+
raise SkillPackageError("Skill cache file set changed")
|
|
100
248
|
|
|
101
249
|
def _find_skill_root(self, extract_dir: Path) -> Path:
|
|
102
250
|
if (extract_dir / "SKILL.md").exists():
|
ksadk/skills/runtime/agent.py
CHANGED
|
@@ -13,6 +13,7 @@ from ksadk.skills.models import SkillRef
|
|
|
13
13
|
from ksadk.skills.package_store import PackageStore
|
|
14
14
|
from ksadk.skills.runtime import loader as runtime_loader
|
|
15
15
|
from ksadk.skills.runtime import registry as runtime_registry
|
|
16
|
+
from ksadk.skills.runtime.artifact_delivery import export_artifacts
|
|
16
17
|
from ksadk.skills.runtime.base import normalize_skill_names
|
|
17
18
|
from ksadk.skills.runtime.executor import (
|
|
18
19
|
WorkflowExecution,
|
|
@@ -36,12 +37,18 @@ from ksadk.skills.runtime.executor import (
|
|
|
36
37
|
from ksadk.skills.runtime.executor import (
|
|
37
38
|
_tail as _executor_tail,
|
|
38
39
|
)
|
|
40
|
+
from ksadk.skills.runtime.pinned import (
|
|
41
|
+
PINNED_PACKAGE_PROTOCOL_VERSION as PINNED_PACKAGE_PROTOCOL_VERSION,
|
|
42
|
+
)
|
|
43
|
+
from ksadk.skills.runtime.pinned import load_pinned_packages
|
|
39
44
|
from ksadk.skills.runtime.request import (
|
|
40
45
|
SkillWorkflowRequest,
|
|
41
46
|
SkillWorkflowRequestError,
|
|
42
47
|
parse_workflow_request,
|
|
43
48
|
)
|
|
44
49
|
|
|
50
|
+
ARTIFACT_DELIVERY_PROTOCOL_VERSION = 1
|
|
51
|
+
|
|
45
52
|
|
|
46
53
|
def _skill_space_ids() -> list[str]:
|
|
47
54
|
return runtime_registry.skill_space_ids()
|
|
@@ -126,13 +133,31 @@ def run_agent(
|
|
|
126
133
|
return 1
|
|
127
134
|
|
|
128
135
|
prompt = request.workflow_prompt
|
|
129
|
-
selected_skill_names = request.skill_names
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
selected_skill_names = request.skill_names
|
|
137
|
+
if request.pinned_packages is not None:
|
|
138
|
+
if request.package_directory is None:
|
|
139
|
+
raise SkillWorkflowRequestError("Pinned Skill delivery directory is missing")
|
|
140
|
+
loaded_skills = load_pinned_packages(request.pinned_packages, request.package_directory)
|
|
141
|
+
else:
|
|
142
|
+
selected_skill_names = selected_skill_names or _selected_skill_names()
|
|
143
|
+
loaded_skills = _load_skills(
|
|
144
|
+
prompt=prompt,
|
|
145
|
+
skill_names=selected_skill_names,
|
|
146
|
+
service_transport=service_transport,
|
|
147
|
+
)
|
|
135
148
|
execution = _execute_workflow(prompt, loaded_skills, selected_skill_names=selected_skill_names)
|
|
149
|
+
if request.collect_artifacts and request.package_directory is not None:
|
|
150
|
+
try:
|
|
151
|
+
root = Path(os.environ.get("KSADK_SKILL_WORKDIR") or "/tmp/ksadk-skill-workflow")
|
|
152
|
+
receipt = export_artifacts(
|
|
153
|
+
execution.output_files, root, request.package_directory / "artifacts.zip"
|
|
154
|
+
)
|
|
155
|
+
execution.artifact_bundle = receipt.model_dump()
|
|
156
|
+
except Exception:
|
|
157
|
+
execution.status = "failed"
|
|
158
|
+
execution.error = "Skill artifact delivery failed"
|
|
159
|
+
execution.output_files = []
|
|
160
|
+
execution.artifacts = []
|
|
136
161
|
print(f"workflow={prompt}")
|
|
137
162
|
print(f"skill_spaces={','.join(_skill_space_ids())}")
|
|
138
163
|
print(f"loaded_skills={','.join(skill.name for skill in loaded_skills)}")
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Bounded, verified artifact delivery before a Skill sandbox is destroyed."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import io
|
|
7
|
+
import os
|
|
8
|
+
import shutil
|
|
9
|
+
import stat
|
|
10
|
+
import tempfile
|
|
11
|
+
import zipfile
|
|
12
|
+
from pathlib import Path, PurePosixPath
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
15
|
+
|
|
16
|
+
MAX_FILES = 100
|
|
17
|
+
MAX_FILE_BYTES = 20 * 1024 * 1024
|
|
18
|
+
MAX_TOTAL_BYTES = 100 * 1024 * 1024
|
|
19
|
+
MAX_BUNDLE_BYTES = MAX_TOTAL_BYTES + 1024 * 1024
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ArtifactDeliveryError(ValueError):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ArtifactBundle(BaseModel):
|
|
27
|
+
model_config = ConfigDict(extra="forbid", frozen=True, hide_input_in_errors=True)
|
|
28
|
+
|
|
29
|
+
sha256: str = Field(pattern=r"^[0-9a-f]{64}$", strict=True)
|
|
30
|
+
size: int = Field(ge=0, le=MAX_BUNDLE_BYTES, strict=True)
|
|
31
|
+
file_count: int = Field(ge=0, le=MAX_FILES, strict=True)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _name(raw: str) -> str:
|
|
35
|
+
path = PurePosixPath(raw)
|
|
36
|
+
if (
|
|
37
|
+
not raw
|
|
38
|
+
or len(raw) > 512
|
|
39
|
+
or path.is_absolute()
|
|
40
|
+
or ".." in path.parts
|
|
41
|
+
or "\\" in raw
|
|
42
|
+
or ":" in raw
|
|
43
|
+
or "\x00" in raw
|
|
44
|
+
or str(path) != raw
|
|
45
|
+
or raw == "."
|
|
46
|
+
):
|
|
47
|
+
raise ArtifactDeliveryError("Invalid artifact relative path")
|
|
48
|
+
return raw
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def export_artifacts(paths: list[str], root: Path, destination: Path) -> ArtifactBundle:
|
|
52
|
+
"""Only export regular files under the execution workspace, never symlinks."""
|
|
53
|
+
if len(paths) > MAX_FILES:
|
|
54
|
+
raise ArtifactDeliveryError("Too many artifacts")
|
|
55
|
+
root = root.resolve()
|
|
56
|
+
total = 0
|
|
57
|
+
names = set()
|
|
58
|
+
opened = zipfile.ZipFile(destination, "x", compression=zipfile.ZIP_STORED)
|
|
59
|
+
try:
|
|
60
|
+
with opened as archive:
|
|
61
|
+
for raw in paths:
|
|
62
|
+
path = Path(raw)
|
|
63
|
+
if not path.is_absolute():
|
|
64
|
+
path = root / path
|
|
65
|
+
try:
|
|
66
|
+
relative = path.relative_to(root)
|
|
67
|
+
name = _name(relative.as_posix())
|
|
68
|
+
except ValueError:
|
|
69
|
+
raise ArtifactDeliveryError(
|
|
70
|
+
"Artifact is outside the execution workspace"
|
|
71
|
+
) from None
|
|
72
|
+
if name in names:
|
|
73
|
+
raise ArtifactDeliveryError("Duplicate artifact path")
|
|
74
|
+
names.add(name)
|
|
75
|
+
current = root
|
|
76
|
+
for part in relative.parts:
|
|
77
|
+
current = current / part
|
|
78
|
+
if current.is_symlink():
|
|
79
|
+
raise ArtifactDeliveryError("Artifact links are not allowed")
|
|
80
|
+
descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
|
|
81
|
+
with os.fdopen(descriptor, "rb") as source:
|
|
82
|
+
info = os.fstat(source.fileno())
|
|
83
|
+
if not stat.S_ISREG(info.st_mode) or info.st_size > MAX_FILE_BYTES:
|
|
84
|
+
raise ArtifactDeliveryError("Artifact is not a bounded regular file")
|
|
85
|
+
content = source.read(MAX_FILE_BYTES + 1)
|
|
86
|
+
total += len(content)
|
|
87
|
+
if len(content) > MAX_FILE_BYTES or total > MAX_TOTAL_BYTES:
|
|
88
|
+
raise ArtifactDeliveryError("Artifact size limit exceeded")
|
|
89
|
+
archive.writestr(name, content)
|
|
90
|
+
os.chmod(destination, 0o600)
|
|
91
|
+
content = destination.read_bytes()
|
|
92
|
+
return ArtifactBundle(
|
|
93
|
+
sha256=hashlib.sha256(content).hexdigest(), size=len(content), file_count=len(names)
|
|
94
|
+
)
|
|
95
|
+
except Exception:
|
|
96
|
+
destination.unlink(missing_ok=True)
|
|
97
|
+
raise
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def import_artifacts(
|
|
101
|
+
content: bytes, receipt: ArtifactBundle, *, parent: Path | None = None
|
|
102
|
+
) -> list[str]:
|
|
103
|
+
"""Verify the full bundle before publishing any consumer-visible paths."""
|
|
104
|
+
if len(content) != receipt.size or hashlib.sha256(content).hexdigest() != receipt.sha256:
|
|
105
|
+
raise ArtifactDeliveryError("Artifact bundle integrity mismatch")
|
|
106
|
+
directory = Path(tempfile.mkdtemp(prefix="ksadk-skill-artifacts-", dir=parent))
|
|
107
|
+
try:
|
|
108
|
+
with zipfile.ZipFile(io.BytesIO(content)) as archive:
|
|
109
|
+
entries = archive.infolist()
|
|
110
|
+
if len(entries) != receipt.file_count:
|
|
111
|
+
raise ArtifactDeliveryError("Artifact file count mismatch")
|
|
112
|
+
total = 0
|
|
113
|
+
names = set()
|
|
114
|
+
outputs = []
|
|
115
|
+
for entry in entries:
|
|
116
|
+
name = _name(entry.filename)
|
|
117
|
+
mode = entry.external_attr >> 16
|
|
118
|
+
if name in names or entry.is_dir() or stat.S_IFMT(mode) not in {0, stat.S_IFREG}:
|
|
119
|
+
raise ArtifactDeliveryError("Artifact bundle contains invalid file entries")
|
|
120
|
+
names.add(name)
|
|
121
|
+
total += entry.file_size
|
|
122
|
+
if entry.file_size > MAX_FILE_BYTES or total > MAX_TOTAL_BYTES:
|
|
123
|
+
raise ArtifactDeliveryError("Artifact size limit exceeded")
|
|
124
|
+
with archive.open(entry) as source:
|
|
125
|
+
data = source.read(MAX_FILE_BYTES + 1)
|
|
126
|
+
if len(data) != entry.file_size or len(data) > MAX_FILE_BYTES:
|
|
127
|
+
raise ArtifactDeliveryError("Artifact size mismatch")
|
|
128
|
+
target = directory / name
|
|
129
|
+
target.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
130
|
+
with target.open("xb") as output:
|
|
131
|
+
os.chmod(target, 0o600)
|
|
132
|
+
output.write(data)
|
|
133
|
+
outputs.append(str(target))
|
|
134
|
+
if not outputs:
|
|
135
|
+
directory.rmdir()
|
|
136
|
+
return outputs
|
|
137
|
+
except Exception:
|
|
138
|
+
shutil.rmtree(directory)
|
|
139
|
+
raise
|
|
@@ -2,7 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
+
import secrets
|
|
6
|
+
import tempfile
|
|
5
7
|
import time
|
|
8
|
+
from pathlib import Path, PurePosixPath
|
|
6
9
|
from typing import Any
|
|
7
10
|
|
|
8
11
|
from ksadk.sandbox import (
|
|
@@ -12,6 +15,9 @@ from ksadk.sandbox import (
|
|
|
12
15
|
from ksadk.sandbox import (
|
|
13
16
|
SandboxInputFile as RuntimeSandboxInputFile,
|
|
14
17
|
)
|
|
18
|
+
from ksadk.sandbox.e2b_connection import ExplicitE2BConnection
|
|
19
|
+
from ksadk.skills.package_store import SkillPackage
|
|
20
|
+
from ksadk.skills.runtime.artifact_delivery import ArtifactBundle, import_artifacts
|
|
15
21
|
from ksadk.skills.runtime.base import (
|
|
16
22
|
SandboxInputFile,
|
|
17
23
|
SkillRuntimeError,
|
|
@@ -20,6 +26,7 @@ from ksadk.skills.runtime.base import (
|
|
|
20
26
|
normalize_skill_names,
|
|
21
27
|
parse_output_files,
|
|
22
28
|
)
|
|
29
|
+
from ksadk.skills.runtime.pinned import read_archive, stage_packages
|
|
23
30
|
|
|
24
31
|
|
|
25
32
|
def _bool_env(name: str, default: bool = True) -> bool:
|
|
@@ -48,6 +55,10 @@ def _redact(value: str) -> str:
|
|
|
48
55
|
|
|
49
56
|
|
|
50
57
|
class E2BSkillRuntimeBackend:
|
|
58
|
+
def preflight(self) -> None:
|
|
59
|
+
"""Read-only local dependency check; does not prove upstream authorization."""
|
|
60
|
+
self.sandbox_backend.check_available()
|
|
61
|
+
|
|
51
62
|
def __init__(
|
|
52
63
|
self,
|
|
53
64
|
*,
|
|
@@ -55,6 +66,8 @@ class E2BSkillRuntimeBackend:
|
|
|
55
66
|
template_id: str,
|
|
56
67
|
timeout: int = 900,
|
|
57
68
|
allow_internet_access: bool = True,
|
|
69
|
+
connection: ExplicitE2BConnection | None = None,
|
|
70
|
+
artifact_directory: Path | None = None,
|
|
58
71
|
):
|
|
59
72
|
if not template_id:
|
|
60
73
|
raise SkillRuntimeError(
|
|
@@ -64,6 +77,7 @@ class E2BSkillRuntimeBackend:
|
|
|
64
77
|
self.template_id = template_id
|
|
65
78
|
self.timeout = timeout
|
|
66
79
|
self.allow_internet_access = allow_internet_access
|
|
80
|
+
self.artifact_directory = artifact_directory
|
|
67
81
|
self.sandbox_backend = E2BSandboxBackend(
|
|
68
82
|
spec=SandboxSpec(
|
|
69
83
|
template_id=template_id,
|
|
@@ -72,6 +86,7 @@ class E2BSkillRuntimeBackend:
|
|
|
72
86
|
metadata={"component": "skill-runtime"},
|
|
73
87
|
),
|
|
74
88
|
sandbox_cls=sandbox_cls,
|
|
89
|
+
connection=connection,
|
|
75
90
|
)
|
|
76
91
|
|
|
77
92
|
@classmethod
|
|
@@ -109,17 +124,31 @@ class E2BSkillRuntimeBackend:
|
|
|
109
124
|
skill_names: list[str] | None = None,
|
|
110
125
|
env: dict[str, str] | None = None,
|
|
111
126
|
input_files: list[SandboxInputFile] | None = None,
|
|
127
|
+
pinned_packages: list[SkillPackage] | None = None,
|
|
112
128
|
timeout: int = 900,
|
|
113
129
|
) -> SkillRuntimeResult:
|
|
114
130
|
session = None
|
|
115
131
|
started = time.monotonic()
|
|
116
132
|
effective_timeout = timeout or self.timeout
|
|
117
133
|
try:
|
|
134
|
+
if pinned_packages is not None:
|
|
135
|
+
for item in input_files or []:
|
|
136
|
+
target = PurePosixPath(item.target_path)
|
|
137
|
+
if (
|
|
138
|
+
not target.is_relative_to("/workspace/inputs")
|
|
139
|
+
or ".." in target.parts
|
|
140
|
+
or "\\" in item.target_path
|
|
141
|
+
):
|
|
142
|
+
raise SkillRuntimeError(
|
|
143
|
+
"Pinned Skill inputs must be under /workspace/inputs"
|
|
144
|
+
)
|
|
118
145
|
sandbox_env = {
|
|
119
146
|
"KSADK_SKILL_SPACE_IDS": ",".join(skill_space_ids),
|
|
120
147
|
"SKILL_SPACE_ID": skill_space_ids[0] if skill_space_ids else "",
|
|
121
148
|
}
|
|
122
|
-
if
|
|
149
|
+
if pinned_packages is None and (
|
|
150
|
+
public_spaces := os.environ.get("KSADK_PUBLIC_SKILL_SPACE_IDS")
|
|
151
|
+
):
|
|
123
152
|
sandbox_env["KSADK_PUBLIC_SKILL_SPACE_IDS"] = public_spaces
|
|
124
153
|
selected_skill_names = format_skill_names_env(skill_names)
|
|
125
154
|
if selected_skill_names:
|
|
@@ -135,26 +164,89 @@ class E2BSkillRuntimeBackend:
|
|
|
135
164
|
)
|
|
136
165
|
|
|
137
166
|
request_path = "/tmp/ksadk-workflow-request.json"
|
|
167
|
+
request = {
|
|
168
|
+
"workflow_prompt": workflow_prompt,
|
|
169
|
+
"skill_names": normalize_skill_names(skill_names),
|
|
170
|
+
}
|
|
171
|
+
if pinned_packages is not None:
|
|
172
|
+
probe = session.run_command(
|
|
173
|
+
"python -I -c 'from ksadk.skills.runtime.agent import "
|
|
174
|
+
"PINNED_PACKAGE_PROTOCOL_VERSION, ARTIFACT_DELIVERY_PROTOCOL_VERSION; "
|
|
175
|
+
'print(f"{PINNED_PACKAGE_PROTOCOL_VERSION}:{ARTIFACT_DELIVERY_PROTOCOL_VERSION}")\'',
|
|
176
|
+
timeout=min(effective_timeout, 10),
|
|
177
|
+
env=sandbox_env,
|
|
178
|
+
)
|
|
179
|
+
if probe.exit_code != 0 or probe.stdout.strip() != "1:1":
|
|
180
|
+
raise SkillRuntimeError(
|
|
181
|
+
"Sandbox runtime does not support pinned Skill protocol v1"
|
|
182
|
+
)
|
|
183
|
+
delivery = "/tmp/ksadk-pinned-" + secrets.token_hex(16)
|
|
184
|
+
prepared = session.run_command(
|
|
185
|
+
f"mkdir -m 700 {delivery}", timeout=min(effective_timeout, 10), env=sandbox_env
|
|
186
|
+
)
|
|
187
|
+
if prepared.exit_code != 0:
|
|
188
|
+
raise SkillRuntimeError("Could not prepare pinned Skill delivery directory")
|
|
189
|
+
with tempfile.TemporaryDirectory(prefix="ksadk-skill-transfer-") as directory:
|
|
190
|
+
entries = stage_packages(pinned_packages, Path(directory))
|
|
191
|
+
for entry in entries:
|
|
192
|
+
session.write_file(
|
|
193
|
+
f"{delivery}/{entry.archive_name}",
|
|
194
|
+
read_archive(Path(directory) / entry.archive_name),
|
|
195
|
+
)
|
|
196
|
+
request["pinned_packages"] = [entry.model_dump() for entry in entries]
|
|
197
|
+
request["pinned_protocol_version"] = 1
|
|
198
|
+
request["collect_artifacts"] = True
|
|
199
|
+
sandbox_env["KSADK_SKILL_WORKDIR"] = f"{delivery}/work"
|
|
200
|
+
request_path = f"{delivery}/workflow-request.json"
|
|
138
201
|
session.write_file(
|
|
139
202
|
request_path,
|
|
140
203
|
json.dumps(
|
|
141
|
-
|
|
142
|
-
"workflow_prompt": workflow_prompt,
|
|
143
|
-
"skill_names": normalize_skill_names(skill_names),
|
|
144
|
-
},
|
|
204
|
+
request,
|
|
145
205
|
ensure_ascii=False,
|
|
146
206
|
).encode("utf-8"),
|
|
147
207
|
)
|
|
148
208
|
command = f"python -u /home/ksadk/agent.py --request-file {request_path}"
|
|
209
|
+
if pinned_packages is not None:
|
|
210
|
+
command = (
|
|
211
|
+
f"python -I -u -m ksadk.skills.runtime.agent --request-file {request_path}"
|
|
212
|
+
)
|
|
149
213
|
result = session.run_command(command, timeout=effective_timeout, env=sandbox_env)
|
|
150
214
|
stdout = result.stdout
|
|
215
|
+
output_files = parse_output_files(stdout)
|
|
216
|
+
if pinned_packages is not None:
|
|
217
|
+
payloads = [
|
|
218
|
+
json.loads(line.split("=", 1)[1])
|
|
219
|
+
for line in stdout.splitlines()
|
|
220
|
+
if line.startswith("workflow_result=")
|
|
221
|
+
]
|
|
222
|
+
if len(payloads) != 1 or not isinstance(payloads[0], dict):
|
|
223
|
+
raise SkillRuntimeError("Sandbox did not return a unique workflow result")
|
|
224
|
+
payload = payloads[0]
|
|
225
|
+
if payload.get("artifact_bundle") is None:
|
|
226
|
+
raise SkillRuntimeError("Sandbox did not return an artifact delivery receipt")
|
|
227
|
+
receipt = ArtifactBundle.model_validate(payload["artifact_bundle"])
|
|
228
|
+
content = session.read_file_bytes(
|
|
229
|
+
f"{delivery}/artifacts.zip", max_bytes=receipt.size
|
|
230
|
+
)
|
|
231
|
+
output_files = import_artifacts(content, receipt, parent=self.artifact_directory)
|
|
232
|
+
payload["output_files"] = output_files
|
|
233
|
+
payload["artifacts"] = output_files
|
|
234
|
+
stdout = (
|
|
235
|
+
"\n".join(
|
|
236
|
+
"workflow_result=" + json.dumps(payload, ensure_ascii=False, sort_keys=True)
|
|
237
|
+
if line.startswith("workflow_result=")
|
|
238
|
+
else line
|
|
239
|
+
for line in stdout.splitlines()
|
|
240
|
+
)
|
|
241
|
+
+ "\n"
|
|
242
|
+
)
|
|
151
243
|
return SkillRuntimeResult(
|
|
152
244
|
runtime_id=session.sandbox_id,
|
|
153
245
|
exit_code=result.exit_code,
|
|
154
246
|
stdout=stdout,
|
|
155
247
|
stderr=result.stderr,
|
|
156
248
|
duration_ms=int((time.monotonic() - started) * 1000),
|
|
157
|
-
output_files=
|
|
249
|
+
output_files=output_files,
|
|
158
250
|
)
|
|
159
251
|
except Exception as exc:
|
|
160
252
|
error_type = type(exc).__name__
|