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,988 @@
1
+ """Runtime-native Codex AgentProvider for the controlled PluginHost.
2
+
3
+ The provider only projects an immutable AgentBundle into the existing Codex
4
+ RuntimeAdapter/RuntimeExecutor conversation path. Canonical SessionEvents and
5
+ native thread continuation remain owned by that path; no provider-local event
6
+ stream or transcript is created here.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import json
13
+ import os
14
+ import re
15
+ from collections.abc import Callable, Mapping, Sequence
16
+ from dataclasses import dataclass, replace
17
+ from pathlib import Path, PurePosixPath
18
+ from typing import Any
19
+ from urllib.parse import urlparse
20
+
21
+ from ksadk.plugins.bundle import ResolvedPluginBundle
22
+ from ksadk.plugins.contracts import CompositionProfile, PluginManifest
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
+ )
29
+ from ksadk.runtime import (
30
+ RuntimeExecutor,
31
+ RuntimeLaunchContext,
32
+ RuntimeServices,
33
+ )
34
+ from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
35
+ from ksadk.sessions import create_session_service
36
+ from ksadk.sessions.base import BaseSessionService
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class CodexProviderInventory:
41
+ provider: str
42
+ model: str
43
+ mcp_servers: tuple[str, ...]
44
+ skills: tuple[str, ...]
45
+
46
+
47
+ @dataclass(frozen=True)
48
+ class CodexTurnRequest:
49
+ user_id: str
50
+ session_id: str | None
51
+ messages: tuple[Mapping[str, Any], ...]
52
+ request_metadata: Mapping[str, Any] | None = None
53
+ invocation_id: str | None = None
54
+ model: str | None = None
55
+ collaboration_mode: str | None = None
56
+ goal_objective: str | None = None
57
+
58
+ @classmethod
59
+ def parse(cls, value: Any) -> "CodexTurnRequest":
60
+ if isinstance(value, cls):
61
+ return value
62
+ if not isinstance(value, Mapping):
63
+ raise PluginHostError("codex_input_invalid", "Codex input must be an object")
64
+ allowed_fields = {
65
+ "user_id",
66
+ "userId",
67
+ "session_id",
68
+ "sessionId",
69
+ "messages",
70
+ "input",
71
+ "request_metadata",
72
+ "requestMetadata",
73
+ "invocation_id",
74
+ "invocationId",
75
+ "model",
76
+ "collaboration_mode",
77
+ "collaborationMode",
78
+ "goal_objective",
79
+ "goalObjective",
80
+ }
81
+ unsupported = sorted(str(field) for field in value if field not in allowed_fields)
82
+ if unsupported:
83
+ raise PluginHostError(
84
+ "codex_input_unsupported",
85
+ "Codex input contains undeclared fields: " + ", ".join(unsupported),
86
+ )
87
+ _reject_aliased_duplicates(
88
+ value,
89
+ ("user_id", "userId"),
90
+ ("session_id", "sessionId"),
91
+ ("request_metadata", "requestMetadata"),
92
+ ("invocation_id", "invocationId"),
93
+ ("collaboration_mode", "collaborationMode"),
94
+ ("goal_objective", "goalObjective"),
95
+ )
96
+ if "messages" in value and "input" in value:
97
+ raise PluginHostError(
98
+ "codex_input_invalid",
99
+ "Codex input must use exactly one of messages or input",
100
+ )
101
+ user_id = str(value.get("user_id") or value.get("userId") or "").strip()
102
+ if not user_id:
103
+ raise PluginHostError("codex_input_invalid", "Codex input requires user_id")
104
+ raw_messages = value.get("messages")
105
+ if raw_messages is None and value.get("input") is not None:
106
+ raw_messages = ({"role": "user", "content": value.get("input")},)
107
+ if not isinstance(raw_messages, Sequence) or isinstance(raw_messages, (str, bytes)):
108
+ raise PluginHostError("codex_input_invalid", "Codex input requires messages")
109
+ messages: list[Mapping[str, Any]] = []
110
+ for index, message in enumerate(raw_messages):
111
+ if not isinstance(message, Mapping):
112
+ raise PluginHostError(
113
+ "codex_input_invalid", f"Codex messages[{index}] must be an object"
114
+ )
115
+ role = str(message.get("role") or "").strip()
116
+ if role not in {"system", "user", "assistant", "tool"}:
117
+ raise PluginHostError(
118
+ "codex_input_invalid",
119
+ f"Codex messages[{index}] has unsupported role {role!r}",
120
+ )
121
+ messages.append(dict(message))
122
+ if not messages or messages[-1].get("role") != "user":
123
+ raise PluginHostError("codex_input_invalid", "Codex turn must end with a user message")
124
+ metadata = value.get("request_metadata") or value.get("requestMetadata")
125
+ if metadata is not None and not isinstance(metadata, Mapping):
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()
129
+ if len(invocation_id) > 256:
130
+ raise PluginHostError(
131
+ "codex_input_invalid", "Codex invocation_id exceeds 256 characters"
132
+ )
133
+ model = str(value.get("model") or "").strip()
134
+ if len(model) > 256:
135
+ raise PluginHostError("codex_input_invalid", "Codex model exceeds 256 characters")
136
+ collaboration_mode = (
137
+ str(value.get("collaboration_mode") or value.get("collaborationMode") or "")
138
+ .strip()
139
+ .lower()
140
+ )
141
+ if collaboration_mode and collaboration_mode not in {"default", "plan"}:
142
+ raise PluginHostError(
143
+ "codex_input_unsupported",
144
+ "Codex collaboration_mode must be default or plan",
145
+ )
146
+ goal_objective = str(
147
+ value.get("goal_objective") or value.get("goalObjective") or ""
148
+ ).strip()
149
+ if len(goal_objective) > 4096:
150
+ raise PluginHostError(
151
+ "codex_input_invalid", "Codex goal_objective exceeds 4096 characters"
152
+ )
153
+ return cls(
154
+ user_id=user_id,
155
+ session_id=session_id or None,
156
+ messages=tuple(messages),
157
+ request_metadata=dict(metadata) if metadata is not None else None,
158
+ invocation_id=invocation_id or None,
159
+ model=model or None,
160
+ collaboration_mode=collaboration_mode or None,
161
+ goal_objective=goal_objective or None,
162
+ )
163
+
164
+
165
+ @dataclass(frozen=True)
166
+ class CodexTurnResult:
167
+ session_id: str
168
+ output_text: str
169
+ usage: Mapping[str, Any]
170
+ metadata: Mapping[str, Any]
171
+ inventory: CodexProviderInventory
172
+
173
+
174
+ @dataclass(frozen=True)
175
+ class _CodexBundleConfig:
176
+ model: str
177
+ allowed_models: tuple[str, ...]
178
+ prompt: str
179
+ project_dir: Path
180
+ launch_config: Mapping[str, Any]
181
+ inventory: CodexProviderInventory
182
+
183
+
184
+ class CodexAgentProviderRuntime:
185
+ """ExecutableAgentProvider that preserves Codex native loop ownership."""
186
+
187
+ def __init__(
188
+ self,
189
+ *,
190
+ plugin_id: str,
191
+ session_service: BaseSessionService,
192
+ codex_client_factory: Callable[..., Any] | None,
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,
197
+ ) -> None:
198
+ self._plugin_id = plugin_id
199
+ self._session_service = session_service
200
+ self._client_factory = codex_client_factory
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
205
+ self._ready = False
206
+ self._disposed = False
207
+ self._last_activation: CodexAgentActivation | None = None
208
+
209
+ @property
210
+ def disposed(self) -> bool:
211
+ return self._disposed
212
+
213
+ @property
214
+ def last_activation(self) -> "CodexAgentActivation | None":
215
+ return self._last_activation
216
+
217
+ async def start(self) -> None:
218
+ if self._disposed:
219
+ raise RuntimeError("Codex provider is disposed")
220
+ self._ready = True
221
+
222
+ async def health(self) -> bool:
223
+ return self._ready and not self._disposed
224
+
225
+ async def drain(self) -> None:
226
+ self._ready = False
227
+
228
+ async def dispose(self) -> None:
229
+ self._ready = False
230
+ self._disposed = True
231
+
232
+ async def prepare(
233
+ self,
234
+ bundle: ResolvedPluginBundle,
235
+ *,
236
+ capabilities: PluginExecutionContext,
237
+ ) -> "CodexAgentActivation":
238
+ if not self._ready or self._disposed:
239
+ raise PluginHostError("codex_provider_unavailable", "Codex provider is not ready")
240
+ _reject_external_execution(bundle, capabilities)
241
+ projection = await project_mcp_capabilities(
242
+ capabilities,
243
+ bundle,
244
+ activation_only=True,
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
273
+ self._last_activation = activation
274
+ return activation
275
+
276
+
277
+ class CodexAgentProviderFactory:
278
+ def __init__(
279
+ self,
280
+ *,
281
+ session_service: BaseSessionService | None = None,
282
+ codex_client_factory: Callable[..., Any] | None = None,
283
+ credential_resolver: Any = None,
284
+ ) -> None:
285
+ self._session_service = session_service
286
+ self._client_factory = codex_client_factory
287
+ self._credentials = credential_resolver
288
+ self.runtime: CodexAgentProviderRuntime | None = None
289
+
290
+ async def stage(
291
+ self,
292
+ manifest: PluginManifest,
293
+ *,
294
+ profile: CompositionProfile,
295
+ services: Mapping[str, Any],
296
+ ) -> CodexAgentProviderRuntime:
297
+ del profile
298
+ service = self._session_service or services.get("session_service")
299
+ if service is None:
300
+ service = create_session_service(backend="memory")
301
+ if not isinstance(service, BaseSessionService):
302
+ raise PluginHostError(
303
+ "codex_session_service_invalid",
304
+ "Codex provider requires a BaseSessionService",
305
+ )
306
+ client_factory = self._client_factory or services.get("codex_client_factory")
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
+ )
318
+ self.runtime = CodexAgentProviderRuntime(
319
+ plugin_id=manifest.metadata.id,
320
+ session_service=service,
321
+ codex_client_factory=client_factory,
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,
326
+ )
327
+ return self.runtime
328
+
329
+
330
+ class CodexAgentActivation:
331
+ def __init__(
332
+ self,
333
+ *,
334
+ bundle: ResolvedPluginBundle,
335
+ config: _CodexBundleConfig,
336
+ session_service: BaseSessionService,
337
+ codex_client_factory: Callable[..., Any] | None,
338
+ mcp_projection: MCPProjectionLease,
339
+ runtime_executor: RuntimeExecutor | None = None,
340
+ ) -> None:
341
+ self._bundle = bundle
342
+ self._config = config
343
+ self._session_service = session_service
344
+ self._mcp_projection = mcp_projection
345
+ self._executor = runtime_executor or RuntimeExecutor(codex_runtime_registry())
346
+ self._launch_context = RuntimeLaunchContext(
347
+ runtime_type="codex",
348
+ project_dir=config.project_dir,
349
+ config=config.launch_config,
350
+ services=RuntimeServices(codex_client_factory=codex_client_factory),
351
+ )
352
+ self._ready = False
353
+ self._disposed = False
354
+ self._kernel_adapters: list[Any] = []
355
+
356
+ @property
357
+ def disposed(self) -> bool:
358
+ return self._disposed
359
+
360
+ async def start(self) -> None:
361
+ if self._disposed:
362
+ raise RuntimeError("Codex activation is disposed")
363
+ self._ready = True
364
+
365
+ async def health(self) -> bool:
366
+ return self._ready and not self._disposed
367
+
368
+ async def execute(self, request: Any) -> CodexTurnResult:
369
+ if not self._ready or self._disposed:
370
+ raise PluginHostError("codex_activation_unavailable", "Codex activation is not ready")
371
+ turn = CodexTurnRequest.parse(request)
372
+ selected_model = turn.model or self._config.model
373
+ if selected_model not in self._config.allowed_models:
374
+ raise PluginHostError(
375
+ "codex_model_unsupported",
376
+ f"Codex model {selected_model!r} is not declared by the immutable Bundle",
377
+ )
378
+ launch_context = self._turn_launch_context(turn)
379
+ preparation = await self._executor.prepare_start(launch_context)
380
+ session_id, result = await invoke_runtime_conversation_once(
381
+ executor=self._executor,
382
+ launch_context=launch_context,
383
+ agent_id=self._bundle.manifest.agent_id,
384
+ user_id=turn.user_id,
385
+ messages=[dict(item) for item in turn.messages],
386
+ session_id=turn.session_id,
387
+ model=selected_model,
388
+ instructions=self._config.prompt,
389
+ request_metadata=turn.request_metadata,
390
+ invocation_id=turn.invocation_id,
391
+ session_service_provider=lambda: self._session_service,
392
+ runtime_preparation=preparation,
393
+ )
394
+ return CodexTurnResult(
395
+ session_id=session_id,
396
+ output_text=str(result.get("output_text") or ""),
397
+ usage=dict(result.get("usage") or {}),
398
+ metadata=dict(result.get("metadata") or {}),
399
+ inventory=CodexProviderInventory(
400
+ provider=self._config.inventory.provider,
401
+ model=selected_model,
402
+ mcp_servers=self._config.inventory.mcp_servers,
403
+ skills=self._config.inventory.skills,
404
+ ),
405
+ )
406
+
407
+ def runtime_adapter(self) -> Any:
408
+ """Create one activation-owned native adapter for AgentKernel.
409
+
410
+ Each Kernel command receives a fresh App Server transport. Durable
411
+ SessionEvent metadata reconnects the next command to the same Codex
412
+ Thread, while retaining adapters here lets activation disposal close a
413
+ command that is still active during Profile drain.
414
+ """
415
+
416
+ if not self._ready or self._disposed:
417
+ raise PluginHostError("codex_activation_unavailable", "Codex activation is not ready")
418
+ adapter = self._executor.create_adapter(self._launch_context)
419
+ self._kernel_adapters.append(adapter)
420
+ return adapter
421
+
422
+ def _turn_launch_context(self, turn: CodexTurnRequest) -> RuntimeLaunchContext:
423
+ config = dict(self._config.launch_config)
424
+ if turn.model:
425
+ config["model"] = turn.model
426
+ if turn.collaboration_mode:
427
+ config["collaboration_mode"] = turn.collaboration_mode
428
+ if turn.goal_objective:
429
+ config["goal_objective"] = turn.goal_objective
430
+ return RuntimeLaunchContext(
431
+ runtime_type=self._launch_context.runtime_type,
432
+ project_dir=self._launch_context.project_dir,
433
+ config=config,
434
+ services=self._launch_context.services,
435
+ deployment_mode=self._launch_context.deployment_mode,
436
+ )
437
+
438
+ async def drain(self) -> None:
439
+ self._ready = False
440
+
441
+ async def abort(self) -> None:
442
+ await self._mcp_projection.aclose()
443
+
444
+ async def dispose(self) -> None:
445
+ self._ready = False
446
+ first_error: BaseException | None = None
447
+ for adapter in reversed(self._kernel_adapters):
448
+ close_all = getattr(adapter, "close_all", None)
449
+ if not callable(close_all):
450
+ continue
451
+ try:
452
+ await close_all()
453
+ except BaseException as error: # cleanup must continue
454
+ if first_error is None:
455
+ first_error = error
456
+ self._kernel_adapters.clear()
457
+ try:
458
+ await self._executor.close_all()
459
+ except BaseException as error: # cleanup must continue
460
+ if first_error is None:
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
467
+ self._disposed = True
468
+ if first_error is not None:
469
+ raise first_error
470
+
471
+
472
+ def _reject_aliased_duplicates(
473
+ value: Mapping[str, Any],
474
+ *aliases: tuple[str, str],
475
+ ) -> None:
476
+ for snake_case, camel_case in aliases:
477
+ if snake_case in value and camel_case in value:
478
+ raise PluginHostError(
479
+ "codex_input_invalid",
480
+ f"Codex input cannot contain both {snake_case} and {camel_case}",
481
+ )
482
+
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
+
538
+ def _reject_external_execution(
539
+ bundle: ResolvedPluginBundle,
540
+ capabilities: PluginExecutionContext,
541
+ ) -> None:
542
+ del capabilities
543
+ profile_config = bundle.composition.profile.agent_provider.config
544
+ allowed_config = {
545
+ "runtimeType", "runtimeVersion", "studioManifestDigest", "studioBuildFingerprint",
546
+ }
547
+ unsupported_config = sorted(set(profile_config) - allowed_config)
548
+ execution = bundle.resolved_agent_spec.get("execution")
549
+ strategy = (
550
+ str(execution.get("strategy") or "direct").strip()
551
+ if isinstance(execution, Mapping)
552
+ else "direct"
553
+ )
554
+ if unsupported_config:
555
+ raise PluginHostError(
556
+ "codex_provider_config_unsupported",
557
+ "Codex AgentProvider received unsupported configuration: "
558
+ + ", ".join(unsupported_config),
559
+ )
560
+ if strategy != "direct":
561
+ raise PluginHostError(
562
+ "codex_external_execution_unsupported",
563
+ f"Codex AgentProvider owns its execution semantics and does not support {strategy!r}",
564
+ )
565
+
566
+
567
+ def _resolve_bundle_config(
568
+ bundle: ResolvedPluginBundle,
569
+ *,
570
+ plugin_id: str,
571
+ credential_resolver: Any,
572
+ runtime_state_root: Path | None,
573
+ local_launch: RuntimeLaunchContext | None = None,
574
+ ) -> _CodexBundleConfig:
575
+ spec = bundle.resolved_agent_spec
576
+ raw_model = spec.get("model")
577
+ if not isinstance(raw_model, Mapping):
578
+ raise PluginHostError(
579
+ "codex_bundle_model_invalid", "Bundle resolved model must be an object"
580
+ )
581
+ model = str(raw_model.get("model") or "").strip()
582
+ if not model:
583
+ raise PluginHostError(
584
+ "codex_bundle_model_missing", "Bundle resolved Agent spec has no model"
585
+ )
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")
594
+ instructions = spec.get("instructions")
595
+ if not isinstance(instructions, Mapping):
596
+ raise PluginHostError(
597
+ "codex_bundle_prompt_invalid", "Bundle instructions must be an object"
598
+ )
599
+ prompt = "\n\n".join(
600
+ part
601
+ for part in (
602
+ str(instructions.get("system") or "").strip(),
603
+ str(instructions.get("task") or "").strip(),
604
+ )
605
+ if part
606
+ )
607
+ if not prompt:
608
+ raise PluginHostError(
609
+ "codex_bundle_prompt_missing", "Bundle resolved Agent spec has no instructions"
610
+ )
611
+ capabilities = spec.get("capabilities")
612
+ if not isinstance(capabilities, Mapping):
613
+ raise PluginHostError(
614
+ "codex_bundle_capabilities_invalid", "Bundle capabilities must be an object"
615
+ )
616
+ if capabilities.get("tools"):
617
+ raise PluginHostError(
618
+ "codex_tools_unsupported", "Codex only accepts its native tools, MCP, and Skills"
619
+ )
620
+ skills = _resolve_skills(bundle.root, capabilities.get("skills"))
621
+ mcp_servers, mcp_env = _resolve_mcp(
622
+ capabilities.get("mcpServers") or capabilities.get("mcp_servers"),
623
+ credential_resolver=credential_resolver,
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
+ )
633
+ execution = spec.get("execution")
634
+ execution = execution if isinstance(execution, Mapping) else {}
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
+ )
639
+ launch_config: dict[str, Any] = {
640
+ "model": model,
641
+ "models": list(allowed_models),
642
+ "prompt": str(instructions.get("system") or "").strip(),
643
+ "task_prompt": str(instructions.get("task") or "").strip(),
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"),
648
+ "approval_mode": str(execution.get("approvalMode") or execution.get("approval_mode") or ""),
649
+ "turn_timeout_seconds": int(
650
+ execution.get("timeoutSeconds") or execution.get("timeout_seconds") or 120
651
+ ),
652
+ "mcp_servers": mcp_servers,
653
+ "skills": skills,
654
+ "env": {**mcp_env, **model_env},
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
661
+ return _CodexBundleConfig(
662
+ model=model,
663
+ allowed_models=allowed_models,
664
+ prompt=prompt,
665
+ project_dir=project_dir,
666
+ launch_config=launch_config,
667
+ inventory=CodexProviderInventory(
668
+ provider=plugin_id,
669
+ model=model,
670
+ mcp_servers=tuple(item["name"] for item in mcp_servers),
671
+ skills=tuple(item["name"] for item in skills),
672
+ ),
673
+ )
674
+
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
+
786
+ def _resolve_allowed_models(
787
+ bundle: ResolvedPluginBundle,
788
+ *,
789
+ default_model: str,
790
+ ) -> tuple[str, ...]:
791
+ """Read the immutable model allowlist produced by the Bundle compiler.
792
+
793
+ Older Bundle fixtures without ``runtime-lock.json`` remain pinned to their
794
+ resolved default. A declared lock is already digest-verified by
795
+ ``PluginBundleResolver``; malformed model inventory must fail activation
796
+ instead of silently widening run-level model selection.
797
+ """
798
+
799
+ if not any(entry.path == "runtime-lock.json" for entry in bundle.manifest.files):
800
+ return (default_model,)
801
+ try:
802
+ payload = json.loads((bundle.root / "runtime-lock.json").read_text(encoding="utf-8"))
803
+ except (OSError, UnicodeError, json.JSONDecodeError) as error:
804
+ raise PluginHostError(
805
+ "codex_bundle_model_inventory_invalid",
806
+ "Bundle runtime-lock.json is not a valid model inventory",
807
+ ) from error
808
+ if not isinstance(payload, Mapping):
809
+ raise PluginHostError(
810
+ "codex_bundle_model_inventory_invalid",
811
+ "Bundle runtime-lock.json must be an object",
812
+ )
813
+ raw_models = payload.get("models")
814
+ if not isinstance(raw_models, Sequence) or isinstance(raw_models, (str, bytes)):
815
+ raise PluginHostError(
816
+ "codex_bundle_model_inventory_invalid",
817
+ "Bundle runtime-lock.json must declare models as a list",
818
+ )
819
+ models = tuple(dict.fromkeys(str(item).strip() for item in raw_models if str(item).strip()))
820
+ if not models or default_model not in models:
821
+ raise PluginHostError(
822
+ "codex_bundle_model_inventory_invalid",
823
+ "Bundle model inventory must include its resolved default model",
824
+ )
825
+ return models
826
+
827
+
828
+ def _resolve_skills(root: Path, value: Any) -> list[dict[str, str]]:
829
+ if value is None:
830
+ return []
831
+ if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
832
+ raise PluginHostError("codex_skill_invalid", "Bundle Skills must be a list")
833
+ resolved: list[dict[str, str]] = []
834
+ seen: set[str] = set()
835
+ for index, item in enumerate(value):
836
+ if not isinstance(item, Mapping):
837
+ raise PluginHostError(
838
+ "codex_skill_invalid", f"Bundle Skills[{index}] must be an object"
839
+ )
840
+ name = str(item.get("name") or "").strip()
841
+ relative = PurePosixPath(str(item.get("bundlePath") or item.get("bundle_path") or ""))
842
+ if not name or not relative.parts or relative.is_absolute() or ".." in relative.parts:
843
+ raise PluginHostError(
844
+ "codex_skill_invalid", f"Bundle Skills[{index}] has an invalid native path"
845
+ )
846
+ path = (root / Path(*relative.parts)).resolve()
847
+ try:
848
+ path.relative_to(root)
849
+ except ValueError as error:
850
+ raise PluginHostError(
851
+ "codex_skill_invalid", f"Bundle Skill {name!r} escapes the Bundle root"
852
+ ) from error
853
+ if not (path / "SKILL.md").is_file():
854
+ raise PluginHostError("codex_skill_missing", f"Bundle Skill {name!r} has no SKILL.md")
855
+ if name in seen:
856
+ raise PluginHostError("codex_skill_invalid", f"duplicate Bundle Skill {name!r}")
857
+ seen.add(name)
858
+ # Codex's native SkillInput expects the concrete SKILL.md source, not
859
+ # its containing directory. A directory is accepted by the Python
860
+ # model but silently omitted by the real App Server turn projection.
861
+ resolved.append({"name": name, "path": str(path / "SKILL.md")})
862
+ return resolved
863
+
864
+
865
+ def _resolve_mcp(
866
+ value: Any,
867
+ *,
868
+ credential_resolver: Any,
869
+ ) -> tuple[list[dict[str, Any]], dict[str, str]]:
870
+ if value is None:
871
+ return [], {}
872
+ if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
873
+ raise PluginHostError("codex_mcp_invalid", "Bundle MCP servers must be a list")
874
+ servers: list[dict[str, Any]] = []
875
+ env: dict[str, str] = {}
876
+ seen: set[str] = set()
877
+ for index, item in enumerate(value):
878
+ if not isinstance(item, Mapping):
879
+ raise PluginHostError(
880
+ "codex_mcp_invalid", f"Bundle MCP servers[{index}] must be an object"
881
+ )
882
+ name = str(item.get("name") or "").strip()
883
+ transport = str(item.get("transport") or "").strip().lower()
884
+ url = str(item.get("endpointUrl") or item.get("endpoint_url") or "").strip()
885
+ if not name or name in seen:
886
+ raise PluginHostError("codex_mcp_invalid", "Bundle MCP names must be unique")
887
+ env_refs = item.get("envRefs") or item.get("env_refs") or {}
888
+ if not isinstance(env_refs, Mapping):
889
+ raise PluginHostError(
890
+ "codex_mcp_invalid", f"Bundle MCP {name!r} envRefs must be an object"
891
+ )
892
+ if transport in {"http", "sse"} and len(env_refs) > 1:
893
+ raise PluginHostError(
894
+ "codex_mcp_credentials_unsupported",
895
+ f"Codex HTTP MCP {name!r} accepts at most one bearer credential",
896
+ )
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] = {}
939
+ for env_name, reference in env_refs.items():
940
+ env_key = str(env_name).strip()
941
+ ref = str(reference).strip()
942
+ if not re.fullmatch(r"[A-Za-z_][A-Za-z0-9_]*", env_key) or not ref.startswith(
943
+ ("env://", "secret://", "credential://", "vault://")
944
+ ):
945
+ raise PluginHostError(
946
+ "codex_mcp_credential_invalid",
947
+ f"Bundle MCP {name!r} contains an invalid credential reference",
948
+ )
949
+ if credential_resolver is None:
950
+ raise PluginHostError(
951
+ "codex_mcp_credential_unavailable",
952
+ f"Bundle MCP {name!r} requires a credential resolver",
953
+ )
954
+ try:
955
+ value = (
956
+ credential_resolver.resolve(ref)
957
+ if hasattr(credential_resolver, "resolve")
958
+ else credential_resolver(ref)
959
+ )
960
+ except Exception as error:
961
+ raise PluginHostError(
962
+ "codex_mcp_credential_unavailable",
963
+ f"Bundle MCP {name!r} credential could not be resolved",
964
+ ) from error
965
+ if not str(value):
966
+ raise PluginHostError(
967
+ "codex_mcp_credential_unavailable",
968
+ f"Bundle MCP {name!r} credential is empty",
969
+ )
970
+ env[env_key] = str(value)
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
977
+ servers.append(server)
978
+ seen.add(name)
979
+ return servers, env
980
+
981
+
982
+ __all__ = [
983
+ "CodexAgentProviderFactory",
984
+ "CodexAgentProviderRuntime",
985
+ "CodexProviderInventory",
986
+ "CodexTurnRequest",
987
+ "CodexTurnResult",
988
+ ]