agentengine-sdk-python 0.8.2__py3-none-any.whl → 0.8.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (563) hide show
  1. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +22 -28
  2. agentengine_sdk_python-0.8.4.dist-info/RECORD +1070 -0
  3. ksadk/_build_provenance.json +1 -0
  4. ksadk/agui/_agent_helpers.py +4 -0
  5. ksadk/api/client.py +108 -91
  6. ksadk/builders/code_builder.py +36 -9
  7. ksadk/builders/framework_requirements.py +2 -1
  8. ksadk/builders/ks3_uploader.py +36 -7
  9. ksadk/builders/managed_runtime_builder.py +4 -0
  10. ksadk/cli/__init__.py +38 -3
  11. ksadk/cli/cmd_managed_runtime.py +13 -1
  12. ksadk/cli/cmd_plugin.py +662 -0
  13. ksadk/cli/cmd_web.py +2 -5
  14. ksadk/cli/runtime_bootstrap.py +23 -1
  15. ksadk/codex/client.py +424 -96
  16. ksadk/codex/projection.py +24 -0
  17. ksadk/codex/runtime.py +83 -283
  18. ksadk/common/auth.py +16 -10
  19. ksadk/configs/env_registry.py +59 -3
  20. ksadk/configs/settings.py +9 -0
  21. ksadk/context_engine/contributors.py +73 -8
  22. ksadk/conversations/__init__.py +19 -0
  23. ksadk/conversations/context.py +104 -24
  24. ksadk/conversations/contracts.py +266 -0
  25. ksadk/conversations/message_projection.py +154 -15
  26. ksadk/conversations/projector.py +614 -0
  27. ksadk/conversations/reducer.py +98 -0
  28. ksadk/conversations/runtime_invocation.py +5 -0
  29. ksadk/conversations/runtime_payloads.py +1 -0
  30. ksadk/conversations/runtime_preparation.py +30 -27
  31. ksadk/conversations/runtime_resume.py +50 -2
  32. ksadk/conversations/runtime_stream_events.py +5 -0
  33. ksadk/conversations/runtime_streaming.py +25 -7
  34. ksadk/deployment/env_forward.py +2 -2
  35. ksadk/deployment/providers/serverless.py +1 -1
  36. ksadk/events/_v1_compat/projection.py +2 -0
  37. ksadk/events/adapters/_codex_validators.py +18 -7
  38. ksadk/events/adapters/codex.py +190 -0
  39. ksadk/events/adapters/langgraph.py +15 -1
  40. ksadk/events/canonical_store.py +3 -1
  41. ksadk/events/projections.py +1 -1
  42. ksadk/harness/__init__.py +45 -35
  43. ksadk/harness/config.py +2 -2
  44. ksadk/harness/runtime.py +75 -16
  45. ksadk/harness/tools.py +38 -13
  46. ksadk/interaction/provider.py +1 -0
  47. ksadk/interaction/providers/langgraph.py +1 -0
  48. ksadk/kernel/bootstrap.py +28 -4
  49. ksadk/kernel/contract_fingerprints.py +5 -4
  50. ksadk/kernel/contracts.py +8 -0
  51. ksadk/kernel/control.py +1 -0
  52. ksadk/kernel/ingress.py +36 -2
  53. ksadk/kernel/memory_store.py +1 -0
  54. ksadk/kernel/postgres_store.py +1 -0
  55. ksadk/kernel/sqlite_store.py +28 -0
  56. ksadk/kernel/store.py +3 -0
  57. ksadk/kernel/worker.py +76 -10
  58. ksadk/knowledge_base/client.py +57 -27
  59. ksadk/mcp_runtime/__init__.py +12 -4
  60. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  61. ksadk/memory/adk/resilient_session_service.py +25 -17
  62. ksadk/memory/adk/short_term_memory.py +26 -9
  63. ksadk/memory/models.py +7 -4
  64. ksadk/memory/provider_resolver.py +3 -0
  65. ksadk/memory/providers/local_sqlite.py +7 -0
  66. ksadk/model_proxy/server.py +10 -5
  67. ksadk/plugins/__init__.py +171 -0
  68. ksadk/plugins/artifacts.py +275 -0
  69. ksadk/plugins/bridges/__init__.py +47 -0
  70. ksadk/plugins/bridges/codex.py +659 -0
  71. ksadk/plugins/bridges/dsh.py +1300 -0
  72. ksadk/plugins/builtins.py +746 -0
  73. ksadk/plugins/bundle.py +246 -0
  74. ksadk/plugins/bundle_security.py +191 -0
  75. ksadk/plugins/codex_manifest.py +983 -0
  76. ksadk/plugins/composition.py +537 -0
  77. ksadk/plugins/context_contributor.py +437 -0
  78. ksadk/plugins/contracts.py +569 -0
  79. ksadk/plugins/delivery.py +153 -0
  80. ksadk/plugins/dsh_installation_digest.py +71 -0
  81. ksadk/plugins/dsh_toolchain.py +1024 -0
  82. ksadk/plugins/ecosystem_bridge.py +1105 -0
  83. ksadk/plugins/ecosystem_probe.py +191 -0
  84. ksadk/plugins/host.py +787 -0
  85. ksadk/plugins/kernel_adapter.py +205 -0
  86. ksadk/plugins/providers/__init__.py +108 -0
  87. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  88. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  89. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  90. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  91. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  92. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  93. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  94. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  95. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  96. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  97. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  98. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  99. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  100. ksadk/plugins/providers/bundles/ksadk-codex/cordis.patch.yml +3 -0
  101. ksadk/plugins/providers/bundles/ksadk-codex/index.mjs +18 -0
  102. ksadk/plugins/providers/bundles/ksadk-codex/package.json +19 -0
  103. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  104. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  105. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  106. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  107. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  108. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  109. ksadk/plugins/providers/bundles/ksadk-harness/cordis.patch.yml +3 -0
  110. ksadk/plugins/providers/bundles/ksadk-harness/index.mjs +19 -0
  111. ksadk/plugins/providers/bundles/ksadk-harness/package.json +19 -0
  112. ksadk/plugins/providers/codex.py +988 -0
  113. ksadk/plugins/providers/codex_dsh.py +83 -0
  114. ksadk/plugins/providers/codex_native.py +368 -0
  115. ksadk/plugins/providers/codex_turn.py +301 -0
  116. ksadk/plugins/providers/dsh.py +951 -0
  117. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  118. ksadk/plugins/providers/dsh_descriptor_host.py +226 -0
  119. ksadk/plugins/providers/dsh_mcp.py +467 -0
  120. ksadk/plugins/providers/harness.py +632 -0
  121. ksadk/plugins/providers/harness_dsh.py +91 -0
  122. ksadk/plugins/providers/legacy.py +215 -0
  123. ksadk/plugins/providers/legacy_catalog.py +100 -0
  124. ksadk/plugins/providers/mcp_projection.py +150 -0
  125. ksadk/plugins/providers/platform_resources.py +657 -0
  126. ksadk/plugins/providers/shipped_dsh.py +370 -0
  127. ksadk/plugins/resolver.py +338 -0
  128. ksadk/plugins/subagent_providers/__init__.py +12 -0
  129. ksadk/plugins/subagent_providers/codex.py +443 -0
  130. ksadk/plugins/subagents.py +333 -0
  131. ksadk/resource_runtime/__init__.py +4 -0
  132. ksadk/resource_runtime/broker.py +616 -0
  133. ksadk/resource_runtime/build_artifacts.py +165 -0
  134. ksadk/resource_runtime/contracts.py +138 -0
  135. ksadk/resource_runtime/discovery_receipts.py +100 -0
  136. ksadk/resource_runtime/discovery_skills.py +172 -0
  137. ksadk/resource_runtime/errors.py +6 -0
  138. ksadk/resource_runtime/ipc.py +142 -0
  139. ksadk/resource_runtime/kernel_approval.py +165 -0
  140. ksadk/resource_runtime/knowledge.py +114 -0
  141. ksadk/resource_runtime/langgraph.py +94 -0
  142. ksadk/resource_runtime/leases.py +191 -0
  143. ksadk/resource_runtime/managed_projection.py +186 -0
  144. ksadk/resource_runtime/mcp_server.py +138 -0
  145. ksadk/resource_runtime/memory_provider.py +318 -0
  146. ksadk/resource_runtime/memory_receipts.py +34 -0
  147. ksadk/resource_runtime/operation_ledger.py +211 -0
  148. ksadk/resource_runtime/plugin_config.py +48 -0
  149. ksadk/resource_runtime/policy_authorization.py +54 -0
  150. ksadk/resource_runtime/process.py +110 -0
  151. ksadk/resource_runtime/skill_artifacts.py +153 -0
  152. ksadk/resource_runtime/skill_runtime.py +42 -0
  153. ksadk/resource_runtime/skill_workspace.py +118 -0
  154. ksadk/resource_runtime/skills.py +215 -0
  155. ksadk/resource_runtime/snapshots.py +180 -0
  156. ksadk/resource_runtime/socket_server.py +103 -0
  157. ksadk/resource_runtime/supervisor.py +380 -0
  158. ksadk/resource_runtime/worker.py +504 -0
  159. ksadk/runners/_langgraph_runner_streams.py +74 -6
  160. ksadk/runners/adk_runner.py +149 -11
  161. ksadk/runners/base_runner.py +29 -1
  162. ksadk/runners/langgraph_runner.py +475 -145
  163. ksadk/runtime/_runner_adapter/stream_mapping.py +193 -60
  164. ksadk/runtime/adapter.py +3 -0
  165. ksadk/runtime/conversation_execution.py +92 -16
  166. ksadk/runtime/executor.py +78 -2
  167. ksadk/runtime/factory.py +30 -200
  168. ksadk/runtime/framework_adapters.py +41 -0
  169. ksadk/runtime/preprocessing.py +10 -2
  170. ksadk/runtime/runner_adapter.py +78 -14
  171. ksadk/runtime_context.py +40 -2
  172. ksadk/sandbox/__init__.py +2 -1
  173. ksadk/sandbox/backends/e2b.py +52 -11
  174. ksadk/sandbox/backends/local_process.py +9 -0
  175. ksadk/sandbox/base.py +2 -0
  176. ksadk/sandbox/e2b_connection.py +66 -0
  177. ksadk/sandbox/factory.py +72 -0
  178. ksadk/scheduler/__init__.py +18 -0
  179. ksadk/scheduler/calendar.py +102 -0
  180. ksadk/scheduler/contracts.py +254 -0
  181. ksadk/scheduler/dispatcher.py +129 -0
  182. ksadk/scheduler/engine.py +416 -0
  183. ksadk/scheduler/sqlite_store.py +581 -0
  184. ksadk/server/composition.py +2 -0
  185. ksadk/server/factory.py +5 -0
  186. ksadk/server/persistence_capability.py +516 -0
  187. ksadk/server/routes/control.py +210 -46
  188. ksadk/server/routes/dependencies.py +15 -0
  189. ksadk/server/routes/models.py +47 -4
  190. ksadk/server/routes/projection.py +252 -12
  191. ksadk/server/routes/sessions.py +284 -107
  192. ksadk/server/routes/streaming.py +43 -9
  193. ksadk/server/static/assets/{ArtifactsPanel-DSU1sWD_.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  194. ksadk/server/static/assets/{CodeBlock-DOH6MVcn.js → CodeBlock-b4C7upmO.js} +3 -3
  195. ksadk/server/static/assets/{MathMessageMarkdown-BL8my1R2.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  196. ksadk/server/static/assets/{MermaidBlock-Dz4IP-Tx.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  197. ksadk/server/static/assets/{NativeTerminalPanel-DUrK0JpZ.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  198. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-g20pFzNV.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  199. ksadk/server/static/assets/{arc-C4FzinUA.js → arc-bTohInsS.js} +1 -1
  200. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  201. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-DpIqL5h4.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  202. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-BjkljTNz.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  203. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-Dk_ieq2X.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  204. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  205. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  206. ksadk/server/static/assets/{chunk-5VM5RSS4-BVHAchFb.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  207. ksadk/server/static/assets/{chunk-F27PBJKO-C-ipQzuS.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  208. ksadk/server/static/assets/{chunk-G27WJ6UU-C2EyJbIK.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  209. ksadk/server/static/assets/{chunk-JWPE2WC7-vYvVJb_M.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  210. ksadk/server/static/assets/{chunk-LCL6LL3I-BcI6ysPT.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  211. ksadk/server/static/assets/{chunk-POPQ4Y6H-C030x_Z1.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  212. ksadk/server/static/assets/{chunk-RHFEMEQ7-yyGpsz4n.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  213. ksadk/server/static/assets/{chunk-SVP7TREG-BLTlmMU7.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  214. ksadk/server/static/assets/{chunk-XXDRQBXY-C_32ArgP.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  215. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  216. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  217. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-9YQYwdl0.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  218. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  219. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-ErLF5N13.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  220. ksadk/server/static/assets/{dagre-3AP2YEHR-DFiQF-6f.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  221. ksadk/server/static/assets/{dagre-BuhGnRI1.js → dagre-UBpgon5q.js} +1 -1
  222. ksadk/server/static/assets/{diagram-S7CK7UJ4-Bt1v8-GC.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  223. ksadk/server/static/assets/{diagram-UQ7AKVKN-DSCxJdBK.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  224. ksadk/server/static/assets/{diagram-VSXAHHWV-DHfYwp_9.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  225. ksadk/server/static/assets/{diagram-VX7I27RA-DdzD-4Le.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  226. ksadk/server/static/assets/{diagram-Z3DM3KII-Du-nAJ9F.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  227. ksadk/server/static/assets/{dist-B7seoj3d.js → dist-B2_CVgKv.js} +1 -1
  228. ksadk/server/static/assets/{dist-CSh_DE14.js → dist-B3FR1SKK.js} +1 -1
  229. ksadk/server/static/assets/{dist-DUX-id_F.js → dist-BIr4DSRq.js} +1 -1
  230. ksadk/server/static/assets/{dist-C_wsv-Qd.js → dist-BgV_owcB.js} +1 -1
  231. ksadk/server/static/assets/{dist-W-TIVntx.js → dist-Bj730Ib4.js} +1 -1
  232. ksadk/server/static/assets/{dist-BytlxIDT.js → dist-BnaTiyzN.js} +1 -1
  233. ksadk/server/static/assets/{dist-CXYYBw3_.js → dist-C1NMAY5a.js} +1 -1
  234. ksadk/server/static/assets/{dist-dDdADKFA.js → dist-C5_ZAZsG.js} +1 -1
  235. ksadk/server/static/assets/{dist-BVDffZ0U.js → dist-CB9iJrvg.js} +1 -1
  236. ksadk/server/static/assets/{dist-Bf2M8m3N.js → dist-CFzsn6BG.js} +1 -1
  237. ksadk/server/static/assets/{dist-ngtN0DJB.js → dist-Cf125P_m.js} +1 -1
  238. ksadk/server/static/assets/{dist-BE7bu-DL.js → dist-ClYUxfeK.js} +1 -1
  239. ksadk/server/static/assets/{dist-DNp6rLRA.js → dist-DFD6Qa6T.js} +1 -1
  240. ksadk/server/static/assets/{dist-BX8z72IC.js → dist-DVCOWtha.js} +1 -1
  241. ksadk/server/static/assets/{dist-dydu68Fl.js → dist-D_ctSS2i.js} +1 -1
  242. ksadk/server/static/assets/{dist-ClxGviKw.js → dist-DiixqL0J.js} +1 -1
  243. ksadk/server/static/assets/{dist-BjU6y-A2.js → dist-DoVSwoDb.js} +1 -1
  244. ksadk/server/static/assets/{dist-Dq9gLD7L.js → dist-DvFK7p5S.js} +1 -1
  245. ksadk/server/static/assets/{dist-8hqcx0sU.js → dist-QfkEHOlb.js} +1 -1
  246. ksadk/server/static/assets/{dist-CttYUqzS.js → dist-btbmmX5O.js} +1 -1
  247. ksadk/server/static/assets/{dist-DmldrHd_.js → dist-fBO2v5Kt.js} +1 -1
  248. ksadk/server/static/assets/{dist-DnfXs8Vn.js → dist-ufY3F5p6.js} +1 -1
  249. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-Da9C9NO1.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  250. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-EAGqqR79.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  251. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  252. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  253. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-DqJsKb59.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  254. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  255. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-B6g4dtDi.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  256. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  257. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  258. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  259. ksadk/server/static/assets/{infoDiagram-RXCK75RN-Djm_nbd5.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  260. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-DWya9SG2.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  261. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DutxhSNI.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  262. ksadk/server/static/assets/{kanban-definition-3QL26DDD-DJdOF8Fm.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  263. ksadk/server/static/assets/{katex-vFWytM5c.js → katex-B4weu383.js} +1 -1
  264. ksadk/server/static/assets/{linear-BHjG8b-J.js → linear-V-MgYHW1.js} +1 -1
  265. ksadk/server/static/assets/{mermaid-parser.core-KGSy4jWT.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  266. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-9-HC88D4.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  267. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  268. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-DrEZd4fD.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  269. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  270. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-DpjqOFFp.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  271. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-BiNhgOXX.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  272. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  273. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  274. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  275. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  276. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  277. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-_Y3Ojg6G.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  278. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-DeCFdg9K.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  279. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-CPH75rhw.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  280. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-OEpQQdr4.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  281. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-heUErzhI.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  282. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-DvA3jSMB.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  283. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  284. ksadk/server/static/assets/{swimlanes-XN3QIQJK-CR-dfN_t.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  285. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  286. ksadk/server/static/assets/{timeline-definition-24CTP7MA-DAVJf1TX.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  287. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  288. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  289. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-DwM8eDkh.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  290. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  291. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DZL-Zz2t.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  292. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  293. ksadk/server/static/index.html +2 -2
  294. ksadk/session_context.py +66 -0
  295. ksadk/sessions/__init__.py +11 -21
  296. ksadk/sessions/_local_service_sync.py +263 -1
  297. ksadk/sessions/base.py +176 -0
  298. ksadk/sessions/errors.py +4 -0
  299. ksadk/sessions/in_memory.py +309 -19
  300. ksadk/sessions/local_service.py +83 -1
  301. ksadk/sessions/persistence.py +275 -0
  302. ksadk/sessions/postgres_service.py +358 -0
  303. ksadk/sessions/resilience.py +8 -0
  304. ksadk/sessions/resilient.py +362 -4
  305. ksadk/sessions/topology.py +135 -0
  306. ksadk/skills/models.py +26 -4
  307. ksadk/skills/package_store.py +186 -38
  308. ksadk/skills/runtime/agent.py +31 -6
  309. ksadk/skills/runtime/artifact_delivery.py +139 -0
  310. ksadk/skills/runtime/backends/e2b.py +98 -6
  311. ksadk/skills/runtime/backends/local.py +73 -8
  312. ksadk/skills/runtime/base.py +3 -0
  313. ksadk/skills/runtime/executor.py +2 -0
  314. ksadk/skills/runtime/loader.py +10 -2
  315. ksadk/skills/runtime/pinned.py +114 -0
  316. ksadk/skills/runtime/request.py +31 -0
  317. ksadk/skills/service_client.py +211 -24
  318. ksadk/studio/agent_lifecycle.py +26 -20
  319. ksadk/studio/api.py +714 -90
  320. ksadk/studio/api_catalog_routes.py +23 -0
  321. ksadk/studio/api_contracts.py +34 -1
  322. ksadk/studio/api_plugin_routes.py +911 -0
  323. ksadk/studio/api_resource_connections.py +183 -0
  324. ksadk/studio/attachment_store.py +187 -0
  325. ksadk/studio/authoring.py +10 -4
  326. ksadk/studio/authoring_coordinator.py +31 -16
  327. ksadk/studio/builder.py +199 -43
  328. ksadk/studio/cloud.py +346 -104
  329. ksadk/studio/cloud_shared_web.py +565 -0
  330. ksadk/studio/codex_agent_service.py +140 -27
  331. ksadk/studio/codex_builder.py +294 -16
  332. ksadk/studio/codex_credentials.py +90 -0
  333. ksadk/studio/codex_manifest.py +51 -4
  334. ksadk/studio/codex_plugin_store.py +746 -0
  335. ksadk/studio/codex_provider_build.py +231 -0
  336. ksadk/studio/codex_run.py +200 -29
  337. ksadk/studio/compatibility_report.py +456 -0
  338. ksadk/studio/compiler.py +84 -15
  339. ksadk/studio/contracts.py +249 -4
  340. ksadk/studio/dsh_application.py +137 -0
  341. ksadk/studio/dsh_capability_service.py +1107 -0
  342. ksadk/studio/dsh_models.py +59 -0
  343. ksadk/studio/dsh_provider_registration.py +1075 -0
  344. ksadk/studio/event_store.py +54 -6
  345. ksadk/studio/framework_run.py +37 -4
  346. ksadk/studio/hosted_kernel.py +89 -14
  347. ksadk/studio/mcp_runtime.py +11 -3
  348. ksadk/studio/model_client.py +2 -2
  349. ksadk/studio/operations.py +12 -2
  350. ksadk/studio/plugin_composition.py +468 -0
  351. ksadk/studio/plugin_kernel_adapter.py +28 -0
  352. ksadk/studio/plugin_runtime.py +831 -0
  353. ksadk/studio/resource_authority.py +637 -0
  354. ksadk/studio/resource_binding_validation.py +77 -0
  355. ksadk/studio/resource_build_admission.py +196 -0
  356. ksadk/studio/resource_build_materializer.py +149 -0
  357. ksadk/studio/resource_catalog.py +149 -3
  358. ksadk/studio/resource_connections.py +220 -0
  359. ksadk/studio/run_service.py +1144 -96
  360. ksadk/studio/runtime_source.py +24 -8
  361. ksadk/studio/scheduler_assistant.py +317 -0
  362. ksadk/studio/scheduler_runtime.py +383 -0
  363. ksadk/studio/scheduler_service.py +214 -0
  364. ksadk/studio/service.py +1131 -95
  365. ksadk/studio/shared_web.py +610 -87
  366. ksadk/studio/soul.py +52 -0
  367. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  368. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  369. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  372. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  373. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  377. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  378. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  379. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  380. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  381. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  382. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  383. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  384. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  385. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  386. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  387. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  388. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  389. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  390. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  391. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  392. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  393. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  394. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  395. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  396. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  397. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  398. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  399. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  400. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  401. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  402. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  403. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  404. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  405. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  406. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  407. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  408. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  409. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  410. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  411. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  412. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  413. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  414. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  415. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  416. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  417. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  418. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  419. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  420. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  421. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  422. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  423. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  424. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  425. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  426. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  427. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  428. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  429. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  430. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  431. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  432. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  433. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  434. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  435. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  436. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  437. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  438. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  439. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  440. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  441. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  442. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  443. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  444. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  445. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  446. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  447. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  448. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  449. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  450. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  451. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  452. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  453. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  454. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  455. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  456. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  457. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  458. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  459. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  460. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  461. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  462. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  463. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  464. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  465. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  466. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  467. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  468. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  469. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  470. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  471. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  472. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  473. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  474. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  475. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  476. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  477. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  478. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  479. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  480. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  481. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  482. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  483. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  484. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  485. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  486. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  487. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  488. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  489. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  490. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  491. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  492. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  493. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  494. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  495. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  496. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  497. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  498. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  499. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  500. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  501. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  502. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  503. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  504. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  505. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  506. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  507. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  508. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  509. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  510. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  511. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  512. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  513. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  514. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  515. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  516. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  517. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  518. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  519. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  520. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  521. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  522. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  523. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  524. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  525. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  526. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  527. ksadk/studio/static/index.html +2 -2
  528. ksadk/studio/validator.py +1 -1
  529. ksadk/studio/workspace.py +1 -0
  530. ksadk/version.py +1 -1
  531. ksadk_runtime_common/workspace_files/path_utils.py +41 -0
  532. agentengine_sdk_python-0.8.2.dist-info/RECORD +0 -778
  533. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +0 -1
  534. ksadk/server/static/assets/channel-4cQHKtx1.js +0 -1
  535. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +0 -1
  536. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +0 -1
  537. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +0 -1
  538. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +0 -1
  539. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +0 -1
  540. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +0 -1
  541. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +0 -1
  542. ksadk/server/static/assets/index-8ipRcQ-M.js +0 -240
  543. ksadk/server/static/assets/index-ByFCqjlh.css +0 -2
  544. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +0 -1
  545. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +0 -1
  546. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +0 -1
  547. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +0 -1
  548. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +0 -1
  549. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +0 -1
  550. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +0 -1
  551. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +0 -1
  552. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +0 -1
  553. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +0 -8
  554. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +0 -1
  555. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +0 -1
  556. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +0 -1
  557. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  558. ksadk/studio/static/assets/index-BLpcdrgW.css +0 -1
  559. ksadk/studio/static/assets/index-CYekR2Xv.js +0 -260
  560. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  561. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  562. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  563. {agentengine_sdk_python-0.8.2.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1024 @@
1
+ """Managed DeepSeek Harness toolchain and standard bundle developer workflow.
2
+
3
+ KsADK does not copy, fork, or rebuild DeepSeek Harness. It installs one
4
+ published CLI package into an isolated AgentEngine configuration directory and
5
+ delegates bundle composition to that exact executable. Plugin source remains
6
+ an ordinary npm package that follows DSH's public ``dsh.bundle.patch`` format.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import json
12
+ import os
13
+ import re
14
+ import shutil
15
+ import subprocess
16
+ import tempfile
17
+ import time
18
+ import uuid
19
+ from collections.abc import Callable, Mapping, Sequence
20
+ from contextlib import contextmanager
21
+ from dataclasses import dataclass
22
+ from pathlib import Path
23
+ from typing import Any, Iterator, Literal
24
+
25
+ from pydantic import BaseModel, ConfigDict
26
+
27
+ from ksadk.configs.global_config import get_global_config_dir
28
+ from ksadk.plugins.bridges.dsh import (
29
+ DshBridgeError,
30
+ DshProfilePluginBridge,
31
+ dsh_subprocess_environment,
32
+ )
33
+
34
+ DSH_PACKAGE = "@deepseek-ai/dsh"
35
+ DSH_VERSION = "0.1.2-rc.1"
36
+ DSH_PACKAGE_SPEC = f"{DSH_PACKAGE}@{DSH_VERSION}"
37
+ DSH_GITHUB_TAG = "dsh-v0.1.2-rc.1"
38
+ DSH_GITHUB_COMMIT = "a66e4702047846cdaa10c66c9d3df3951f5ea70d"
39
+ CORDIS_VERSION_RANGE = "^4.0.2"
40
+ PNPM_VERSION = "11.7.0"
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
+
56
+ TOOLCHAIN_HOME_ENV = "AGENTENGINE_PLUGIN_TOOLCHAIN_HOME"
57
+ PNPM_BIN_ENV = "AGENTENGINE_PNPM_BIN"
58
+
59
+ _VERSION = re.compile(r"\b(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\b")
60
+ _PACKAGE_NAME = re.compile(
61
+ r"^(?:@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*$"
62
+ )
63
+ _LOCK_TIMEOUT_SECONDS = 30.0
64
+ _STALE_LOCK_SECONDS = 10 * 60
65
+ _MAX_MANIFEST_BYTES = 2 * 1024 * 1024
66
+
67
+
68
+ def _to_camel(value: str) -> str:
69
+ head, *tail = value.split("_")
70
+ return head + "".join(part.capitalize() for part in tail)
71
+
72
+
73
+ class _ToolchainModel(BaseModel):
74
+ model_config = ConfigDict(
75
+ alias_generator=_to_camel,
76
+ populate_by_name=True,
77
+ extra="forbid",
78
+ frozen=True,
79
+ )
80
+
81
+
82
+ class DshToolchainStatus(_ToolchainModel):
83
+ package: Literal["@deepseek-ai/dsh"] = DSH_PACKAGE
84
+ expected_version: Literal["0.1.2-rc.1"] = DSH_VERSION
85
+ installed: bool
86
+ usable: bool
87
+ root: str
88
+ executable: str | None = None
89
+ actual_version: str | None = None
90
+ lockfile_present: bool = False
91
+ pnpm_available: bool = False
92
+ pnpm_version: str | None = None
93
+ problem: str | None = None
94
+
95
+
96
+ class DshPluginCreateResult(_ToolchainModel):
97
+ ecosystem: Literal["dsh"] = "dsh"
98
+ package_name: str
99
+ target: str
100
+ entrypoint: str
101
+ bundle_patch: str
102
+
103
+
104
+ class DshPluginValidationResult(_ToolchainModel):
105
+ ecosystem: Literal["dsh"] = "dsh"
106
+ package_name: str
107
+ package_version: str
108
+ host_version: str
109
+ profile_digest: str
110
+ lifecycle: tuple[str, ...] = (
111
+ "install",
112
+ "project",
113
+ "disable",
114
+ "enable",
115
+ "uninstall",
116
+ )
117
+
118
+
119
+ class DshPluginPackResult(_ToolchainModel):
120
+ ecosystem: Literal["dsh"] = "dsh"
121
+ package_name: str
122
+ package_version: str
123
+ artifact: str
124
+
125
+
126
+ class DshToolchainError(RuntimeError):
127
+ """Base error for the managed DSH development toolchain."""
128
+
129
+
130
+ class DshToolchainUnavailableError(DshToolchainError):
131
+ pass
132
+
133
+
134
+ class DshToolchainVersionMismatchError(DshToolchainError):
135
+ pass
136
+
137
+
138
+ class DshToolchainInstallError(DshToolchainError):
139
+ pass
140
+
141
+
142
+ class DshPluginSourceError(DshToolchainError):
143
+ pass
144
+
145
+
146
+ class DshPluginValidationError(DshToolchainError):
147
+ def __init__(
148
+ self,
149
+ stage: str,
150
+ message: str = "DSH plugin validation failed",
151
+ *,
152
+ diagnostic: str | None = None,
153
+ ) -> None:
154
+ super().__init__(message)
155
+ self.stage = stage
156
+ self.diagnostic = diagnostic
157
+
158
+
159
+ class DshPluginPackError(DshToolchainError):
160
+ pass
161
+
162
+
163
+ @dataclass(frozen=True)
164
+ class CommandResult:
165
+ stdout: str = ""
166
+ stderr: str = ""
167
+
168
+
169
+ CommandRunner = Callable[[Sequence[str], Path, Mapping[str, str]], CommandResult]
170
+
171
+
172
+ class DshToolchainManager:
173
+ """Install and resolve the one supported published DSH CLI version."""
174
+
175
+ def __init__(
176
+ self,
177
+ *,
178
+ base_dir: Path | None = None,
179
+ pnpm_command: Sequence[str] | None = None,
180
+ command_runner: CommandRunner | None = None,
181
+ lock_timeout_seconds: float = _LOCK_TIMEOUT_SECONDS,
182
+ ) -> None:
183
+ configured = os.environ.get(TOOLCHAIN_HOME_ENV, "").strip()
184
+ base = (
185
+ base_dir
186
+ or (Path(configured).expanduser() if configured else None)
187
+ or get_global_config_dir() / "plugin-toolchains"
188
+ )
189
+ self._base_dir = base.expanduser().resolve()
190
+ self._root = self._base_dir / "dsh" / DSH_VERSION
191
+ self._pnpm_command = tuple(pnpm_command) if pnpm_command is not None else None
192
+ if self._pnpm_command is not None and not self._pnpm_command:
193
+ raise ValueError("pnpm command cannot be empty")
194
+ self._runner = command_runner or self._run_command
195
+ self._lock_timeout_seconds = lock_timeout_seconds
196
+ self._assert_safe_managed_root(self._root)
197
+
198
+ @property
199
+ def root(self) -> Path:
200
+ return self._root
201
+
202
+ @property
203
+ def executable(self) -> Path:
204
+ return self._root / "node_modules" / ".bin" / "dsh"
205
+
206
+ def status(self) -> DshToolchainStatus:
207
+ """Inspect the managed installation without mutating it."""
208
+
209
+ pnpm_path, pnpm_version = self._inspect_pnpm()
210
+ manifest_valid = self._manifest_is_pinned()
211
+ lock_valid = self._lockfile_is_pinned()
212
+ executable = self.executable
213
+ if not manifest_valid:
214
+ problem = "not_installed" if not self._root.exists() else "manifest_mismatch"
215
+ return self._status(
216
+ installed=False,
217
+ usable=False,
218
+ pnpm_path=pnpm_path,
219
+ pnpm_version=pnpm_version,
220
+ problem=problem,
221
+ )
222
+ if not lock_valid:
223
+ return self._status(
224
+ installed=True,
225
+ usable=False,
226
+ pnpm_path=pnpm_path,
227
+ pnpm_version=pnpm_version,
228
+ problem="lockfile_missing_or_mismatched",
229
+ )
230
+ try:
231
+ resolved = executable.resolve(strict=True)
232
+ except (FileNotFoundError, OSError):
233
+ return self._status(
234
+ installed=True,
235
+ usable=False,
236
+ pnpm_path=pnpm_path,
237
+ pnpm_version=pnpm_version,
238
+ problem="executable_missing",
239
+ )
240
+ if not resolved.is_relative_to(self._root.resolve()):
241
+ return self._status(
242
+ installed=True,
243
+ usable=False,
244
+ pnpm_path=pnpm_path,
245
+ pnpm_version=pnpm_version,
246
+ executable=str(resolved),
247
+ problem="executable_outside_managed_root",
248
+ )
249
+ try:
250
+ actual = self._command_version((str(executable),), cwd=self._root)
251
+ except DshToolchainUnavailableError:
252
+ return self._status(
253
+ installed=True,
254
+ usable=False,
255
+ pnpm_path=pnpm_path,
256
+ pnpm_version=pnpm_version,
257
+ executable=str(executable),
258
+ problem="executable_unavailable",
259
+ )
260
+ if actual != DSH_VERSION:
261
+ return self._status(
262
+ installed=True,
263
+ usable=False,
264
+ pnpm_path=pnpm_path,
265
+ pnpm_version=pnpm_version,
266
+ executable=str(executable),
267
+ actual_version=actual,
268
+ problem="version_mismatch",
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
+ )
280
+ return self._status(
281
+ installed=True,
282
+ usable=True,
283
+ pnpm_path=pnpm_path,
284
+ pnpm_version=pnpm_version,
285
+ executable=str(executable),
286
+ actual_version=actual,
287
+ )
288
+
289
+ def install(self) -> DshToolchainStatus:
290
+ """Atomically install the pinned official npm package with a pnpm lock."""
291
+
292
+ pnpm = self.require_pnpm()
293
+ with self._install_lock():
294
+ current = self.status()
295
+ if current.usable:
296
+ return current
297
+ parent = self._root.parent
298
+ parent.mkdir(parents=True, exist_ok=True, mode=0o700)
299
+ self._clean_abandoned_staging(parent)
300
+ staging = Path(tempfile.mkdtemp(prefix=f".{DSH_VERSION}.install-", dir=parent))
301
+ backup: Path | None = None
302
+ try:
303
+ self._write_install_manifest(staging)
304
+ environment = self._installation_environment()
305
+ self._runner(
306
+ (
307
+ *pnpm,
308
+ "install",
309
+ "--lockfile-only",
310
+ "--ignore-scripts",
311
+ "--config.auto-install-peers=true",
312
+ ),
313
+ staging,
314
+ environment,
315
+ )
316
+ lockfile = staging / "pnpm-lock.yaml"
317
+ if not self._lockfile_is_pinned(lockfile):
318
+ raise DshToolchainInstallError(
319
+ "pnpm did not create a lockfile pinned to the supported DSH package"
320
+ )
321
+ self._runner(
322
+ (
323
+ *pnpm,
324
+ "install",
325
+ "--frozen-lockfile",
326
+ "--ignore-scripts",
327
+ "--config.auto-install-peers=true",
328
+ ),
329
+ staging,
330
+ environment,
331
+ )
332
+ staged_executable = staging / "node_modules" / ".bin" / "dsh"
333
+ resolved = staged_executable.resolve(strict=True)
334
+ if not resolved.is_relative_to(staging.resolve()):
335
+ raise DshToolchainInstallError(
336
+ "installed DSH executable escapes the managed toolchain directory"
337
+ )
338
+ actual = self._command_version((str(staged_executable),), cwd=staging)
339
+ if actual != DSH_VERSION:
340
+ raise DshToolchainVersionMismatchError(
341
+ f"expected DSH {DSH_VERSION}, got {actual}"
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
+ )
347
+ self._write_receipt(staging, actual)
348
+ if self._root.exists():
349
+ backup = parent / f".{DSH_VERSION}.backup-{uuid.uuid4().hex}"
350
+ os.replace(self._root, backup)
351
+ try:
352
+ os.replace(staging, self._root)
353
+ installed = self.status()
354
+ if not installed.usable:
355
+ raise DshToolchainInstallError(
356
+ f"installed DSH toolchain failed verification: {installed.problem}"
357
+ )
358
+ except BaseException:
359
+ if self._root.exists():
360
+ shutil.rmtree(self._root)
361
+ if backup is not None and backup.exists():
362
+ os.replace(backup, self._root)
363
+ raise
364
+ if backup is not None and backup.exists():
365
+ shutil.rmtree(backup)
366
+ return installed
367
+ except DshToolchainError:
368
+ raise
369
+ except Exception as error:
370
+ raise DshToolchainInstallError("could not install the DSH toolchain") from error
371
+ finally:
372
+ if staging.exists():
373
+ shutil.rmtree(staging)
374
+ if backup is not None and backup.exists() and self._root.exists():
375
+ shutil.rmtree(backup)
376
+
377
+ def require_command(self, explicit: str | Path | None = None) -> tuple[str, ...]:
378
+ """Return an exact-version DSH executable, managed unless explicitly set."""
379
+
380
+ if explicit is not None and str(explicit).strip():
381
+ executable = self._resolve_program(str(explicit))
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)
385
+ if actual != DSH_VERSION:
386
+ raise DshToolchainVersionMismatchError(
387
+ f"expected DSH {DSH_VERSION}, got {actual}"
388
+ )
389
+ return (executable,)
390
+ state = self.status()
391
+ if state.problem == "version_mismatch":
392
+ raise DshToolchainVersionMismatchError(
393
+ f"expected DSH {DSH_VERSION}, got {state.actual_version or 'unknown'}"
394
+ )
395
+ if not state.usable or state.executable is None:
396
+ raise DshToolchainUnavailableError(
397
+ "managed DSH toolchain is not installed; run "
398
+ "`agentengine plugin toolchain install`"
399
+ )
400
+ return (state.executable,)
401
+
402
+ def resolve_module_entry(self, package_name: str) -> Path:
403
+ """Resolve one dependency from the pinned DSH installation.
404
+
405
+ Provider sidecars may need the exact Cordis implementation owned by
406
+ their DSH host. Resolution is anchored at the installed DSH package,
407
+ never at a source checkout or the caller's ambient ``node_modules``.
408
+ The result is fenced to the managed toolchain root.
409
+ """
410
+
411
+ self._validate_package_name(package_name)
412
+ self.require_command()
413
+ dsh_manifest = self._root / "node_modules" / DSH_PACKAGE / "package.json"
414
+ try:
415
+ dsh_manifest = dsh_manifest.resolve(strict=True)
416
+ except (FileNotFoundError, OSError) as error:
417
+ raise DshToolchainUnavailableError(
418
+ "managed DSH package manifest is unavailable"
419
+ ) from error
420
+ node = self._resolve_program("node")
421
+ script = (
422
+ "const {createRequire}=require('node:module');"
423
+ f"const resolve=createRequire({json.dumps(str(dsh_manifest))}).resolve;"
424
+ f"process.stdout.write(resolve({json.dumps(package_name)}));"
425
+ )
426
+ try:
427
+ result = self._invoke((node, "-e", script), cwd=self._root)
428
+ except DshToolchainError as error:
429
+ raise DshToolchainUnavailableError(
430
+ f"managed DSH dependency is unavailable: {package_name}"
431
+ ) from error
432
+ raw = result.stdout.strip()
433
+ try:
434
+ resolved = Path(raw).resolve(strict=True)
435
+ except (FileNotFoundError, OSError) as error:
436
+ raise DshToolchainUnavailableError(
437
+ f"managed DSH dependency is unavailable: {package_name}"
438
+ ) from error
439
+ if not resolved.is_relative_to(self._root):
440
+ raise DshToolchainUnavailableError(
441
+ f"managed DSH dependency escapes the toolchain root: {package_name}"
442
+ )
443
+ return resolved
444
+
445
+ def require_pnpm(self) -> tuple[str, ...]:
446
+ command = self._resolve_pnpm_command()
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
+ )
463
+ match = _VERSION.search(result.stdout or result.stderr)
464
+ if match is None:
465
+ raise DshToolchainUnavailableError("pnpm did not report a parseable version")
466
+ if match.group(1) != PNPM_VERSION:
467
+ raise DshToolchainVersionMismatchError(
468
+ f"expected pnpm {PNPM_VERSION}, got {match.group(1)}"
469
+ )
470
+ return command
471
+
472
+ def _status(
473
+ self,
474
+ *,
475
+ installed: bool,
476
+ usable: bool,
477
+ pnpm_path: str | None,
478
+ pnpm_version: str | None,
479
+ problem: str | None = None,
480
+ executable: str | None = None,
481
+ actual_version: str | None = None,
482
+ ) -> DshToolchainStatus:
483
+ return DshToolchainStatus(
484
+ installed=installed,
485
+ usable=usable,
486
+ root=str(self._root),
487
+ executable=executable,
488
+ actual_version=actual_version,
489
+ lockfile_present=(self._root / "pnpm-lock.yaml").is_file(),
490
+ pnpm_available=pnpm_path is not None,
491
+ pnpm_version=pnpm_version,
492
+ problem=problem,
493
+ )
494
+
495
+ def _inspect_pnpm(self) -> tuple[str | None, str | None]:
496
+ try:
497
+ command = self.require_pnpm()
498
+ result = self._runner(
499
+ (*command, "--version"),
500
+ self._root,
501
+ self._pnpm_environment(),
502
+ )
503
+ except DshToolchainError:
504
+ return None, None
505
+ match = _VERSION.search(result.stdout or result.stderr)
506
+ return " ".join(command), match.group(1) if match else None
507
+
508
+ def _resolve_pnpm_command(self) -> tuple[str, ...]:
509
+ if self._pnpm_command is not None:
510
+ command = self._pnpm_command
511
+ else:
512
+ configured = os.environ.get(PNPM_BIN_ENV, "").strip()
513
+ if configured:
514
+ command = (configured,)
515
+ else:
516
+ corepack = shutil.which("corepack")
517
+ command = (
518
+ (corepack, f"pnpm@{PNPM_VERSION}")
519
+ if corepack is not None
520
+ else ("pnpm",)
521
+ )
522
+ executable = self._resolve_program(command[0])
523
+ return (executable, *command[1:])
524
+
525
+ def _manifest_is_pinned(self, path: Path | None = None) -> bool:
526
+ manifest_path = path or self._root / "package.json"
527
+ try:
528
+ payload = json.loads(manifest_path.read_text(encoding="utf-8"))
529
+ except (FileNotFoundError, OSError, UnicodeError, json.JSONDecodeError):
530
+ return False
531
+ return (
532
+ isinstance(payload, dict)
533
+ and payload.get("private") is True
534
+ and payload.get("packageManager") == f"pnpm@{PNPM_VERSION}"
535
+ and isinstance(payload.get("dependencies"), dict)
536
+ and payload["dependencies"].get(DSH_PACKAGE) == DSH_VERSION
537
+ )
538
+
539
+ def _lockfile_is_pinned(self, path: Path | None = None) -> bool:
540
+ lockfile = path or self._root / "pnpm-lock.yaml"
541
+ try:
542
+ if lockfile.stat().st_size > _MAX_MANIFEST_BYTES:
543
+ return False
544
+ value = lockfile.read_text(encoding="utf-8")
545
+ except (FileNotFoundError, OSError, UnicodeError):
546
+ return False
547
+ return DSH_PACKAGE in value and DSH_VERSION in value
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
+
577
+ def _command_version(self, command: Sequence[str], *, cwd: Path) -> str:
578
+ result = self._invoke((*command, "--version"), cwd=cwd)
579
+ match = _VERSION.search(result.stdout or result.stderr)
580
+ if match is None:
581
+ raise DshToolchainUnavailableError("DSH did not report a parseable version")
582
+ return match.group(1)
583
+
584
+ def _invoke(self, command: Sequence[str], *, cwd: Path) -> CommandResult:
585
+ try:
586
+ return self._runner(tuple(command), cwd, dsh_subprocess_environment())
587
+ except DshToolchainError:
588
+ raise
589
+ except Exception as error:
590
+ raise DshToolchainUnavailableError("toolchain command could not be executed") from error
591
+
592
+ @staticmethod
593
+ def _resolve_program(value: str) -> str:
594
+ candidate = Path(value).expanduser()
595
+ if candidate.is_absolute() or len(candidate.parts) > 1:
596
+ if not candidate.is_file():
597
+ raise DshToolchainUnavailableError(f"required executable is unavailable: {value}")
598
+ return str(candidate.resolve())
599
+ resolved = shutil.which(value)
600
+ if resolved is None:
601
+ raise DshToolchainUnavailableError(f"required executable is unavailable: {value}")
602
+ return resolved
603
+
604
+ @staticmethod
605
+ def _validate_package_name(name: str) -> None:
606
+ if len(name) > 214 or not _PACKAGE_NAME.fullmatch(name):
607
+ raise DshToolchainUnavailableError("invalid managed DSH package name")
608
+
609
+ def _write_install_manifest(self, root: Path) -> None:
610
+ self._write_json(
611
+ root / "package.json",
612
+ {
613
+ "name": "agentengine-managed-dsh-toolchain",
614
+ "private": True,
615
+ "packageManager": f"pnpm@{PNPM_VERSION}",
616
+ "dependencies": {DSH_PACKAGE: DSH_VERSION},
617
+ },
618
+ )
619
+
620
+ def _write_receipt(self, root: Path, actual: str) -> None:
621
+ self._write_json(
622
+ root / "toolchain.json",
623
+ {
624
+ "schemaVersion": 1,
625
+ "package": DSH_PACKAGE,
626
+ "requestedVersion": DSH_VERSION,
627
+ "actualVersion": actual,
628
+ "githubTag": DSH_GITHUB_TAG,
629
+ "githubCommit": DSH_GITHUB_COMMIT,
630
+ "distribution": "core",
631
+ "corePackages": list(DSH_CORE_PACKAGES),
632
+ "packageManager": f"pnpm@{PNPM_VERSION}",
633
+ },
634
+ )
635
+
636
+ @staticmethod
637
+ def _write_json(path: Path, value: object) -> None:
638
+ path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
639
+ temporary = path.with_name(f".{path.name}.{uuid.uuid4().hex}.tmp")
640
+ try:
641
+ temporary.write_text(
642
+ json.dumps(value, ensure_ascii=False, indent=2) + "\n",
643
+ encoding="utf-8",
644
+ )
645
+ temporary.chmod(0o600)
646
+ os.replace(temporary, path)
647
+ finally:
648
+ temporary.unlink(missing_ok=True)
649
+
650
+ @staticmethod
651
+ def _installation_environment() -> dict[str, str]:
652
+ environment = dsh_subprocess_environment()
653
+ environment.update(
654
+ {
655
+ "CI": "1",
656
+ "COREPACK_ENABLE_PROJECT_SPEC": "0",
657
+ "NPM_CONFIG_AUDIT": "false",
658
+ "NPM_CONFIG_FUND": "false",
659
+ }
660
+ )
661
+ return environment
662
+
663
+ @staticmethod
664
+ def _pnpm_environment() -> dict[str, str]:
665
+ environment = dsh_subprocess_environment()
666
+ environment["COREPACK_ENABLE_PROJECT_SPEC"] = "0"
667
+ return environment
668
+
669
+ @contextmanager
670
+ def _install_lock(self) -> Iterator[None]:
671
+ parent = self._root.parent
672
+ parent.mkdir(parents=True, exist_ok=True, mode=0o700)
673
+ lock = parent / f".{DSH_VERSION}.install.lock"
674
+ deadline = time.monotonic() + self._lock_timeout_seconds
675
+ while True:
676
+ try:
677
+ lock.mkdir(mode=0o700)
678
+ self._write_json(lock / "owner.json", {"pid": os.getpid()})
679
+ break
680
+ except FileExistsError:
681
+ if self._lock_is_stale(lock):
682
+ try:
683
+ shutil.rmtree(lock)
684
+ except FileNotFoundError:
685
+ pass
686
+ continue
687
+ if time.monotonic() >= deadline:
688
+ raise DshToolchainInstallError(
689
+ "another DSH toolchain installation is still in progress"
690
+ )
691
+ time.sleep(0.05)
692
+ try:
693
+ yield
694
+ finally:
695
+ shutil.rmtree(lock, ignore_errors=True)
696
+
697
+ @staticmethod
698
+ def _lock_is_stale(lock: Path) -> bool:
699
+ try:
700
+ age = time.time() - lock.stat().st_mtime
701
+ except FileNotFoundError:
702
+ return False
703
+ if age <= _STALE_LOCK_SECONDS:
704
+ return False
705
+ try:
706
+ payload = json.loads((lock / "owner.json").read_text(encoding="utf-8"))
707
+ pid = int(payload.get("pid", -1))
708
+ except (OSError, ValueError, TypeError, json.JSONDecodeError):
709
+ return True
710
+ if pid <= 0:
711
+ return True
712
+ try:
713
+ os.kill(pid, 0)
714
+ except ProcessLookupError:
715
+ return True
716
+ except (PermissionError, OSError):
717
+ return False
718
+ return False
719
+
720
+ @staticmethod
721
+ def _clean_abandoned_staging(parent: Path) -> None:
722
+ for candidate in parent.glob(f".{DSH_VERSION}.install-*"):
723
+ if candidate.is_dir() and candidate.parent == parent:
724
+ shutil.rmtree(candidate)
725
+
726
+ def _assert_safe_managed_root(self, root: Path) -> None:
727
+ if root.name != DSH_VERSION or root.parent.name != "dsh":
728
+ raise ValueError("managed DSH root must end in dsh/<pinned-version>")
729
+ if root in {Path(root.anchor), Path.home().resolve(), self._base_dir}:
730
+ raise ValueError("managed DSH root is too broad")
731
+
732
+ @staticmethod
733
+ def _run_command(
734
+ command: Sequence[str],
735
+ cwd: Path,
736
+ environment: Mapping[str, str],
737
+ ) -> CommandResult:
738
+ try:
739
+ completed = subprocess.run(
740
+ list(command),
741
+ cwd=cwd,
742
+ env=dict(environment),
743
+ check=False,
744
+ capture_output=True,
745
+ text=True,
746
+ timeout=180,
747
+ )
748
+ except (OSError, subprocess.TimeoutExpired) as error:
749
+ raise DshToolchainUnavailableError("toolchain command did not complete") from error
750
+ if completed.returncode != 0:
751
+ diagnostic = _redact_diagnostic(completed.stderr or completed.stdout)
752
+ raise DshToolchainInstallError(
753
+ f"toolchain command failed with exit code {completed.returncode}"
754
+ + (f": {diagnostic[-2000:]}" if diagnostic else "")
755
+ )
756
+ return CommandResult(stdout=completed.stdout, stderr=completed.stderr)
757
+
758
+
759
+ class DshPluginDeveloper:
760
+ """Create, validate, and pack standard DSH npm bundle projects."""
761
+
762
+ def __init__(
763
+ self,
764
+ *,
765
+ toolchain: DshToolchainManager | None = None,
766
+ explicit_dsh: str | Path | None = None,
767
+ bridge_factory: Callable[..., DshProfilePluginBridge] = DshProfilePluginBridge,
768
+ command_runner: CommandRunner | None = None,
769
+ ) -> None:
770
+ self._toolchain = toolchain or DshToolchainManager(command_runner=command_runner)
771
+ self._explicit_dsh = explicit_dsh
772
+ self._bridge_factory = bridge_factory
773
+ self._runner = command_runner or DshToolchainManager._run_command
774
+
775
+ def create(self, target: Path, *, package_name: str | None = None) -> DshPluginCreateResult:
776
+ target = target.expanduser().resolve()
777
+ if target.exists():
778
+ raise DshPluginSourceError("plugin target already exists")
779
+ name = package_name or self._default_package_name(target.name)
780
+ self._validate_package_name(name)
781
+ target.parent.mkdir(parents=True, exist_ok=True)
782
+ target.mkdir(mode=0o755)
783
+ try:
784
+ package = {
785
+ "name": name,
786
+ "version": "0.1.0",
787
+ "description": "A DeepSeek Harness Cordis plugin bundle.",
788
+ "type": "module",
789
+ "main": "index.js",
790
+ "types": "index.d.ts",
791
+ "files": ["index.js", "index.d.ts", "cordis.patch.yml"],
792
+ "engines": {"node": ">=22.19.0"},
793
+ "peerDependencies": {"@deepseek-ai/cordis": CORDIS_VERSION_RANGE},
794
+ "dsh": {"bundle": {"patch": "./cordis.patch.yml"}},
795
+ }
796
+ (target / "package.json").write_text(
797
+ json.dumps(package, ensure_ascii=False, indent=2) + "\n",
798
+ encoding="utf-8",
799
+ )
800
+ (target / "cordis.patch.yml").write_text(
801
+ "- insert:\n"
802
+ " - id: plugin-main\n"
803
+ f" name: {json.dumps(name)}\n",
804
+ encoding="utf-8",
805
+ )
806
+ symbol = re.sub(r"[^A-Za-z0-9]+", "-", name).strip("-") or "plugin"
807
+ (target / "index.js").write_text(
808
+ f"export const name = {json.dumps(symbol)}\n\n"
809
+ "/** @param {import('@deepseek-ai/cordis').Context} ctx */\n"
810
+ "export function apply(ctx) {\n"
811
+ " // Register resources through Cordis effects so unload is reversible.\n"
812
+ " ctx.effect(() => () => {})\n"
813
+ "}\n",
814
+ encoding="utf-8",
815
+ )
816
+ (target / "index.d.ts").write_text(
817
+ "import type { Context } from '@deepseek-ai/cordis'\n\n"
818
+ "export declare const name: string\n"
819
+ "export declare function apply(ctx: Context): void\n",
820
+ encoding="utf-8",
821
+ )
822
+ except BaseException:
823
+ shutil.rmtree(target, ignore_errors=True)
824
+ raise
825
+ return DshPluginCreateResult(
826
+ package_name=name,
827
+ target=str(target),
828
+ entrypoint="index.js",
829
+ bundle_patch="cordis.patch.yml",
830
+ )
831
+
832
+ def validate(self, source: str | Path) -> DshPluginValidationResult:
833
+ local_source, _package = self._resolve_local_bundle(source)
834
+ source_value = str(local_source) if local_source is not None else str(source).strip()
835
+ command = self._toolchain.require_command(self._explicit_dsh)
836
+ stage = "start"
837
+ with tempfile.TemporaryDirectory(prefix="agentengine-dsh-validate-") as directory:
838
+ root = Path(directory)
839
+ try:
840
+ with self._bridge_factory(
841
+ dsh_home=root / "home",
842
+ profile="validate",
843
+ dsh_command=command,
844
+ cwd=(local_source.parent if local_source is not None else Path.cwd()),
845
+ ) as bridge:
846
+ stage = "install"
847
+ installed = bridge.install_plugin(
848
+ source_value,
849
+ accept_host_permissions=True,
850
+ )
851
+ stage = "project"
852
+ projection = bridge.project_profile()
853
+ stage = "disable"
854
+ bridge.set_enabled(installed.name, enabled=False)
855
+ stage = "enable"
856
+ bridge.set_enabled(installed.name, enabled=True)
857
+ stage = "uninstall"
858
+ bridge.uninstall_plugin(installed.name)
859
+ return DshPluginValidationResult(
860
+ package_name=installed.name,
861
+ package_version=installed.version,
862
+ host_version=projection.host_version,
863
+ profile_digest=projection.config_digest,
864
+ )
865
+ except DshToolchainError:
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
874
+ except DshBridgeError as error:
875
+ raise DshPluginValidationError(
876
+ stage,
877
+ diagnostic=_redact_diagnostic(str(error)),
878
+ ) from error
879
+ except Exception as error:
880
+ raise DshPluginValidationError(
881
+ stage,
882
+ diagnostic=_redact_diagnostic(str(error)),
883
+ ) from error
884
+
885
+ def pack(
886
+ self,
887
+ source: Path,
888
+ *,
889
+ output_dir: Path | None = None,
890
+ ) -> DshPluginPackResult:
891
+ local_source, package = self._resolve_local_bundle(source)
892
+ assert local_source is not None
893
+ if not local_source.is_dir():
894
+ raise DshPluginSourceError("only a DSH bundle source directory can be packed")
895
+ output = (output_dir or local_source / "dist").expanduser().resolve()
896
+ output.mkdir(parents=True, exist_ok=True)
897
+ before = {item.resolve() for item in output.glob("*.tgz") if item.is_file()}
898
+ pnpm = self._toolchain.require_pnpm()
899
+ environment = dsh_subprocess_environment()
900
+ # Keep the pinned pnpm selected above even when an ancestor workspace
901
+ # declares another package manager through Corepack.
902
+ environment["COREPACK_ENABLE_PROJECT_SPEC"] = "0"
903
+ try:
904
+ self._runner(
905
+ (*pnpm, "pack", "--pack-destination", str(output)),
906
+ local_source,
907
+ environment,
908
+ )
909
+ except DshToolchainError as error:
910
+ raise DshPluginPackError("pnpm could not pack the DSH bundle") from error
911
+ except Exception as error:
912
+ raise DshPluginPackError("pnpm could not pack the DSH bundle") from error
913
+ created = [
914
+ item.resolve()
915
+ for item in output.glob("*.tgz")
916
+ if item.is_file() and item.resolve() not in before
917
+ ]
918
+ if len(created) != 1 or not created[0].is_relative_to(output):
919
+ raise DshPluginPackError("pnpm pack did not produce exactly one bounded npm tarball")
920
+ return DshPluginPackResult(
921
+ package_name=str(package["name"]),
922
+ package_version=str(package["version"]),
923
+ artifact=str(created[0]),
924
+ )
925
+
926
+ @classmethod
927
+ def _resolve_local_bundle(
928
+ cls,
929
+ source: str | Path,
930
+ ) -> tuple[Path | None, dict[str, Any]]:
931
+ raw = str(source).strip()
932
+ candidate = Path(raw).expanduser()
933
+ looks_local = isinstance(source, Path) or candidate.is_absolute() or raw.startswith(".")
934
+ if not candidate.exists():
935
+ if looks_local:
936
+ raise DshPluginSourceError("local DSH plugin source does not exist")
937
+ if not raw or raw.startswith("-") or any(char in raw for char in "\r\n\0"):
938
+ raise DshPluginSourceError("invalid DSH plugin source")
939
+ return None, {}
940
+ root = candidate.resolve()
941
+ if root.is_file() and root.name.endswith(".tgz"):
942
+ return root, {}
943
+ if root.is_file() and root.name == "package.json":
944
+ root = root.parent
945
+ if not root.is_dir():
946
+ raise DshPluginSourceError("local DSH plugin source must be a directory")
947
+ manifest_path = root / "package.json"
948
+ try:
949
+ if manifest_path.stat().st_size > _MAX_MANIFEST_BYTES:
950
+ raise DshPluginSourceError("DSH plugin package.json is too large")
951
+ package = json.loads(manifest_path.read_text(encoding="utf-8"))
952
+ except FileNotFoundError:
953
+ raise DshPluginSourceError("DSH plugin package.json is missing") from None
954
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
955
+ raise DshPluginSourceError("DSH plugin package.json is invalid") from error
956
+ if not isinstance(package, dict):
957
+ raise DshPluginSourceError("DSH plugin package.json must be an object")
958
+ name = package.get("name")
959
+ version = package.get("version")
960
+ if not isinstance(name, str) or not isinstance(version, str) or not version.strip():
961
+ raise DshPluginSourceError("DSH plugin package name/version is invalid")
962
+ cls._validate_package_name(name)
963
+ dsh = package.get("dsh")
964
+ bundle = dsh.get("bundle") if isinstance(dsh, dict) else None
965
+ patch = bundle.get("patch") if isinstance(bundle, dict) else None
966
+ if not isinstance(patch, str) or not patch.strip():
967
+ raise DshPluginSourceError("package.json must declare dsh.bundle.patch")
968
+ relative = Path(patch)
969
+ target = (root / relative).resolve()
970
+ if relative.is_absolute() or ".." in relative.parts or not target.is_relative_to(root):
971
+ raise DshPluginSourceError("dsh.bundle.patch must stay inside the package")
972
+ if not target.is_file():
973
+ raise DshPluginSourceError("declared DSH bundle patch does not exist")
974
+ return root, package
975
+
976
+ @staticmethod
977
+ def _default_package_name(target_name: str) -> str:
978
+ value = re.sub(r"[^a-z0-9._-]+", "-", target_name.casefold()).strip("-._")
979
+ if not value:
980
+ value = "plugin"
981
+ return value if value.startswith("dsh-") else f"dsh-{value}"
982
+
983
+ @staticmethod
984
+ def _validate_package_name(name: str) -> None:
985
+ if len(name) > 214 or not _PACKAGE_NAME.fullmatch(name):
986
+ raise DshPluginSourceError("plugin name must be a valid lowercase npm package name")
987
+
988
+
989
+ __all__ = [
990
+ "CORDIS_VERSION_RANGE",
991
+ "DSH_CORE_PACKAGES",
992
+ "DSH_GITHUB_COMMIT",
993
+ "DSH_GITHUB_TAG",
994
+ "DSH_PACKAGE",
995
+ "DSH_PACKAGE_SPEC",
996
+ "DSH_VERSION",
997
+ "PNPM_BIN_ENV",
998
+ "PNPM_VERSION",
999
+ "TOOLCHAIN_HOME_ENV",
1000
+ "CommandResult",
1001
+ "DshPluginCreateResult",
1002
+ "DshPluginDeveloper",
1003
+ "DshPluginPackError",
1004
+ "DshPluginPackResult",
1005
+ "DshPluginSourceError",
1006
+ "DshPluginValidationError",
1007
+ "DshPluginValidationResult",
1008
+ "DshToolchainError",
1009
+ "DshToolchainInstallError",
1010
+ "DshToolchainManager",
1011
+ "DshToolchainStatus",
1012
+ "DshToolchainUnavailableError",
1013
+ "DshToolchainVersionMismatchError",
1014
+ ]
1015
+
1016
+
1017
+ def _redact_diagnostic(value: str) -> str:
1018
+ value = re.sub(r"(https?://)[^/\s:@]+:[^/\s@]+@", r"\1[redacted]@", value, flags=re.I)
1019
+ return re.sub(
1020
+ r"((?:token|password|authorization|_authToken)\s*[:=]\s*)[^\s]+",
1021
+ r"\1[redacted]",
1022
+ value,
1023
+ flags=re.I,
1024
+ ).strip()