agentengine-sdk-python 0.8.3__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.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
- ksadk/_build_provenance.json +1 -1
- ksadk/api/client.py +105 -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 +1 -0
- ksadk/cli/__init__.py +32 -3
- ksadk/cli/cmd_managed_runtime.py +13 -1
- ksadk/cli/cmd_plugin.py +6 -1
- 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 +56 -298
- ksadk/common/auth.py +16 -10
- ksadk/configs/env_registry.py +29 -1
- ksadk/conversations/message_projection.py +135 -14
- ksadk/conversations/projector.py +4 -6
- 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/adapters/_codex_validators.py +18 -7
- ksadk/events/adapters/langgraph.py +15 -1
- ksadk/events/canonical_store.py +3 -1
- ksadk/events/projections.py +1 -1
- ksadk/harness/config.py +2 -2
- ksadk/harness/runtime.py +27 -27
- 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/ingress.py +15 -2
- ksadk/kernel/sqlite_store.py +27 -0
- ksadk/kernel/store.py +3 -0
- ksadk/kernel/worker.py +65 -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/model_proxy/server.py +10 -5
- ksadk/plugins/__init__.py +4 -0
- ksadk/plugins/artifacts.py +275 -0
- ksadk/plugins/bridges/__init__.py +4 -2
- ksadk/plugins/bridges/codex.py +120 -13
- ksadk/plugins/bridges/dsh.py +340 -156
- ksadk/plugins/builtins.py +35 -36
- ksadk/plugins/bundle_security.py +28 -4
- ksadk/plugins/codex_manifest.py +983 -0
- ksadk/plugins/composition.py +8 -0
- ksadk/plugins/contracts.py +118 -0
- ksadk/plugins/delivery.py +153 -0
- ksadk/plugins/dsh_installation_digest.py +71 -0
- ksadk/plugins/dsh_toolchain.py +110 -21
- ksadk/plugins/ecosystem_probe.py +6 -6
- ksadk/plugins/host.py +102 -39
- ksadk/plugins/kernel_adapter.py +205 -0
- ksadk/plugins/providers/__init__.py +23 -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-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/codex.py +335 -69
- ksadk/plugins/providers/codex_native.py +368 -0
- ksadk/plugins/providers/codex_turn.py +301 -0
- ksadk/plugins/providers/dsh_capabilities.py +1389 -0
- ksadk/plugins/providers/dsh_mcp.py +467 -0
- ksadk/plugins/providers/harness.py +118 -113
- ksadk/plugins/providers/mcp_projection.py +150 -0
- ksadk/plugins/providers/platform_resources.py +657 -0
- ksadk/plugins/resolver.py +8 -1
- 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 +142 -18
- ksadk/runtime/adapter.py +2 -0
- ksadk/runtime/conversation_execution.py +92 -16
- ksadk/runtime/executor.py +78 -2
- ksadk/runtime/factory.py +29 -273
- ksadk/runtime/framework_adapters.py +23 -0
- ksadk/runtime/preprocessing.py +10 -2
- ksadk/runtime/runner_adapter.py +73 -14
- ksadk/runtime_context.py +40 -2
- 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/scheduler/sqlite_store.py +18 -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-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
- ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
- ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
- ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
- ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
- ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
- ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
- ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
- ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
- ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.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-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
- ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
- ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
- ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
- ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
- ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
- ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
- ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
- ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.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-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
- ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
- ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
- ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
- ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
- ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
- ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
- ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
- ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
- ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
- ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
- ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
- ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
- ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
- ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
- ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
- ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
- ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
- ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
- ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
- ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
- ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
- ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
- ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
- ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
- ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
- ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
- ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
- ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
- ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
- ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
- ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
- ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.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-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
- ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.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-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
- ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
- ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
- ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
- ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
- ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
- ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
- ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.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-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
- ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
- ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
- ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.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-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
- ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
- ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
- ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
- ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
- ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
- ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.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-8mfKcxvG.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-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
- ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
- ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.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 +167 -28
- ksadk/studio/api.py +224 -42
- ksadk/studio/api_catalog_routes.py +18 -0
- ksadk/studio/api_plugin_routes.py +526 -95
- ksadk/studio/api_resource_connections.py +183 -0
- ksadk/studio/authoring_coordinator.py +19 -14
- ksadk/studio/builder.py +76 -0
- ksadk/studio/cloud.py +342 -104
- ksadk/studio/cloud_shared_web.py +565 -0
- ksadk/studio/codex_agent_service.py +128 -26
- ksadk/studio/codex_builder.py +241 -2
- ksadk/studio/codex_credentials.py +90 -0
- ksadk/studio/codex_manifest.py +31 -4
- ksadk/studio/codex_plugin_store.py +746 -0
- ksadk/studio/codex_provider_build.py +231 -0
- ksadk/studio/codex_run.py +184 -25
- ksadk/studio/compatibility_report.py +12 -1
- ksadk/studio/compiler.py +78 -14
- ksadk/studio/contracts.py +132 -6
- 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 +320 -13
- ksadk/studio/hosted_kernel.py +88 -13
- ksadk/studio/mcp_runtime.py +11 -3
- ksadk/studio/model_client.py +2 -2
- ksadk/studio/plugin_composition.py +190 -23
- ksadk/studio/plugin_kernel_adapter.py +12 -112
- ksadk/studio/plugin_runtime.py +224 -45
- 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 +143 -2
- ksadk/studio/resource_connections.py +220 -0
- ksadk/studio/run_service.py +462 -52
- ksadk/studio/runtime_source.py +15 -7
- ksadk/studio/scheduler_assistant.py +317 -0
- ksadk/studio/scheduler_runtime.py +9 -0
- ksadk/studio/scheduler_service.py +3 -0
- ksadk/studio/service.py +490 -44
- ksadk/studio/shared_web.py +446 -62
- 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/version.py +1 -1
- ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
- ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
- ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
- ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
- ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
- ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
- ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
- ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
- ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
- ksadk/server/static/assets/index-B2k_urY8.js +0 -241
- ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
- ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
- ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
- ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
- ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
- ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
- ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
- ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
- ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
- ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
- ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
- ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
- ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
- ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
- ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
- ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
- ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
- {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
ksadk/plugins/composition.py
CHANGED
|
@@ -102,6 +102,7 @@ class CompositionPolicy:
|
|
|
102
102
|
context_contributors: Mapping[str, PluginCapabilitySelection] = field(
|
|
103
103
|
default_factory=dict
|
|
104
104
|
)
|
|
105
|
+
host_capabilities: tuple[PluginCapabilitySelection, ...] = ()
|
|
105
106
|
renderers: tuple[PluginCapabilitySelection, ...] = ()
|
|
106
107
|
default_runtime: str = "codex"
|
|
107
108
|
|
|
@@ -185,6 +186,13 @@ class CompositionCompiler:
|
|
|
185
186
|
field="policy.sessionStore",
|
|
186
187
|
)
|
|
187
188
|
|
|
189
|
+
for selection in self._policy.host_capabilities:
|
|
190
|
+
self._append_selection(
|
|
191
|
+
capabilities,
|
|
192
|
+
selection,
|
|
193
|
+
field="policy.hostCapabilities",
|
|
194
|
+
)
|
|
195
|
+
|
|
188
196
|
if revision.spec.memory.enabled:
|
|
189
197
|
memory = self._policy.memory_providers.get(revision.spec.memory.provider_ref)
|
|
190
198
|
if memory is None:
|
ksadk/plugins/contracts.py
CHANGED
|
@@ -5,13 +5,16 @@ Only the models exported through ``__all__`` are public Phase 2 contracts.
|
|
|
5
5
|
they project DSH/Codex host inventory into the Python composition engine and
|
|
6
6
|
are not a third installable package format or a stable public contract.
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
from __future__ import annotations
|
|
9
10
|
|
|
10
11
|
import hashlib
|
|
11
12
|
import json
|
|
12
13
|
import re
|
|
13
14
|
from collections.abc import Mapping
|
|
15
|
+
from pathlib import PurePosixPath
|
|
14
16
|
from typing import Any, Literal
|
|
17
|
+
from urllib.parse import urlsplit
|
|
15
18
|
|
|
16
19
|
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
17
20
|
|
|
@@ -98,6 +101,77 @@ class CapabilityOffer(PluginContractModel):
|
|
|
98
101
|
return value
|
|
99
102
|
|
|
100
103
|
|
|
104
|
+
class PluginSourceSnapshot(PluginContractModel):
|
|
105
|
+
"""Credential-free upstream identity retained in an immutable plugin lock.
|
|
106
|
+
|
|
107
|
+
Lifecycle hosts (Codex App Server or DSH) remain responsible for resolving
|
|
108
|
+
and installing packages. This record only captures the exact source that
|
|
109
|
+
was admitted so a later build cannot silently follow a mutable marketplace,
|
|
110
|
+
Git branch, npm tag, or local directory.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
ecosystem: Literal["ksadk", "codex", "dsh"]
|
|
114
|
+
type: Literal["builtin", "registry", "local", "git", "npm", "market", "runtime-native"]
|
|
115
|
+
requested: str = Field(min_length=1, max_length=2048)
|
|
116
|
+
resolved: str = Field(min_length=1, max_length=2048)
|
|
117
|
+
integrity: str | None = Field(default=None, max_length=512)
|
|
118
|
+
marketplace: str | None = Field(default=None, max_length=256)
|
|
119
|
+
registry: str | None = Field(default=None, max_length=2048)
|
|
120
|
+
|
|
121
|
+
@field_validator("requested", "resolved", "integrity", "marketplace", "registry")
|
|
122
|
+
@classmethod
|
|
123
|
+
def validate_public_coordinate(cls, value: str | None) -> str | None:
|
|
124
|
+
if value is None:
|
|
125
|
+
return None
|
|
126
|
+
if value != value.strip() or any(ord(character) < 32 for character in value):
|
|
127
|
+
raise ValueError("plugin source coordinates must be trimmed printable text")
|
|
128
|
+
# Build artifacts and inventories are routinely shared. A source URL
|
|
129
|
+
# therefore cannot retain embedded credentials, query tokens, or URL
|
|
130
|
+
# fragments. Authentication remains a host-owned credential concern.
|
|
131
|
+
if "://" in value:
|
|
132
|
+
parsed = urlsplit(value)
|
|
133
|
+
if parsed.username or parsed.password or parsed.query or parsed.fragment:
|
|
134
|
+
raise ValueError("plugin source coordinates must not contain credentials")
|
|
135
|
+
return value
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class LockedPluginComponent(PluginContractModel):
|
|
139
|
+
"""One selected native component and the bytes admitted for a build."""
|
|
140
|
+
|
|
141
|
+
id: str = Field(min_length=1, max_length=256)
|
|
142
|
+
kind: Literal["skill", "mcp", "hook", "app", "client"]
|
|
143
|
+
digest: str
|
|
144
|
+
path: str | None = Field(default=None, max_length=512)
|
|
145
|
+
|
|
146
|
+
@field_validator("id")
|
|
147
|
+
@classmethod
|
|
148
|
+
def validate_component_id(cls, value: str) -> str:
|
|
149
|
+
if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._:/-]*", value):
|
|
150
|
+
raise ValueError("plugin component id is invalid")
|
|
151
|
+
return value
|
|
152
|
+
|
|
153
|
+
@field_validator("digest")
|
|
154
|
+
@classmethod
|
|
155
|
+
def validate_component_digest(cls, value: str) -> str:
|
|
156
|
+
return _validate_digest(value)
|
|
157
|
+
|
|
158
|
+
@field_validator("path")
|
|
159
|
+
@classmethod
|
|
160
|
+
def validate_component_path(cls, value: str | None) -> str | None:
|
|
161
|
+
if value is None:
|
|
162
|
+
return None
|
|
163
|
+
if "\\" in value:
|
|
164
|
+
raise ValueError("plugin component paths must use POSIX separators")
|
|
165
|
+
path = PurePosixPath(value)
|
|
166
|
+
if (
|
|
167
|
+
path.is_absolute()
|
|
168
|
+
or not path.parts
|
|
169
|
+
or any(part in {"", ".", ".."} for part in path.parts)
|
|
170
|
+
):
|
|
171
|
+
raise ValueError("plugin component path must stay relative to the plugin root")
|
|
172
|
+
return value
|
|
173
|
+
|
|
174
|
+
|
|
101
175
|
class CapabilityRequirement(PluginContractModel):
|
|
102
176
|
definition: str
|
|
103
177
|
version: str = Field(min_length=1, max_length=128)
|
|
@@ -122,12 +196,26 @@ class PluginProvenance(PluginContractModel):
|
|
|
122
196
|
digest: str
|
|
123
197
|
signature_ref: str | None = Field(default=None, max_length=512)
|
|
124
198
|
license: str | None = Field(default=None, max_length=128)
|
|
199
|
+
upstream: PluginSourceSnapshot | None = None
|
|
200
|
+
components: tuple[LockedPluginComponent, ...] | None = None
|
|
125
201
|
|
|
126
202
|
@field_validator("digest")
|
|
127
203
|
@classmethod
|
|
128
204
|
def validate_digest(cls, value: str) -> str:
|
|
129
205
|
return _validate_digest(value)
|
|
130
206
|
|
|
207
|
+
@field_validator("components")
|
|
208
|
+
@classmethod
|
|
209
|
+
def validate_components(
|
|
210
|
+
cls, value: tuple[LockedPluginComponent, ...] | None
|
|
211
|
+
) -> tuple[LockedPluginComponent, ...] | None:
|
|
212
|
+
if value is None:
|
|
213
|
+
return None
|
|
214
|
+
identities = [(item.kind, item.id) for item in value]
|
|
215
|
+
if len(identities) != len(set(identities)):
|
|
216
|
+
raise ValueError("plugin components must have unique kind/id identities")
|
|
217
|
+
return tuple(sorted(value, key=lambda item: (item.kind, item.id, item.digest)))
|
|
218
|
+
|
|
131
219
|
|
|
132
220
|
class PluginSpec(PluginContractModel):
|
|
133
221
|
domain: Literal["ksadk-platform", "runtime-native"]
|
|
@@ -303,6 +391,8 @@ class PluginLockEntry(PluginContractModel):
|
|
|
303
391
|
license: str | None = Field(default=None, max_length=128)
|
|
304
392
|
provides: list[LockedCapability] = Field(default_factory=list)
|
|
305
393
|
dependencies: list[PluginDependency] = Field(default_factory=list)
|
|
394
|
+
upstream: PluginSourceSnapshot | None = None
|
|
395
|
+
components: tuple[LockedPluginComponent, ...] | None = None
|
|
306
396
|
|
|
307
397
|
@field_validator("id")
|
|
308
398
|
@classmethod
|
|
@@ -321,6 +411,32 @@ class PluginLockEntry(PluginContractModel):
|
|
|
321
411
|
def validate_digest(cls, value: str) -> str:
|
|
322
412
|
return _validate_digest(value)
|
|
323
413
|
|
|
414
|
+
@field_validator("components")
|
|
415
|
+
@classmethod
|
|
416
|
+
def validate_components(
|
|
417
|
+
cls, value: tuple[LockedPluginComponent, ...] | None
|
|
418
|
+
) -> tuple[LockedPluginComponent, ...] | None:
|
|
419
|
+
if value is None:
|
|
420
|
+
return None
|
|
421
|
+
identities = [(item.kind, item.id) for item in value]
|
|
422
|
+
if len(identities) != len(set(identities)):
|
|
423
|
+
raise ValueError("plugin lock components must have unique kind/id identities")
|
|
424
|
+
return tuple(sorted(value, key=lambda item: (item.kind, item.id, item.digest)))
|
|
425
|
+
|
|
426
|
+
@model_validator(mode="after")
|
|
427
|
+
def validate_external_snapshot(self) -> "PluginLockEntry":
|
|
428
|
+
if self.upstream is not None:
|
|
429
|
+
compatible_sources = {
|
|
430
|
+
"builtin": {"builtin"},
|
|
431
|
+
"registry": {"registry", "npm"},
|
|
432
|
+
"local": {"local", "git", "npm"},
|
|
433
|
+
"market": {"market", "local", "git", "npm"},
|
|
434
|
+
"runtime-native": {"runtime-native"},
|
|
435
|
+
}
|
|
436
|
+
if self.upstream.type not in compatible_sources[self.source]:
|
|
437
|
+
raise ValueError("plugin lock source and upstream source type are inconsistent")
|
|
438
|
+
return self
|
|
439
|
+
|
|
324
440
|
|
|
325
441
|
class PluginLock(PluginContractModel):
|
|
326
442
|
"""The current Bundle v2 lock shape, now with an exact typed entry form."""
|
|
@@ -442,10 +558,12 @@ def plugin_lock_digest(lock: PluginLock) -> str:
|
|
|
442
558
|
__all__ = [
|
|
443
559
|
"CapabilityDefinition",
|
|
444
560
|
"CompositionProfile",
|
|
561
|
+
"LockedPluginComponent",
|
|
445
562
|
"PluginLock",
|
|
446
563
|
"PluginLockEntry",
|
|
447
564
|
"PluginInventory",
|
|
448
565
|
"PluginInventoryItem",
|
|
566
|
+
"PluginSourceSnapshot",
|
|
449
567
|
"canonical_plugin_lock",
|
|
450
568
|
"plugin_lock_digest",
|
|
451
569
|
]
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""Cloud restoration of one frozen Codex marketplace before serving traffic.
|
|
2
|
+
|
|
3
|
+
The control plane admits immutable artifact references. The platform init
|
|
4
|
+
container downloads and extracts the selected archive from internal KS3; the
|
|
5
|
+
runtime verifies that materialized tree before it becomes visible to Codex.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import errno
|
|
11
|
+
import hashlib
|
|
12
|
+
import json
|
|
13
|
+
import os
|
|
14
|
+
import tempfile
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any, Literal
|
|
17
|
+
|
|
18
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
19
|
+
|
|
20
|
+
from ksadk.builders.managed_runtime_builder import serialize_managed_runtime_manifest
|
|
21
|
+
from ksadk.codex.client import CodexPluginBootstrap
|
|
22
|
+
from ksadk.plugins.artifacts import (
|
|
23
|
+
PluginArtifactReceipt,
|
|
24
|
+
restore_materialized_plugin_artifact,
|
|
25
|
+
restore_plugin_artifact,
|
|
26
|
+
)
|
|
27
|
+
from ksadk.resource_runtime.managed_projection import native_codex_plugin_bindings
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class PluginDelivery(BaseModel):
|
|
31
|
+
model_config = ConfigDict(extra="forbid")
|
|
32
|
+
schema_version: Literal["ksadk.plugin-delivery/v1"] = "ksadk.plugin-delivery/v1"
|
|
33
|
+
artifact_id: str | None = Field(default=None, pattern=r"^[0-9a-f-]{36}$")
|
|
34
|
+
artifact_path: str = Field(pattern=r"^ks3://[a-z0-9][a-z0-9.-]*/[^\s]+\.zip$")
|
|
35
|
+
storage_region: str = Field(min_length=1, max_length=100)
|
|
36
|
+
receipt: PluginArtifactReceipt
|
|
37
|
+
build_id: str = Field(pattern=r"^build_[0-9a-f]{8,64}$")
|
|
38
|
+
manifest_sha256: str = Field(pattern=r"^[0-9a-f]{64}$")
|
|
39
|
+
marketplace_name: str = Field(min_length=1, max_length=256)
|
|
40
|
+
plugin_names: list[str] = Field(min_length=1, max_length=128)
|
|
41
|
+
snapshot_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$")
|
|
42
|
+
bindings: list[dict[str, Any]] = Field(min_length=1, max_length=128)
|
|
43
|
+
|
|
44
|
+
def validate_manifest(self, manifest: dict[str, Any]) -> None:
|
|
45
|
+
digest = hashlib.sha256(serialize_managed_runtime_manifest(manifest)).hexdigest()
|
|
46
|
+
if digest != self.manifest_sha256:
|
|
47
|
+
raise ValueError("Plugin delivery belongs to a different manifest")
|
|
48
|
+
runtime = manifest.get("runtime") or {}
|
|
49
|
+
if runtime.get("name") != "codex" or runtime.get("version") != self.receipt.runtime_version:
|
|
50
|
+
raise ValueError("Plugin delivery runtime does not match the manifest")
|
|
51
|
+
bindings = native_codex_plugin_bindings(manifest)
|
|
52
|
+
if self.bindings != bindings:
|
|
53
|
+
raise ValueError("Plugin delivery does not match the selected components")
|
|
54
|
+
|
|
55
|
+
def bootstrap(self, path: Path) -> CodexPluginBootstrap:
|
|
56
|
+
return CodexPluginBootstrap(
|
|
57
|
+
marketplace_path=str(path.resolve()),
|
|
58
|
+
marketplace_name=self.marketplace_name,
|
|
59
|
+
plugin_names=tuple(self.plugin_names),
|
|
60
|
+
snapshot_digest=self.snapshot_digest,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def restore_delivery(delivery: PluginDelivery, archive: Path, work_dir: Path) -> dict[str, Any]:
|
|
65
|
+
"""Restore into a content-addressed directory; recheck cached bytes on restart."""
|
|
66
|
+
if (
|
|
67
|
+
archive.stat().st_size != delivery.receipt.size_bytes
|
|
68
|
+
or "sha256:" + hashlib.sha256(archive.read_bytes()).hexdigest()
|
|
69
|
+
!= delivery.receipt.artifact_digest
|
|
70
|
+
):
|
|
71
|
+
raise ValueError("Downloaded plugin artifact does not match its receipt")
|
|
72
|
+
target = work_dir / ".agentkit" / "cloud-plugins" / delivery.receipt.artifact_digest[7:]
|
|
73
|
+
bootstrap = delivery.bootstrap(target)
|
|
74
|
+
if not target.exists():
|
|
75
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
with tempfile.TemporaryDirectory(prefix=".plugin-publish-", dir=target.parent) as tmp:
|
|
77
|
+
staged = Path(tmp) / "marketplace"
|
|
78
|
+
restore_plugin_artifact(archive, delivery.receipt, staged)
|
|
79
|
+
try:
|
|
80
|
+
os.rename(staged, target)
|
|
81
|
+
except OSError as exc:
|
|
82
|
+
# Concurrent workers can publish the same immutable tree. Only
|
|
83
|
+
# an existing destination is recoverable; verify its bytes below.
|
|
84
|
+
if exc.errno not in {errno.EEXIST, errno.ENOTEMPTY} or not target.is_dir():
|
|
85
|
+
raise
|
|
86
|
+
bootstrap.verify()
|
|
87
|
+
return {
|
|
88
|
+
"codex_home_key": delivery.build_id,
|
|
89
|
+
"codex_plugin_bootstrap": {
|
|
90
|
+
"marketplace_path": str(target.resolve()),
|
|
91
|
+
"marketplace_name": delivery.marketplace_name,
|
|
92
|
+
"plugin_names": delivery.plugin_names,
|
|
93
|
+
"snapshot_digest": delivery.snapshot_digest,
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def restore_materialized_delivery(
|
|
99
|
+
delivery: PluginDelivery, source: Path, work_dir: Path
|
|
100
|
+
) -> dict[str, Any]:
|
|
101
|
+
"""Install a platform-downloaded tree into the workload-scoped cache."""
|
|
102
|
+
target = work_dir / ".agentkit" / "cloud-plugins" / delivery.receipt.artifact_digest[7:]
|
|
103
|
+
bootstrap = delivery.bootstrap(target)
|
|
104
|
+
if not target.exists():
|
|
105
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
106
|
+
with tempfile.TemporaryDirectory(prefix=".plugin-publish-", dir=target.parent) as tmp:
|
|
107
|
+
staged = Path(tmp) / "marketplace"
|
|
108
|
+
restore_materialized_plugin_artifact(source, delivery.receipt, staged)
|
|
109
|
+
try:
|
|
110
|
+
os.rename(staged, target)
|
|
111
|
+
except OSError as exc:
|
|
112
|
+
if exc.errno not in {errno.EEXIST, errno.ENOTEMPTY} or not target.is_dir():
|
|
113
|
+
raise
|
|
114
|
+
bootstrap.verify()
|
|
115
|
+
return {
|
|
116
|
+
"codex_home_key": delivery.build_id,
|
|
117
|
+
"codex_plugin_bootstrap": {
|
|
118
|
+
"marketplace_path": str(target.resolve()),
|
|
119
|
+
"marketplace_name": delivery.marketplace_name,
|
|
120
|
+
"plugin_names": delivery.plugin_names,
|
|
121
|
+
"snapshot_digest": delivery.snapshot_digest,
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def prepare_cloud_plugins(manifest: dict[str, Any], work_dir: Path) -> dict[str, Any]:
|
|
127
|
+
"""Verify and activate the init-container-materialized plugin artifact."""
|
|
128
|
+
bindings = native_codex_plugin_bindings(manifest)
|
|
129
|
+
if not bindings:
|
|
130
|
+
return {}
|
|
131
|
+
raw = os.environ.get("AGENTENGINE_PLUGIN_DELIVERY", "")
|
|
132
|
+
if not raw:
|
|
133
|
+
raise ValueError("Native plugins require an admitted cloud delivery reference")
|
|
134
|
+
delivery = PluginDelivery.model_validate_json(raw)
|
|
135
|
+
delivery.validate_manifest(manifest)
|
|
136
|
+
source_value = os.environ.get("AGENTENGINE_PLUGIN_ARTIFACT_DIR", "").strip()
|
|
137
|
+
if not source_value:
|
|
138
|
+
raise ValueError("Native plugins require a materialized cloud artifact")
|
|
139
|
+
source = Path(source_value)
|
|
140
|
+
work_dir.mkdir(parents=True, exist_ok=True)
|
|
141
|
+
config = restore_materialized_delivery(delivery, source, work_dir)
|
|
142
|
+
# Only non-secret, verified launch data is persisted. Recreated each startup.
|
|
143
|
+
path = work_dir / ".agentkit" / "cloud-plugin-launch.json"
|
|
144
|
+
with tempfile.NamedTemporaryFile(
|
|
145
|
+
mode="w", dir=path.parent, prefix=".plugin-launch-", delete=False
|
|
146
|
+
) as stream:
|
|
147
|
+
temp = Path(stream.name)
|
|
148
|
+
json.dump({"manifest_sha256": delivery.manifest_sha256, "config": config}, stream)
|
|
149
|
+
try:
|
|
150
|
+
os.replace(temp, path)
|
|
151
|
+
finally:
|
|
152
|
+
temp.unlink(missing_ok=True)
|
|
153
|
+
return config
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""Fingerprint the installed DSH dependency tree without importing plugin code."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import os
|
|
7
|
+
import stat
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DshInstallationDigestError(ValueError):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def installation_digest(
|
|
16
|
+
root: Path, *, max_files: int = 100000, max_bytes: int = 512 * 1024 * 1024
|
|
17
|
+
) -> str:
|
|
18
|
+
"""Include installed bytes, execute bits and in-tree link targets.
|
|
19
|
+
|
|
20
|
+
External links cannot establish a closed Build input and are rejected. The
|
|
21
|
+
caller holds the profile lifecycle lock; this is not same-user OS isolation.
|
|
22
|
+
"""
|
|
23
|
+
if type(max_files) is not int or type(max_bytes) is not int or min(max_files, max_bytes) < 1:
|
|
24
|
+
raise DshInstallationDigestError("DSH digest limits must be positive integers")
|
|
25
|
+
if root.is_symlink() or not root.is_dir():
|
|
26
|
+
raise DshInstallationDigestError("DSH installation root must be a real directory")
|
|
27
|
+
root = root.resolve()
|
|
28
|
+
digest = hashlib.sha256()
|
|
29
|
+
count = total = 0
|
|
30
|
+
|
|
31
|
+
def failed_walk(error: OSError) -> None:
|
|
32
|
+
raise DshInstallationDigestError("DSH installed tree cannot be read") from error
|
|
33
|
+
|
|
34
|
+
for directory, dirs, files in os.walk(root, followlinks=False, onerror=failed_walk):
|
|
35
|
+
dirs.sort()
|
|
36
|
+
files.sort()
|
|
37
|
+
for name in sorted(dirs + files):
|
|
38
|
+
path = Path(directory) / name
|
|
39
|
+
count += 1
|
|
40
|
+
if count > max_files:
|
|
41
|
+
raise DshInstallationDigestError("DSH installation exceeds entry limit")
|
|
42
|
+
relative = path.relative_to(root).as_posix()
|
|
43
|
+
info = path.lstat()
|
|
44
|
+
mode = stat.S_IFMT(info.st_mode)
|
|
45
|
+
digest.update(relative.encode() + b"\0")
|
|
46
|
+
if mode == stat.S_IFLNK:
|
|
47
|
+
try:
|
|
48
|
+
target = path.resolve(strict=True).relative_to(root).as_posix()
|
|
49
|
+
except (OSError, ValueError, RuntimeError):
|
|
50
|
+
raise DshInstallationDigestError(
|
|
51
|
+
"DSH dependency link escapes the installed tree"
|
|
52
|
+
) from None
|
|
53
|
+
digest.update(b"link\0" + target.encode() + b"\0")
|
|
54
|
+
elif mode == stat.S_IFDIR:
|
|
55
|
+
digest.update(b"dir\0")
|
|
56
|
+
elif mode == stat.S_IFREG:
|
|
57
|
+
digest.update(b"file\0" + str(info.st_mode & 0o111).encode() + b"\0")
|
|
58
|
+
content_digest = hashlib.sha256()
|
|
59
|
+
descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
|
|
60
|
+
with os.fdopen(descriptor, "rb") as stream:
|
|
61
|
+
if not stat.S_ISREG(os.fstat(stream.fileno()).st_mode):
|
|
62
|
+
raise DshInstallationDigestError("DSH dependency is not a regular file")
|
|
63
|
+
while chunk := stream.read(65536):
|
|
64
|
+
total += len(chunk)
|
|
65
|
+
if total > max_bytes:
|
|
66
|
+
raise DshInstallationDigestError("DSH installation exceeds byte limit")
|
|
67
|
+
content_digest.update(chunk)
|
|
68
|
+
digest.update(content_digest.digest())
|
|
69
|
+
else:
|
|
70
|
+
raise DshInstallationDigestError("DSH installation contains a special file")
|
|
71
|
+
return "sha256:" + digest.hexdigest()
|
ksadk/plugins/dsh_toolchain.py
CHANGED
|
@@ -32,11 +32,27 @@ from ksadk.plugins.bridges.dsh import (
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
DSH_PACKAGE = "@deepseek-ai/dsh"
|
|
35
|
-
DSH_VERSION = "0.1.
|
|
35
|
+
DSH_VERSION = "0.1.2-rc.1"
|
|
36
36
|
DSH_PACKAGE_SPEC = f"{DSH_PACKAGE}@{DSH_VERSION}"
|
|
37
|
-
|
|
37
|
+
DSH_GITHUB_TAG = "dsh-v0.1.2-rc.1"
|
|
38
|
+
DSH_GITHUB_COMMIT = "a66e4702047846cdaa10c66c9d3df3951f5ea70d"
|
|
39
|
+
CORDIS_VERSION_RANGE = "^4.0.2"
|
|
38
40
|
PNPM_VERSION = "11.7.0"
|
|
39
41
|
|
|
42
|
+
# The managed package is a complete Core DSH distribution. Keep these
|
|
43
|
+
# packages explicit so a registry/dist-tag mistake cannot silently degrade the
|
|
44
|
+
# installation into the old capability-only mini host.
|
|
45
|
+
DSH_CORE_PACKAGES = (
|
|
46
|
+
"@deepseek-ai/dsh-base",
|
|
47
|
+
"@deepseek-ai/dsh-web-app",
|
|
48
|
+
"@deepseek-ai/dsh-cordis-client-runner",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-cordis",
|
|
50
|
+
"@deepseek-ai/dsh-app-boot",
|
|
51
|
+
"@deepseek-ai/dsh-headless",
|
|
52
|
+
"@deepseek-ai/dsh-sdk-app",
|
|
53
|
+
"@deepseek-ai/dsh-mcp-client",
|
|
54
|
+
)
|
|
55
|
+
|
|
40
56
|
TOOLCHAIN_HOME_ENV = "AGENTENGINE_PLUGIN_TOOLCHAIN_HOME"
|
|
41
57
|
PNPM_BIN_ENV = "AGENTENGINE_PNPM_BIN"
|
|
42
58
|
|
|
@@ -65,7 +81,7 @@ class _ToolchainModel(BaseModel):
|
|
|
65
81
|
|
|
66
82
|
class DshToolchainStatus(_ToolchainModel):
|
|
67
83
|
package: Literal["@deepseek-ai/dsh"] = DSH_PACKAGE
|
|
68
|
-
expected_version: Literal["0.1.
|
|
84
|
+
expected_version: Literal["0.1.2-rc.1"] = DSH_VERSION
|
|
69
85
|
installed: bool
|
|
70
86
|
usable: bool
|
|
71
87
|
root: str
|
|
@@ -128,9 +144,16 @@ class DshPluginSourceError(DshToolchainError):
|
|
|
128
144
|
|
|
129
145
|
|
|
130
146
|
class DshPluginValidationError(DshToolchainError):
|
|
131
|
-
def __init__(
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
stage: str,
|
|
150
|
+
message: str = "DSH plugin validation failed",
|
|
151
|
+
*,
|
|
152
|
+
diagnostic: str | None = None,
|
|
153
|
+
) -> None:
|
|
132
154
|
super().__init__(message)
|
|
133
155
|
self.stage = stage
|
|
156
|
+
self.diagnostic = diagnostic
|
|
134
157
|
|
|
135
158
|
|
|
136
159
|
class DshPluginPackError(DshToolchainError):
|
|
@@ -244,6 +267,16 @@ class DshToolchainManager:
|
|
|
244
267
|
actual_version=actual,
|
|
245
268
|
problem="version_mismatch",
|
|
246
269
|
)
|
|
270
|
+
if not self._core_package_graph_is_complete():
|
|
271
|
+
return self._status(
|
|
272
|
+
installed=True,
|
|
273
|
+
usable=False,
|
|
274
|
+
pnpm_path=pnpm_path,
|
|
275
|
+
pnpm_version=pnpm_version,
|
|
276
|
+
executable=str(executable),
|
|
277
|
+
actual_version=actual,
|
|
278
|
+
problem="core_packages_missing_or_mismatched",
|
|
279
|
+
)
|
|
247
280
|
return self._status(
|
|
248
281
|
installed=True,
|
|
249
282
|
usable=True,
|
|
@@ -307,6 +340,10 @@ class DshToolchainManager:
|
|
|
307
340
|
raise DshToolchainVersionMismatchError(
|
|
308
341
|
f"expected DSH {DSH_VERSION}, got {actual}"
|
|
309
342
|
)
|
|
343
|
+
if not self._core_package_graph_is_complete(staging):
|
|
344
|
+
raise DshToolchainInstallError(
|
|
345
|
+
"installed DSH package does not contain the pinned Core runtime graph"
|
|
346
|
+
)
|
|
310
347
|
self._write_receipt(staging, actual)
|
|
311
348
|
if self._root.exists():
|
|
312
349
|
backup = parent / f".{DSH_VERSION}.backup-{uuid.uuid4().hex}"
|
|
@@ -342,7 +379,9 @@ class DshToolchainManager:
|
|
|
342
379
|
|
|
343
380
|
if explicit is not None and str(explicit).strip():
|
|
344
381
|
executable = self._resolve_program(str(explicit))
|
|
345
|
-
|
|
382
|
+
# An explicit installation does not require the managed default root
|
|
383
|
+
# to exist (for example in a fresh Studio HOME).
|
|
384
|
+
actual = self._command_version((executable,), cwd=Path(executable).parent)
|
|
346
385
|
if actual != DSH_VERSION:
|
|
347
386
|
raise DshToolchainVersionMismatchError(
|
|
348
387
|
f"expected DSH {DSH_VERSION}, got {actual}"
|
|
@@ -405,11 +444,22 @@ class DshToolchainManager:
|
|
|
405
444
|
|
|
406
445
|
def require_pnpm(self) -> tuple[str, ...]:
|
|
407
446
|
command = self._resolve_pnpm_command()
|
|
408
|
-
|
|
409
|
-
(
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
447
|
+
if self._root.exists():
|
|
448
|
+
result = self._runner(
|
|
449
|
+
(*command, "--version"),
|
|
450
|
+
self._root,
|
|
451
|
+
self._pnpm_environment(),
|
|
452
|
+
)
|
|
453
|
+
else:
|
|
454
|
+
# pnpm walks parent directories looking for packageManager. A
|
|
455
|
+
# first install under a home directory must not inherit an
|
|
456
|
+
# unrelated Yarn/npm project from one of those parents.
|
|
457
|
+
with tempfile.TemporaryDirectory(prefix="ksadk-pnpm-probe-") as directory:
|
|
458
|
+
result = self._runner(
|
|
459
|
+
(*command, "--version"),
|
|
460
|
+
Path(directory),
|
|
461
|
+
self._pnpm_environment(),
|
|
462
|
+
)
|
|
413
463
|
match = _VERSION.search(result.stdout or result.stderr)
|
|
414
464
|
if match is None:
|
|
415
465
|
raise DshToolchainUnavailableError("pnpm did not report a parseable version")
|
|
@@ -472,15 +522,6 @@ class DshToolchainManager:
|
|
|
472
522
|
executable = self._resolve_program(command[0])
|
|
473
523
|
return (executable, *command[1:])
|
|
474
524
|
|
|
475
|
-
def _pnpm_probe_cwd(self) -> Path:
|
|
476
|
-
# require_pnpm() must also work before the managed toolchain root
|
|
477
|
-
# exists (first install), so the version probe cannot unconditionally
|
|
478
|
-
# use self._root as cwd.
|
|
479
|
-
if self._root.exists():
|
|
480
|
-
return self._root
|
|
481
|
-
self._base_dir.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
482
|
-
return self._base_dir
|
|
483
|
-
|
|
484
525
|
def _manifest_is_pinned(self, path: Path | None = None) -> bool:
|
|
485
526
|
manifest_path = path or self._root / "package.json"
|
|
486
527
|
try:
|
|
@@ -505,6 +546,34 @@ class DshToolchainManager:
|
|
|
505
546
|
return False
|
|
506
547
|
return DSH_PACKAGE in value and DSH_VERSION in value
|
|
507
548
|
|
|
549
|
+
def _core_package_graph_is_complete(self, root: Path | None = None) -> bool:
|
|
550
|
+
install_root = root or self._root
|
|
551
|
+
dsh_manifest = install_root / "node_modules" / DSH_PACKAGE / "package.json"
|
|
552
|
+
try:
|
|
553
|
+
resolved_manifest = dsh_manifest.resolve(strict=True)
|
|
554
|
+
payload = json.loads(resolved_manifest.read_text(encoding="utf-8"))
|
|
555
|
+
except (FileNotFoundError, OSError, UnicodeError, json.JSONDecodeError):
|
|
556
|
+
return False
|
|
557
|
+
dependencies = payload.get("dependencies") if isinstance(payload, dict) else None
|
|
558
|
+
if not isinstance(dependencies, dict):
|
|
559
|
+
return False
|
|
560
|
+
for package in DSH_CORE_PACKAGES:
|
|
561
|
+
requirement = dependencies.get(package)
|
|
562
|
+
# pnpm keeps transitive dependencies beside the real dsh package
|
|
563
|
+
# inside its virtual store, not necessarily at the project root.
|
|
564
|
+
manifest = (
|
|
565
|
+
resolved_manifest.parent.parent.parent
|
|
566
|
+
/ Path(*package.split("/"))
|
|
567
|
+
/ "package.json"
|
|
568
|
+
)
|
|
569
|
+
if (
|
|
570
|
+
not isinstance(requirement, str)
|
|
571
|
+
or DSH_VERSION not in requirement
|
|
572
|
+
or not manifest.is_file()
|
|
573
|
+
):
|
|
574
|
+
return False
|
|
575
|
+
return True
|
|
576
|
+
|
|
508
577
|
def _command_version(self, command: Sequence[str], *, cwd: Path) -> str:
|
|
509
578
|
result = self._invoke((*command, "--version"), cwd=cwd)
|
|
510
579
|
match = _VERSION.search(result.stdout or result.stderr)
|
|
@@ -556,6 +625,10 @@ class DshToolchainManager:
|
|
|
556
625
|
"package": DSH_PACKAGE,
|
|
557
626
|
"requestedVersion": DSH_VERSION,
|
|
558
627
|
"actualVersion": actual,
|
|
628
|
+
"githubTag": DSH_GITHUB_TAG,
|
|
629
|
+
"githubCommit": DSH_GITHUB_COMMIT,
|
|
630
|
+
"distribution": "core",
|
|
631
|
+
"corePackages": list(DSH_CORE_PACKAGES),
|
|
559
632
|
"packageManager": f"pnpm@{PNPM_VERSION}",
|
|
560
633
|
},
|
|
561
634
|
)
|
|
@@ -791,10 +864,23 @@ class DshPluginDeveloper:
|
|
|
791
864
|
)
|
|
792
865
|
except DshToolchainError:
|
|
793
866
|
raise
|
|
867
|
+
except ValueError as error:
|
|
868
|
+
if stage == "install":
|
|
869
|
+
raise DshPluginSourceError(str(error)) from error
|
|
870
|
+
raise DshPluginValidationError(
|
|
871
|
+
stage,
|
|
872
|
+
diagnostic=_redact_diagnostic(str(error)),
|
|
873
|
+
) from error
|
|
794
874
|
except DshBridgeError as error:
|
|
795
|
-
raise DshPluginValidationError(
|
|
875
|
+
raise DshPluginValidationError(
|
|
876
|
+
stage,
|
|
877
|
+
diagnostic=_redact_diagnostic(str(error)),
|
|
878
|
+
) from error
|
|
796
879
|
except Exception as error:
|
|
797
|
-
raise DshPluginValidationError(
|
|
880
|
+
raise DshPluginValidationError(
|
|
881
|
+
stage,
|
|
882
|
+
diagnostic=_redact_diagnostic(str(error)),
|
|
883
|
+
) from error
|
|
798
884
|
|
|
799
885
|
def pack(
|
|
800
886
|
self,
|
|
@@ -902,6 +988,9 @@ class DshPluginDeveloper:
|
|
|
902
988
|
|
|
903
989
|
__all__ = [
|
|
904
990
|
"CORDIS_VERSION_RANGE",
|
|
991
|
+
"DSH_CORE_PACKAGES",
|
|
992
|
+
"DSH_GITHUB_COMMIT",
|
|
993
|
+
"DSH_GITHUB_TAG",
|
|
905
994
|
"DSH_PACKAGE",
|
|
906
995
|
"DSH_PACKAGE_SPEC",
|
|
907
996
|
"DSH_VERSION",
|
ksadk/plugins/ecosystem_probe.py
CHANGED
|
@@ -13,6 +13,7 @@ import json
|
|
|
13
13
|
from pathlib import Path
|
|
14
14
|
from typing import Any
|
|
15
15
|
|
|
16
|
+
from ksadk.plugins.codex_manifest import CodexPluginManifestError, load_codex_plugin_manifest
|
|
16
17
|
from ksadk.plugins.ecosystem_bridge import (
|
|
17
18
|
BridgeProbeExchange,
|
|
18
19
|
BridgeProbeRequest,
|
|
@@ -111,9 +112,10 @@ def probe_ecosystem_manifests(
|
|
|
111
112
|
codex_path = root / ".codex-plugin" / "plugin.json"
|
|
112
113
|
if codex_path.exists():
|
|
113
114
|
raw = _read_manifest(codex_path, root=root)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
try:
|
|
116
|
+
load_codex_plugin_manifest(root)
|
|
117
|
+
except CodexPluginManifestError as exc:
|
|
118
|
+
raise EcosystemProbeError(str(exc)) from exc
|
|
117
119
|
candidates.append(
|
|
118
120
|
_candidate(
|
|
119
121
|
ecosystem="codex",
|
|
@@ -176,9 +178,7 @@ def probe_ecosystem_manifests(
|
|
|
176
178
|
raise EcosystemProbeError("selected manifest was not detected in the source directory")
|
|
177
179
|
selection_required = len(candidates) > 1 and selected_manifest_ref is None
|
|
178
180
|
selected = (
|
|
179
|
-
None
|
|
180
|
-
if selection_required
|
|
181
|
-
else selected_manifest_ref or candidates[0].manifest_ref
|
|
181
|
+
None if selection_required else selected_manifest_ref or candidates[0].manifest_ref
|
|
182
182
|
)
|
|
183
183
|
result = BridgeProbeResult(
|
|
184
184
|
candidates=tuple(candidates),
|