agentengine-sdk-python 0.8.3__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 (509) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
  2. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/api/client.py +105 -91
  5. ksadk/builders/code_builder.py +36 -9
  6. ksadk/builders/framework_requirements.py +2 -1
  7. ksadk/builders/ks3_uploader.py +36 -7
  8. ksadk/builders/managed_runtime_builder.py +1 -0
  9. ksadk/cli/__init__.py +32 -3
  10. ksadk/cli/cmd_managed_runtime.py +13 -1
  11. ksadk/cli/cmd_plugin.py +6 -1
  12. ksadk/cli/cmd_web.py +2 -5
  13. ksadk/cli/runtime_bootstrap.py +23 -1
  14. ksadk/codex/client.py +424 -96
  15. ksadk/codex/projection.py +24 -0
  16. ksadk/codex/runtime.py +56 -298
  17. ksadk/common/auth.py +16 -10
  18. ksadk/configs/env_registry.py +29 -1
  19. ksadk/conversations/message_projection.py +135 -14
  20. ksadk/conversations/projector.py +4 -6
  21. ksadk/conversations/runtime_invocation.py +5 -0
  22. ksadk/conversations/runtime_payloads.py +1 -0
  23. ksadk/conversations/runtime_preparation.py +30 -27
  24. ksadk/conversations/runtime_resume.py +50 -2
  25. ksadk/conversations/runtime_stream_events.py +5 -0
  26. ksadk/conversations/runtime_streaming.py +25 -7
  27. ksadk/deployment/env_forward.py +2 -2
  28. ksadk/deployment/providers/serverless.py +1 -1
  29. ksadk/events/adapters/_codex_validators.py +18 -7
  30. ksadk/events/adapters/langgraph.py +15 -1
  31. ksadk/events/canonical_store.py +3 -1
  32. ksadk/events/projections.py +1 -1
  33. ksadk/harness/config.py +2 -2
  34. ksadk/harness/runtime.py +27 -27
  35. ksadk/harness/tools.py +38 -13
  36. ksadk/interaction/provider.py +1 -0
  37. ksadk/interaction/providers/langgraph.py +1 -0
  38. ksadk/kernel/bootstrap.py +28 -4
  39. ksadk/kernel/ingress.py +15 -2
  40. ksadk/kernel/sqlite_store.py +27 -0
  41. ksadk/kernel/store.py +3 -0
  42. ksadk/kernel/worker.py +65 -10
  43. ksadk/knowledge_base/client.py +57 -27
  44. ksadk/mcp_runtime/__init__.py +12 -4
  45. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  46. ksadk/memory/adk/resilient_session_service.py +25 -17
  47. ksadk/memory/adk/short_term_memory.py +26 -9
  48. ksadk/memory/models.py +7 -4
  49. ksadk/memory/provider_resolver.py +3 -0
  50. ksadk/model_proxy/server.py +10 -5
  51. ksadk/plugins/__init__.py +4 -0
  52. ksadk/plugins/artifacts.py +275 -0
  53. ksadk/plugins/bridges/__init__.py +4 -2
  54. ksadk/plugins/bridges/codex.py +120 -13
  55. ksadk/plugins/bridges/dsh.py +340 -156
  56. ksadk/plugins/builtins.py +35 -36
  57. ksadk/plugins/bundle_security.py +28 -4
  58. ksadk/plugins/codex_manifest.py +983 -0
  59. ksadk/plugins/composition.py +8 -0
  60. ksadk/plugins/contracts.py +118 -0
  61. ksadk/plugins/delivery.py +153 -0
  62. ksadk/plugins/dsh_installation_digest.py +71 -0
  63. ksadk/plugins/dsh_toolchain.py +110 -21
  64. ksadk/plugins/ecosystem_probe.py +6 -6
  65. ksadk/plugins/host.py +102 -39
  66. ksadk/plugins/kernel_adapter.py +205 -0
  67. ksadk/plugins/providers/__init__.py +23 -0
  68. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  69. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  70. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  71. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  72. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  73. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  74. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  75. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  76. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  77. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  78. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  79. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  80. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  81. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  82. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  83. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  84. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  85. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  86. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  87. ksadk/plugins/providers/codex.py +335 -69
  88. ksadk/plugins/providers/codex_native.py +368 -0
  89. ksadk/plugins/providers/codex_turn.py +301 -0
  90. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  91. ksadk/plugins/providers/dsh_mcp.py +467 -0
  92. ksadk/plugins/providers/harness.py +118 -113
  93. ksadk/plugins/providers/mcp_projection.py +150 -0
  94. ksadk/plugins/providers/platform_resources.py +657 -0
  95. ksadk/plugins/resolver.py +8 -1
  96. ksadk/resource_runtime/__init__.py +4 -0
  97. ksadk/resource_runtime/broker.py +616 -0
  98. ksadk/resource_runtime/build_artifacts.py +165 -0
  99. ksadk/resource_runtime/contracts.py +138 -0
  100. ksadk/resource_runtime/discovery_receipts.py +100 -0
  101. ksadk/resource_runtime/discovery_skills.py +172 -0
  102. ksadk/resource_runtime/errors.py +6 -0
  103. ksadk/resource_runtime/ipc.py +142 -0
  104. ksadk/resource_runtime/kernel_approval.py +165 -0
  105. ksadk/resource_runtime/knowledge.py +114 -0
  106. ksadk/resource_runtime/langgraph.py +94 -0
  107. ksadk/resource_runtime/leases.py +191 -0
  108. ksadk/resource_runtime/managed_projection.py +186 -0
  109. ksadk/resource_runtime/mcp_server.py +138 -0
  110. ksadk/resource_runtime/memory_provider.py +318 -0
  111. ksadk/resource_runtime/memory_receipts.py +34 -0
  112. ksadk/resource_runtime/operation_ledger.py +211 -0
  113. ksadk/resource_runtime/plugin_config.py +48 -0
  114. ksadk/resource_runtime/policy_authorization.py +54 -0
  115. ksadk/resource_runtime/process.py +110 -0
  116. ksadk/resource_runtime/skill_artifacts.py +153 -0
  117. ksadk/resource_runtime/skill_runtime.py +42 -0
  118. ksadk/resource_runtime/skill_workspace.py +118 -0
  119. ksadk/resource_runtime/skills.py +215 -0
  120. ksadk/resource_runtime/snapshots.py +180 -0
  121. ksadk/resource_runtime/socket_server.py +103 -0
  122. ksadk/resource_runtime/supervisor.py +380 -0
  123. ksadk/resource_runtime/worker.py +504 -0
  124. ksadk/runners/_langgraph_runner_streams.py +74 -6
  125. ksadk/runners/adk_runner.py +149 -11
  126. ksadk/runners/base_runner.py +29 -1
  127. ksadk/runners/langgraph_runner.py +475 -145
  128. ksadk/runtime/_runner_adapter/stream_mapping.py +142 -18
  129. ksadk/runtime/adapter.py +2 -0
  130. ksadk/runtime/conversation_execution.py +92 -16
  131. ksadk/runtime/executor.py +78 -2
  132. ksadk/runtime/factory.py +29 -273
  133. ksadk/runtime/framework_adapters.py +23 -0
  134. ksadk/runtime/preprocessing.py +10 -2
  135. ksadk/runtime/runner_adapter.py +73 -14
  136. ksadk/runtime_context.py +40 -2
  137. ksadk/sandbox/backends/e2b.py +52 -11
  138. ksadk/sandbox/backends/local_process.py +9 -0
  139. ksadk/sandbox/base.py +2 -0
  140. ksadk/sandbox/e2b_connection.py +66 -0
  141. ksadk/scheduler/sqlite_store.py +18 -0
  142. ksadk/server/composition.py +2 -0
  143. ksadk/server/factory.py +5 -0
  144. ksadk/server/persistence_capability.py +516 -0
  145. ksadk/server/routes/control.py +210 -46
  146. ksadk/server/routes/dependencies.py +15 -0
  147. ksadk/server/routes/models.py +47 -4
  148. ksadk/server/routes/projection.py +252 -12
  149. ksadk/server/routes/sessions.py +284 -107
  150. ksadk/server/routes/streaming.py +43 -9
  151. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  152. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
  153. ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  154. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  155. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  156. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  157. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
  158. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  159. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  160. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  161. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  162. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  163. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  164. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  165. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  166. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  167. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  168. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  169. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  170. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  171. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  172. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  173. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  174. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  175. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  176. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  177. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  178. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  179. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
  180. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  181. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  182. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  183. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  184. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  185. ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
  186. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
  187. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
  188. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
  189. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
  190. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
  191. ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
  192. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
  193. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
  194. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
  195. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
  196. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
  197. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
  198. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
  199. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
  200. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
  201. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
  202. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
  203. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
  204. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
  205. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
  206. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
  207. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  208. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  209. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  210. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  211. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  212. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  213. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  214. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  215. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  216. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  217. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  218. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  219. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  220. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  221. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
  222. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
  223. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  224. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  225. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  226. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  227. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  228. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  229. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  230. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  231. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  232. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  233. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  234. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  235. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  236. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  237. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  238. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  239. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  240. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  241. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  242. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  243. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  244. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  245. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  246. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  247. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  248. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  249. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  250. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  251. ksadk/server/static/index.html +2 -2
  252. ksadk/session_context.py +66 -0
  253. ksadk/sessions/__init__.py +11 -21
  254. ksadk/sessions/_local_service_sync.py +263 -1
  255. ksadk/sessions/base.py +176 -0
  256. ksadk/sessions/errors.py +4 -0
  257. ksadk/sessions/in_memory.py +309 -19
  258. ksadk/sessions/local_service.py +83 -1
  259. ksadk/sessions/persistence.py +275 -0
  260. ksadk/sessions/postgres_service.py +358 -0
  261. ksadk/sessions/resilience.py +8 -0
  262. ksadk/sessions/resilient.py +362 -4
  263. ksadk/sessions/topology.py +135 -0
  264. ksadk/skills/models.py +26 -4
  265. ksadk/skills/package_store.py +186 -38
  266. ksadk/skills/runtime/agent.py +31 -6
  267. ksadk/skills/runtime/artifact_delivery.py +139 -0
  268. ksadk/skills/runtime/backends/e2b.py +98 -6
  269. ksadk/skills/runtime/backends/local.py +73 -8
  270. ksadk/skills/runtime/base.py +3 -0
  271. ksadk/skills/runtime/executor.py +2 -0
  272. ksadk/skills/runtime/loader.py +10 -2
  273. ksadk/skills/runtime/pinned.py +114 -0
  274. ksadk/skills/runtime/request.py +31 -0
  275. ksadk/skills/service_client.py +167 -28
  276. ksadk/studio/api.py +224 -42
  277. ksadk/studio/api_catalog_routes.py +18 -0
  278. ksadk/studio/api_plugin_routes.py +526 -95
  279. ksadk/studio/api_resource_connections.py +183 -0
  280. ksadk/studio/authoring_coordinator.py +19 -14
  281. ksadk/studio/builder.py +76 -0
  282. ksadk/studio/cloud.py +342 -104
  283. ksadk/studio/cloud_shared_web.py +565 -0
  284. ksadk/studio/codex_agent_service.py +128 -26
  285. ksadk/studio/codex_builder.py +241 -2
  286. ksadk/studio/codex_credentials.py +90 -0
  287. ksadk/studio/codex_manifest.py +31 -4
  288. ksadk/studio/codex_plugin_store.py +746 -0
  289. ksadk/studio/codex_provider_build.py +231 -0
  290. ksadk/studio/codex_run.py +184 -25
  291. ksadk/studio/compatibility_report.py +12 -1
  292. ksadk/studio/compiler.py +78 -14
  293. ksadk/studio/contracts.py +132 -6
  294. ksadk/studio/dsh_application.py +137 -0
  295. ksadk/studio/dsh_capability_service.py +1107 -0
  296. ksadk/studio/dsh_models.py +59 -0
  297. ksadk/studio/dsh_provider_registration.py +320 -13
  298. ksadk/studio/hosted_kernel.py +88 -13
  299. ksadk/studio/mcp_runtime.py +11 -3
  300. ksadk/studio/model_client.py +2 -2
  301. ksadk/studio/plugin_composition.py +190 -23
  302. ksadk/studio/plugin_kernel_adapter.py +12 -112
  303. ksadk/studio/plugin_runtime.py +224 -45
  304. ksadk/studio/resource_authority.py +637 -0
  305. ksadk/studio/resource_binding_validation.py +77 -0
  306. ksadk/studio/resource_build_admission.py +196 -0
  307. ksadk/studio/resource_build_materializer.py +149 -0
  308. ksadk/studio/resource_catalog.py +143 -2
  309. ksadk/studio/resource_connections.py +220 -0
  310. ksadk/studio/run_service.py +462 -52
  311. ksadk/studio/runtime_source.py +15 -7
  312. ksadk/studio/scheduler_assistant.py +317 -0
  313. ksadk/studio/scheduler_runtime.py +9 -0
  314. ksadk/studio/scheduler_service.py +3 -0
  315. ksadk/studio/service.py +490 -44
  316. ksadk/studio/shared_web.py +446 -62
  317. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  318. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  319. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  320. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  321. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  322. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  323. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  324. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  325. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  326. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  327. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  328. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  329. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  330. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  331. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  332. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  333. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  334. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  335. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  336. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  337. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  338. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  339. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  340. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  341. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  342. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  343. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  344. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  345. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  346. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  347. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  348. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  349. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  350. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  351. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  352. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  353. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  354. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  355. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  356. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  357. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  358. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  359. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  360. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  361. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  362. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  363. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  364. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  365. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  366. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  367. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  368. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  369. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  372. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  373. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  377. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  378. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  379. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  380. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  381. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  382. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  383. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  384. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  385. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  386. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  387. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  388. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  389. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  390. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  391. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  392. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  393. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  394. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  395. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  396. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  397. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  398. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  399. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  400. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  401. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  402. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  403. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  404. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  405. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  406. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  407. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  408. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  409. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  410. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  411. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  412. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  413. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  414. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  415. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  416. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  417. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  418. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  419. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  420. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  421. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  422. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  423. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  424. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  425. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  426. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  427. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  428. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  429. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  430. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  431. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  432. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  433. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  434. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  435. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  436. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  437. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  438. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  439. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  440. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  441. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  442. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  443. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  444. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  445. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  446. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  447. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  448. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  449. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  450. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  451. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  452. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  453. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  454. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  455. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  456. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  457. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  458. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  459. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  460. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  461. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  462. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  463. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  464. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  465. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  466. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  467. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  468. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  469. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  470. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  471. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  472. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  473. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  474. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  475. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  476. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  477. ksadk/studio/static/index.html +2 -2
  478. ksadk/version.py +1 -1
  479. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  480. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  481. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  482. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  483. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  484. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  485. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  486. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  487. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  488. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  489. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  490. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  491. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  492. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  493. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  494. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  495. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  496. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  497. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  498. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  499. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  500. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  501. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  502. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  503. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  504. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  505. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  506. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  507. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  508. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  509. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -8,20 +8,28 @@ stream or transcript is created here.
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import hashlib
11
12
  import json
13
+ import os
14
+ import re
12
15
  from collections.abc import Callable, Mapping, Sequence
13
- from dataclasses import dataclass
16
+ from dataclasses import dataclass, replace
14
17
  from pathlib import Path, PurePosixPath
15
18
  from typing import Any
19
+ from urllib.parse import urlparse
16
20
 
17
21
  from ksadk.plugins.bundle import ResolvedPluginBundle
18
22
  from ksadk.plugins.contracts import CompositionProfile, PluginManifest
19
23
  from ksadk.plugins.host import PluginExecutionContext, PluginHostError
24
+ from ksadk.plugins.providers.codex_native import codex_runtime_registry
25
+ from ksadk.plugins.providers.mcp_projection import (
26
+ MCPProjectionLease,
27
+ project_mcp_capabilities,
28
+ )
20
29
  from ksadk.runtime import (
21
30
  RuntimeExecutor,
22
31
  RuntimeLaunchContext,
23
32
  RuntimeServices,
24
- build_default_runtime_registry,
25
33
  )
26
34
  from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
27
35
  from ksadk.sessions import create_session_service
@@ -96,9 +104,7 @@ class CodexTurnRequest:
96
104
  raw_messages = value.get("messages")
97
105
  if raw_messages is None and value.get("input") is not None:
98
106
  raw_messages = ({"role": "user", "content": value.get("input")},)
99
- if not isinstance(raw_messages, Sequence) or isinstance(
100
- raw_messages, (str, bytes)
101
- ):
107
+ if not isinstance(raw_messages, Sequence) or isinstance(raw_messages, (str, bytes)):
102
108
  raise PluginHostError("codex_input_invalid", "Codex input requires messages")
103
109
  messages: list[Mapping[str, Any]] = []
104
110
  for index, message in enumerate(raw_messages):
@@ -114,29 +120,19 @@ class CodexTurnRequest:
114
120
  )
115
121
  messages.append(dict(message))
116
122
  if not messages or messages[-1].get("role") != "user":
117
- raise PluginHostError(
118
- "codex_input_invalid", "Codex turn must end with a user message"
119
- )
123
+ raise PluginHostError("codex_input_invalid", "Codex turn must end with a user message")
120
124
  metadata = value.get("request_metadata") or value.get("requestMetadata")
121
125
  if metadata is not None and not isinstance(metadata, Mapping):
122
- raise PluginHostError(
123
- "codex_input_invalid", "request_metadata must be an object"
124
- )
125
- session_id = str(
126
- value.get("session_id") or value.get("sessionId") or ""
127
- ).strip()
128
- invocation_id = str(
129
- value.get("invocation_id") or value.get("invocationId") or ""
130
- ).strip()
126
+ raise PluginHostError("codex_input_invalid", "request_metadata must be an object")
127
+ session_id = str(value.get("session_id") or value.get("sessionId") or "").strip()
128
+ invocation_id = str(value.get("invocation_id") or value.get("invocationId") or "").strip()
131
129
  if len(invocation_id) > 256:
132
130
  raise PluginHostError(
133
131
  "codex_input_invalid", "Codex invocation_id exceeds 256 characters"
134
132
  )
135
133
  model = str(value.get("model") or "").strip()
136
134
  if len(model) > 256:
137
- raise PluginHostError(
138
- "codex_input_invalid", "Codex model exceeds 256 characters"
139
- )
135
+ raise PluginHostError("codex_input_invalid", "Codex model exceeds 256 characters")
140
136
  collaboration_mode = (
141
137
  str(value.get("collaboration_mode") or value.get("collaborationMode") or "")
142
138
  .strip()
@@ -195,11 +191,17 @@ class CodexAgentProviderRuntime:
195
191
  session_service: BaseSessionService,
196
192
  codex_client_factory: Callable[..., Any] | None,
197
193
  credential_resolver: Any = None,
194
+ runtime_state_root: Path | None = None,
195
+ local_launch_resolver: Callable[..., RuntimeLaunchContext | None] | None = None,
196
+ runtime_executor: RuntimeExecutor | None = None,
198
197
  ) -> None:
199
198
  self._plugin_id = plugin_id
200
199
  self._session_service = session_service
201
200
  self._client_factory = codex_client_factory
202
201
  self._credentials = credential_resolver
202
+ self._runtime_state_root = runtime_state_root
203
+ self._local_launch_resolver = local_launch_resolver
204
+ self._runtime_executor = runtime_executor
203
205
  self._ready = False
204
206
  self._disposed = False
205
207
  self._last_activation: CodexAgentActivation | None = None
@@ -234,21 +236,40 @@ class CodexAgentProviderRuntime:
234
236
  capabilities: PluginExecutionContext,
235
237
  ) -> "CodexAgentActivation":
236
238
  if not self._ready or self._disposed:
237
- raise PluginHostError(
238
- "codex_provider_unavailable", "Codex provider is not ready"
239
- )
239
+ raise PluginHostError("codex_provider_unavailable", "Codex provider is not ready")
240
240
  _reject_external_execution(bundle, capabilities)
241
- config = _resolve_bundle_config(
241
+ projection = await project_mcp_capabilities(
242
+ capabilities,
242
243
  bundle,
243
- plugin_id=self._plugin_id,
244
- credential_resolver=self._credentials,
245
- )
246
- activation = CodexAgentActivation(
247
- bundle=bundle,
248
- config=config,
249
- session_service=self._session_service,
250
- codex_client_factory=self._client_factory,
244
+ activation_only=True,
251
245
  )
246
+ marker = bundle.composition.profile.agent_provider.config.get("studioManifestDigest")
247
+ launch = self._local_launch_resolver(bundle) if self._local_launch_resolver else None
248
+ if marker is not None and launch is None:
249
+ await projection.aclose()
250
+ raise PluginHostError("codex_local_build_required", "Local Codex Build is unavailable")
251
+ try:
252
+ config = _with_projected_mcp(
253
+ _resolve_bundle_config(
254
+ bundle,
255
+ plugin_id=self._plugin_id,
256
+ credential_resolver=self._credentials,
257
+ runtime_state_root=self._runtime_state_root,
258
+ local_launch=launch,
259
+ ),
260
+ projection,
261
+ )
262
+ activation = CodexAgentActivation(
263
+ bundle=bundle,
264
+ config=config,
265
+ session_service=self._session_service,
266
+ codex_client_factory=self._client_factory,
267
+ mcp_projection=projection,
268
+ runtime_executor=self._runtime_executor,
269
+ )
270
+ except BaseException:
271
+ await projection.aclose()
272
+ raise
252
273
  self._last_activation = activation
253
274
  return activation
254
275
 
@@ -284,11 +305,24 @@ class CodexAgentProviderFactory:
284
305
  )
285
306
  client_factory = self._client_factory or services.get("codex_client_factory")
286
307
  credentials = self._credentials or services.get("credential_resolver")
308
+ raw_state_root = services.get("runtime_state_root")
309
+ runtime_state_root = (
310
+ Path(str(raw_state_root)).expanduser().resolve() if raw_state_root is not None else None
311
+ )
312
+ runtime_executor = services.get("runtime_executor")
313
+ if runtime_executor is not None and not isinstance(runtime_executor, RuntimeExecutor):
314
+ raise PluginHostError(
315
+ "codex_runtime_executor_invalid",
316
+ "Codex provider requires a RuntimeExecutor",
317
+ )
287
318
  self.runtime = CodexAgentProviderRuntime(
288
319
  plugin_id=manifest.metadata.id,
289
320
  session_service=service,
290
321
  codex_client_factory=client_factory,
291
322
  credential_resolver=credentials,
323
+ runtime_state_root=runtime_state_root,
324
+ local_launch_resolver=services.get("codex_local_launch_resolver"),
325
+ runtime_executor=runtime_executor,
292
326
  )
293
327
  return self.runtime
294
328
 
@@ -301,11 +335,14 @@ class CodexAgentActivation:
301
335
  config: _CodexBundleConfig,
302
336
  session_service: BaseSessionService,
303
337
  codex_client_factory: Callable[..., Any] | None,
338
+ mcp_projection: MCPProjectionLease,
339
+ runtime_executor: RuntimeExecutor | None = None,
304
340
  ) -> None:
305
341
  self._bundle = bundle
306
342
  self._config = config
307
343
  self._session_service = session_service
308
- self._executor = RuntimeExecutor(build_default_runtime_registry())
344
+ self._mcp_projection = mcp_projection
345
+ self._executor = runtime_executor or RuntimeExecutor(codex_runtime_registry())
309
346
  self._launch_context = RuntimeLaunchContext(
310
347
  runtime_type="codex",
311
348
  project_dir=config.project_dir,
@@ -330,9 +367,7 @@ class CodexAgentActivation:
330
367
 
331
368
  async def execute(self, request: Any) -> CodexTurnResult:
332
369
  if not self._ready or self._disposed:
333
- raise PluginHostError(
334
- "codex_activation_unavailable", "Codex activation is not ready"
335
- )
370
+ raise PluginHostError("codex_activation_unavailable", "Codex activation is not ready")
336
371
  turn = CodexTurnRequest.parse(request)
337
372
  selected_model = turn.model or self._config.model
338
373
  if selected_model not in self._config.allowed_models:
@@ -379,9 +414,7 @@ class CodexAgentActivation:
379
414
  """
380
415
 
381
416
  if not self._ready or self._disposed:
382
- raise PluginHostError(
383
- "codex_activation_unavailable", "Codex activation is not ready"
384
- )
417
+ raise PluginHostError("codex_activation_unavailable", "Codex activation is not ready")
385
418
  adapter = self._executor.create_adapter(self._launch_context)
386
419
  self._kernel_adapters.append(adapter)
387
420
  return adapter
@@ -405,6 +438,9 @@ class CodexAgentActivation:
405
438
  async def drain(self) -> None:
406
439
  self._ready = False
407
440
 
441
+ async def abort(self) -> None:
442
+ await self._mcp_projection.aclose()
443
+
408
444
  async def dispose(self) -> None:
409
445
  self._ready = False
410
446
  first_error: BaseException | None = None
@@ -423,6 +459,11 @@ class CodexAgentActivation:
423
459
  except BaseException as error: # cleanup must continue
424
460
  if first_error is None:
425
461
  first_error = error
462
+ try:
463
+ await self._mcp_projection.aclose()
464
+ except BaseException as error: # security cleanup must still finish
465
+ if first_error is None:
466
+ first_error = error
426
467
  self._disposed = True
427
468
  if first_error is not None:
428
469
  raise first_error
@@ -440,13 +481,69 @@ def _reject_aliased_duplicates(
440
481
  )
441
482
 
442
483
 
484
+ def _with_projected_mcp(
485
+ config: _CodexBundleConfig,
486
+ projection: MCPProjectionLease,
487
+ ) -> _CodexBundleConfig:
488
+ """Add activation-scoped connectors to Codex's generic launch config."""
489
+
490
+ launch = dict(config.launch_config)
491
+ servers = [dict(item) for item in launch.get("mcp_servers") or []]
492
+ environment = dict(launch.get("env") or {})
493
+ names = {str(item.get("name") or "") for item in servers}
494
+ for spec in projection.specs:
495
+ parsed = urlparse(spec.url)
496
+ if (
497
+ parsed.scheme not in {"http", "https"}
498
+ or not parsed.hostname
499
+ or parsed.username is not None
500
+ or parsed.password is not None
501
+ or parsed.fragment
502
+ ):
503
+ raise PluginHostError(
504
+ "codex_mcp_projection_invalid",
505
+ f"projected MCP connector {spec.name!r} has an invalid endpoint",
506
+ )
507
+ if spec.name in names:
508
+ raise PluginHostError(
509
+ "codex_mcp_projection_ambiguous",
510
+ f"projected MCP connector {spec.name!r} conflicts with the Bundle",
511
+ )
512
+ server: dict[str, Any] = {
513
+ "name": spec.name,
514
+ "transport": "http",
515
+ "url": spec.url,
516
+ }
517
+ if spec.api_key is not None:
518
+ suffix = hashlib.sha256(spec.name.encode()).hexdigest()[:16].upper()
519
+ env_key = f"KSADK_ACTIVATION_MCP_TOKEN_{suffix}"
520
+ if env_key in environment:
521
+ raise PluginHostError(
522
+ "codex_mcp_projection_ambiguous",
523
+ f"projected MCP connector {spec.name!r} has an environment collision",
524
+ )
525
+ environment[env_key] = spec.api_key
526
+ server["env_key"] = env_key
527
+ servers.append(server)
528
+ names.add(spec.name)
529
+ launch["mcp_servers"] = servers
530
+ launch["env"] = environment
531
+ inventory = replace(
532
+ config.inventory,
533
+ mcp_servers=tuple(item["name"] for item in servers),
534
+ )
535
+ return replace(config, launch_config=launch, inventory=inventory)
536
+
537
+
443
538
  def _reject_external_execution(
444
539
  bundle: ResolvedPluginBundle,
445
540
  capabilities: PluginExecutionContext,
446
541
  ) -> None:
447
542
  del capabilities
448
543
  profile_config = bundle.composition.profile.agent_provider.config
449
- allowed_config = {"runtimeType", "runtimeVersion"}
544
+ allowed_config = {
545
+ "runtimeType", "runtimeVersion", "studioManifestDigest", "studioBuildFingerprint",
546
+ }
450
547
  unsupported_config = sorted(set(profile_config) - allowed_config)
451
548
  execution = bundle.resolved_agent_spec.get("execution")
452
549
  strategy = (
@@ -472,6 +569,8 @@ def _resolve_bundle_config(
472
569
  *,
473
570
  plugin_id: str,
474
571
  credential_resolver: Any,
572
+ runtime_state_root: Path | None,
573
+ local_launch: RuntimeLaunchContext | None = None,
475
574
  ) -> _CodexBundleConfig:
476
575
  spec = bundle.resolved_agent_spec
477
576
  raw_model = spec.get("model")
@@ -485,6 +584,13 @@ def _resolve_bundle_config(
485
584
  "codex_bundle_model_missing", "Bundle resolved Agent spec has no model"
486
585
  )
487
586
  allowed_models = _resolve_allowed_models(bundle, default_model=model)
587
+ if local_launch is not None:
588
+ # The trusted host verified the original Codex manifest referenced by
589
+ # this Bundle. YAML-only model names may have no Catalog profile IDs.
590
+ model = str(local_launch.config["model"])
591
+ allowed_models = tuple(local_launch.config["models"])
592
+ if not allowed_models or model not in allowed_models:
593
+ raise PluginHostError("codex_bundle_model_inventory_invalid", "Invalid local models")
488
594
  instructions = spec.get("instructions")
489
595
  if not isinstance(instructions, Mapping):
490
596
  raise PluginHostError(
@@ -512,29 +618,46 @@ def _resolve_bundle_config(
512
618
  "codex_tools_unsupported", "Codex only accepts its native tools, MCP, and Skills"
513
619
  )
514
620
  skills = _resolve_skills(bundle.root, capabilities.get("skills"))
515
- mcp_servers, env = _resolve_mcp(
621
+ mcp_servers, mcp_env = _resolve_mcp(
516
622
  capabilities.get("mcpServers") or capabilities.get("mcp_servers"),
517
623
  credential_resolver=credential_resolver,
518
624
  )
625
+ # Local Studio has already resolved its original Codex credential policy.
626
+ # A second, stricter generic Bundle lookup would reject native-auth builds
627
+ # before their approved launch environment can be applied below.
628
+ model_env = {} if local_launch is not None else _resolve_model_env(
629
+ raw_model,
630
+ model=model,
631
+ credential_resolver=credential_resolver,
632
+ )
519
633
  execution = spec.get("execution")
520
634
  execution = execution if isinstance(execution, Mapping) else {}
521
- project_dir = bundle.root / "runtime"
522
- if not project_dir.is_dir():
523
- project_dir = bundle.root
635
+ project_dir = (
636
+ local_launch.project_dir if local_launch is not None
637
+ else _resolve_runtime_workspace(bundle, runtime_state_root=runtime_state_root)
638
+ )
524
639
  launch_config: dict[str, Any] = {
525
640
  "model": model,
526
641
  "models": list(allowed_models),
527
642
  "prompt": str(instructions.get("system") or "").strip(),
528
643
  "task_prompt": str(instructions.get("task") or "").strip(),
529
- "sandbox": str(execution.get("sandbox") or "read_only"),
644
+ # Match Studio's workspace default. A missing execution stanza should
645
+ # still allow ordinary project work while auto-reviewing risky actions;
646
+ # read-only remains available when the Bundle declares it explicitly.
647
+ "sandbox": str(execution.get("sandbox") or "workspace_write_auto"),
530
648
  "approval_mode": str(execution.get("approvalMode") or execution.get("approval_mode") or ""),
531
649
  "turn_timeout_seconds": int(
532
650
  execution.get("timeoutSeconds") or execution.get("timeout_seconds") or 120
533
651
  ),
534
652
  "mcp_servers": mcp_servers,
535
653
  "skills": skills,
536
- "env": env,
654
+ "env": {**mcp_env, **model_env},
537
655
  }
656
+ if local_launch is not None:
657
+ launch_config.update(local_launch.config)
658
+ # Local launch compatibility never replaces immutable Bundle Skill bytes.
659
+ launch_config["skills"] = skills
660
+ launch_config["enforce_bound_skills"] = True
538
661
  return _CodexBundleConfig(
539
662
  model=model,
540
663
  allowed_models=allowed_models,
@@ -550,6 +673,116 @@ def _resolve_bundle_config(
550
673
  )
551
674
 
552
675
 
676
+ def _resolve_runtime_workspace(
677
+ bundle: ResolvedPluginBundle,
678
+ *,
679
+ runtime_state_root: Path | None,
680
+ ) -> Path:
681
+ """Keep Codex state and generated files outside the immutable Bundle.
682
+
683
+ A Bundle is integrity-checked again whenever a session opens. Using it as
684
+ Codex's working directory lets CODEX_HOME and ordinary workspace writes add
685
+ undeclared files, which makes the next open look like bundle corruption.
686
+ """
687
+
688
+ state_root = (
689
+ runtime_state_root
690
+ if runtime_state_root is not None
691
+ else bundle.root.parent / ".runtime-state"
692
+ ).resolve()
693
+ safe_agent_id = (
694
+ "".join(
695
+ character if character.isalnum() or character in {"-", "_", "."} else "-"
696
+ for character in bundle.manifest.agent_id
697
+ ).strip("-.")
698
+ or "agent"
699
+ )
700
+ workspace = (state_root / "codex-workspaces" / safe_agent_id).resolve()
701
+ try:
702
+ workspace.relative_to(bundle.root)
703
+ except ValueError:
704
+ pass
705
+ else:
706
+ raise PluginHostError(
707
+ "codex_runtime_state_invalid",
708
+ "Codex runtime state must be outside the immutable Bundle",
709
+ )
710
+ try:
711
+ workspace.mkdir(parents=True, exist_ok=True)
712
+ except OSError as error:
713
+ raise PluginHostError(
714
+ "codex_runtime_state_unavailable",
715
+ "Codex runtime workspace could not be initialized",
716
+ ) from error
717
+ return workspace
718
+
719
+
720
+ def _resolve_model_env(
721
+ value: Mapping[str, Any],
722
+ *,
723
+ model: str,
724
+ credential_resolver: Any,
725
+ ) -> dict[str, str]:
726
+ """Resolve the Bundle-pinned model connection for the Codex subprocess."""
727
+
728
+ endpoint = str(
729
+ value.get("endpointUrl")
730
+ or value.get("endpoint_url")
731
+ or value.get("baseUrl")
732
+ or value.get("base_url")
733
+ or ""
734
+ ).strip()
735
+ for suffix in ("/chat/completions", "/responses"):
736
+ if endpoint.endswith(suffix):
737
+ endpoint = endpoint[: -len(suffix)]
738
+ break
739
+
740
+ env = {"OPENAI_MODEL_NAME": model}
741
+ if endpoint:
742
+ env["OPENAI_BASE_URL"] = endpoint.rstrip("/")
743
+ env["OPENAI_API_BASE"] = endpoint.rstrip("/")
744
+
745
+ wire_api = str(value.get("wireApi") or value.get("wire_api") or "").strip().lower()
746
+ host = (urlparse(endpoint).hostname or "").lower() if endpoint else ""
747
+ if "KSADK_CODEX_USE_PROXY" not in os.environ and (
748
+ wire_api == "chat" or host == "kspmas.ksyun.com" or host.endswith(".kspmas.ksyun.com")
749
+ ):
750
+ # Codex speaks Responses natively. Known chat-only gateways need the
751
+ # local protocol bridge and must not spend the first turn probing an
752
+ # endpoint whose protocol is already declared by the immutable Bundle.
753
+ env["KSADK_CODEX_USE_PROXY"] = "1"
754
+
755
+ reference = str(value.get("credentialRef") or value.get("credential_ref") or "").strip()
756
+ if not reference:
757
+ return env
758
+ if credential_resolver is None:
759
+ raise PluginHostError(
760
+ "codex_model_credential_unavailable",
761
+ "Codex Bundle model requires a credential resolver",
762
+ )
763
+ try:
764
+ credential = (
765
+ credential_resolver.resolve(reference)
766
+ if hasattr(credential_resolver, "resolve")
767
+ else credential_resolver(reference)
768
+ )
769
+ except Exception as error:
770
+ raise PluginHostError(
771
+ "codex_model_credential_unavailable",
772
+ "Codex Bundle model credential could not be resolved",
773
+ ) from error
774
+ if not str(credential):
775
+ raise PluginHostError(
776
+ "codex_model_credential_unavailable",
777
+ "Codex Bundle model credential is empty",
778
+ )
779
+ # Model connection keys are reserved for the model. An MCP binding may use
780
+ # arbitrary environment names, but it must not replace the model gateway's
781
+ # credential or endpoint in the child process.
782
+ env["OPENAI_API_KEY"] = str(credential)
783
+ return env
784
+
785
+
553
786
  def _resolve_allowed_models(
554
787
  bundle: ResolvedPluginBundle,
555
788
  *,
@@ -563,14 +796,10 @@ def _resolve_allowed_models(
563
796
  instead of silently widening run-level model selection.
564
797
  """
565
798
 
566
- if not any(
567
- entry.path == "runtime-lock.json" for entry in bundle.manifest.files
568
- ):
799
+ if not any(entry.path == "runtime-lock.json" for entry in bundle.manifest.files):
569
800
  return (default_model,)
570
801
  try:
571
- payload = json.loads(
572
- (bundle.root / "runtime-lock.json").read_text(encoding="utf-8")
573
- )
802
+ payload = json.loads((bundle.root / "runtime-lock.json").read_text(encoding="utf-8"))
574
803
  except (OSError, UnicodeError, json.JSONDecodeError) as error:
575
804
  raise PluginHostError(
576
805
  "codex_bundle_model_inventory_invalid",
@@ -587,9 +816,7 @@ def _resolve_allowed_models(
587
816
  "codex_bundle_model_inventory_invalid",
588
817
  "Bundle runtime-lock.json must declare models as a list",
589
818
  )
590
- models = tuple(
591
- dict.fromkeys(str(item).strip() for item in raw_models if str(item).strip())
592
- )
819
+ models = tuple(dict.fromkeys(str(item).strip() for item in raw_models if str(item).strip()))
593
820
  if not models or default_model not in models:
594
821
  raise PluginHostError(
595
822
  "codex_bundle_model_inventory_invalid",
@@ -624,9 +851,7 @@ def _resolve_skills(root: Path, value: Any) -> list[dict[str, str]]:
624
851
  "codex_skill_invalid", f"Bundle Skill {name!r} escapes the Bundle root"
625
852
  ) from error
626
853
  if not (path / "SKILL.md").is_file():
627
- raise PluginHostError(
628
- "codex_skill_missing", f"Bundle Skill {name!r} has no SKILL.md"
629
- )
854
+ raise PluginHostError("codex_skill_missing", f"Bundle Skill {name!r} has no SKILL.md")
630
855
  if name in seen:
631
856
  raise PluginHostError("codex_skill_invalid", f"duplicate Bundle Skill {name!r}")
632
857
  seen.add(name)
@@ -641,12 +866,12 @@ def _resolve_mcp(
641
866
  value: Any,
642
867
  *,
643
868
  credential_resolver: Any,
644
- ) -> tuple[list[dict[str, str]], dict[str, str]]:
869
+ ) -> tuple[list[dict[str, Any]], dict[str, str]]:
645
870
  if value is None:
646
871
  return [], {}
647
872
  if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
648
873
  raise PluginHostError("codex_mcp_invalid", "Bundle MCP servers must be a list")
649
- servers: list[dict[str, str]] = []
874
+ servers: list[dict[str, Any]] = []
650
875
  env: dict[str, str] = {}
651
876
  seen: set[str] = set()
652
877
  for index, item in enumerate(value):
@@ -659,26 +884,62 @@ def _resolve_mcp(
659
884
  url = str(item.get("endpointUrl") or item.get("endpoint_url") or "").strip()
660
885
  if not name or name in seen:
661
886
  raise PluginHostError("codex_mcp_invalid", "Bundle MCP names must be unique")
662
- if transport not in {"http", "sse"} or not url:
663
- raise PluginHostError(
664
- "codex_mcp_transport_unsupported",
665
- f"Codex Bundle MCP {name!r} requires an http/sse endpoint",
666
- )
667
887
  env_refs = item.get("envRefs") or item.get("env_refs") or {}
668
888
  if not isinstance(env_refs, Mapping):
669
889
  raise PluginHostError(
670
890
  "codex_mcp_invalid", f"Bundle MCP {name!r} envRefs must be an object"
671
891
  )
672
- if len(env_refs) > 1:
892
+ if transport in {"http", "sse"} and len(env_refs) > 1:
673
893
  raise PluginHostError(
674
894
  "codex_mcp_credentials_unsupported",
675
895
  f"Codex HTTP MCP {name!r} accepts at most one bearer credential",
676
896
  )
677
- server = {"name": name, "url": url}
897
+ if transport == "stdio":
898
+ command = str(item.get("command") or "").strip()
899
+ raw_args = item.get("args") or []
900
+ if (
901
+ not command
902
+ or not isinstance(raw_args, Sequence)
903
+ or isinstance(raw_args, (str, bytes))
904
+ or len(raw_args) > 128
905
+ or any(
906
+ not isinstance(argument, str) or len(argument) > 4096 or "\x00" in argument
907
+ for argument in raw_args
908
+ )
909
+ ):
910
+ raise PluginHostError(
911
+ "codex_mcp_invalid",
912
+ f"Codex Bundle stdio MCP {name!r} has an invalid command or args",
913
+ )
914
+ executable = Path(command).name.casefold()
915
+ if executable in {"sh", "bash", "zsh", "cmd", "cmd.exe", "powershell", "pwsh"}:
916
+ raise PluginHostError(
917
+ "codex_mcp_command_denied",
918
+ f"Codex Bundle stdio MCP {name!r} cannot launch a shell",
919
+ )
920
+ if any(argument in {"-c", "-e", "--eval"} for argument in raw_args):
921
+ raise PluginHostError(
922
+ "codex_mcp_command_denied",
923
+ f"Codex Bundle stdio MCP {name!r} cannot use inline evaluation",
924
+ )
925
+ server: dict[str, Any] = {
926
+ "name": name,
927
+ "transport": "stdio",
928
+ "command": command,
929
+ "args": list(raw_args),
930
+ }
931
+ elif transport in {"http", "sse"} and url:
932
+ server = {"name": name, "transport": transport, "url": url}
933
+ else:
934
+ raise PluginHostError(
935
+ "codex_mcp_transport_unsupported",
936
+ f"Codex Bundle MCP {name!r} requires stdio or an http/sse endpoint",
937
+ )
938
+ forwarded_env: dict[str, str] = {}
678
939
  for env_name, reference in env_refs.items():
679
940
  env_key = str(env_name).strip()
680
941
  ref = str(reference).strip()
681
- if not env_key or not ref.startswith(
942
+ if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", env_key) or not ref.startswith(
682
943
  ("env://", "secret://", "credential://", "vault://")
683
944
  ):
684
945
  raise PluginHostError(
@@ -707,7 +968,12 @@ def _resolve_mcp(
707
968
  f"Bundle MCP {name!r} credential is empty",
708
969
  )
709
970
  env[env_key] = str(value)
710
- server["env_key"] = env_key
971
+ if transport == "stdio":
972
+ forwarded_env[env_key] = ref
973
+ else:
974
+ server["env_key"] = env_key
975
+ if forwarded_env:
976
+ server["env_refs"] = forwarded_env
711
977
  servers.append(server)
712
978
  seen.add(name)
713
979
  return servers, env