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,1075 @@
1
+ """Managed DSH AgentProvider registration for the normal Studio lifecycle.
2
+
3
+ Studio treats the selected DSH Profile as the installed/enabled source of
4
+ truth, then starts each AgentProvider contribution in its own fixed-command
5
+ sidecar. Only descriptor-fenced, ready registrations enter Studio's selector;
6
+ ordinary client-only DSH bundles remain visible to plugin management without
7
+ being mistaken for AgentProviders.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import asyncio
13
+ import json
14
+ import os
15
+ import shutil
16
+ import tempfile
17
+ from collections.abc import Callable, Mapping, Sequence
18
+ from dataclasses import dataclass
19
+ from pathlib import Path
20
+ from typing import Any, Literal
21
+
22
+ import yaml
23
+ from pydantic import BaseModel, ConfigDict
24
+
25
+ from ksadk.plugins.bridges.dsh import (
26
+ DshPluginInventory,
27
+ DshProfilePluginBridge,
28
+ DshProfileProjection,
29
+ )
30
+ from ksadk.plugins.contracts import CompositionProfile, PluginManifest
31
+ from ksadk.plugins.dsh_toolchain import DSH_CORE_PACKAGES, DshToolchainManager
32
+ from ksadk.plugins.host import ManagedPlugin, PluginHostError
33
+ from ksadk.plugins.providers.codex_dsh import (
34
+ SHIPPED_CODEX_DSH_PACKAGE,
35
+ SHIPPED_CODEX_PROVIDER_VERSION,
36
+ KsADKCodexDshBridgeFactory,
37
+ shipped_codex_dsh_bundle,
38
+ shipped_codex_dsh_host_command,
39
+ )
40
+ from ksadk.plugins.providers.dsh import (
41
+ DshAgentProviderFactory,
42
+ DshAgentProviderHost,
43
+ DshAgentProviderRegistration,
44
+ )
45
+ from ksadk.plugins.providers.harness_dsh import (
46
+ SHIPPED_HARNESS_DSH_PACKAGE,
47
+ SHIPPED_HARNESS_PROVIDER_VERSION,
48
+ KsADKHarnessDshBridgeFactory,
49
+ shipped_harness_dsh_bundle,
50
+ shipped_harness_dsh_host_command,
51
+ )
52
+
53
+ _PROFILE_FILES = ("package.json", "cordis.patch.yml", "index.mjs")
54
+ _MAX_PACKAGE_JSON_BYTES = 2 * 1024 * 1024
55
+ _DSH_PLATFORM_BUNDLES = frozenset(DSH_CORE_PACKAGES)
56
+ _SHIPPED_PROVIDER_PACKAGES = frozenset({SHIPPED_CODEX_DSH_PACKAGE, SHIPPED_HARNESS_DSH_PACKAGE})
57
+ _SHIPPED_RESOURCE_PACKAGES = (
58
+ ("@kingsoftcloud/dsh-platform-resources", "dsh-platform-resources"),
59
+ ("@kingsoftcloud/dsh-knowledge", "dsh-knowledge"),
60
+ ("@kingsoftcloud/dsh-memory", "dsh-memory"),
61
+ ("@kingsoftcloud/dsh-skill-center", "dsh-skill-center"),
62
+ )
63
+ _SHIPPED_RESOURCE_VERSION = "0.1.0"
64
+ _RESOURCE_RUNTIME_BUNDLE = "@deepseek-ai/dsh-web-app"
65
+
66
+
67
+ class StudioDshProviderRegistrationError(RuntimeError):
68
+ """A selected DSH Profile could not produce trustworthy registrations."""
69
+
70
+ def __init__(self, code: str, message: str) -> None:
71
+ super().__init__(message)
72
+ self.code = code
73
+
74
+
75
+ class StudioDshProviderStatus(BaseModel):
76
+ """Lifecycle evidence for one installed DSH Profile package."""
77
+
78
+ model_config = ConfigDict(extra="forbid", frozen=True)
79
+
80
+ package_name: str
81
+ package_version: str
82
+ display_name: str = ""
83
+ state: Literal["installed", "enabled", "ready", "bound", "failed", "disposed"]
84
+ provider_ref: str | None = None
85
+ error_code: str | None = None
86
+
87
+
88
+ class StudioDshProviderInventory(BaseModel):
89
+ model_config = ConfigDict(extra="forbid", frozen=True)
90
+
91
+ state: Literal["stopped", "starting", "ready", "bound", "failed", "disposed"]
92
+ profile: str
93
+ profile_digest: str | None = None
94
+ providers: tuple[str, ...] = ()
95
+ packages: tuple[StudioDshProviderStatus, ...] = ()
96
+ error_code: str | None = None
97
+
98
+
99
+ @dataclass(frozen=True)
100
+ class StudioDshProviderRegistrations:
101
+ manifests: Mapping[str, PluginManifest]
102
+ factories: Mapping[str, Any]
103
+ inventory: StudioDshProviderInventory
104
+
105
+
106
+ @dataclass(frozen=True)
107
+ class _ProfileSnapshot:
108
+ projection: DshProfileProjection
109
+ packages: tuple[DshPluginInventory, ...]
110
+
111
+
112
+ BridgeFactory = Callable[..., DshProfilePluginBridge]
113
+ HostFactory = Callable[..., DshAgentProviderHost]
114
+
115
+
116
+ class _FreshDshAgentProviderFactory:
117
+ """Give every PluginHost graph an independently owned provider process."""
118
+
119
+ def __init__(
120
+ self,
121
+ command: Sequence[str],
122
+ *,
123
+ projection: DshProfileProjection,
124
+ cwd: Path,
125
+ environment: Mapping[str, str],
126
+ registration: DshAgentProviderRegistration,
127
+ host_factory: HostFactory,
128
+ ) -> None:
129
+ self._command = tuple(command)
130
+ self._projection = projection
131
+ self._cwd = cwd
132
+ self._environment = dict(environment)
133
+ self._registration = registration
134
+ self._host_factory = host_factory
135
+
136
+ async def stage(
137
+ self,
138
+ manifest: PluginManifest,
139
+ *,
140
+ profile: CompositionProfile,
141
+ services: Mapping[str, Any],
142
+ ) -> ManagedPlugin:
143
+ host = self._host_factory(
144
+ self._command,
145
+ projection=self._projection,
146
+ cwd=self._cwd,
147
+ environment=self._environment,
148
+ )
149
+ try:
150
+ current = await host.registration()
151
+ if current != self._registration:
152
+ raise PluginHostError(
153
+ "dsh_provider_registration_changed",
154
+ "DSH provider registration changed after Studio discovery",
155
+ )
156
+ return await DshAgentProviderFactory(host, current).stage(
157
+ manifest,
158
+ profile=profile,
159
+ services=services,
160
+ )
161
+ except BaseException:
162
+ await host.dispose()
163
+ raise
164
+
165
+
166
+ class _FreshShippedDshBridgeFactory:
167
+ """Bind a shipped provider to a host owned by the consuming PluginHost loop."""
168
+
169
+ def __init__(
170
+ self,
171
+ command: Sequence[str],
172
+ *,
173
+ projection: DshProfileProjection,
174
+ cwd: Path,
175
+ environment: Mapping[str, str],
176
+ registration: DshAgentProviderRegistration,
177
+ package_name: str,
178
+ host_factory: HostFactory,
179
+ ) -> None:
180
+ self._command = tuple(command)
181
+ self._projection = projection
182
+ self._cwd = cwd
183
+ self._environment = dict(environment)
184
+ self._registration = registration
185
+ self._package_name = package_name
186
+ self._host_factory = host_factory
187
+
188
+ async def stage(
189
+ self,
190
+ manifest: PluginManifest,
191
+ *,
192
+ profile: CompositionProfile,
193
+ services: Mapping[str, Any],
194
+ ) -> ManagedPlugin:
195
+ host = self._host_factory(
196
+ self._command,
197
+ projection=self._projection,
198
+ cwd=self._cwd,
199
+ environment=self._environment,
200
+ )
201
+ try:
202
+ current = await host.registration()
203
+ if current != self._registration:
204
+ raise PluginHostError(
205
+ "dsh_provider_registration_changed",
206
+ "DSH provider registration changed after Studio discovery",
207
+ )
208
+ if self._package_name == SHIPPED_CODEX_DSH_PACKAGE:
209
+ factory: Any = KsADKCodexDshBridgeFactory(host, current, owns_host=True)
210
+ elif self._package_name == SHIPPED_HARNESS_DSH_PACKAGE:
211
+ factory = KsADKHarnessDshBridgeFactory(host, current, owns_host=True)
212
+ else: # guarded by _register_package
213
+ raise PluginHostError(
214
+ "dsh_provider_package_unsupported",
215
+ "shipped DSH provider package is unsupported",
216
+ )
217
+ return await factory.stage(manifest, profile=profile, services=services)
218
+ except BaseException:
219
+ await host.dispose()
220
+ raise
221
+
222
+
223
+ class StudioDshProviderRegistrationManager:
224
+ """Own Profile discovery, provider preflight, registration, and disposal."""
225
+
226
+ def __init__(
227
+ self,
228
+ workspace: Path,
229
+ *,
230
+ dsh_home: Path,
231
+ profile: str = "web",
232
+ dsh_command: Sequence[str] | None = None,
233
+ node_command: Sequence[str] | None = None,
234
+ cordis_module: Path | None = None,
235
+ bridge_factory: BridgeFactory = DshProfilePluginBridge,
236
+ host_factory: HostFactory = DshAgentProviderHost,
237
+ ) -> None:
238
+ self._workspace = workspace.resolve()
239
+ self._dsh_home = dsh_home.expanduser().resolve()
240
+ self._profile = profile
241
+ self._dsh_command = tuple(dsh_command) if dsh_command is not None else None
242
+ self._node_command = tuple(node_command) if node_command is not None else None
243
+ self._cordis_module = cordis_module.resolve() if cordis_module is not None else None
244
+ self._bridge_factory = bridge_factory
245
+ self._host_factory = host_factory
246
+ self._lock = asyncio.Lock()
247
+ self._hosts: dict[str, DshAgentProviderHost] = {}
248
+ self._registrations: StudioDshProviderRegistrations | None = None
249
+ self._inventory = StudioDshProviderInventory(state="stopped", profile=profile)
250
+
251
+ @classmethod
252
+ def discover(cls, workspace: Path) -> "StudioDshProviderRegistrationManager | None":
253
+ """Discover an initialized managed Profile without downloading tools."""
254
+
255
+ configured_home = os.environ.get("KSADK_DSH_HOME", "").strip()
256
+ home = (
257
+ Path(configured_home).expanduser()
258
+ if configured_home
259
+ else workspace / ".agentkit" / "dsh-home"
260
+ )
261
+ profile = os.environ.get("KSADK_DSH_PROFILE", "").strip() or "web"
262
+ configured_bin = os.environ.get("KSADK_DSH_BIN", "").strip()
263
+ manifest = home / "profiles" / profile / "package.json"
264
+ if not manifest.is_file():
265
+ return None
266
+ try:
267
+ payload = json.loads(manifest.read_text(encoding="utf-8"))
268
+ except (OSError, UnicodeError, json.JSONDecodeError):
269
+ return None
270
+ dsh = payload.get("dsh") if isinstance(payload, dict) else None
271
+ profile_payload = dsh.get("profile") if isinstance(dsh, dict) else None
272
+ bundles = profile_payload.get("bundles") if isinstance(profile_payload, dict) else None
273
+ if not isinstance(bundles, list) or any(not isinstance(item, str) for item in bundles):
274
+ return None
275
+ command = (str(Path(configured_bin).expanduser()),) if configured_bin else None
276
+ return cls(workspace, dsh_home=home, profile=profile, dsh_command=command)
277
+
278
+ @classmethod
279
+ def discover_or_create_workspace_default(
280
+ cls, workspace: Path
281
+ ) -> "StudioDshProviderRegistrationManager | None":
282
+ """Discover DSH or prepare the isolated first-run Studio Profile.
283
+
284
+ The default is deliberately narrower than :meth:`discover`: only the
285
+ Studio-owned ``.agentkit/dsh-home`` and official ``web`` Profile qualify for
286
+ automatic official-provider bootstrap. Explicit DSH homes/profiles
287
+ are user-owned and are never mutated by Studio startup.
288
+ """
289
+
290
+ configured_home = os.environ.get("KSADK_DSH_HOME", "").strip()
291
+ configured_profile = os.environ.get("KSADK_DSH_PROFILE", "").strip()
292
+ if configured_home or configured_profile:
293
+ return cls.discover(workspace)
294
+ root = workspace.resolve()
295
+ home = root / ".agentkit" / "dsh-home"
296
+ configured_bin = os.environ.get("KSADK_DSH_BIN", "").strip()
297
+ if configured_bin:
298
+ command: Sequence[str] | None = (str(Path(configured_bin).expanduser()),)
299
+ else:
300
+ try:
301
+ command = DshToolchainManager().require_command()
302
+ except Exception:
303
+ # DSH is optional. A missing toolchain must not make the
304
+ # normal Studio/legacy Codex path unavailable.
305
+ return None
306
+ return cls(root, dsh_home=home, profile="web", dsh_command=command)
307
+
308
+ @classmethod
309
+ def create_workspace_resource_default(
310
+ cls, workspace: Path
311
+ ) -> "StudioDshProviderRegistrationManager | None":
312
+ """Own the official-only Profile frozen into resource Builds."""
313
+
314
+ if os.environ.get("KSADK_DSH_HOME", "").strip() or os.environ.get(
315
+ "KSADK_DSH_PROFILE", ""
316
+ ).strip():
317
+ return None
318
+ root = workspace.resolve()
319
+ configured_bin = os.environ.get("KSADK_DSH_BIN", "").strip()
320
+ if configured_bin:
321
+ command: Sequence[str] | None = (str(Path(configured_bin).expanduser()),)
322
+ else:
323
+ try:
324
+ command = DshToolchainManager().require_command()
325
+ except Exception:
326
+ return None
327
+ return cls(
328
+ root,
329
+ dsh_home=root / ".agentkit" / "dsh-home",
330
+ profile="agentkit-resources",
331
+ dsh_command=command,
332
+ )
333
+
334
+ @property
335
+ def inventory(self) -> StudioDshProviderInventory:
336
+ return self._inventory
337
+
338
+ @property
339
+ def _owns_workspace_default_profile(self) -> bool:
340
+ configured_home = os.environ.get("KSADK_DSH_HOME", "").strip()
341
+ configured_profile = os.environ.get("KSADK_DSH_PROFILE", "").strip()
342
+ expected_home = (self._workspace / ".agentkit" / "dsh-home").resolve()
343
+ return (
344
+ not configured_home
345
+ and not configured_profile
346
+ and self._profile in {"web", "agentkit-resources"}
347
+ and self._dsh_home == expected_home
348
+ )
349
+
350
+ async def bootstrap_official_codex_provider(
351
+ self,
352
+ ) -> Literal["installed", "already_enabled", "disabled", "skipped"]:
353
+ """Apply the wheel-owned Codex default once for the Studio Profile.
354
+
355
+ This method never enables an existing disabled package and never
356
+ mutates an explicit/user-owned DSH Profile. The marker also preserves
357
+ an explicit uninstall across future Studio starts.
358
+ """
359
+
360
+ if not self._owns_workspace_default_profile:
361
+ return "skipped"
362
+ async with self._lock:
363
+ return await asyncio.to_thread(self._bootstrap_official_codex_provider_sync)
364
+
365
+ def _bootstrap_official_codex_provider_sync(
366
+ self,
367
+ ) -> Literal["installed", "already_enabled", "disabled", "skipped"]:
368
+ """Perform the blocking DSH package mutation outside the event loop."""
369
+
370
+ if not self._owns_workspace_default_profile:
371
+ return "skipped"
372
+ marker = self._default_marker_path
373
+ marker_payload = self._read_default_marker(marker)
374
+ command = self._dsh_command or DshToolchainManager().require_command()
375
+ shipped = shipped_codex_dsh_bundle()
376
+ with self._bridge_factory(
377
+ dsh_home=self._dsh_home,
378
+ profile=self._profile,
379
+ dsh_command=command,
380
+ cwd=self._workspace,
381
+ ) as bridge:
382
+ self._repair_owned_profile_layout(bridge)
383
+ installed = {item.name: item for item in bridge.list_plugins()}
384
+ current = installed.get(SHIPPED_CODEX_DSH_PACKAGE)
385
+ if current is None:
386
+ if marker_payload.get("codexProviderApplied") is True:
387
+ return "skipped"
388
+ current = bridge.install_plugin(str(shipped.root), accept_host_permissions=True)
389
+ if current.name != SHIPPED_CODEX_DSH_PACKAGE:
390
+ raise StudioDshProviderRegistrationError(
391
+ "codex_dsh_package_mismatch",
392
+ "the official Codex install returned a different package",
393
+ )
394
+ result: Literal["installed", "already_enabled", "disabled"] = "installed"
395
+ else:
396
+ result = "already_enabled" if current.enabled else "disabled"
397
+ if current.version != SHIPPED_CODEX_PROVIDER_VERSION:
398
+ raise StudioDshProviderRegistrationError(
399
+ "codex_dsh_bundle_not_active",
400
+ "the official Codex DSH Bundle version is not supported",
401
+ )
402
+ if not current.enabled and result == "installed":
403
+ current = bridge.set_enabled(SHIPPED_CODEX_DSH_PACKAGE, enabled=True)
404
+ if not current.enabled:
405
+ raise StudioDshProviderRegistrationError(
406
+ "codex_dsh_enable_failed",
407
+ "the official Codex DSH Bundle did not become enabled",
408
+ )
409
+ self._verify_shipped_bundle_bytes(SHIPPED_CODEX_DSH_PACKAGE)
410
+ if marker_payload.get("codexProviderApplied") is not True:
411
+ self._write_default_marker(
412
+ marker,
413
+ {
414
+ **marker_payload,
415
+ "version": 1,
416
+ "codexProviderApplied": True,
417
+ "codexProviderVersion": SHIPPED_CODEX_PROVIDER_VERSION,
418
+ },
419
+ )
420
+ return result
421
+
422
+ async def bootstrap_official_resource_plugins(
423
+ self,
424
+ ) -> Literal["installed", "already_enabled", "disabled", "skipped"]:
425
+ """Apply the wheel-owned platform-resource stack once to Studio's Profile."""
426
+
427
+ if not self._owns_workspace_default_profile:
428
+ return "skipped"
429
+ async with self._lock:
430
+ return await asyncio.to_thread(self._bootstrap_official_resource_plugins_sync)
431
+
432
+ def _bootstrap_official_resource_plugins_sync(
433
+ self,
434
+ ) -> Literal["installed", "already_enabled", "disabled", "skipped"]:
435
+ if not self._owns_workspace_default_profile:
436
+ return "skipped"
437
+ marker = self._default_marker_path
438
+ marker_payload = self._read_default_marker(marker)
439
+ command = self._dsh_command or DshToolchainManager().require_command()
440
+ installed_any = False
441
+ disabled = False
442
+ enable_defaults = marker_payload.get("platformResourcesEnabled") is not True
443
+ with self._bridge_factory(
444
+ dsh_home=self._dsh_home,
445
+ profile=self._profile,
446
+ dsh_command=command,
447
+ cwd=self._workspace,
448
+ ) as bridge:
449
+ self._repair_owned_profile_layout(bridge)
450
+ inventory = {item.name: item for item in bridge.list_plugins()}
451
+ for package_name, directory_name in _SHIPPED_RESOURCE_PACKAGES:
452
+ current = inventory.get(package_name)
453
+ if current is None:
454
+ # A completed marker plus a missing package records a later,
455
+ # explicit uninstall. Startup must preserve that choice.
456
+ if marker_payload.get("platformResourcesApplied") is True:
457
+ continue
458
+ root = (
459
+ Path(__file__).parents[1]
460
+ / "plugins"
461
+ / "providers"
462
+ / "bundles"
463
+ / directory_name
464
+ )
465
+ current = bridge.install_plugin(
466
+ str(root), accept_host_permissions=True
467
+ )
468
+ if current.name != package_name:
469
+ raise StudioDshProviderRegistrationError(
470
+ "resource_dsh_package_mismatch",
471
+ "an official resource install returned a different package",
472
+ )
473
+ installed_any = True
474
+ if current.version != _SHIPPED_RESOURCE_VERSION:
475
+ raise StudioDshProviderRegistrationError(
476
+ "resource_dsh_bundle_not_active",
477
+ "an official platform resource Bundle version is not supported",
478
+ )
479
+ if not current.enabled and enable_defaults:
480
+ current = bridge.set_enabled(package_name, enabled=True)
481
+ if not current.enabled:
482
+ raise StudioDshProviderRegistrationError(
483
+ "resource_dsh_enable_failed",
484
+ "an official platform resource Bundle did not become enabled",
485
+ )
486
+ disabled = disabled or not current.enabled
487
+ self._verify_shipped_resource_bundle_bytes(package_name, directory_name)
488
+ if self._profile == "agentkit-resources":
489
+ self._ensure_resource_runtime_bundle()
490
+ if marker_payload.get("platformResourcesApplied") is not True:
491
+ self._write_default_marker(
492
+ marker,
493
+ {
494
+ **marker_payload,
495
+ "version": 1,
496
+ "platformResourcesApplied": True,
497
+ "platformResourcesEnabled": True,
498
+ "platformResourcesVersion": _SHIPPED_RESOURCE_VERSION,
499
+ },
500
+ )
501
+ elif enable_defaults:
502
+ self._write_default_marker(
503
+ marker,
504
+ {**marker_payload, "platformResourcesEnabled": True},
505
+ )
506
+ if disabled:
507
+ return "disabled"
508
+ return "installed" if installed_any else "already_enabled"
509
+
510
+ def _ensure_resource_runtime_bundle(self) -> None:
511
+ """Give the private resource Profile the official loopback transport.
512
+
513
+ The capability exporter uses DSH's authenticated ``webServer`` and
514
+ ``connection`` services even when no browser UI is mounted. Custom
515
+ Profiles start with only ``dsh-base``, so the Studio-owned execution
516
+ Profile must explicitly include DSH's official web runtime layer.
517
+ """
518
+
519
+ manifest_path = self._profile_root / "package.json"
520
+ try:
521
+ if manifest_path.stat().st_size > _MAX_PACKAGE_JSON_BYTES:
522
+ raise ValueError("package.json is too large")
523
+ payload = json.loads(manifest_path.read_text(encoding="utf-8"))
524
+ dsh = payload.get("dsh")
525
+ profile = dsh.get("profile") if isinstance(dsh, dict) else None
526
+ bundles = profile.get("bundles") if isinstance(profile, dict) else None
527
+ if not isinstance(bundles, list) or any(
528
+ not isinstance(item, str) for item in bundles
529
+ ):
530
+ raise ValueError("bundle order is invalid")
531
+ except (OSError, UnicodeError, json.JSONDecodeError, ValueError) as error:
532
+ raise StudioDshProviderRegistrationError(
533
+ "resource_dsh_profile_invalid",
534
+ "the official resource execution Profile is invalid",
535
+ ) from error
536
+ if _RESOURCE_RUNTIME_BUNDLE in bundles:
537
+ return
538
+ try:
539
+ base_index = bundles.index("@deepseek-ai/dsh-base")
540
+ except ValueError as error:
541
+ raise StudioDshProviderRegistrationError(
542
+ "resource_dsh_profile_invalid",
543
+ "the official resource execution Profile has no DSH base Bundle",
544
+ ) from error
545
+ bundles.insert(base_index + 1, _RESOURCE_RUNTIME_BUNDLE)
546
+ self._write_default_marker(manifest_path, payload)
547
+
548
+ def _repair_owned_profile_layout(self, bridge: DshProfilePluginBridge) -> None:
549
+ """Repair only Studio's default legacy Profile before projecting it.
550
+
551
+ Older Studio versions created the ``web`` Profile with pnpm's hoisted
552
+ linker. Some community dependency graphs then contained links to the
553
+ ambient pnpm store and could not form a closed Build snapshot. The
554
+ frozen lock remains the authority; the bridge keeps the original tree
555
+ as an atomic rollback point while reinstalling the isolated layout.
556
+ """
557
+
558
+ if not self._owns_workspace_default_profile:
559
+ return
560
+ settings_path = self._dsh_home / "profiles" / self._profile / "pnpm-workspace.yaml"
561
+ if not settings_path.is_file():
562
+ return
563
+ try:
564
+ settings = yaml.safe_load(settings_path.read_text(encoding="utf-8"))
565
+ except (OSError, UnicodeError, yaml.YAMLError) as error:
566
+ raise StudioDshProviderRegistrationError(
567
+ "dsh_profile_layout_invalid",
568
+ "the Studio-owned DSH Profile layout settings are unreadable",
569
+ ) from error
570
+ if not isinstance(settings, dict):
571
+ raise StudioDshProviderRegistrationError(
572
+ "dsh_profile_layout_invalid",
573
+ "the Studio-owned DSH Profile layout settings are invalid",
574
+ )
575
+ if settings.get("nodeLinker") not in {"hoisted", "isolated"}:
576
+ return
577
+ bridge.migrate_to_isolated_layout(
578
+ accept_host_permissions=True,
579
+ recover_external_dependency_links=True,
580
+ )
581
+
582
+ @property
583
+ def _default_marker_path(self) -> Path:
584
+ # Scope the bootstrap receipt to the owned Profile. Older Studio
585
+ # builds used one workspace-wide marker while their default Profile
586
+ # was ``studio``. Reusing that marker after the default moved to
587
+ # official Core's ``web`` Profile incorrectly skipped first-run
588
+ # installation and left Studio with no runnable DSH Profile.
589
+ return self._workspace / ".agentkit" / f"official-dsh-defaults-{self._profile}.json"
590
+
591
+ @staticmethod
592
+ def _read_default_marker(path: Path) -> dict[str, object]:
593
+ try:
594
+ payload = json.loads(path.read_text(encoding="utf-8")) if path.is_file() else {}
595
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
596
+ raise StudioDshProviderRegistrationError(
597
+ "dsh_default_marker_invalid",
598
+ "the Studio official DSH defaults marker is unreadable",
599
+ ) from error
600
+ if not isinstance(payload, dict):
601
+ raise StudioDshProviderRegistrationError(
602
+ "dsh_default_marker_invalid",
603
+ "the Studio official DSH defaults marker is invalid",
604
+ )
605
+ return payload
606
+
607
+ @staticmethod
608
+ def _write_default_marker(path: Path, payload: Mapping[str, object]) -> None:
609
+ path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
610
+ descriptor, temporary = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
611
+ try:
612
+ with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
613
+ json.dump(payload, handle, ensure_ascii=False, sort_keys=True)
614
+ handle.write("\n")
615
+ handle.flush()
616
+ os.fsync(handle.fileno())
617
+ os.chmod(temporary, 0o600)
618
+ os.replace(temporary, path)
619
+ finally:
620
+ try:
621
+ os.unlink(temporary)
622
+ except FileNotFoundError:
623
+ pass
624
+
625
+ @property
626
+ def host_pid(self) -> int | None:
627
+ return next(iter(self.host_pids), None)
628
+
629
+ @property
630
+ def host_pids(self) -> tuple[int, ...]:
631
+ return tuple(host.pid for host in self._hosts.values() if host.pid is not None)
632
+
633
+ async def start(self) -> StudioDshProviderRegistrations:
634
+ async with self._lock:
635
+ if self._registrations is not None:
636
+ return self._registrations
637
+ if self._inventory.state == "disposed":
638
+ raise StudioDshProviderRegistrationError(
639
+ "dsh_provider_manager_disposed",
640
+ "Studio DSH provider registration manager is disposed",
641
+ )
642
+ self._inventory = StudioDshProviderInventory(state="starting", profile=self._profile)
643
+ try:
644
+ snapshot = await asyncio.to_thread(self._discover_profile)
645
+ result = await self._register_snapshot(snapshot)
646
+ except BaseException as error:
647
+ await self._dispose_hosts()
648
+ code = str(getattr(error, "code", "dsh_provider_registration_failed"))
649
+ self._inventory = StudioDshProviderInventory(
650
+ state="failed", profile=self._profile, error_code=code
651
+ )
652
+ if isinstance(error, (asyncio.CancelledError, KeyboardInterrupt, SystemExit)):
653
+ raise
654
+ raise StudioDshProviderRegistrationError(
655
+ code,
656
+ "managed DSH Profile could not be projected safely",
657
+ ) from error
658
+ self._registrations = result
659
+ self._inventory = result.inventory
660
+ return result
661
+
662
+ async def refresh(self) -> StudioDshProviderRegistrations:
663
+ async with self._lock:
664
+ if self._inventory.state == "disposed":
665
+ raise StudioDshProviderRegistrationError(
666
+ "dsh_provider_manager_disposed",
667
+ "Studio DSH provider registration manager is disposed",
668
+ )
669
+ self._registrations = None
670
+ await self._dispose_hosts()
671
+ self._inventory = StudioDshProviderInventory(state="stopped", profile=self._profile)
672
+ return await self.start()
673
+
674
+ def mark_bound(self, provider_refs: Sequence[str]) -> None:
675
+ if self._registrations is None or self._inventory.state != "ready":
676
+ raise StudioDshProviderRegistrationError(
677
+ "dsh_provider_registration_not_ready",
678
+ "DSH provider registrations cannot be bound before preflight",
679
+ )
680
+ expected = tuple(self._registrations.manifests)
681
+ if tuple(provider_refs) != expected:
682
+ raise StudioDshProviderRegistrationError(
683
+ "dsh_provider_registration_mismatch",
684
+ "Studio did not bind the exact ready DSH provider registration set",
685
+ )
686
+ packages = tuple(
687
+ item.model_copy(update={"state": "bound"})
688
+ if item.state == "ready" and item.provider_ref in expected
689
+ else item
690
+ for item in self._inventory.packages
691
+ )
692
+ self._inventory = self._inventory.model_copy(
693
+ update={"state": "bound", "packages": packages}
694
+ )
695
+
696
+ async def aclose(self) -> None:
697
+ async with self._lock:
698
+ self._registrations = None
699
+ await self._dispose_hosts()
700
+ packages = tuple(
701
+ item.model_copy(update={"state": "disposed"})
702
+ if item.state in {"ready", "bound"}
703
+ else item
704
+ for item in self._inventory.packages
705
+ )
706
+ self._inventory = StudioDshProviderInventory(
707
+ state="disposed",
708
+ profile=self._profile,
709
+ profile_digest=self._inventory.profile_digest,
710
+ packages=packages,
711
+ )
712
+
713
+ def _discover_profile(self) -> _ProfileSnapshot:
714
+ command = self._dsh_command or DshToolchainManager().require_command()
715
+ with self._bridge_factory(
716
+ dsh_home=self._dsh_home,
717
+ profile=self._profile,
718
+ dsh_command=command,
719
+ cwd=self._workspace,
720
+ ) as bridge:
721
+ packages = bridge.list_plugins()
722
+ projection = bridge.project_profile()
723
+ enabled = {item.name for item in packages if item.enabled}
724
+ projected = set(projection.bundles)
725
+ if not enabled.issubset(projected) or projected - enabled - _DSH_PLATFORM_BUNDLES:
726
+ raise StudioDshProviderRegistrationError(
727
+ "dsh_provider_profile_inventory_mismatch",
728
+ "DSH installed inventory and projected Profile disagree",
729
+ )
730
+ return _ProfileSnapshot(projection=projection, packages=packages)
731
+
732
+ async def _register_snapshot(
733
+ self, snapshot: _ProfileSnapshot
734
+ ) -> StudioDshProviderRegistrations:
735
+ manifests: dict[str, PluginManifest] = {}
736
+ factories: dict[str, Any] = {}
737
+ statuses = [
738
+ StudioDshProviderStatus(
739
+ package_name=item.name,
740
+ package_version=item.version,
741
+ display_name=item.display_name,
742
+ state="enabled" if item.enabled else "installed",
743
+ )
744
+ for item in snapshot.packages
745
+ ]
746
+ provider_packages: dict[str, str] = {}
747
+ for index, package in enumerate(snapshot.packages):
748
+ if not package.enabled:
749
+ continue
750
+ host: DshAgentProviderHost | None = None
751
+ try:
752
+ registration, factory, host = await self._register_package(
753
+ package, snapshot.projection
754
+ )
755
+ if registration is None or factory is None or host is None:
756
+ continue
757
+ descriptor = registration.descriptor
758
+ provider_ref = f"plugin://{descriptor.provider_id}@{descriptor.provider_version}"
759
+ prior_package = provider_packages.get(provider_ref)
760
+ if prior_package is not None:
761
+ await host.dispose()
762
+ prior_host = self._hosts.pop(prior_package, None)
763
+ if prior_host is not None:
764
+ await prior_host.dispose()
765
+ manifests.pop(provider_ref, None)
766
+ factories.pop(provider_ref, None)
767
+ statuses[index] = statuses[index].model_copy(
768
+ update={
769
+ "state": "failed",
770
+ "provider_ref": provider_ref,
771
+ "error_code": "dsh_provider_registration_conflict",
772
+ }
773
+ )
774
+ for prior_index, status in enumerate(statuses):
775
+ if status.package_name == prior_package:
776
+ statuses[prior_index] = status.model_copy(
777
+ update={
778
+ "state": "failed",
779
+ "error_code": "dsh_provider_registration_conflict",
780
+ }
781
+ )
782
+ break
783
+ continue
784
+ provider_packages[provider_ref] = package.name
785
+ manifests[provider_ref] = registration.manifest
786
+ factories[provider_ref] = factory
787
+ # Discovery is a bounded admission probe. Keeping its process
788
+ # alive would bind Studio construction to that event loop and
789
+ # make later API or Scheduler loops reuse foreign transports.
790
+ # The fresh factory repeats the exact registration fence and
791
+ # owns its execution host in the consuming PluginHost loop.
792
+ await host.dispose()
793
+ statuses[index] = statuses[index].model_copy(
794
+ update={
795
+ "state": "ready",
796
+ "provider_ref": provider_ref,
797
+ "display_name": descriptor.display_name,
798
+ }
799
+ )
800
+ except BaseException as error:
801
+ if host is not None:
802
+ try:
803
+ await host.dispose()
804
+ except BaseException:
805
+ pass
806
+ if isinstance(error, (asyncio.CancelledError, KeyboardInterrupt, SystemExit)):
807
+ raise
808
+ statuses[index] = statuses[index].model_copy(
809
+ update={
810
+ "state": "failed",
811
+ "error_code": str(
812
+ getattr(error, "code", "dsh_provider_registration_failed")
813
+ ),
814
+ }
815
+ )
816
+ inventory = StudioDshProviderInventory(
817
+ state="ready",
818
+ profile=self._profile,
819
+ profile_digest=snapshot.projection.config_digest,
820
+ providers=tuple(manifests),
821
+ packages=tuple(statuses),
822
+ )
823
+ return StudioDshProviderRegistrations(
824
+ manifests=manifests, factories=factories, inventory=inventory
825
+ )
826
+
827
+ async def _register_package(
828
+ self,
829
+ package: DshPluginInventory,
830
+ projection: DshProfileProjection,
831
+ ) -> tuple[
832
+ DshAgentProviderRegistration | None,
833
+ Any | None,
834
+ DshAgentProviderHost | None,
835
+ ]:
836
+ if package.name in _SHIPPED_PROVIDER_PACKAGES:
837
+ error_prefix = (
838
+ "codex_dsh" if package.name == SHIPPED_CODEX_DSH_PACKAGE else "harness_dsh"
839
+ )
840
+ expected_version = (
841
+ SHIPPED_CODEX_PROVIDER_VERSION
842
+ if package.name == SHIPPED_CODEX_DSH_PACKAGE
843
+ else SHIPPED_HARNESS_PROVIDER_VERSION
844
+ )
845
+ if package.version != expected_version:
846
+ raise StudioDshProviderRegistrationError(
847
+ f"{error_prefix}_bundle_not_active",
848
+ "the exact shipped DSH AgentProvider Bundle is not active",
849
+ )
850
+ self._verify_shipped_bundle_bytes(package.name)
851
+ command = (
852
+ shipped_codex_dsh_host_command()
853
+ if package.name == SHIPPED_CODEX_DSH_PACKAGE
854
+ else shipped_harness_dsh_host_command()
855
+ )
856
+ cwd = self._workspace
857
+ environment: dict[str, str] = {}
858
+ else:
859
+ entry = self._provider_host_entry(package.name)
860
+ if entry is None:
861
+ return None, None, None
862
+ command = (*self._resolve_node_command(), str(entry))
863
+ cwd = self._profile_root
864
+ environment = {"KSADK_DSH_CORDIS_MODULE": str(self._resolve_cordis_module())}
865
+ host = self._host_factory(
866
+ command,
867
+ projection=projection,
868
+ cwd=cwd,
869
+ environment=environment,
870
+ )
871
+ try:
872
+ registration = await host.registration()
873
+ if registration.descriptor.plugin_name != package.name:
874
+ raise PluginHostError(
875
+ "dsh_provider_package_mismatch",
876
+ "DSH provider descriptor does not match its installed package",
877
+ )
878
+ provider_inventory = await host.inventory()
879
+ if provider_inventory.state != "ready":
880
+ raise PluginHostError(
881
+ "dsh_provider_inventory_not_ready",
882
+ "DSH AgentProvider inventory is not ready",
883
+ )
884
+ if package.name in _SHIPPED_PROVIDER_PACKAGES:
885
+ factory: Any = _FreshShippedDshBridgeFactory(
886
+ command,
887
+ projection=projection,
888
+ cwd=cwd,
889
+ environment=environment,
890
+ registration=registration,
891
+ package_name=package.name,
892
+ host_factory=self._host_factory,
893
+ )
894
+ else:
895
+ factory = _FreshDshAgentProviderFactory(
896
+ command,
897
+ projection=projection,
898
+ cwd=cwd,
899
+ environment=environment,
900
+ registration=registration,
901
+ host_factory=self._host_factory,
902
+ )
903
+ return registration, factory, host
904
+ except BaseException:
905
+ await host.dispose()
906
+ raise
907
+
908
+ @property
909
+ def _profile_root(self) -> Path:
910
+ return self._dsh_home / "profiles" / self._profile
911
+
912
+ def _provider_host_entry(self, package_name: str) -> Path | None:
913
+ package_root = self._profile_root / "node_modules"
914
+ for segment in package_name.split("/"):
915
+ package_root /= segment
916
+ manifest_path = package_root / "package.json"
917
+ try:
918
+ if manifest_path.stat().st_size > _MAX_PACKAGE_JSON_BYTES:
919
+ raise ValueError("package.json is too large")
920
+ payload = json.loads(manifest_path.read_text(encoding="utf-8"))
921
+ except (OSError, UnicodeError, json.JSONDecodeError, ValueError) as error:
922
+ raise PluginHostError(
923
+ "dsh_provider_package_invalid",
924
+ "installed DSH provider package.json is invalid",
925
+ ) from error
926
+ exports = payload.get("exports") if isinstance(payload, dict) else None
927
+ if not isinstance(exports, dict) or "./provider-host" not in exports:
928
+ return None
929
+ relative = exports.get("./provider-host")
930
+ if not isinstance(relative, str) or not relative.startswith("./"):
931
+ raise PluginHostError(
932
+ "dsh_provider_host_export_invalid",
933
+ "DSH provider-host export must be one relative file",
934
+ )
935
+ try:
936
+ resolved_root = package_root.resolve(strict=True)
937
+ entry = (resolved_root / relative).resolve(strict=True)
938
+ except (OSError, RuntimeError) as error:
939
+ raise PluginHostError(
940
+ "dsh_provider_host_unavailable",
941
+ "DSH provider-host export is unavailable",
942
+ ) from error
943
+ if not entry.is_relative_to(resolved_root) or not entry.is_file():
944
+ raise PluginHostError(
945
+ "dsh_provider_host_export_invalid",
946
+ "DSH provider-host export escapes its installed package",
947
+ )
948
+ return entry
949
+
950
+ def _resolve_node_command(self) -> tuple[str, ...]:
951
+ if self._node_command is not None:
952
+ if not self._node_command:
953
+ raise PluginHostError("dsh_provider_node_unavailable", "Node command is empty")
954
+ return self._node_command
955
+ configured = os.environ.get("NODE", "").strip() or "node"
956
+ resolved = shutil.which(configured)
957
+ if resolved is None:
958
+ raise PluginHostError("dsh_provider_node_unavailable", "Node executable is unavailable")
959
+ return (str(Path(resolved).resolve()),)
960
+
961
+ def _resolve_cordis_module(self) -> Path:
962
+ if self._cordis_module is not None:
963
+ return self._cordis_module
964
+ return DshToolchainManager().resolve_module_entry("@deepseek-ai/cordis")
965
+
966
+ async def _dispose_hosts(self) -> None:
967
+ hosts = tuple(self._hosts.values())
968
+ self._hosts.clear()
969
+ for host in hosts:
970
+ try:
971
+ await host.dispose()
972
+ except BaseException:
973
+ pass
974
+
975
+ def _verify_shipped_bundle_bytes(self, package_name: str) -> None:
976
+ if package_name == SHIPPED_CODEX_DSH_PACKAGE:
977
+ shipped = shipped_codex_dsh_bundle().root
978
+ error_prefix = "codex_dsh"
979
+ elif package_name == SHIPPED_HARNESS_DSH_PACKAGE:
980
+ shipped = shipped_harness_dsh_bundle().root
981
+ error_prefix = "harness_dsh"
982
+ else: # pragma: no cover - callers use the closed official allowlist
983
+ raise ValueError(f"unsupported shipped DSH package {package_name!r}")
984
+ installed = self._profile_root / "node_modules"
985
+ for segment in package_name.split("/"):
986
+ installed /= segment
987
+ try:
988
+ matches = all(
989
+ (installed / name).read_bytes().rstrip() == (shipped / name).read_bytes().rstrip()
990
+ for name in _PROFILE_FILES
991
+ )
992
+ except OSError as error:
993
+ raise StudioDshProviderRegistrationError(
994
+ f"{error_prefix}_bundle_unreadable",
995
+ "the installed DSH AgentProvider Bundle cannot be verified",
996
+ ) from error
997
+ if not matches:
998
+ raise StudioDshProviderRegistrationError(
999
+ f"{error_prefix}_bundle_digest_mismatch",
1000
+ "the installed DSH AgentProvider Bundle differs from the wheel-owned Bundle",
1001
+ )
1002
+
1003
+ def _verify_shipped_resource_bundle_bytes(
1004
+ self, package_name: str, directory_name: str
1005
+ ) -> None:
1006
+ shipped = (
1007
+ Path(__file__).parents[1]
1008
+ / "plugins"
1009
+ / "providers"
1010
+ / "bundles"
1011
+ / directory_name
1012
+ )
1013
+ installed = self._profile_root / "node_modules"
1014
+ for segment in package_name.split("/"):
1015
+ installed /= segment
1016
+ names = ["package.json", "cordis.patch.yml", "index.mjs"]
1017
+ if directory_name == "dsh-platform-resources":
1018
+ names.append("client.mjs")
1019
+ try:
1020
+ package_matches = json.loads(
1021
+ (installed / "package.json").read_text(encoding="utf-8")
1022
+ ) == json.loads((shipped / "package.json").read_text(encoding="utf-8"))
1023
+ matches = package_matches and all(
1024
+ (installed / name).read_bytes().rstrip()
1025
+ == (shipped / name).read_bytes().rstrip()
1026
+ for name in names
1027
+ if name != "package.json"
1028
+ )
1029
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
1030
+ raise StudioDshProviderRegistrationError(
1031
+ "resource_dsh_bundle_unreadable",
1032
+ "an installed platform resource Bundle cannot be verified",
1033
+ ) from error
1034
+ if not matches:
1035
+ raise StudioDshProviderRegistrationError(
1036
+ "resource_dsh_bundle_digest_mismatch",
1037
+ "an installed platform resource Bundle differs from the wheel-owned Bundle",
1038
+ )
1039
+
1040
+
1041
+ def merge_provider_registrations(
1042
+ *registrations: StudioDshProviderRegistrations,
1043
+ ) -> tuple[dict[str, PluginManifest], dict[str, Any]]:
1044
+ """Merge registration sources without last-writer-wins ambiguity."""
1045
+
1046
+ manifests: dict[str, PluginManifest] = {}
1047
+ factories: dict[str, Any] = {}
1048
+ for item in registrations:
1049
+ if item.manifests.keys() != item.factories.keys():
1050
+ raise StudioDshProviderRegistrationError(
1051
+ "dsh_provider_registration_partial",
1052
+ "provider manifests and factories must have identical exact references",
1053
+ )
1054
+ for provider_ref, manifest in item.manifests.items():
1055
+ if provider_ref in manifests and (
1056
+ manifests[provider_ref] != manifest
1057
+ or factories[provider_ref] is not item.factories[provider_ref]
1058
+ ):
1059
+ raise StudioDshProviderRegistrationError(
1060
+ "dsh_provider_registration_conflict",
1061
+ "multiple DSH registrations disagree for one exact provider reference",
1062
+ )
1063
+ manifests[provider_ref] = manifest
1064
+ factories[provider_ref] = item.factories[provider_ref]
1065
+ return manifests, factories
1066
+
1067
+
1068
+ __all__ = [
1069
+ "StudioDshProviderInventory",
1070
+ "StudioDshProviderRegistrationError",
1071
+ "StudioDshProviderRegistrationManager",
1072
+ "StudioDshProviderRegistrations",
1073
+ "StudioDshProviderStatus",
1074
+ "merge_provider_registrations",
1075
+ ]