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,370 @@
1
+ """Shared implementation for wheel-owned DSH AgentProvider bundles.
2
+
3
+ Provider-specific modules declare identity and select an execution factory.
4
+ This module owns the repeated package validation, fixed host command,
5
+ registration fences, and bridge lifecycle. It does not own an agent loop.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import sys
12
+ from collections.abc import Mapping
13
+ from dataclasses import dataclass
14
+ from pathlib import Path
15
+ from typing import Any, Protocol
16
+
17
+ from ksadk.plugins.bundle import ResolvedPluginBundle
18
+ from ksadk.plugins.contracts import CompositionProfile, PluginManifest
19
+ from ksadk.plugins.host import PluginExecutionContext, PluginHostError
20
+ from ksadk.plugins.providers.dsh import (
21
+ DshAgentProviderHost,
22
+ DshAgentProviderRegistration,
23
+ dsh_agent_provider_manifest,
24
+ )
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class ShippedDshProviderSpec:
29
+ key: str
30
+ display_name: str
31
+ package_name: str
32
+ provider_id: str
33
+ version: str
34
+ bundle_directory: str
35
+ bridge_required_code: str
36
+ bridge_required_message: str
37
+
38
+ @property
39
+ def provider_ref(self) -> str:
40
+ return f"plugin://{self.provider_id}@{self.version}"
41
+
42
+ def error_code(self, suffix: str) -> str:
43
+ return f"{self.key}_dsh_{suffix}"
44
+
45
+
46
+ CODEX_DSH_SPEC = ShippedDshProviderSpec(
47
+ key="codex",
48
+ display_name="Codex",
49
+ package_name="@kingsoftcloud/ksadk-codex-provider",
50
+ provider_id="io.ksadk.codex-provider",
51
+ version="1.0.0",
52
+ bundle_directory="ksadk-codex",
53
+ bridge_required_code="codex_provider_bridge_required",
54
+ bridge_required_message=(
55
+ "Codex execution requires the registration-gated RuntimeAdapter bridge"
56
+ ),
57
+ )
58
+
59
+ HARNESS_DSH_SPEC = ShippedDshProviderSpec(
60
+ key="harness",
61
+ display_name="KsADK Harness",
62
+ package_name="@kingsoftcloud/ksadk-harness-provider",
63
+ provider_id="io.ksadk.harness-provider",
64
+ version="1.0.0",
65
+ bundle_directory="ksadk-harness",
66
+ bridge_required_code="harness_legacy_bridge_required",
67
+ bridge_required_message=(
68
+ "Harness execution requires the registration-gated RuntimeAdapter bridge"
69
+ ),
70
+ )
71
+
72
+ SHIPPED_DSH_PROVIDER_SPECS = {
73
+ CODEX_DSH_SPEC.key: CODEX_DSH_SPEC,
74
+ HARNESS_DSH_SPEC.key: HARNESS_DSH_SPEC,
75
+ }
76
+
77
+
78
+ @dataclass(frozen=True)
79
+ class ShippedDshBundle:
80
+ package_name: str
81
+ version: str
82
+ root: Path
83
+ patch: Path
84
+
85
+
86
+ def load_shipped_dsh_bundle(spec: ShippedDshProviderSpec) -> ShippedDshBundle:
87
+ """Locate and validate one immutable DSH bundle shipped in the wheel."""
88
+
89
+ root = Path(__file__).with_name("bundles") / spec.bundle_directory
90
+ package_path = root / "package.json"
91
+ try:
92
+ payload = json.loads(package_path.read_text(encoding="utf-8"))
93
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
94
+ raise PluginHostError(
95
+ spec.error_code("bundle_invalid"),
96
+ f"shipped {spec.display_name} DSH Bundle package.json is unavailable",
97
+ ) from error
98
+ if not isinstance(payload, dict):
99
+ raise PluginHostError(
100
+ spec.error_code("bundle_invalid"),
101
+ f"shipped {spec.display_name} DSH Bundle package.json must be an object",
102
+ )
103
+ dsh = payload.get("dsh")
104
+ bundle = dsh.get("bundle") if isinstance(dsh, dict) else None
105
+ patch_value = bundle.get("patch") if isinstance(bundle, dict) else None
106
+ if (
107
+ payload.get("name") != spec.package_name
108
+ or payload.get("version") != spec.version
109
+ or patch_value != "./cordis.patch.yml"
110
+ or "ksadk" in payload
111
+ ):
112
+ raise PluginHostError(
113
+ spec.error_code("bundle_invalid"),
114
+ f"shipped {spec.display_name} provider is not a standard pinned DSH Bundle",
115
+ )
116
+ patch = (root / str(patch_value)).resolve()
117
+ try:
118
+ patch.relative_to(root.resolve())
119
+ except ValueError as error:
120
+ raise PluginHostError(
121
+ spec.error_code("bundle_invalid"),
122
+ "DSH Bundle patch escapes its package root",
123
+ ) from error
124
+ if not patch.is_file() or not (root / "index.mjs").is_file():
125
+ raise PluginHostError(
126
+ spec.error_code("bundle_invalid"),
127
+ "DSH Bundle contribution files are missing",
128
+ )
129
+ return ShippedDshBundle(
130
+ package_name=spec.package_name,
131
+ version=spec.version,
132
+ root=root.resolve(),
133
+ patch=patch,
134
+ )
135
+
136
+
137
+ def shipped_dsh_host_command(
138
+ spec: ShippedDshProviderSpec,
139
+ *,
140
+ python_executable: str | None = None,
141
+ ) -> tuple[str, ...]:
142
+ """Return fixed argv; bundle content never controls the executable."""
143
+
144
+ load_shipped_dsh_bundle(spec)
145
+ executable = str(python_executable or sys.executable).strip()
146
+ if not executable or "\x00" in executable:
147
+ raise PluginHostError(spec.error_code("host_invalid"), "Python host executable is invalid")
148
+ return executable, "-m", "ksadk.plugins.providers.dsh_descriptor_host", spec.key
149
+
150
+
151
+ class _ExecutionRuntime(Protocol):
152
+ async def start(self) -> None: ...
153
+
154
+ async def health(self) -> bool: ...
155
+
156
+ async def prepare(
157
+ self,
158
+ bundle: ResolvedPluginBundle,
159
+ *,
160
+ capabilities: PluginExecutionContext,
161
+ ) -> Any: ...
162
+
163
+ async def drain(self) -> None: ...
164
+
165
+ async def dispose(self) -> None: ...
166
+
167
+
168
+ class _ExecutionFactory(Protocol):
169
+ async def stage(
170
+ self,
171
+ manifest: PluginManifest,
172
+ *,
173
+ profile: CompositionProfile,
174
+ services: Mapping[str, Any],
175
+ ) -> _ExecutionRuntime: ...
176
+
177
+
178
+ class ShippedDshBridgeRuntime:
179
+ """DSH registration lifecycle delegating execution to the owning runtime."""
180
+
181
+ def __init__(
182
+ self,
183
+ *,
184
+ spec: ShippedDshProviderSpec,
185
+ host: DshAgentProviderHost,
186
+ registration: DshAgentProviderRegistration,
187
+ execution_runtime: _ExecutionRuntime,
188
+ owns_host: bool,
189
+ ) -> None:
190
+ self._spec = spec
191
+ self._host = host
192
+ self._registration = registration
193
+ self._execution_runtime = execution_runtime
194
+ self._owns_host = owns_host
195
+ self._started = False
196
+ self._disposed = False
197
+
198
+ async def start(self) -> None:
199
+ if self._disposed:
200
+ raise PluginHostError(
201
+ self._spec.error_code("bridge_disposed"),
202
+ f"{self._spec.display_name} DSH bridge is disposed",
203
+ )
204
+ current = await self._host.registration()
205
+ require_same_registration(self._spec, current, self._registration)
206
+ await self._execution_runtime.start()
207
+ self._started = True
208
+
209
+ async def health(self) -> bool:
210
+ if not self._started or self._disposed:
211
+ return False
212
+ return await self._host.health() and await self._execution_runtime.health()
213
+
214
+ async def prepare(
215
+ self,
216
+ bundle: ResolvedPluginBundle,
217
+ *,
218
+ capabilities: PluginExecutionContext,
219
+ ) -> Any:
220
+ if not await self.health():
221
+ raise PluginHostError(
222
+ self._spec.error_code("bridge_unavailable"),
223
+ f"{self._spec.display_name} DSH provider is not ready",
224
+ )
225
+ if bundle.composition.profile.agent_provider.ref != self._spec.provider_ref:
226
+ raise PluginHostError(
227
+ self._spec.error_code("profile_mismatch"),
228
+ "Agent Bundle does not select the registered "
229
+ f"{self._spec.display_name} DSH provider",
230
+ )
231
+ return await self._execution_runtime.prepare(bundle, capabilities=capabilities)
232
+
233
+ async def drain(self) -> None:
234
+ if self._disposed:
235
+ return
236
+ await self._execution_runtime.drain()
237
+ if self._owns_host and self._host.pid is not None:
238
+ await self._host.drain()
239
+ self._started = False
240
+
241
+ async def dispose(self) -> None:
242
+ if self._disposed:
243
+ return
244
+ self._disposed = True
245
+ self._started = False
246
+ first_error: BaseException | None = None
247
+ try:
248
+ await self._execution_runtime.dispose()
249
+ except BaseException as error: # cleanup must continue
250
+ first_error = error
251
+ if self._owns_host:
252
+ try:
253
+ await self._host.dispose()
254
+ except BaseException as error: # cleanup must continue
255
+ if first_error is None:
256
+ first_error = error
257
+ if first_error is not None:
258
+ raise first_error
259
+
260
+
261
+ class ShippedDshBridgeFactory:
262
+ """Admit one exact DSH registration and create its execution bridge."""
263
+
264
+ runtime_class = ShippedDshBridgeRuntime
265
+
266
+ def __init__(
267
+ self,
268
+ *,
269
+ spec: ShippedDshProviderSpec,
270
+ host: DshAgentProviderHost,
271
+ registration: DshAgentProviderRegistration,
272
+ execution_factory: _ExecutionFactory,
273
+ owns_host: bool = True,
274
+ ) -> None:
275
+ validate_registration(spec, registration)
276
+ self._spec = spec
277
+ self._host = host
278
+ self._registration = registration
279
+ self._execution_factory = execution_factory
280
+ self._owns_host = owns_host
281
+ self.runtime: ShippedDshBridgeRuntime | None = None
282
+
283
+ async def stage(
284
+ self,
285
+ manifest: PluginManifest,
286
+ *,
287
+ profile: CompositionProfile,
288
+ services: Mapping[str, Any],
289
+ ) -> ShippedDshBridgeRuntime:
290
+ expected_manifest = dsh_agent_provider_manifest(
291
+ self._registration.descriptor,
292
+ preflight=self._registration.preflight,
293
+ )
294
+ if manifest != expected_manifest:
295
+ raise PluginHostError(
296
+ self._spec.error_code("manifest_mismatch"),
297
+ f"{self._spec.display_name} provider manifest did not come from "
298
+ "the ready DSH registration",
299
+ )
300
+ if profile.agent_provider.ref != self._spec.provider_ref:
301
+ raise PluginHostError(
302
+ self._spec.error_code("profile_mismatch"),
303
+ "composition profile does not select the shipped "
304
+ f"{self._spec.display_name} DSH provider",
305
+ )
306
+ current = await self._host.registration()
307
+ require_same_registration(self._spec, current, self._registration)
308
+ execution_runtime = await self._execution_factory.stage(
309
+ manifest, profile=profile, services=services
310
+ )
311
+ self.runtime = self.runtime_class(
312
+ spec=self._spec,
313
+ host=self._host,
314
+ registration=self._registration,
315
+ execution_runtime=execution_runtime,
316
+ owns_host=self._owns_host,
317
+ )
318
+ return self.runtime
319
+
320
+
321
+ def validate_registration(
322
+ spec: ShippedDshProviderSpec,
323
+ registration: DshAgentProviderRegistration,
324
+ ) -> None:
325
+ descriptor = registration.descriptor
326
+ preflight = registration.preflight
327
+ if (
328
+ descriptor.provider_id != spec.provider_id
329
+ or descriptor.provider_version != spec.version
330
+ or descriptor.plugin_name != spec.package_name
331
+ or not preflight.ready
332
+ or preflight.profile_digest != descriptor.profile_digest
333
+ or preflight.descriptor_digest != descriptor.descriptor_digest
334
+ ):
335
+ raise PluginHostError(
336
+ spec.error_code("registration_invalid"),
337
+ f"{spec.display_name} DSH registration does not match the shipped provider fences",
338
+ )
339
+
340
+
341
+ def require_same_registration(
342
+ spec: ShippedDshProviderSpec,
343
+ current: DshAgentProviderRegistration,
344
+ expected: DshAgentProviderRegistration,
345
+ ) -> None:
346
+ validate_registration(spec, current)
347
+ if (
348
+ current.descriptor != expected.descriptor
349
+ or current.preflight != expected.preflight
350
+ or current.manifest != expected.manifest
351
+ ):
352
+ raise PluginHostError(
353
+ spec.error_code("registration_changed"),
354
+ f"{spec.display_name} DSH provider changed after admission",
355
+ )
356
+
357
+
358
+ __all__ = [
359
+ "CODEX_DSH_SPEC",
360
+ "HARNESS_DSH_SPEC",
361
+ "SHIPPED_DSH_PROVIDER_SPECS",
362
+ "ShippedDshBridgeFactory",
363
+ "ShippedDshBridgeRuntime",
364
+ "ShippedDshBundle",
365
+ "ShippedDshProviderSpec",
366
+ "load_shipped_dsh_bundle",
367
+ "require_same_registration",
368
+ "shipped_dsh_host_command",
369
+ "validate_registration",
370
+ ]
@@ -0,0 +1,338 @@
1
+ """Pure, deterministic Profile -> PluginLock resolver.
2
+
3
+ This module is intentionally side-effect free: it resolves only supplied
4
+ manifests and never imports their entrypoints. PluginHost will later own
5
+ admission, staging, start, health, and disposal.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import hashlib
11
+ import json
12
+ import re
13
+ from dataclasses import dataclass, field
14
+ from typing import Iterable
15
+
16
+ from ksadk.plugins.contracts import (
17
+ CompositionProfile,
18
+ LockedCapability,
19
+ PluginDependency,
20
+ PluginLock,
21
+ PluginLockEntry,
22
+ PluginManifest,
23
+ PluginReference,
24
+ plugin_lock_digest,
25
+ )
26
+
27
+
28
+ class PluginResolutionError(ValueError):
29
+ """Stable, typed rejection from the pure composition resolver."""
30
+
31
+ def __init__(self, code: str, message: str) -> None:
32
+ super().__init__(message)
33
+ self.code = code
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class ResolvedComposition:
38
+ profile: CompositionProfile
39
+ profile_digest: str
40
+ plugin_lock: PluginLock
41
+ plugin_lock_digest: str
42
+ # Build-time audit facts from the exact manifests that produced the lock.
43
+ # This is an internal immutable projection, not another wire manifest: the
44
+ # public Bundle continues to bind only CompositionProfile and PluginLock.
45
+ manifests: tuple[PluginManifest, ...] = ()
46
+ # Studio stamps the exact AgentDraft snapshot used to select resources.
47
+ # Generic resolver callers leave this empty; a composed Studio build must
48
+ # require it so a composition from another revision cannot be paired with
49
+ # a newly compiled resolved-agent-spec.
50
+ source_digest: str = field(default="", compare=False, repr=False)
51
+
52
+
53
+ def canonical_composition_profile(profile: CompositionProfile) -> bytes:
54
+ return json.dumps(
55
+ profile.model_dump(by_alias=True, exclude_none=True, mode="json"),
56
+ ensure_ascii=False,
57
+ sort_keys=True,
58
+ separators=(",", ":"),
59
+ ).encode("utf-8")
60
+
61
+
62
+ def composition_profile_digest(profile: CompositionProfile) -> str:
63
+ return f"sha256:{hashlib.sha256(canonical_composition_profile(profile)).hexdigest()}"
64
+
65
+
66
+ class PluginRegistry:
67
+ """Immutable in-memory manifest catalog used by build-time resolution."""
68
+
69
+ def __init__(self, manifests: Iterable[PluginManifest]) -> None:
70
+ indexed: dict[tuple[str, str], PluginManifest] = {}
71
+ for manifest in manifests:
72
+ key = (manifest.metadata.id, manifest.metadata.version)
73
+ if key in indexed:
74
+ raise PluginResolutionError(
75
+ "plugin_manifest_duplicate",
76
+ f"duplicate plugin manifest {manifest.metadata.id}@{manifest.metadata.version}",
77
+ )
78
+ indexed[key] = manifest
79
+ self._manifests = indexed
80
+
81
+ def resolve(self, profile: CompositionProfile) -> ResolvedComposition:
82
+ """Resolve the requested graph without running any plugin code."""
83
+
84
+ selected: dict[str, PluginManifest] = {}
85
+ dependencies: dict[str, set[str]] = {}
86
+
87
+ def select_reference(reference: PluginReference) -> PluginManifest:
88
+ plugin_id, version = _parse_plugin_reference(reference.ref)
89
+ manifest = self._manifests.get((plugin_id, version))
90
+ if manifest is None:
91
+ raise PluginResolutionError(
92
+ "plugin_manifest_unresolved",
93
+ f"plugin {plugin_id}@{version} is not in the selected catalog",
94
+ )
95
+ select_manifest(manifest)
96
+ return manifest
97
+
98
+ def select_manifest(manifest: PluginManifest) -> None:
99
+ plugin_id = manifest.metadata.id
100
+ if plugin_id in selected:
101
+ if selected[plugin_id].metadata.version != manifest.metadata.version:
102
+ raise PluginResolutionError(
103
+ "plugin_version_conflict",
104
+ f"profile requires conflicting versions of plugin {plugin_id}",
105
+ )
106
+ return
107
+ selected[plugin_id] = manifest
108
+ dependencies.setdefault(plugin_id, set())
109
+ for requirement in manifest.spec.requires:
110
+ provider = self._resolve_requirement(requirement.definition, requirement.version)
111
+ if provider.metadata.id == plugin_id:
112
+ raise PluginResolutionError(
113
+ "plugin_dependency_cycle",
114
+ f"plugin {plugin_id} cannot provide its own required capability",
115
+ )
116
+ dependencies[plugin_id].add(provider.metadata.id)
117
+ select_manifest(provider)
118
+
119
+ provider = select_reference(profile.agent_provider)
120
+ self._require_agent_provider(provider)
121
+ for capability in profile.capabilities:
122
+ if capability.ref.startswith("plugin://"):
123
+ # A capability entry uses the same pinning grammar as the
124
+ # agent provider, but it has no special agent-provider role.
125
+ plugin_id, version = _parse_plugin_reference(capability.ref)
126
+ manifest = self._manifests.get((plugin_id, version))
127
+ if manifest is None:
128
+ raise PluginResolutionError(
129
+ "plugin_manifest_unresolved",
130
+ f"plugin {plugin_id}@{version} is not in the selected catalog",
131
+ )
132
+ select_manifest(manifest)
133
+
134
+ self._validate_unique_slots(selected.values())
135
+ lock = self._build_lock(selected, dependencies)
136
+ return ResolvedComposition(
137
+ profile=profile,
138
+ profile_digest=composition_profile_digest(profile),
139
+ plugin_lock=lock,
140
+ plugin_lock_digest=plugin_lock_digest(lock),
141
+ manifests=tuple(
142
+ sorted(
143
+ selected.values(),
144
+ key=lambda item: (item.metadata.id, item.metadata.version),
145
+ )
146
+ ),
147
+ )
148
+
149
+ def manifest_for(self, plugin_id: str, version: str) -> PluginManifest:
150
+ """Return an exact manifest already admitted to this local catalog."""
151
+
152
+ manifest = self._manifests.get((plugin_id, version))
153
+ if manifest is None:
154
+ raise PluginResolutionError(
155
+ "plugin_manifest_unresolved",
156
+ f"plugin {plugin_id}@{version} is not in the selected catalog",
157
+ )
158
+ return manifest
159
+
160
+ def _resolve_requirement(self, definition: str, constraint: str) -> PluginManifest:
161
+ candidates = [
162
+ manifest
163
+ for manifest in self._manifests.values()
164
+ if any(offer.definition == definition for offer in manifest.spec.provides)
165
+ and _version_satisfies(manifest.metadata.version, constraint)
166
+ ]
167
+ if not candidates:
168
+ raise PluginResolutionError(
169
+ "plugin_requirement_unresolved",
170
+ f"no plugin provides {definition!r} matching {constraint!r}",
171
+ )
172
+ if len(candidates) > 1:
173
+ names = ", ".join(
174
+ f"{item.metadata.id}@{item.metadata.version}"
175
+ for item in sorted(
176
+ candidates,
177
+ key=lambda item: (item.metadata.id, item.metadata.version),
178
+ )
179
+ )
180
+ raise PluginResolutionError(
181
+ "plugin_requirement_ambiguous",
182
+ f"multiple plugins provide {definition!r}: {names}",
183
+ )
184
+ return candidates[0]
185
+
186
+ @staticmethod
187
+ def _require_agent_provider(manifest: PluginManifest) -> None:
188
+ if any(
189
+ offer.definition == "agent.provider/v1"
190
+ and offer.slot == "agent.execution"
191
+ and offer.mode == "unique"
192
+ for offer in manifest.spec.provides
193
+ ):
194
+ return
195
+ raise PluginResolutionError(
196
+ "agent_provider_invalid",
197
+ f"plugin {manifest.metadata.id}@{manifest.metadata.version} "
198
+ "does not own agent.execution",
199
+ )
200
+
201
+ @staticmethod
202
+ def _validate_unique_slots(manifests: Iterable[PluginManifest]) -> None:
203
+ owners: dict[str, str] = {}
204
+ for manifest in manifests:
205
+ for offer in manifest.spec.provides:
206
+ if offer.mode != "unique":
207
+ continue
208
+ existing = owners.get(offer.slot)
209
+ if existing and existing != manifest.metadata.id:
210
+ raise PluginResolutionError(
211
+ "plugin_slot_conflict",
212
+ f"unique slot {offer.slot!r} is owned by both {existing} "
213
+ f"and {manifest.metadata.id}",
214
+ )
215
+ owners[offer.slot] = manifest.metadata.id
216
+
217
+ @staticmethod
218
+ def _build_lock(
219
+ selected: dict[str, PluginManifest], dependencies: dict[str, set[str]]
220
+ ) -> PluginLock:
221
+ entries: list[PluginLockEntry] = []
222
+ for plugin_id, manifest in selected.items():
223
+ entries.append(
224
+ PluginLockEntry(
225
+ id=plugin_id,
226
+ version=manifest.metadata.version,
227
+ digest=manifest.spec.provenance.digest,
228
+ source=manifest.spec.provenance.source,
229
+ signature_ref=manifest.spec.provenance.signature_ref,
230
+ license=manifest.spec.provenance.license,
231
+ upstream=manifest.spec.provenance.upstream,
232
+ components=manifest.spec.provenance.components,
233
+ provides=[
234
+ LockedCapability(
235
+ definition=offer.definition,
236
+ slot=offer.slot,
237
+ owner=plugin_id,
238
+ )
239
+ for offer in manifest.spec.provides
240
+ ],
241
+ dependencies=[
242
+ PluginDependency(
243
+ id=dependency_id,
244
+ version=selected[dependency_id].metadata.version,
245
+ digest=selected[dependency_id].spec.provenance.digest,
246
+ )
247
+ for dependency_id in sorted(dependencies.get(plugin_id, set()))
248
+ ],
249
+ )
250
+ )
251
+ return PluginLock(plugins=entries)
252
+
253
+
254
+ def _parse_plugin_reference(value: str) -> tuple[str, str]:
255
+ # The Pydantic type validates this at the public boundary. Keeping the
256
+ # parser defensive makes this pure resolver safe for values reconstructed
257
+ # by other language consumers.
258
+ if not value.startswith("plugin://") or "@" not in value:
259
+ raise PluginResolutionError(
260
+ "plugin_reference_invalid", f"invalid plugin reference {value!r}"
261
+ )
262
+ plugin_id, version = value.removeprefix("plugin://").rsplit("@", 1)
263
+ return plugin_id, version
264
+
265
+
266
+ _COMPARATOR = re.compile(r"^(>=|<=|>|<|=)?(\d+)\.(\d+)\.(\d+)$")
267
+
268
+
269
+ def _version_satisfies(version: str, constraint: str) -> bool:
270
+ """Small exact-range evaluator for manifest capability requirements.
271
+
272
+ The manifest accepts a SemVer range string rather than an unbounded
273
+ dependency resolver. P2-00A supports the explicit comparator form used
274
+ by the contract examples (for example ``>=1,<2``); unsupported forms are
275
+ rejected instead of silently accepting a possibly incompatible plugin.
276
+ """
277
+
278
+ parsed_version = _parse_release(version, field="plugin version")
279
+ comparators = [part.strip() for part in constraint.split(",") if part.strip()]
280
+ if not comparators:
281
+ raise PluginResolutionError("plugin_constraint_invalid", "empty plugin requirement version")
282
+ for comparator in comparators:
283
+ match = _COMPARATOR.fullmatch(comparator)
284
+ if match is None:
285
+ # ``>=1,<2`` is a concise allowed major range in the published
286
+ # manifest. Expand it deterministically rather than treating it
287
+ # as a lax string comparison.
288
+ major_range = re.fullmatch(r"(>=|>|<=|<)(\d+)", comparator)
289
+ if major_range is None:
290
+ raise PluginResolutionError(
291
+ "plugin_constraint_invalid",
292
+ f"unsupported plugin requirement version {constraint!r}",
293
+ )
294
+ operator, major = major_range.groups()
295
+ target = (int(major), 0, 0)
296
+ else:
297
+ operator = match.group(1) or "="
298
+ target = (
299
+ int(match.group(2)),
300
+ int(match.group(3)),
301
+ int(match.group(4)),
302
+ )
303
+ if not _compare(parsed_version, target, operator):
304
+ return False
305
+ return True
306
+
307
+
308
+ def version_satisfies(version: str, constraint: str) -> bool:
309
+ """Evaluate the exact compatibility-range grammar used by plugin manifests."""
310
+
311
+ return _version_satisfies(version, constraint)
312
+
313
+
314
+ def _parse_release(value: str, *, field: str) -> tuple[int, int, int]:
315
+ match = re.match(r"^(\d+)\.(\d+)\.(\d+)", value)
316
+ if match is None:
317
+ raise PluginResolutionError("plugin_constraint_invalid", f"invalid {field} {value!r}")
318
+ return int(match.group(1)), int(match.group(2)), int(match.group(3))
319
+
320
+
321
+ def _compare(left: tuple[int, int, int], right: tuple[int, int, int], operator: str) -> bool:
322
+ return {
323
+ ">": left > right,
324
+ ">=": left >= right,
325
+ "<": left < right,
326
+ "<=": left <= right,
327
+ "=": left == right,
328
+ }[operator]
329
+
330
+
331
+ __all__ = [
332
+ "PluginRegistry",
333
+ "PluginResolutionError",
334
+ "ResolvedComposition",
335
+ "canonical_composition_profile",
336
+ "composition_profile_digest",
337
+ "version_satisfies",
338
+ ]