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,226 @@
1
+ """Single frozen descriptor host for wheel-owned DSH AgentProviders.
2
+
3
+ The provider key is a fixed command argument selected by KsADK. The host
4
+ owns discovery and lifecycle only; model credentials and execution services
5
+ remain in the parent RuntimeAdapter bridge.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import sys
12
+ from dataclasses import dataclass
13
+ from typing import Any, Sequence
14
+
15
+ from ksadk.plugins.providers.dsh import (
16
+ DSH_AGENT_PROVIDER_HOST_METHODS,
17
+ DSH_AGENT_PROVIDER_HOST_PROTOCOL,
18
+ DshAgentProviderDescriptor,
19
+ )
20
+ from ksadk.plugins.providers.shipped_dsh import (
21
+ SHIPPED_DSH_PROVIDER_SPECS,
22
+ ShippedDshProviderSpec,
23
+ )
24
+
25
+
26
+ class HostRequestError(RuntimeError):
27
+ def __init__(self, code: str, message: str) -> None:
28
+ super().__init__(message)
29
+ self.code = code
30
+
31
+
32
+ @dataclass
33
+ class DescriptorHostState:
34
+ spec: ShippedDshProviderSpec
35
+ profile: dict[str, Any] | None = None
36
+ descriptor: DshAgentProviderDescriptor | None = None
37
+ state: str = "ready"
38
+
39
+ def handshake(self, params: dict[str, Any]) -> dict[str, Any]:
40
+ projection = self._profile(params)
41
+ bundles = projection.get("bundles")
42
+ if not isinstance(bundles, list) or self.spec.package_name not in bundles:
43
+ raise HostRequestError(
44
+ self.spec.error_code("bundle_inactive"),
45
+ f"{self.spec.display_name} Bundle is not active in the selected DSH Profile",
46
+ )
47
+ if self.profile is not None and (
48
+ projection.get("configDigest") != self.profile.get("configDigest")
49
+ ):
50
+ raise HostRequestError(
51
+ self.spec.error_code("profile_changed"),
52
+ "host cannot cross a DSH Profile fence",
53
+ )
54
+ self.profile = projection
55
+ self.descriptor = DshAgentProviderDescriptor.model_validate(
56
+ {
57
+ "providerId": self.spec.provider_id,
58
+ "providerVersion": self.spec.version,
59
+ "displayName": self.spec.display_name,
60
+ "pluginName": self.spec.package_name,
61
+ "profile": projection.get("profile"),
62
+ "profileDigest": projection.get("configDigest"),
63
+ "runtimeProtocols": ["agentkit.runtime/v1"],
64
+ }
65
+ )
66
+ return {
67
+ "protocolVersion": DSH_AGENT_PROVIDER_HOST_PROTOCOL,
68
+ "methods": sorted(DSH_AGENT_PROVIDER_HOST_METHODS),
69
+ "hostVersion": self.spec.version,
70
+ }
71
+
72
+ def describe(self, params: dict[str, Any]) -> dict[str, Any]:
73
+ descriptor = self._require_ready_descriptor()
74
+ if self._profile(params).get("configDigest") != descriptor.profile_digest:
75
+ raise HostRequestError(
76
+ self.spec.error_code("profile_mismatch"),
77
+ "descriptor crossed a DSH Profile fence",
78
+ )
79
+ return descriptor.model_dump(by_alias=True, mode="json")
80
+
81
+ def preflight(self, params: dict[str, Any]) -> dict[str, Any]:
82
+ descriptor = self._require_ready_descriptor()
83
+ self._check_fences(params)
84
+ return {
85
+ "ready": self.state == "ready",
86
+ "descriptorDigest": descriptor.descriptor_digest,
87
+ "profileDigest": descriptor.profile_digest,
88
+ }
89
+
90
+ def inventory(self, params: dict[str, Any]) -> dict[str, Any]:
91
+ descriptor = self._require_descriptor()
92
+ self._check_fences(params, profile_optional=True)
93
+ return {
94
+ "providerId": descriptor.provider_id,
95
+ "providerVersion": descriptor.provider_version,
96
+ "profile": descriptor.profile,
97
+ "profileDigest": descriptor.profile_digest,
98
+ "descriptorDigest": descriptor.descriptor_digest,
99
+ "state": self.state,
100
+ "activationCount": 0,
101
+ }
102
+
103
+ def health(self, params: dict[str, Any]) -> dict[str, Any]:
104
+ if params.get("activationId"):
105
+ return {"healthy": False}
106
+ return {"healthy": self.state == "ready"}
107
+
108
+ def drain(self, params: dict[str, Any]) -> dict[str, Any]:
109
+ if params.get("scope") != "provider":
110
+ raise self._execution_bridge_required()
111
+ self.state = "draining"
112
+ return {"ok": True}
113
+
114
+ def dispose(self, params: dict[str, Any]) -> dict[str, Any]:
115
+ if params.get("scope") != "host":
116
+ raise self._execution_bridge_required()
117
+ self.state = "disposed"
118
+ return {"ok": True}
119
+
120
+ def dispatch(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
121
+ handler = getattr(self, method, None)
122
+ if method in {
123
+ "handshake",
124
+ "describe",
125
+ "preflight",
126
+ "inventory",
127
+ "health",
128
+ "drain",
129
+ "dispose",
130
+ } and callable(handler):
131
+ return handler(params)
132
+ raise self._execution_bridge_required()
133
+
134
+ def _profile(self, params: dict[str, Any]) -> dict[str, Any]:
135
+ value = params.get("profile")
136
+ if not isinstance(value, dict):
137
+ raise HostRequestError(
138
+ self.spec.error_code("profile_invalid"),
139
+ "request requires a DSH Profile projection",
140
+ )
141
+ return value
142
+
143
+ def _require_descriptor(self) -> DshAgentProviderDescriptor:
144
+ if self.descriptor is None:
145
+ raise HostRequestError(
146
+ self.spec.error_code("handshake_required"),
147
+ "DSH Profile handshake is incomplete",
148
+ )
149
+ return self.descriptor
150
+
151
+ def _require_ready_descriptor(self) -> DshAgentProviderDescriptor:
152
+ descriptor = self._require_descriptor()
153
+ if self.state != "ready":
154
+ raise HostRequestError(
155
+ self.spec.error_code("provider_unavailable"),
156
+ f"{self.spec.display_name} DSH provider is not ready",
157
+ )
158
+ return descriptor
159
+
160
+ def _check_fences(self, params: dict[str, Any], *, profile_optional: bool = False) -> None:
161
+ descriptor = self._require_descriptor()
162
+ if not profile_optional and params.get("profileDigest") != descriptor.profile_digest:
163
+ raise HostRequestError(
164
+ self.spec.error_code("profile_mismatch"),
165
+ "request crossed a DSH Profile fence",
166
+ )
167
+ if params.get("descriptorDigest") != descriptor.descriptor_digest:
168
+ raise HostRequestError(
169
+ self.spec.error_code("descriptor_mismatch"),
170
+ "request crossed a descriptor fence",
171
+ )
172
+
173
+ def _execution_bridge_required(self) -> HostRequestError:
174
+ return HostRequestError(
175
+ self.spec.bridge_required_code,
176
+ self.spec.bridge_required_message,
177
+ )
178
+
179
+
180
+ def main(argv: Sequence[str] | None = None) -> int:
181
+ arguments = list(sys.argv[1:] if argv is None else argv)
182
+ if len(arguments) != 1 or arguments[0] not in SHIPPED_DSH_PROVIDER_SPECS:
183
+ return 2
184
+ spec = SHIPPED_DSH_PROVIDER_SPECS[arguments[0]]
185
+ state = DescriptorHostState(spec)
186
+ for line in sys.stdin:
187
+ request: dict[str, Any] | None = None
188
+ try:
189
+ value = json.loads(line)
190
+ if not isinstance(value, dict):
191
+ raise HostRequestError(
192
+ spec.error_code("request_invalid"), "request must be an object"
193
+ )
194
+ request = value
195
+ request_id = request.get("id")
196
+ method = request.get("method")
197
+ params = request.get("params") or {}
198
+ if (
199
+ not isinstance(request_id, str)
200
+ or method not in DSH_AGENT_PROVIDER_HOST_METHODS
201
+ or not isinstance(params, dict)
202
+ ):
203
+ raise HostRequestError(
204
+ spec.error_code("request_invalid"), "request envelope is invalid"
205
+ )
206
+ response = {"id": request_id, "result": state.dispatch(str(method), params)}
207
+ except Exception as error: # protocol boundary must always answer
208
+ response = {
209
+ "id": request.get("id") if isinstance(request, dict) else "unknown",
210
+ "error": {
211
+ "code": getattr(error, "code", spec.error_code("internal_error")),
212
+ "message": str(error),
213
+ },
214
+ }
215
+ sys.stdout.write(json.dumps(response, separators=(",", ":")) + "\n")
216
+ sys.stdout.flush()
217
+ if state.state == "disposed":
218
+ break
219
+ return 0
220
+
221
+
222
+ if __name__ == "__main__": # pragma: no cover - subprocess entrypoint
223
+ raise SystemExit(main())
224
+
225
+
226
+ __all__ = ["DescriptorHostState", "HostRequestError", "main"]
@@ -0,0 +1,467 @@
1
+ """PluginHost adapter for the ephemeral DSH Profile MCP lease.
2
+
3
+ The immutable Bundle records only the DSH Profile identity and capability
4
+ digests. The loopback URL and bearer credential are obtained from Studio's
5
+ profile-level lifecycle service after PluginHost activation and are never
6
+ serialized into the Agent spec, composition, or plugin lock.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import hashlib
13
+ import re
14
+ from collections.abc import Mapping, Sequence
15
+ from typing import Any, cast
16
+
17
+ from ksadk.harness.config import McpToolSpec
18
+ from ksadk.plugins.bundle import ResolvedPluginBundle
19
+ from ksadk.plugins.contracts import CompositionProfile, PluginManifest
20
+ from ksadk.plugins.dsh_toolchain import DSH_PACKAGE_SPEC
21
+ from ksadk.plugins.host import PluginHostError
22
+ from ksadk.plugins.providers.dsh import DSH_HOST_USER_PERMISSION
23
+ from ksadk.plugins.providers.dsh_capabilities import (
24
+ DshMcpConnectorLease,
25
+ DshProfileCapabilityDescriptor,
26
+ load_dsh_capability_bundle,
27
+ )
28
+
29
+ DSH_PROFILE_MCP_PLUGIN_ID = "io.ksadk.mcp.dsh-profile"
30
+ DSH_PROFILE_MCP_PLUGIN_VERSION = "1.0.0"
31
+ DSH_PROFILE_TOOL_PERMISSION = DSH_HOST_USER_PERMISSION
32
+ _PLUGIN_REF = f"plugin://{DSH_PROFILE_MCP_PLUGIN_ID}@{DSH_PROFILE_MCP_PLUGIN_VERSION}"
33
+ _MODEL_TOOL_NAME = re.compile(r"^[A-Za-z0-9_-]{1,64}$")
34
+
35
+
36
+ def dsh_harness_tool_alias(name: str, prefix: str | None = None) -> str:
37
+ """Return a deterministic OpenAI-compatible alias for one DSH tool."""
38
+
39
+ normalized_prefix = (prefix or "").strip()
40
+ candidate = name
41
+ changed = not bool(_MODEL_TOOL_NAME.fullmatch(candidate))
42
+ if changed:
43
+ stem = re.sub(r"[^A-Za-z0-9_-]", "_", candidate).strip("_") or "tool"
44
+ candidate = f"{stem[:55]}_{hashlib.sha256(name.encode()).hexdigest()[:8]}"
45
+ if normalized_prefix:
46
+ candidate = f"{normalized_prefix}_{candidate}"
47
+ if len(candidate) > 64:
48
+ suffix = hashlib.sha256(name.encode()).hexdigest()[:8]
49
+ candidate = f"{candidate[:55]}_{suffix}"
50
+ if not _MODEL_TOOL_NAME.fullmatch(candidate):
51
+ raise PluginHostError(
52
+ "dsh_mcp_tool_alias_invalid",
53
+ "DSH tool alias is not compatible with the Harness model protocol",
54
+ )
55
+ return candidate
56
+
57
+
58
+ def dsh_profile_mcp_manifest() -> PluginManifest:
59
+ """Return the deterministic platform adapter manifest."""
60
+
61
+ manifest_digest = load_dsh_capability_bundle().digest
62
+ return cast(
63
+ PluginManifest,
64
+ PluginManifest.model_validate(
65
+ {
66
+ "metadata": {
67
+ "id": DSH_PROFILE_MCP_PLUGIN_ID,
68
+ "version": DSH_PROFILE_MCP_PLUGIN_VERSION,
69
+ },
70
+ "spec": {
71
+ "domain": "ksadk-platform",
72
+ "runtime": "python",
73
+ "entrypoint": "ksadk.plugins.providers.dsh_mcp:DshProfileMCPFactory",
74
+ "provides": [
75
+ {
76
+ "definition": "mcp.connector/v1",
77
+ "slot": "mcp.dsh-profile",
78
+ "mode": "multiple",
79
+ }
80
+ ],
81
+ "permissions": ["network:mcp", DSH_PROFILE_TOOL_PERMISSION],
82
+ "isolation": "sidecar",
83
+ "compatibility": {
84
+ "kernelApi": ">=1,<2",
85
+ "runtimeProtocols": ["agentkit.runtime/v1", "2025-06-18"],
86
+ "python": ">=3.10,<3.15",
87
+ },
88
+ "healthContract": "plugin.health/v1",
89
+ "provenance": {
90
+ "source": "runtime-native",
91
+ "digest": manifest_digest,
92
+ "license": "Apache-2.0",
93
+ "upstream": {
94
+ "ecosystem": "dsh",
95
+ "type": "runtime-native",
96
+ "requested": DSH_PACKAGE_SPEC,
97
+ "resolved": DSH_PACKAGE_SPEC,
98
+ },
99
+ "components": [
100
+ {
101
+ "id": "dsh-profile-mcp",
102
+ "kind": "mcp",
103
+ "digest": manifest_digest,
104
+ }
105
+ ],
106
+ },
107
+ },
108
+ }
109
+ ),
110
+ )
111
+
112
+
113
+ def _mapping(value: Any, *, code: str) -> Mapping[str, Any]:
114
+ if not isinstance(value, Mapping):
115
+ raise PluginHostError(code, "expected an object")
116
+ return value
117
+
118
+
119
+ def _required(value: Mapping[str, Any], field: str, *, code: str) -> str:
120
+ item = value.get(field)
121
+ if not isinstance(item, str) or not item.strip():
122
+ raise PluginHostError(code, f"{field} must be a non-empty string")
123
+ return item.strip()
124
+
125
+
126
+ def _optional(value: Any, *, code: str) -> str | None:
127
+ if value is None:
128
+ return None
129
+ if not isinstance(value, str):
130
+ raise PluginHostError(code, "optional string configuration is invalid")
131
+ return value.strip() or None
132
+
133
+
134
+ def _string_list(value: Any, *, code: str) -> tuple[str, ...]:
135
+ if value is None:
136
+ return ()
137
+ if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
138
+ raise PluginHostError(code, "toolFilter must be an array")
139
+ result: list[str] = []
140
+ for item in value:
141
+ if not isinstance(item, str) or not item.strip():
142
+ raise PluginHostError(code, "toolFilter entries must be non-empty strings")
143
+ result.append(item.strip())
144
+ if len(result) != len(set(result)):
145
+ raise PluginHostError(code, "toolFilter entries must be unique")
146
+ return tuple(result)
147
+
148
+
149
+ def _profile_config(profile: CompositionProfile) -> Mapping[str, Any]:
150
+ matches = [item for item in profile.capabilities if item.ref == _PLUGIN_REF]
151
+ if len(matches) != 1:
152
+ raise PluginHostError(
153
+ "dsh_mcp_binding_missing",
154
+ "DSH Profile MCP requires one exact composition capability",
155
+ )
156
+ return cast(Mapping[str, Any], matches[0].config)
157
+
158
+
159
+ def _resource_entry(config: Mapping[str, Any]) -> Mapping[str, Any]:
160
+ resources = config.get("resources")
161
+ if (
162
+ not isinstance(resources, Sequence)
163
+ or isinstance(resources, (str, bytes))
164
+ or len(resources) != 1
165
+ ):
166
+ raise PluginHostError(
167
+ "dsh_mcp_config_invalid",
168
+ "one DSH Profile MCP resource must be selected",
169
+ )
170
+ entry = _mapping(resources[0], code="dsh_mcp_config_invalid")
171
+ if entry.get("kind") != "mcp":
172
+ raise PluginHostError("dsh_mcp_config_invalid", "resource kind must be mcp")
173
+ for field in ("resourceId", "name", "version", "digest"):
174
+ _required(entry, field, code="dsh_mcp_config_invalid")
175
+ return entry
176
+
177
+
178
+ class DshProfileMCPRuntime:
179
+ """Resolve a locked DSH descriptor into one process-scoped MCP spec."""
180
+
181
+ def __init__(self, *, service: Any, profile: CompositionProfile) -> None:
182
+ self._service = service
183
+ self._entry = _resource_entry(_profile_config(profile))
184
+ self._descriptor: DshProfileCapabilityDescriptor | None = None
185
+ self._lease: DshMcpConnectorLease | None = None
186
+ self._issued_scopes: dict[str, DshMcpConnectorLease] = {}
187
+ self._revocation_tasks: dict[str, asyncio.Task[None]] = {}
188
+ self._ready = False
189
+ self._disposed = False
190
+
191
+ async def start(self) -> None:
192
+ if self._disposed:
193
+ raise PluginHostError("dsh_mcp_disposed", "DSH MCP runtime is disposed")
194
+ await self._refresh_lease()
195
+ self._ready = True
196
+
197
+ async def _refresh_lease(self) -> None:
198
+ try:
199
+ snapshot = await self._service.runtime_snapshot()
200
+ descriptor = snapshot.descriptor
201
+ lease = snapshot.lease
202
+ except PluginHostError:
203
+ raise
204
+ except Exception as error: # noqa: BLE001 - lifecycle service boundary
205
+ raise PluginHostError(
206
+ "dsh_mcp_lease_unavailable", "DSH Profile MCP lease is unavailable"
207
+ ) from error
208
+ self._validate_descriptor(descriptor, lease)
209
+ self._descriptor = descriptor
210
+ self._lease = lease
211
+
212
+ async def health(self) -> bool:
213
+ return self._ready and not self._disposed and self._lease is not None
214
+
215
+ async def drain(self) -> None:
216
+ self._ready = False
217
+
218
+ async def dispose(self) -> None:
219
+ self._ready = False
220
+ self._disposed = True
221
+ scopes = tuple(self._issued_scopes)
222
+ first_error: BaseException | None = None
223
+ for token in scopes:
224
+ try:
225
+ await self._revoke_tracked_scope(token)
226
+ except BaseException as error: # revocation must continue
227
+ if first_error is None:
228
+ first_error = error
229
+ self._descriptor = None
230
+ self._lease = None
231
+ if first_error is not None:
232
+ raise first_error
233
+
234
+ async def harness_mcp_specs(self, bundle: ResolvedPluginBundle) -> tuple[McpToolSpec, ...]:
235
+ if not self._ready or self._disposed:
236
+ raise PluginHostError("dsh_mcp_unavailable", "DSH Profile MCP is not ready")
237
+ # A supervised DSH sidecar may have restarted since this PluginHost
238
+ # graph was staged. Resolve and fence the lease at every new Agent
239
+ # activation so stale ports or credentials never escape into a client.
240
+ await self._refresh_lease()
241
+ if self._descriptor is None or self._lease is None: # pragma: no cover - invariant
242
+ raise PluginHostError("dsh_mcp_unavailable", "DSH Profile MCP is not ready")
243
+ resolved = self._resolved_resource(bundle)
244
+ self._validate_resolved_resource(resolved)
245
+ materializer = _mapping(self._entry.get("materializer"), code="dsh_mcp_config_invalid")
246
+ tool_filter = _string_list(
247
+ materializer.get("toolFilter"), code="dsh_mcp_tool_filter_invalid"
248
+ )
249
+ known_tools = {tool.name for tool in self._descriptor.tools}
250
+ unknown = sorted(set(tool_filter) - known_tools)
251
+ if unknown:
252
+ raise PluginHostError(
253
+ "dsh_mcp_tool_filter_invalid",
254
+ f"DSH toolFilter contains unknown tools: {', '.join(unknown)}",
255
+ )
256
+ prefix = _optional(
257
+ materializer.get("toolNamePrefix"),
258
+ code="dsh_mcp_config_invalid",
259
+ )
260
+ aliases = {dsh_harness_tool_alias(name, prefix): name for name in tool_filter}
261
+ if len(aliases) != len(tool_filter):
262
+ raise PluginHostError(
263
+ "dsh_mcp_tool_alias_collision",
264
+ "selected DSH tools produce duplicate Harness aliases",
265
+ )
266
+ resource_name = _required(resolved, "name", code="dsh_mcp_resource_invalid")
267
+ token = self._lease.bearer_token_for_runtime(aliases)
268
+ self._issued_scopes[token] = self._lease
269
+ return (
270
+ McpToolSpec(
271
+ name=resource_name,
272
+ url=self._lease.endpoint,
273
+ api_key=token,
274
+ tool_filter=tuple(aliases),
275
+ tool_name_prefix=None,
276
+ ),
277
+ )
278
+
279
+ async def activation_mcp_specs(
280
+ self,
281
+ bundle: ResolvedPluginBundle,
282
+ *,
283
+ activation_key: str,
284
+ ) -> tuple[McpToolSpec, ...]:
285
+ """Project the same lease through the provider-neutral activation ABI."""
286
+
287
+ del activation_key # compatibility contexts predating PluginHost activation IDs
288
+ return await self.harness_mcp_specs(bundle)
289
+
290
+ async def release_activation_mcp_specs(
291
+ self,
292
+ activation_key: str,
293
+ specs: Sequence[McpToolSpec],
294
+ ) -> None:
295
+ del activation_key
296
+ await self.release_harness_mcp_specs(specs)
297
+
298
+ async def release_harness_mcp_specs(
299
+ self,
300
+ specs: Sequence[McpToolSpec],
301
+ ) -> None:
302
+ """Revoke every activation-scoped credential projected in ``specs``."""
303
+
304
+ first_error: BaseException | None = None
305
+ for spec in specs:
306
+ token = spec.api_key
307
+ if token is None:
308
+ continue
309
+ if token not in self._issued_scopes:
310
+ continue
311
+ try:
312
+ await self._revoke_tracked_scope(token)
313
+ except BaseException as error: # revocation must continue
314
+ if first_error is None:
315
+ first_error = error
316
+ if first_error is not None:
317
+ raise first_error
318
+
319
+ async def _revoke_tracked_scope(self, token: str) -> None:
320
+ lease = self._issued_scopes.get(token)
321
+ if lease is None:
322
+ return
323
+ task = self._revocation_tasks.get(token)
324
+ if task is None:
325
+ task = asyncio.create_task(self._revoke_scope(lease, token))
326
+ self._revocation_tasks[token] = task
327
+ try:
328
+ await asyncio.shield(task)
329
+ except asyncio.CancelledError:
330
+ # The owned task keeps the security action alive. The token stays
331
+ # tracked until revocation succeeds or a later dispose retries it.
332
+ raise
333
+ finally:
334
+ if task.done():
335
+ self._revocation_tasks.pop(token, None)
336
+ task.result()
337
+ self._issued_scopes.pop(token, None)
338
+
339
+ async def _revoke_scope(self, lease: DshMcpConnectorLease, token: str) -> None:
340
+ revoke = getattr(self._service, "revoke_runtime_token", None)
341
+ if not callable(revoke):
342
+ raise PluginHostError(
343
+ "dsh_mcp_revocation_unavailable",
344
+ "DSH capability lifecycle service cannot revoke runtime credentials",
345
+ )
346
+ await revoke(lease, token)
347
+
348
+ def _validate_descriptor(
349
+ self,
350
+ descriptor: DshProfileCapabilityDescriptor,
351
+ lease: DshMcpConnectorLease,
352
+ ) -> None:
353
+ materializer = _mapping(self._entry.get("materializer"), code="dsh_mcp_config_invalid")
354
+ expected = {
355
+ "profile": descriptor.profile,
356
+ "profileDigest": descriptor.profile_digest,
357
+ "descriptorDigest": descriptor.descriptor_digest,
358
+ "inventoryDigest": descriptor.inventory_digest,
359
+ }
360
+ if any(materializer.get(key) != value for key, value in expected.items()):
361
+ raise PluginHostError(
362
+ "dsh_mcp_descriptor_mismatch",
363
+ "DSH Profile changed after this Agent Build was compiled",
364
+ )
365
+ if (
366
+ _required(self._entry, "version", code="dsh_mcp_config_invalid")
367
+ != descriptor.dsh_version
368
+ ):
369
+ raise PluginHostError(
370
+ "dsh_mcp_descriptor_mismatch", "DSH runtime version changed after build"
371
+ )
372
+ if (
373
+ lease.profile != descriptor.profile
374
+ or lease.profile_digest != descriptor.profile_digest
375
+ or lease.descriptor_digest != descriptor.descriptor_digest
376
+ ):
377
+ raise PluginHostError(
378
+ "dsh_mcp_lease_mismatch", "DSH MCP lease does not match the locked descriptor"
379
+ )
380
+
381
+ def _resolved_resource(self, bundle: ResolvedPluginBundle) -> Mapping[str, Any]:
382
+ capabilities = _mapping(
383
+ bundle.resolved_agent_spec.get("capabilities"),
384
+ code="dsh_mcp_bundle_invalid",
385
+ )
386
+ raw = capabilities.get("mcpServers")
387
+ if not isinstance(raw, Sequence) or isinstance(raw, (str, bytes)):
388
+ raise PluginHostError("dsh_mcp_bundle_invalid", "mcpServers is missing")
389
+ matches = [
390
+ _mapping(item, code="dsh_mcp_bundle_invalid")
391
+ for item in raw
392
+ if isinstance(item, Mapping)
393
+ and item.get("name") == self._entry.get("name")
394
+ and item.get("version") == self._entry.get("version")
395
+ and item.get("digest") == self._entry.get("digest")
396
+ ]
397
+ if len(matches) != 1:
398
+ raise PluginHostError(
399
+ "dsh_mcp_resource_mismatch",
400
+ "locked DSH MCP resource is absent from the resolved Agent spec",
401
+ )
402
+ return matches[0]
403
+
404
+ def _validate_resolved_resource(self, resolved: Mapping[str, Any]) -> None:
405
+ assert self._descriptor is not None
406
+ expected = {
407
+ "transport": "http",
408
+ "materialization": "dsh-profile",
409
+ "profile": self._descriptor.profile,
410
+ "profileDigest": self._descriptor.profile_digest,
411
+ "descriptorDigest": self._descriptor.descriptor_digest,
412
+ "inventoryDigest": self._descriptor.inventory_digest,
413
+ }
414
+ if any(resolved.get(key) != value for key, value in expected.items()):
415
+ raise PluginHostError(
416
+ "dsh_mcp_resource_mismatch", "resolved DSH MCP metadata changed after build"
417
+ )
418
+ arguments = resolved.get("args")
419
+ environment = resolved.get("envRefs")
420
+ if (
421
+ resolved.get("endpointUrl") is not None
422
+ or resolved.get("command") is not None
423
+ or arguments not in (None, (), [])
424
+ or (environment is not None and (not isinstance(environment, Mapping) or environment))
425
+ ):
426
+ raise PluginHostError(
427
+ "dsh_mcp_secret_persisted",
428
+ "resolved DSH MCP must not contain runtime connection material",
429
+ )
430
+
431
+
432
+ class DshProfileMCPFactory:
433
+ """Stage the platform adapter against Studio's shared Profile service."""
434
+
435
+ def __init__(self, service: Any) -> None:
436
+ self._service = service
437
+
438
+ async def stage(
439
+ self,
440
+ manifest: PluginManifest,
441
+ *,
442
+ profile: CompositionProfile,
443
+ services: Mapping[str, Any],
444
+ ) -> DshProfileMCPRuntime:
445
+ del services
446
+ service = self._service
447
+ if (
448
+ manifest.metadata.id != DSH_PROFILE_MCP_PLUGIN_ID
449
+ or manifest.metadata.version != DSH_PROFILE_MCP_PLUGIN_VERSION
450
+ ):
451
+ raise PluginHostError("dsh_mcp_manifest_mismatch", "DSH MCP manifest mismatch")
452
+ if service is None:
453
+ raise PluginHostError(
454
+ "dsh_mcp_service_unavailable", "DSH capability lifecycle service is unavailable"
455
+ )
456
+ return DshProfileMCPRuntime(service=service, profile=profile)
457
+
458
+
459
+ __all__ = [
460
+ "DSH_PROFILE_MCP_PLUGIN_ID",
461
+ "DSH_PROFILE_MCP_PLUGIN_VERSION",
462
+ "DSH_PROFILE_TOOL_PERMISSION",
463
+ "DshProfileMCPFactory",
464
+ "DshProfileMCPRuntime",
465
+ "dsh_profile_mcp_manifest",
466
+ "dsh_harness_tool_alias",
467
+ ]