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,870 @@
1
+ import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from 'node:crypto'
2
+
3
+ export const name = 'ksadk-dsh-capability-host'
4
+ export const inject = ['tools', 'webServer', 'connection']
5
+
6
+ export const HOST_PROTOCOL = 'ksadk.dsh-capability-host/v1'
7
+ export const HOST_VERSION = '1.0.0'
8
+ export const MCP_PROTOCOL_VERSION = '2025-06-18'
9
+ export const DEFAULT_CALL_TIMEOUT_MS = 60_000
10
+ export const DEFAULT_MAX_ARGUMENT_BYTES = 256 * 1024
11
+ export const DEFAULT_MAX_RESULT_BYTES = 1024 * 1024
12
+ export const DEFAULT_MAX_REQUEST_BYTES = 1024 * 1024
13
+ export const DEFAULT_MAX_IN_FLIGHT = 64
14
+
15
+ const SUPPORTED_MCP_PROTOCOLS = new Set([
16
+ MCP_PROTOCOL_VERSION,
17
+ '2025-03-26',
18
+ '2024-11-05',
19
+ ])
20
+ const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/
21
+ const TOOL_NAME_PATTERN = /^[A-Za-z0-9_.:-]+$/
22
+
23
+ class RequestTooLargeError extends Error {}
24
+
25
+ function byteLength(value) {
26
+ return Buffer.byteLength(JSON.stringify(value), 'utf8')
27
+ }
28
+
29
+ function assertUnicodeScalars(value) {
30
+ if (typeof value === 'string') {
31
+ for (let index = 0; index < value.length; index += 1) {
32
+ const code = value.charCodeAt(index)
33
+ if (code >= 0xD800 && code <= 0xDBFF) {
34
+ const next = value.charCodeAt(index + 1)
35
+ if (!(next >= 0xDC00 && next <= 0xDFFF)) {
36
+ throw new Error('DSH tool schema contains invalid Unicode')
37
+ }
38
+ index += 1
39
+ } else if (code >= 0xDC00 && code <= 0xDFFF) {
40
+ throw new Error('DSH tool schema contains invalid Unicode')
41
+ }
42
+ }
43
+ return
44
+ }
45
+ if (Array.isArray(value)) {
46
+ for (const item of value) assertUnicodeScalars(item)
47
+ return
48
+ }
49
+ if (value !== null && typeof value === 'object') {
50
+ for (const [key, child] of Object.entries(value)) {
51
+ assertUnicodeScalars(key)
52
+ assertUnicodeScalars(child)
53
+ }
54
+ }
55
+ }
56
+
57
+ function canonical(value) {
58
+ if (value === null) return Buffer.from('n;')
59
+ if (typeof value === 'boolean') return Buffer.from(value ? 'b1;' : 'b0;')
60
+ if (typeof value === 'number') {
61
+ if (!Number.isFinite(value)) throw new Error('tool schemas require finite JSON numbers')
62
+ const bits = Buffer.allocUnsafe(8)
63
+ bits.writeDoubleBE(Object.is(value, -0) ? 0 : value)
64
+ return Buffer.from(`d${bits.toString('hex')};`)
65
+ }
66
+ if (typeof value === 'string') {
67
+ const encoded = Buffer.from(value, 'utf8')
68
+ return Buffer.concat([Buffer.from(`s${encoded.length}:`), encoded])
69
+ }
70
+ if (Array.isArray(value)) {
71
+ return Buffer.concat([Buffer.from(`a${value.length}:`), ...value.map(canonical)])
72
+ }
73
+ if (value !== null && typeof value === 'object') {
74
+ const keys = Object.keys(value).sort((left, right) =>
75
+ Buffer.compare(Buffer.from(left, 'utf8'), Buffer.from(right, 'utf8')))
76
+ return Buffer.concat([
77
+ Buffer.from(`o${keys.length}:`),
78
+ ...keys.flatMap((key) => [canonical(key), canonical(value[key])]),
79
+ ])
80
+ }
81
+ throw new Error('tool schemas must contain only JSON values')
82
+ }
83
+
84
+ function digest(value) {
85
+ return `sha256:${createHash('sha256').update(canonical(value)).digest('hex')}`
86
+ }
87
+
88
+ function positiveInteger(value, fallback, label, maximum) {
89
+ const resolved = value === undefined ? fallback : value
90
+ if (!Number.isSafeInteger(resolved) || resolved < 1 || resolved > maximum) {
91
+ throw new Error(`${label} must be a positive bounded integer`)
92
+ }
93
+ return resolved
94
+ }
95
+
96
+ function requiredEnvironment(name, maximum) {
97
+ const value = process.env[name]
98
+ if (typeof value !== 'string' || value.length < 1 || value.length > maximum || value.includes('\0')) {
99
+ throw new Error(`${name} is required and must be bounded`)
100
+ }
101
+ return value
102
+ }
103
+
104
+ function secureTokenEqual(actual, expected) {
105
+ const left = Buffer.from(actual, 'utf8')
106
+ const right = Buffer.from(expected, 'utf8')
107
+ return left.length === right.length && timingSafeEqual(left, right)
108
+ }
109
+
110
+ function parseScopedToken(presented, token, profileDigest, tools, allowExpired = false) {
111
+ const parts = presented.split('.')
112
+ if (parts[0] === 'ks2') return parseResourceToken(parts, token, profileDigest, tools, allowExpired)
113
+ if (parts.length !== 3 || parts[0] !== 'ks1') return null
114
+ const [, payloadEncoded, signature] = parts
115
+ const expected = createHmac('sha256', token).update(payloadEncoded).digest('base64url')
116
+ if (!secureTokenEqual(signature, expected)) return null
117
+ let payload
118
+ try {
119
+ payload = JSON.parse(Buffer.from(payloadEncoded, 'base64url').toString('utf8'))
120
+ } catch {
121
+ return null
122
+ }
123
+ if (
124
+ payload === null ||
125
+ typeof payload !== 'object' ||
126
+ Array.isArray(payload) ||
127
+ payload.v !== 1 ||
128
+ payload.profileDigest !== profileDigest ||
129
+ typeof payload.jti !== 'string' ||
130
+ !/^[A-Za-z0-9_-]{16,64}$/.test(payload.jti) ||
131
+ !Number.isSafeInteger(payload.exp) ||
132
+ (!allowExpired && payload.exp < Math.floor(Date.now() / 1000)) ||
133
+ payload.exp > Math.floor(Date.now() / 1000) + 86_400 ||
134
+ payload.aliases === null ||
135
+ typeof payload.aliases !== 'object' ||
136
+ Array.isArray(payload.aliases) ||
137
+ Object.keys(payload.aliases).length < 1 ||
138
+ Object.keys(payload.aliases).length > 32
139
+ ) return null
140
+ const aliases = new Map(Object.entries(payload.aliases))
141
+ if ([...aliases].some(([alias, source]) =>
142
+ !/^[A-Za-z0-9_-]{1,64}$/.test(alias) ||
143
+ typeof source !== 'string' ||
144
+ !tools.some((tool) => tool.name === source)
145
+ )) return null
146
+ return { root: false, scopeId: signature, aliases, expiresAt: payload.exp }
147
+ }
148
+
149
+ function parseResourceToken(parts, token, profileDigest, tools, allowExpired) {
150
+ if (parts.length !== 3) return null
151
+ const [, encoded, signature] = parts
152
+ const expected = createHmac('sha256', token).update(`ks2.${encoded}`).digest('base64url')
153
+ if (!secureTokenEqual(signature, expected)) return null
154
+ let payload
155
+ try { payload = JSON.parse(Buffer.from(encoded, 'base64url').toString('utf8')) }
156
+ catch { return null }
157
+ const record = value => value !== null && typeof value === 'object' && !Array.isArray(value)
158
+ const ref = value => typeof value === 'string' && /^\S{1,256}$/u.test(value)
159
+ const now = Math.floor(Date.now() / 1000)
160
+ if (!record(payload) || payload.v !== 2 || payload.profileDigest !== profileDigest ||
161
+ !ref(payload.generationId) || !ref(payload.activationId) ||
162
+ !DIGEST_PATTERN.test(payload.buildDigest ?? '') || !DIGEST_PATTERN.test(payload.bindingSnapshotDigest ?? '') ||
163
+ !Number.isSafeInteger(payload.issuedAt) || !Number.isSafeInteger(payload.expiresAt) ||
164
+ payload.issuedAt > now + 5 || payload.expiresAt <= payload.issuedAt ||
165
+ payload.expiresAt - payload.issuedAt > 600 || (!allowExpired && payload.expiresAt <= now) ||
166
+ typeof payload.jti !== 'string' || !/^[A-Za-z0-9_-]{16,64}$/.test(payload.jti) ||
167
+ !record(payload.identity) || !record(payload.aliases) || !record(payload.resources)) return null
168
+ const identityKeys = ['tenantRef', 'resourcePrincipalRef', 'actorRef', 'memorySubjectRef', 'agentId', 'sessionRef']
169
+ if (Object.keys(payload.identity).length !== identityKeys.length ||
170
+ identityKeys.some(key => !ref(payload.identity[key]))) return null
171
+ const aliases = new Map(Object.entries(payload.aliases))
172
+ if (!aliases.size || aliases.size > 32 || [...aliases].some(([alias, source]) =>
173
+ !/^[A-Za-z0-9_-]{1,64}$/.test(alias) || typeof source !== 'string' ||
174
+ !tools.some(tool => tool.name === source))) return null
175
+ const resources = new Map(Object.entries(payload.resources))
176
+ if (!resources.size || resources.size > 32 || [...resources].some(([source, item]) =>
177
+ ![...aliases.values()].includes(source) || !record(item) || !ref(item.bindingId) ||
178
+ item.operation !== source || typeof item.handle !== 'string' ||
179
+ !/^[A-Za-z0-9_-]{32,256}$/.test(item.handle))) return null
180
+ return { root: false, scopeId: signature, aliases, resources, expiresAt: payload.expiresAt }
181
+ }
182
+
183
+ function authorize(request, token, profileDigest, tools, revokedScopes) {
184
+ const header = request.headers.authorization
185
+ if (typeof header !== 'string' || !header.startsWith('Bearer ')) return null
186
+ if (secureTokenEqual(header, `Bearer ${token}`)) {
187
+ return { root: true, scopeId: 'root', aliases: null, expiresAt: null }
188
+ }
189
+ const now = Math.floor(Date.now() / 1000)
190
+ for (const [scopeId, expiresAt] of revokedScopes) {
191
+ if (expiresAt < now) revokedScopes.delete(scopeId)
192
+ }
193
+ const authorization = parseScopedToken(
194
+ header.slice('Bearer '.length), token, profileDigest, tools)
195
+ if (authorization === null || revokedScopes.has(authorization.scopeId)) return null
196
+ return authorization
197
+ }
198
+
199
+ function originAllowed(request) {
200
+ const origin = request.headers.origin
201
+ if (origin === undefined) return true
202
+ if (Array.isArray(origin) || origin.length > 2048) return false
203
+ try {
204
+ const parsed = new URL(origin)
205
+ return (parsed.protocol === 'http:' || parsed.protocol === 'https:') &&
206
+ (parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1' || parsed.hostname === '[::1]')
207
+ } catch {
208
+ return false
209
+ }
210
+ }
211
+
212
+ function writeJson(response, status, payload, extraHeaders = {}) {
213
+ const body = Buffer.from(JSON.stringify(payload), 'utf8')
214
+ response.writeHead(status, {
215
+ 'Cache-Control': 'no-store',
216
+ 'Content-Type': 'application/json; charset=utf-8',
217
+ 'Content-Length': String(body.length),
218
+ ...extraHeaders,
219
+ })
220
+ response.end(body)
221
+ }
222
+
223
+ function writeEmpty(response, status) {
224
+ response.writeHead(status, {
225
+ 'Cache-Control': 'no-store',
226
+ 'Content-Length': '0',
227
+ })
228
+ response.end()
229
+ }
230
+
231
+ function jsonRpcError(id, code, message, data) {
232
+ return {
233
+ jsonrpc: '2.0',
234
+ id: id ?? null,
235
+ error: {
236
+ code,
237
+ message,
238
+ ...(data === undefined ? {} : { data }),
239
+ },
240
+ }
241
+ }
242
+
243
+ function readBody(request, maximum) {
244
+ return new Promise((resolve, reject) => {
245
+ const declared = Number(request.headers['content-length'])
246
+ if (Number.isFinite(declared) && declared > maximum) {
247
+ request.resume()
248
+ reject(new RequestTooLargeError('request body exceeds the configured limit'))
249
+ return
250
+ }
251
+ const chunks = []
252
+ let size = 0
253
+ let settled = false
254
+ request.on('data', (chunk) => {
255
+ if (settled) return
256
+ size += chunk.length
257
+ if (size > maximum) {
258
+ settled = true
259
+ chunks.length = 0
260
+ reject(new RequestTooLargeError('request body exceeds the configured limit'))
261
+ return
262
+ }
263
+ chunks.push(chunk)
264
+ })
265
+ request.on('end', () => {
266
+ if (!settled) resolve(Buffer.concat(chunks).toString('utf8'))
267
+ })
268
+ request.on('error', (error) => {
269
+ if (!settled) reject(error)
270
+ })
271
+ })
272
+ }
273
+
274
+ function snapshotTools(runtime, maximumBytes) {
275
+ const raw = runtime.schemas()
276
+ if (!Array.isArray(raw) || raw.length > 2048) {
277
+ throw new Error('DSH tool inventory is invalid or too large')
278
+ }
279
+ const seen = new Set()
280
+ const tools = raw.map((schema) => {
281
+ if (schema === null || typeof schema !== 'object' || Array.isArray(schema)) {
282
+ throw new Error('DSH emitted an invalid tool schema')
283
+ }
284
+ const { name, description, parameters } = schema
285
+ if (
286
+ typeof name !== 'string' ||
287
+ name.length < 1 ||
288
+ name.length > 128 ||
289
+ !TOOL_NAME_PATTERN.test(name) ||
290
+ seen.has(name)
291
+ ) {
292
+ throw new Error('DSH emitted an invalid or duplicate tool name')
293
+ }
294
+ if (typeof description !== 'string' || description.length > 16_384) {
295
+ throw new Error(`DSH tool ${name} emitted an invalid description`)
296
+ }
297
+ if (parameters === null || typeof parameters !== 'object' || Array.isArray(parameters)) {
298
+ throw new Error(`DSH tool ${name} emitted an invalid parameters schema`)
299
+ }
300
+ seen.add(name)
301
+ const detached = JSON.parse(JSON.stringify({
302
+ name,
303
+ description: Array.from(description).slice(0, 1024).join(''),
304
+ inputSchema: parameters,
305
+ }))
306
+ assertUnicodeScalars(detached)
307
+ if (byteLength(detached) > maximumBytes) {
308
+ throw new Error(`DSH tool ${name} schema exceeds the configured limit`)
309
+ }
310
+ return detached
311
+ })
312
+ tools.sort((left, right) =>
313
+ Buffer.compare(Buffer.from(left.name, 'utf8'), Buffer.from(right.name, 'utf8')))
314
+ if (byteLength(tools) > maximumBytes) {
315
+ throw new Error('DSH tool inventory exceeds the configured limit')
316
+ }
317
+ return tools
318
+ }
319
+
320
+ function textContent(text) {
321
+ return { type: 'text', text: String(text) }
322
+ }
323
+
324
+ function projectContent(content) {
325
+ if (!Array.isArray(content)) return []
326
+ return content.map((block) => {
327
+ if (block !== null && typeof block === 'object' && !Array.isArray(block)) {
328
+ if (block.type === 'text' && typeof block.text === 'string') return textContent(block.text)
329
+ if (block.type === 'reasoning' && typeof block.text === 'string') return textContent(block.text)
330
+ const kind = typeof block.type === 'string' ? block.type : 'unknown'
331
+ return textContent(`[DSH ${kind} content is not representable on this MCP bridge]`)
332
+ }
333
+ return textContent('[DSH emitted an invalid content block]')
334
+ })
335
+ }
336
+
337
+ function toolFailure(message, code = 'DSH_TOOL_BRIDGE_ERROR') {
338
+ return {
339
+ content: [textContent(`Error: ${message}`)],
340
+ isError: true,
341
+ _meta: { 'io.ksadk/dsh': { code } },
342
+ }
343
+ }
344
+
345
+ function projectToolResult(result, maximumBytes, resourceInvocation = false) {
346
+ if (result === null || typeof result !== 'object' || Array.isArray(result)) {
347
+ return toolFailure('DSH returned an invalid tool result')
348
+ }
349
+ const content = projectContent(result.content)
350
+ const projected = {
351
+ content,
352
+ isError: result.isError === true,
353
+ }
354
+ if (result.isError === true) {
355
+ const failure = result.error
356
+ const message = failure && typeof failure.message === 'string'
357
+ ? failure.message.slice(0, 16_384)
358
+ : 'DSH tool execution failed'
359
+ if (projected.content.length === 0) projected.content.push(textContent(`Error: ${message}`))
360
+ const code = failure?.info && typeof failure.info.code === 'string'
361
+ ? failure.info.code.slice(0, 256)
362
+ : 'DSH_TOOL_ERROR'
363
+ projected._meta = { 'io.ksadk/dsh': { code } }
364
+ } else if (
365
+ result.value !== null &&
366
+ typeof result.value === 'object' &&
367
+ !Array.isArray(result.value)
368
+ ) {
369
+ projected.structuredContent = result.value
370
+ // A successful Cordis invocation may carry a failed resource operation.
371
+ // Apply this domain contract only after authenticated resource admission;
372
+ // ordinary third-party values named "status" retain their existing meaning.
373
+ if (resourceInvocation && ['failed', 'unauthorized'].includes(result.value.status)) {
374
+ projected.isError = true
375
+ const code = typeof result.value.errorCode === 'string'
376
+ && /^(RESOURCE|MEMORY|KNOWLEDGE|SKILL)_[A-Z_]{1,96}$/.test(result.value.errorCode)
377
+ ? result.value.errorCode : 'RESOURCE_OPERATION_FAILED'
378
+ projected._meta = { 'io.ksadk/dsh': { code } }
379
+ }
380
+ } else if (projected.content.length === 0 && result.value !== undefined) {
381
+ projected.content.push(textContent(JSON.stringify(result.value)))
382
+ }
383
+ try {
384
+ if (byteLength(projected) <= maximumBytes) return projected
385
+ } catch {}
386
+ return toolFailure('DSH tool result exceeds the configured bridge limit', 'DSH_RESULT_TOO_LARGE')
387
+ }
388
+
389
+ function requestKey(scopeId, id) {
390
+ return JSON.stringify([scopeId, typeof id, id])
391
+ }
392
+
393
+ function abortOutcome(controller) {
394
+ return new Promise((resolve) => {
395
+ const finish = () => {
396
+ const reason = controller.signal.reason
397
+ resolve({
398
+ kind: 'aborted',
399
+ code: reason?.code === 'DEADLINE_EXCEEDED' ? 'DEADLINE_EXCEEDED' : 'ABORTED',
400
+ })
401
+ }
402
+ if (controller.signal.aborted) finish()
403
+ else controller.signal.addEventListener('abort', finish, { once: true })
404
+ })
405
+ }
406
+
407
+ function validateRequestEnvelope(message) {
408
+ return message !== null &&
409
+ typeof message === 'object' &&
410
+ !Array.isArray(message) &&
411
+ message.jsonrpc === '2.0' &&
412
+ typeof message.method === 'string' &&
413
+ (
414
+ message.id === undefined ||
415
+ typeof message.id === 'string' ||
416
+ (typeof message.id === 'number' && Number.isSafeInteger(message.id))
417
+ )
418
+ }
419
+
420
+ function normalizedProtocol(requested) {
421
+ return SUPPORTED_MCP_PROTOCOLS.has(requested) ? requested : MCP_PROTOCOL_VERSION
422
+ }
423
+
424
+ function emitReadyRecord(record) {
425
+ process.stdout.write(`@@KSADK_DSH_CAPABILITY_READY@@${JSON.stringify(record)}\n`)
426
+ }
427
+
428
+ function emitRuntimeToken(token) {
429
+ process.stdout.write(`@@KSADK_DSH_CAPABILITY_TOKEN@@${token}\n`)
430
+ }
431
+
432
+ function emitBrowserToken(token) {
433
+ process.stdout.write(`@@KSADK_DSH_CORE_TOKEN@@${token}\n`)
434
+ }
435
+
436
+ export async function apply(ctx, config = {}) {
437
+ const profile = requiredEnvironment('KSADK_DSH_PROFILE', 64)
438
+ const profileDigest = requiredEnvironment('KSADK_DSH_PROFILE_DIGEST', 80)
439
+ const dshVersion = requiredEnvironment('KSADK_DSH_VERSION', 64)
440
+ requiredEnvironment('KSADK_DSH_CAPABILITY_READY_STDOUT', 8)
441
+ const token = randomBytes(48).toString('base64url')
442
+ if (!DIGEST_PATTERN.test(profileDigest)) throw new Error('KSADK_DSH_PROFILE_DIGEST is invalid')
443
+
444
+ const callTimeoutMs = positiveInteger(config.callTimeoutMs, DEFAULT_CALL_TIMEOUT_MS, 'callTimeoutMs', 3_600_000)
445
+ const maxArgumentBytes = positiveInteger(config.maxArgumentBytes, DEFAULT_MAX_ARGUMENT_BYTES, 'maxArgumentBytes', 8 * 1024 * 1024)
446
+ const maxResultBytes = positiveInteger(config.maxResultBytes, DEFAULT_MAX_RESULT_BYTES, 'maxResultBytes', 8 * 1024 * 1024)
447
+ const maxRequestBytes = positiveInteger(config.maxRequestBytes, DEFAULT_MAX_REQUEST_BYTES, 'maxRequestBytes', 8 * 1024 * 1024)
448
+ const maxInFlight = positiveInteger(config.maxInFlight, DEFAULT_MAX_IN_FLIGHT, 'maxInFlight', 1024)
449
+ const inventoryQuietMs = positiveInteger(config.inventoryQuietMs, 50, 'inventoryQuietMs', 5_000)
450
+
451
+ const pending = new Map()
452
+ const revokedScopes = new Map()
453
+ let draining = false
454
+ let drifted = false
455
+ let readyWritten = false
456
+ let lastToolChange = Date.now()
457
+ let tools = []
458
+ let resourceBridge = null
459
+ // A pending optional child does not add another Core or block ordinary tools.
460
+ // Its dependency lifecycle clears the reference when the resource plugin stops.
461
+ if (typeof ctx.inject === 'function') ctx.inject(['platformResources'], resourceCtx => {
462
+ const bridge = resourceCtx.platformResources
463
+ resourceBridge = bridge
464
+ resourceCtx.effect(() => () => { if (resourceBridge === bridge) resourceBridge = null })
465
+ })
466
+ let inventoryDigest = digest(tools)
467
+
468
+ let driftCheckTimer = null
469
+ ctx.on('tools/change', () => {
470
+ lastToolChange = Date.now()
471
+ // Upstream plugins (e.g. dsh-ssh) dispose+re-register the same tools when
472
+ // settings re-sync; the intermediate state has a different fingerprint but
473
+ // converges. Debounce: only mark drift if the fingerprint is still
474
+ // different after the quiet window settles.
475
+ if (readyWritten) {
476
+ if (driftCheckTimer !== null) clearTimeout(driftCheckTimer)
477
+ driftCheckTimer = setTimeout(() => {
478
+ driftCheckTimer = null
479
+ const next = snapshotTools(ctx.tools, maxRequestBytes)
480
+ if (digest(next) !== inventoryDigest) drifted = true
481
+ }, inventoryQuietMs)
482
+ }
483
+ }, { global: true })
484
+
485
+ const handleRequest = async (request, response) => {
486
+ response.setHeader('X-Content-Type-Options', 'nosniff')
487
+ response.setHeader('Referrer-Policy', 'no-referrer')
488
+ if (!originAllowed(request)) {
489
+ writeJson(response, 403, { error: 'origin_denied' })
490
+ return
491
+ }
492
+
493
+ let parsedUrl
494
+ try {
495
+ parsedUrl = new URL(request.url ?? '/', 'http://127.0.0.1')
496
+ } catch {
497
+ writeJson(response, 400, { error: 'invalid_url' })
498
+ return
499
+ }
500
+
501
+ const authorization = authorize(request, token, profileDigest, tools, revokedScopes)
502
+
503
+ if (request.method === 'GET' && parsedUrl.pathname === '/health' && parsedUrl.search === '') {
504
+ if (authorization === null) {
505
+ response.setHeader('WWW-Authenticate', 'Bearer')
506
+ writeJson(response, 401, { error: 'unauthorized' })
507
+ return
508
+ }
509
+ writeJson(response, drifted || draining ? 503 : 200, {
510
+ protocolVersion: HOST_PROTOCOL,
511
+ healthy: !drifted && !draining,
512
+ profile,
513
+ profileDigest,
514
+ inventoryDigest,
515
+ toolCount: tools.length,
516
+ inFlight: pending.size,
517
+ drifted,
518
+ draining,
519
+ })
520
+ return
521
+ }
522
+
523
+ if (request.method !== 'POST' || parsedUrl.pathname !== '/mcp' || parsedUrl.search !== '') {
524
+ writeJson(response, 404, { error: 'not_found' })
525
+ return
526
+ }
527
+ if (authorization === null) {
528
+ response.setHeader('WWW-Authenticate', 'Bearer')
529
+ writeJson(response, 401, { error: 'unauthorized' })
530
+ return
531
+ }
532
+ if (!(request.headers['content-type'] ?? '').toLowerCase().startsWith('application/json')) {
533
+ writeJson(response, 415, { error: 'content_type_required' })
534
+ return
535
+ }
536
+
537
+ let message
538
+ try {
539
+ const body = await readBody(request, maxRequestBytes)
540
+ message = JSON.parse(body)
541
+ } catch (error) {
542
+ if (error instanceof RequestTooLargeError) {
543
+ writeJson(response, 413, { error: 'request_too_large' })
544
+ } else {
545
+ writeJson(response, 400, jsonRpcError(null, -32700, 'Parse error'))
546
+ }
547
+ return
548
+ }
549
+ if (!validateRequestEnvelope(message)) {
550
+ writeJson(response, 400, jsonRpcError(message?.id, -32600, 'Invalid Request'))
551
+ return
552
+ }
553
+ // A scoped request may have been authorized before a slow body finished
554
+ // while its activation was revoked by a concurrent root request.
555
+ if (!authorization.root && revokedScopes.has(authorization.scopeId)) {
556
+ response.setHeader('WWW-Authenticate', 'Bearer')
557
+ writeJson(response, 401, { error: 'unauthorized' })
558
+ return
559
+ }
560
+
561
+ const isNotification = message.id === undefined
562
+ const params = message.params ?? {}
563
+ if (params === null || typeof params !== 'object' || Array.isArray(params)) {
564
+ if (isNotification) writeEmpty(response, 202)
565
+ else writeJson(response, 200, jsonRpcError(message.id, -32602, 'Invalid params'))
566
+ return
567
+ }
568
+
569
+ if (message.method === 'notifications/initialized') {
570
+ writeEmpty(response, 202)
571
+ return
572
+ }
573
+ if (message.method === 'notifications/cancelled') {
574
+ const error = new Error('MCP client cancelled the request')
575
+ error.code = 'ABORTED'
576
+ if (authorization.root) {
577
+ for (const active of pending.values()) {
578
+ if (active.requestIdKey === requestKey('', params.requestId)) {
579
+ active.controller.abort(error)
580
+ }
581
+ }
582
+ } else {
583
+ const active = pending.get(requestKey(authorization.scopeId, params.requestId))
584
+ if (active) active.controller.abort(error)
585
+ }
586
+ writeEmpty(response, 202)
587
+ return
588
+ }
589
+ if (isNotification) {
590
+ writeEmpty(response, 202)
591
+ return
592
+ }
593
+
594
+ if (message.method === 'initialize') {
595
+ if (typeof params.protocolVersion !== 'string') {
596
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'protocolVersion is required'))
597
+ return
598
+ }
599
+ writeJson(response, 200, {
600
+ jsonrpc: '2.0',
601
+ id: message.id,
602
+ result: {
603
+ protocolVersion: normalizedProtocol(params.protocolVersion),
604
+ capabilities: { tools: {} },
605
+ serverInfo: { name: '@kingsoftcloud/ksadk-dsh-capability-host', version: HOST_VERSION },
606
+ },
607
+ })
608
+ return
609
+ }
610
+ if (message.method === 'ping') {
611
+ writeJson(response, 200, { jsonrpc: '2.0', id: message.id, result: {} })
612
+ return
613
+ }
614
+ if (message.method === 'io.ksadk/scopes/revoke') {
615
+ if (!authorization.root || typeof params.token !== 'string' || params.token.length > 12 * 1024) {
616
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'valid scoped token is required'))
617
+ return
618
+ }
619
+ const scoped = parseScopedToken(params.token, token, profileDigest, tools, true)
620
+ if (scoped === null) {
621
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'valid scoped token is required'))
622
+ return
623
+ }
624
+ if (!revokedScopes.has(scoped.scopeId) && revokedScopes.size >= 4096) {
625
+ writeJson(response, 200, jsonRpcError(message.id, -32001, 'revocation capacity reached'))
626
+ return
627
+ }
628
+ revokedScopes.set(scoped.scopeId, scoped.expiresAt)
629
+ const error = new Error('MCP credential scope was revoked')
630
+ error.code = 'ABORTED'
631
+ for (const active of pending.values()) {
632
+ if (active.scopeId === scoped.scopeId) active.controller.abort(error)
633
+ }
634
+ writeJson(response, 200, {
635
+ jsonrpc: '2.0',
636
+ id: message.id,
637
+ result: { revoked: true },
638
+ })
639
+ return
640
+ }
641
+ if (draining || drifted) {
642
+ writeJson(response, 200, jsonRpcError(message.id, -32002, 'DSH capability inventory is unavailable'))
643
+ return
644
+ }
645
+ if (message.method === 'tools/list') {
646
+ if (params.cursor !== undefined && params.cursor !== null && params.cursor !== '') {
647
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'cursor is not supported'))
648
+ return
649
+ }
650
+ const candidates = authorization.aliases === null
651
+ ? tools
652
+ : [...authorization.aliases].filter(([, source]) =>
653
+ !resourceBridge?.operationForTool(source) || authorization.resources?.has(source)
654
+ ).map(([alias, source]) => {
655
+ const tool = tools.find((item) => item.name === source)
656
+ return { ...tool, name: alias }
657
+ })
658
+ const checked = await Promise.all(candidates.map(async tool => {
659
+ const source = authorization.aliases?.get(tool.name)
660
+ const resource = authorization.resources?.get(source)
661
+ if (!resource) return tool
662
+ if (!resourceBridge || resourceBridge.operationForTool(source) !== resource.operation) return null
663
+ try {
664
+ const result = await resourceBridge.withInvocation({
665
+ handle: resource.handle,
666
+ deadline: Math.min(Date.now() + 3000, authorization.expiresAt * 1000),
667
+ }, () => resourceBridge.check(resource.operation))
668
+ return result.available === true ? tool : null
669
+ } catch { return null }
670
+ }))
671
+ if (!authorization.root && (revokedScopes.has(authorization.scopeId) ||
672
+ authorization.expiresAt * 1000 <= Date.now())) {
673
+ response.setHeader('WWW-Authenticate', 'Bearer')
674
+ writeJson(response, 401, { error: 'unauthorized' })
675
+ return
676
+ }
677
+ const visibleTools = checked.filter(Boolean)
678
+ writeJson(response, 200, { jsonrpc: '2.0', id: message.id, result: { tools: visibleTools } })
679
+ return
680
+ }
681
+ if (message.method !== 'tools/call') {
682
+ writeJson(response, 200, jsonRpcError(message.id, -32601, 'Method not found'))
683
+ return
684
+ }
685
+ if (typeof params.name !== 'string') {
686
+ writeJson(response, 200, {
687
+ jsonrpc: '2.0',
688
+ id: message.id,
689
+ result: toolFailure('unknown DSH tool', 'UNKNOWN_TOOL'),
690
+ })
691
+ return
692
+ }
693
+ const sourceToolName = authorization.aliases === null
694
+ ? params.name
695
+ : authorization.aliases.get(params.name)
696
+ if (sourceToolName === undefined) {
697
+ writeJson(response, 200, jsonRpcError(message.id, -32003, 'Tool is outside credential scope'))
698
+ return
699
+ }
700
+ if (!tools.some((tool) => tool.name === sourceToolName)) {
701
+ writeJson(response, 200, {
702
+ jsonrpc: '2.0',
703
+ id: message.id,
704
+ result: toolFailure('unknown DSH tool', 'UNKNOWN_TOOL'),
705
+ })
706
+ return
707
+ }
708
+ const resourceOperation = resourceBridge?.operationForTool(sourceToolName)
709
+ const resourceScope = authorization.resources?.get(sourceToolName)
710
+ if ((resourceOperation || resourceScope) &&
711
+ (!resourceBridge || !resourceScope || resourceScope.operation !== resourceOperation)) {
712
+ writeJson(response, 200, { jsonrpc: '2.0', id: message.id,
713
+ result: toolFailure('Resource invocation context is required', 'RESOURCE_CONTEXT_REQUIRED') })
714
+ return
715
+ }
716
+ const argumentsValue = params.arguments ?? {}
717
+ if (argumentsValue === null || typeof argumentsValue !== 'object' || Array.isArray(argumentsValue)) {
718
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'tool arguments must be an object'))
719
+ return
720
+ }
721
+ try {
722
+ if (byteLength(argumentsValue) > maxArgumentBytes) {
723
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'tool arguments exceed the configured limit'))
724
+ return
725
+ }
726
+ } catch {
727
+ writeJson(response, 200, jsonRpcError(message.id, -32602, 'tool arguments must be JSON'))
728
+ return
729
+ }
730
+ if (pending.size >= maxInFlight) {
731
+ writeJson(response, 200, jsonRpcError(message.id, -32001, 'too many in-flight tool calls'))
732
+ return
733
+ }
734
+
735
+ const key = requestKey(authorization.scopeId, message.id)
736
+ if (pending.has(key)) {
737
+ writeJson(response, 200, jsonRpcError(message.id, -32600, 'duplicate in-flight request id'))
738
+ return
739
+ }
740
+ const controller = new AbortController()
741
+ const timeout = setTimeout(() => {
742
+ const error = new Error('DSH tool call deadline exceeded')
743
+ error.code = 'DEADLINE_EXCEEDED'
744
+ controller.abort(error)
745
+ }, callTimeoutMs)
746
+ const completion = Promise.resolve()
747
+ .then(() => {
748
+ const invoke = () => ctx.tools.execute({
749
+ callId: `mcp-${randomUUID()}`, name: sourceToolName,
750
+ arguments: argumentsValue, signal: controller.signal,
751
+ })
752
+ return resourceScope ? resourceBridge.withInvocation({
753
+ handle: resourceScope.handle,
754
+ deadline: Math.min(Date.now() + callTimeoutMs, authorization.expiresAt * 1000),
755
+ signal: controller.signal,
756
+ }, invoke) : invoke()
757
+ })
758
+ .then(
759
+ (result) => ({ kind: 'result', result }),
760
+ (error) => ({ kind: 'error', error }),
761
+ )
762
+ pending.set(key, {
763
+ controller,
764
+ completion,
765
+ scopeId: authorization.scopeId,
766
+ requestIdKey: requestKey('', message.id),
767
+ })
768
+ response.on('close', () => {
769
+ if (!response.writableEnded) {
770
+ const error = new Error('MCP client disconnected')
771
+ error.code = 'ABORTED'
772
+ controller.abort(error)
773
+ }
774
+ })
775
+ let completed = false
776
+ try {
777
+ const outcome = await Promise.race([completion, abortOutcome(controller)])
778
+ completed = outcome.kind !== 'aborted'
779
+ if (outcome.kind === 'result') {
780
+ writeJson(response, 200, {
781
+ jsonrpc: '2.0',
782
+ id: message.id,
783
+ result: projectToolResult(outcome.result, maxResultBytes, Boolean(resourceScope)),
784
+ })
785
+ } else if (outcome.kind === 'aborted') {
786
+ const messageText = outcome.code === 'DEADLINE_EXCEEDED'
787
+ ? 'DSH tool call deadline exceeded'
788
+ : 'DSH tool call was cancelled'
789
+ writeJson(response, 200, {
790
+ jsonrpc: '2.0',
791
+ id: message.id,
792
+ result: toolFailure(messageText, outcome.code),
793
+ })
794
+ } else {
795
+ writeJson(response, 200, jsonRpcError(message.id, -32603, 'DSH tool pipeline failed'))
796
+ }
797
+ } finally {
798
+ clearTimeout(timeout)
799
+ if (completed) pending.delete(key)
800
+ else {
801
+ void completion.then(() => pending.delete(key))
802
+ // AbortSignal is cooperative. A third-party Cordis tool may ignore it
803
+ // forever, so an aborted call cannot be allowed to retain one in-flight
804
+ // slot indefinitely. Give a cooperative tool a short unwind window;
805
+ // otherwise crash this isolated generation and let the Python
806
+ // supervisor reap the process group and start a clean generation.
807
+ const abortGrace = setTimeout(() => {
808
+ if (!pending.has(key)) return
809
+ draining = true
810
+ process.exit(70)
811
+ }, 250)
812
+ abortGrace.unref()
813
+ void completion.then(() => clearTimeout(abortGrace))
814
+ }
815
+ }
816
+ }
817
+ const disposeMcp = ctx.webServer.register({ kind: 'exact', path: '/mcp', handler: handleRequest })
818
+ const disposeHealth = ctx.webServer.register({ kind: 'exact', path: '/health', handler: handleRequest })
819
+ ctx.effect(() => () => {
820
+ draining = true
821
+ for (const entry of pending.values()) {
822
+ entry.controller.abort(new Error('DSH capability host is stopping'))
823
+ }
824
+ disposeHealth()
825
+ disposeMcp()
826
+ })
827
+
828
+ // Reset the quiet baseline after the official Core server has activated:
829
+ // plugins may still be registering tools while the overlay starts.
830
+ lastToolChange = Date.now()
831
+ while (Date.now() - lastToolChange < inventoryQuietMs) {
832
+ await new Promise((resolve) => setTimeout(resolve, inventoryQuietMs))
833
+ }
834
+ tools = snapshotTools(ctx.tools, maxRequestBytes)
835
+ inventoryDigest = digest(tools)
836
+ const port = ctx.webServer.port
837
+ if (!Number.isSafeInteger(port) || port < 1 || port > 65535 || ctx.webServer.host !== '127.0.0.1') {
838
+ throw new Error('DSH Core webServer must bind a loopback TCP port')
839
+ }
840
+ const coreUrl = new URL(ctx.connection.authenticatedUrl(`http://127.0.0.1:${port}`))
841
+ const browserTokens = coreUrl.searchParams.getAll('token')
842
+ if (
843
+ coreUrl.protocol !== 'http:' ||
844
+ coreUrl.hostname !== '127.0.0.1' ||
845
+ coreUrl.port !== String(port) ||
846
+ coreUrl.pathname !== '/' ||
847
+ coreUrl.hash !== '' ||
848
+ [...coreUrl.searchParams.keys()].some((key) => key !== 'token') ||
849
+ browserTokens.length !== 1 ||
850
+ !/^[A-Za-z0-9_-]{32,128}$/.test(browserTokens[0])
851
+ ) {
852
+ throw new Error('DSH Core connection did not provide an authenticated browser URL')
853
+ }
854
+ readyWritten = true
855
+ emitRuntimeToken(token)
856
+ emitBrowserToken(browserTokens[0])
857
+ emitReadyRecord({
858
+ protocolVersion: HOST_PROTOCOL,
859
+ hostVersion: HOST_VERSION,
860
+ dshVersion,
861
+ profile,
862
+ profileDigest,
863
+ definition: 'mcp.connector/v1',
864
+ transport: 'streamable-http',
865
+ endpoint: `http://127.0.0.1:${port}/mcp`,
866
+ inventoryDigest,
867
+ tools,
868
+ webRouteCount: 2,
869
+ })
870
+ }