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.
Files changed (509) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
  2. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/api/client.py +105 -91
  5. ksadk/builders/code_builder.py +36 -9
  6. ksadk/builders/framework_requirements.py +2 -1
  7. ksadk/builders/ks3_uploader.py +36 -7
  8. ksadk/builders/managed_runtime_builder.py +1 -0
  9. ksadk/cli/__init__.py +32 -3
  10. ksadk/cli/cmd_managed_runtime.py +13 -1
  11. ksadk/cli/cmd_plugin.py +6 -1
  12. ksadk/cli/cmd_web.py +2 -5
  13. ksadk/cli/runtime_bootstrap.py +23 -1
  14. ksadk/codex/client.py +424 -96
  15. ksadk/codex/projection.py +24 -0
  16. ksadk/codex/runtime.py +56 -298
  17. ksadk/common/auth.py +16 -10
  18. ksadk/configs/env_registry.py +29 -1
  19. ksadk/conversations/message_projection.py +135 -14
  20. ksadk/conversations/projector.py +4 -6
  21. ksadk/conversations/runtime_invocation.py +5 -0
  22. ksadk/conversations/runtime_payloads.py +1 -0
  23. ksadk/conversations/runtime_preparation.py +30 -27
  24. ksadk/conversations/runtime_resume.py +50 -2
  25. ksadk/conversations/runtime_stream_events.py +5 -0
  26. ksadk/conversations/runtime_streaming.py +25 -7
  27. ksadk/deployment/env_forward.py +2 -2
  28. ksadk/deployment/providers/serverless.py +1 -1
  29. ksadk/events/adapters/_codex_validators.py +18 -7
  30. ksadk/events/adapters/langgraph.py +15 -1
  31. ksadk/events/canonical_store.py +3 -1
  32. ksadk/events/projections.py +1 -1
  33. ksadk/harness/config.py +2 -2
  34. ksadk/harness/runtime.py +27 -27
  35. ksadk/harness/tools.py +38 -13
  36. ksadk/interaction/provider.py +1 -0
  37. ksadk/interaction/providers/langgraph.py +1 -0
  38. ksadk/kernel/bootstrap.py +28 -4
  39. ksadk/kernel/ingress.py +15 -2
  40. ksadk/kernel/sqlite_store.py +27 -0
  41. ksadk/kernel/store.py +3 -0
  42. ksadk/kernel/worker.py +65 -10
  43. ksadk/knowledge_base/client.py +57 -27
  44. ksadk/mcp_runtime/__init__.py +12 -4
  45. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  46. ksadk/memory/adk/resilient_session_service.py +25 -17
  47. ksadk/memory/adk/short_term_memory.py +26 -9
  48. ksadk/memory/models.py +7 -4
  49. ksadk/memory/provider_resolver.py +3 -0
  50. ksadk/model_proxy/server.py +10 -5
  51. ksadk/plugins/__init__.py +4 -0
  52. ksadk/plugins/artifacts.py +275 -0
  53. ksadk/plugins/bridges/__init__.py +4 -2
  54. ksadk/plugins/bridges/codex.py +120 -13
  55. ksadk/plugins/bridges/dsh.py +340 -156
  56. ksadk/plugins/builtins.py +35 -36
  57. ksadk/plugins/bundle_security.py +28 -4
  58. ksadk/plugins/codex_manifest.py +983 -0
  59. ksadk/plugins/composition.py +8 -0
  60. ksadk/plugins/contracts.py +118 -0
  61. ksadk/plugins/delivery.py +153 -0
  62. ksadk/plugins/dsh_installation_digest.py +71 -0
  63. ksadk/plugins/dsh_toolchain.py +110 -21
  64. ksadk/plugins/ecosystem_probe.py +6 -6
  65. ksadk/plugins/host.py +102 -39
  66. ksadk/plugins/kernel_adapter.py +205 -0
  67. ksadk/plugins/providers/__init__.py +23 -0
  68. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  69. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  70. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  71. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  72. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  73. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  74. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  75. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  76. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  77. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  78. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  79. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  80. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  81. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  82. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  83. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  84. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  85. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  86. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  87. ksadk/plugins/providers/codex.py +335 -69
  88. ksadk/plugins/providers/codex_native.py +368 -0
  89. ksadk/plugins/providers/codex_turn.py +301 -0
  90. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  91. ksadk/plugins/providers/dsh_mcp.py +467 -0
  92. ksadk/plugins/providers/harness.py +118 -113
  93. ksadk/plugins/providers/mcp_projection.py +150 -0
  94. ksadk/plugins/providers/platform_resources.py +657 -0
  95. ksadk/plugins/resolver.py +8 -1
  96. ksadk/resource_runtime/__init__.py +4 -0
  97. ksadk/resource_runtime/broker.py +616 -0
  98. ksadk/resource_runtime/build_artifacts.py +165 -0
  99. ksadk/resource_runtime/contracts.py +138 -0
  100. ksadk/resource_runtime/discovery_receipts.py +100 -0
  101. ksadk/resource_runtime/discovery_skills.py +172 -0
  102. ksadk/resource_runtime/errors.py +6 -0
  103. ksadk/resource_runtime/ipc.py +142 -0
  104. ksadk/resource_runtime/kernel_approval.py +165 -0
  105. ksadk/resource_runtime/knowledge.py +114 -0
  106. ksadk/resource_runtime/langgraph.py +94 -0
  107. ksadk/resource_runtime/leases.py +191 -0
  108. ksadk/resource_runtime/managed_projection.py +186 -0
  109. ksadk/resource_runtime/mcp_server.py +138 -0
  110. ksadk/resource_runtime/memory_provider.py +318 -0
  111. ksadk/resource_runtime/memory_receipts.py +34 -0
  112. ksadk/resource_runtime/operation_ledger.py +211 -0
  113. ksadk/resource_runtime/plugin_config.py +48 -0
  114. ksadk/resource_runtime/policy_authorization.py +54 -0
  115. ksadk/resource_runtime/process.py +110 -0
  116. ksadk/resource_runtime/skill_artifacts.py +153 -0
  117. ksadk/resource_runtime/skill_runtime.py +42 -0
  118. ksadk/resource_runtime/skill_workspace.py +118 -0
  119. ksadk/resource_runtime/skills.py +215 -0
  120. ksadk/resource_runtime/snapshots.py +180 -0
  121. ksadk/resource_runtime/socket_server.py +103 -0
  122. ksadk/resource_runtime/supervisor.py +380 -0
  123. ksadk/resource_runtime/worker.py +504 -0
  124. ksadk/runners/_langgraph_runner_streams.py +74 -6
  125. ksadk/runners/adk_runner.py +149 -11
  126. ksadk/runners/base_runner.py +29 -1
  127. ksadk/runners/langgraph_runner.py +475 -145
  128. ksadk/runtime/_runner_adapter/stream_mapping.py +142 -18
  129. ksadk/runtime/adapter.py +2 -0
  130. ksadk/runtime/conversation_execution.py +92 -16
  131. ksadk/runtime/executor.py +78 -2
  132. ksadk/runtime/factory.py +29 -273
  133. ksadk/runtime/framework_adapters.py +23 -0
  134. ksadk/runtime/preprocessing.py +10 -2
  135. ksadk/runtime/runner_adapter.py +73 -14
  136. ksadk/runtime_context.py +40 -2
  137. ksadk/sandbox/backends/e2b.py +52 -11
  138. ksadk/sandbox/backends/local_process.py +9 -0
  139. ksadk/sandbox/base.py +2 -0
  140. ksadk/sandbox/e2b_connection.py +66 -0
  141. ksadk/scheduler/sqlite_store.py +18 -0
  142. ksadk/server/composition.py +2 -0
  143. ksadk/server/factory.py +5 -0
  144. ksadk/server/persistence_capability.py +516 -0
  145. ksadk/server/routes/control.py +210 -46
  146. ksadk/server/routes/dependencies.py +15 -0
  147. ksadk/server/routes/models.py +47 -4
  148. ksadk/server/routes/projection.py +252 -12
  149. ksadk/server/routes/sessions.py +284 -107
  150. ksadk/server/routes/streaming.py +43 -9
  151. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  152. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
  153. ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  154. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  155. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  156. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  157. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
  158. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  159. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  160. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  161. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  162. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  163. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  164. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  165. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  166. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  167. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  168. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  169. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  170. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  171. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  172. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  173. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  174. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  175. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  176. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  177. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  178. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  179. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
  180. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  181. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  182. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  183. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  184. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  185. ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
  186. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
  187. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
  188. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
  189. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
  190. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
  191. ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
  192. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
  193. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
  194. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
  195. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
  196. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
  197. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
  198. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
  199. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
  200. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
  201. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
  202. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
  203. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
  204. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
  205. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
  206. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
  207. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  208. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  209. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  210. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  211. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  212. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  213. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  214. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  215. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  216. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  217. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  218. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  219. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  220. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  221. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
  222. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
  223. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  224. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  225. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  226. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  227. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  228. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  229. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  230. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  231. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  232. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  233. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  234. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  235. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  236. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  237. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  238. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  239. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  240. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  241. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  242. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  243. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  244. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  245. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  246. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  247. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  248. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  249. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  250. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  251. ksadk/server/static/index.html +2 -2
  252. ksadk/session_context.py +66 -0
  253. ksadk/sessions/__init__.py +11 -21
  254. ksadk/sessions/_local_service_sync.py +263 -1
  255. ksadk/sessions/base.py +176 -0
  256. ksadk/sessions/errors.py +4 -0
  257. ksadk/sessions/in_memory.py +309 -19
  258. ksadk/sessions/local_service.py +83 -1
  259. ksadk/sessions/persistence.py +275 -0
  260. ksadk/sessions/postgres_service.py +358 -0
  261. ksadk/sessions/resilience.py +8 -0
  262. ksadk/sessions/resilient.py +362 -4
  263. ksadk/sessions/topology.py +135 -0
  264. ksadk/skills/models.py +26 -4
  265. ksadk/skills/package_store.py +186 -38
  266. ksadk/skills/runtime/agent.py +31 -6
  267. ksadk/skills/runtime/artifact_delivery.py +139 -0
  268. ksadk/skills/runtime/backends/e2b.py +98 -6
  269. ksadk/skills/runtime/backends/local.py +73 -8
  270. ksadk/skills/runtime/base.py +3 -0
  271. ksadk/skills/runtime/executor.py +2 -0
  272. ksadk/skills/runtime/loader.py +10 -2
  273. ksadk/skills/runtime/pinned.py +114 -0
  274. ksadk/skills/runtime/request.py +31 -0
  275. ksadk/skills/service_client.py +167 -28
  276. ksadk/studio/api.py +224 -42
  277. ksadk/studio/api_catalog_routes.py +18 -0
  278. ksadk/studio/api_plugin_routes.py +526 -95
  279. ksadk/studio/api_resource_connections.py +183 -0
  280. ksadk/studio/authoring_coordinator.py +19 -14
  281. ksadk/studio/builder.py +76 -0
  282. ksadk/studio/cloud.py +342 -104
  283. ksadk/studio/cloud_shared_web.py +565 -0
  284. ksadk/studio/codex_agent_service.py +128 -26
  285. ksadk/studio/codex_builder.py +241 -2
  286. ksadk/studio/codex_credentials.py +90 -0
  287. ksadk/studio/codex_manifest.py +31 -4
  288. ksadk/studio/codex_plugin_store.py +746 -0
  289. ksadk/studio/codex_provider_build.py +231 -0
  290. ksadk/studio/codex_run.py +184 -25
  291. ksadk/studio/compatibility_report.py +12 -1
  292. ksadk/studio/compiler.py +78 -14
  293. ksadk/studio/contracts.py +132 -6
  294. ksadk/studio/dsh_application.py +137 -0
  295. ksadk/studio/dsh_capability_service.py +1107 -0
  296. ksadk/studio/dsh_models.py +59 -0
  297. ksadk/studio/dsh_provider_registration.py +320 -13
  298. ksadk/studio/hosted_kernel.py +88 -13
  299. ksadk/studio/mcp_runtime.py +11 -3
  300. ksadk/studio/model_client.py +2 -2
  301. ksadk/studio/plugin_composition.py +190 -23
  302. ksadk/studio/plugin_kernel_adapter.py +12 -112
  303. ksadk/studio/plugin_runtime.py +224 -45
  304. ksadk/studio/resource_authority.py +637 -0
  305. ksadk/studio/resource_binding_validation.py +77 -0
  306. ksadk/studio/resource_build_admission.py +196 -0
  307. ksadk/studio/resource_build_materializer.py +149 -0
  308. ksadk/studio/resource_catalog.py +143 -2
  309. ksadk/studio/resource_connections.py +220 -0
  310. ksadk/studio/run_service.py +462 -52
  311. ksadk/studio/runtime_source.py +15 -7
  312. ksadk/studio/scheduler_assistant.py +317 -0
  313. ksadk/studio/scheduler_runtime.py +9 -0
  314. ksadk/studio/scheduler_service.py +3 -0
  315. ksadk/studio/service.py +490 -44
  316. ksadk/studio/shared_web.py +446 -62
  317. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  318. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  319. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  320. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  321. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  322. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  323. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  324. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  325. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  326. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  327. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  328. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  329. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  330. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  331. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  332. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  333. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  334. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  335. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  336. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  337. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  338. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  339. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  340. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  341. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  342. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  343. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  344. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  345. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  346. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  347. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  348. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  349. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  350. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  351. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  352. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  353. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  354. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  355. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  356. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  357. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  358. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  359. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  360. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  361. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  362. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  363. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  364. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  365. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  366. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  367. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  368. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  369. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  372. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  373. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  377. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  378. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  379. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  380. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  381. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  382. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  383. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  384. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  385. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  386. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  387. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  388. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  389. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  390. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  391. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  392. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  393. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  394. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  395. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  396. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  397. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  398. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  399. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  400. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  401. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  402. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  403. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  404. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  405. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  406. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  407. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  408. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  409. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  410. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  411. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  412. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  413. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  414. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  415. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  416. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  417. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  418. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  419. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  420. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  421. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  422. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  423. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  424. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  425. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  426. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  427. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  428. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  429. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  430. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  431. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  432. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  433. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  434. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  435. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  436. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  437. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  438. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  439. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  440. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  441. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  442. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  443. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  444. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  445. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  446. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  447. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  448. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  449. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  450. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  451. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  452. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  453. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  454. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  455. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  456. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  457. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  458. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  459. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  460. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  461. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  462. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  463. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  464. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  465. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  466. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  467. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  468. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  469. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  470. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  471. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  472. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  473. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  474. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  475. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  476. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  477. ksadk/studio/static/index.html +2 -2
  478. ksadk/version.py +1 -1
  479. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  480. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  481. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  482. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  483. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  484. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  485. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  486. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  487. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  488. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  489. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  490. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  491. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  492. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  493. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  494. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  495. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  496. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  497. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  498. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  499. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  500. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  501. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  502. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  503. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  504. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  505. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  506. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  507. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  508. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  509. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -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:
@@ -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()
@@ -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.1-rc.2"
35
+ DSH_VERSION = "0.1.2-rc.1"
36
36
  DSH_PACKAGE_SPEC = f"{DSH_PACKAGE}@{DSH_VERSION}"
37
- CORDIS_VERSION_RANGE = "^4.0.1"
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.1-rc.2"] = DSH_VERSION
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__(self, stage: str, message: str = "DSH plugin validation failed") -> None:
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
- actual = self._command_version((executable,), cwd=self._root)
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
- result = self._runner(
409
- (*command, "--version"),
410
- self._pnpm_probe_cwd(),
411
- self._pnpm_environment(),
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(stage) from error
875
+ raise DshPluginValidationError(
876
+ stage,
877
+ diagnostic=_redact_diagnostic(str(error)),
878
+ ) from error
796
879
  except Exception as error:
797
- raise DshPluginValidationError(stage) from error
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",
@@ -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
- payload = _json_object(raw, name=".codex-plugin/plugin.json")
115
- if not isinstance(payload.get("name"), str) or not payload["name"]:
116
- raise EcosystemProbeError("Codex plugin manifest requires a non-empty name")
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),