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
@@ -31,11 +31,33 @@ def _managed_a2a_card() -> Any:
31
31
  def create_runtime_web_app(detection: Any, agent_path: Path) -> FastAPI:
32
32
  """Compose one detected project around the canonical RuntimeExecutor."""
33
33
 
34
+ config = dict(getattr(detection, "raw_config", None) or {})
35
+ managed_runtime = os.getenv("AGENTENGINE_MANAGED_RUNTIME") == "1"
36
+ if managed_runtime:
37
+ from ksadk.resource_runtime.managed_projection import native_codex_plugin_bindings
38
+
39
+ if managed_runtime and native_codex_plugin_bindings(config):
40
+ import hashlib
41
+ import json
42
+
43
+ from ksadk.builders.managed_runtime_builder import serialize_managed_runtime_manifest
44
+
45
+ launch = json.loads((agent_path / ".agentkit/cloud-plugin-launch.json").read_text())
46
+ if (
47
+ launch["manifest_sha256"]
48
+ != hashlib.sha256(serialize_managed_runtime_manifest(config)).hexdigest()
49
+ ):
50
+ raise ValueError("Restored plugin launch does not match the runtime declaration")
51
+ config.update(launch["config"])
52
+ if managed_runtime:
53
+ from ksadk.resource_runtime.managed_projection import apply_managed_platform_resources
54
+
55
+ apply_managed_platform_resources(config)
34
56
  context = RuntimeLaunchContext(
35
57
  runtime_type=str(detection.type.value),
36
58
  project_dir=agent_path,
37
59
  detection=detection,
38
- config=dict(getattr(detection, "raw_config", None) or {}),
60
+ config=config,
39
61
  )
40
62
  return create_runtime_app(
41
63
  RuntimeAppConfig(
ksadk/codex/client.py CHANGED
@@ -19,13 +19,19 @@
19
19
  from __future__ import annotations
20
20
 
21
21
  import asyncio
22
+ import hashlib
23
+ import json
22
24
  import os
23
25
  import queue
26
+ import re
24
27
  import secrets
28
+ import stat
25
29
  import threading
26
30
  from abc import ABC, abstractmethod
31
+ from collections.abc import Mapping
27
32
  from dataclasses import dataclass, field
28
33
  from importlib.metadata import PackageNotFoundError, version
34
+ from pathlib import Path
29
35
  from typing import Any, AsyncIterator, Optional
30
36
  from uuid import uuid4
31
37
 
@@ -46,6 +52,193 @@ class CodexCapabilityUnavailableError(RuntimeError):
46
52
  """A caller-required Codex capability cannot be preserved by this route."""
47
53
 
48
54
 
55
+ class CodexPluginBootstrapError(CodexCapabilityUnavailableError):
56
+ """A pinned Codex plugin marketplace could not be admitted or installed."""
57
+
58
+
59
+ _CODEX_PLUGIN_DIGEST = re.compile(r"^sha256:[0-9a-f]{64}$")
60
+ _CODEX_PLUGIN_NAME = re.compile(r"^[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)*$")
61
+ _CODEX_MARKETPLACE_MANIFEST = Path(".agents/plugins/marketplace.json")
62
+ _CODEX_MARKETPLACE_MAX_FILES = 20_000
63
+ _CODEX_MARKETPLACE_MAX_BYTES = 256 * 1024 * 1024
64
+ _CODEX_MARKETPLACE_MAX_MANIFEST_BYTES = 4 * 1024 * 1024
65
+
66
+
67
+ def codex_marketplace_tree_digest(marketplace_path: str | Path) -> str:
68
+ """Hash one immutable local marketplace using the snapshot tree algorithm.
69
+
70
+ The format deliberately matches ``ksadk.plugins.codex_manifest``: sorted
71
+ relative POSIX path, NUL, decimal byte length, NUL, bytes, NUL. Directories
72
+ are ignored and symlinks are rejected, so a launch cannot substitute files
73
+ behind the digest-pinned build artifact.
74
+ """
75
+
76
+ root = Path(marketplace_path).expanduser()
77
+ if not root.is_absolute():
78
+ raise ValueError("Codex plugin marketplace_path must be absolute")
79
+ if root.is_symlink():
80
+ raise ValueError("Codex plugin marketplace root must not be a symlink")
81
+ if not root.is_dir():
82
+ raise ValueError("Codex plugin marketplace_path must name an existing directory")
83
+ manifest_path = root / _CODEX_MARKETPLACE_MANIFEST
84
+ if manifest_path.is_symlink() or not manifest_path.is_file():
85
+ raise ValueError(
86
+ "Codex plugin marketplace is missing a regular .agents/plugins/marketplace.json"
87
+ )
88
+
89
+ files: list[Path] = []
90
+ for candidate in sorted(
91
+ root.rglob("*"),
92
+ key=lambda item: item.relative_to(root).as_posix(),
93
+ ):
94
+ relative = candidate.relative_to(root).as_posix()
95
+ if candidate.is_symlink():
96
+ raise ValueError(f"Codex plugin marketplace must not contain symlinks: {relative}")
97
+ if candidate.is_dir():
98
+ continue
99
+ if not candidate.is_file():
100
+ raise ValueError("Codex plugin marketplace may contain regular files only: " + relative)
101
+ files.append(candidate)
102
+ if len(files) > _CODEX_MARKETPLACE_MAX_FILES:
103
+ raise ValueError(
104
+ f"Codex plugin marketplace exceeds {_CODEX_MARKETPLACE_MAX_FILES} regular files"
105
+ )
106
+
107
+ digest = hashlib.sha256()
108
+ total_bytes = 0
109
+ for candidate in files:
110
+ relative = candidate.relative_to(root).as_posix()
111
+ try:
112
+ raw = candidate.read_bytes()
113
+ except OSError as exc:
114
+ raise ValueError(f"Codex plugin marketplace file cannot be read: {relative}") from exc
115
+ total_bytes += len(raw)
116
+ if total_bytes > _CODEX_MARKETPLACE_MAX_BYTES:
117
+ raise ValueError(
118
+ f"Codex plugin marketplace exceeds {_CODEX_MARKETPLACE_MAX_BYTES} content bytes"
119
+ )
120
+ digest.update(relative.encode("utf-8"))
121
+ digest.update(b"\0")
122
+ digest.update(f"{stat.S_IMODE(candidate.stat().st_mode) & 0o111:03o}".encode("ascii"))
123
+ digest.update(b"\0")
124
+ digest.update(str(len(raw)).encode("ascii"))
125
+ digest.update(b"\0")
126
+ digest.update(raw)
127
+ digest.update(b"\0")
128
+ return "sha256:" + digest.hexdigest()
129
+
130
+
131
+ @dataclass(frozen=True)
132
+ class CodexPluginBootstrap:
133
+ """Digest-pinned launch contract for one build-local Codex marketplace."""
134
+
135
+ marketplace_path: str
136
+ marketplace_name: str
137
+ plugin_names: tuple[str, ...]
138
+ snapshot_digest: str
139
+
140
+ def __post_init__(self) -> None:
141
+ root = Path(self.marketplace_path).expanduser()
142
+ if not root.is_absolute():
143
+ raise ValueError("Codex plugin marketplace_path must be absolute")
144
+ if not self.marketplace_name or len(self.marketplace_name) > 256:
145
+ raise ValueError("Codex plugin marketplace_name must be 1..256 characters")
146
+ if _CODEX_PLUGIN_NAME.fullmatch(self.marketplace_name) is None:
147
+ raise ValueError("Codex plugin marketplace_name has an unsupported format")
148
+ if not self.plugin_names:
149
+ raise ValueError("Codex plugin plugin_names must not be empty")
150
+ if any(
151
+ not isinstance(name, str)
152
+ or len(name) > 256
153
+ or _CODEX_PLUGIN_NAME.fullmatch(name) is None
154
+ for name in self.plugin_names
155
+ ):
156
+ raise ValueError("Codex plugin plugin_names contain an unsupported name")
157
+ if tuple(sorted(set(self.plugin_names))) != self.plugin_names:
158
+ raise ValueError("Codex plugin plugin_names must be unique and lock-sorted")
159
+ if _CODEX_PLUGIN_DIGEST.fullmatch(self.snapshot_digest) is None:
160
+ raise ValueError("Codex plugin snapshot_digest must be a lowercase sha256 digest")
161
+
162
+ @classmethod
163
+ def from_mapping(cls, value: Mapping[str, Any]) -> "CodexPluginBootstrap":
164
+ expected = {
165
+ "marketplace_path",
166
+ "marketplace_name",
167
+ "plugin_names",
168
+ "snapshot_digest",
169
+ }
170
+ supplied = set(value)
171
+ if supplied != expected:
172
+ missing = sorted(expected - supplied)
173
+ unexpected = sorted(supplied - expected)
174
+ details: list[str] = []
175
+ if missing:
176
+ details.append("missing " + ", ".join(missing))
177
+ if unexpected:
178
+ details.append("unexpected " + ", ".join(unexpected))
179
+ raise ValueError("invalid Codex plugin bootstrap config: " + "; ".join(details))
180
+ raw_names = value["plugin_names"]
181
+ if not isinstance(raw_names, (list, tuple)):
182
+ raise ValueError("Codex plugin plugin_names must be an array")
183
+ return cls(
184
+ marketplace_path=str(value["marketplace_path"]),
185
+ marketplace_name=str(value["marketplace_name"]),
186
+ plugin_names=tuple(raw_names),
187
+ snapshot_digest=str(value["snapshot_digest"]),
188
+ )
189
+
190
+ @property
191
+ def root(self) -> Path:
192
+ return Path(self.marketplace_path).expanduser()
193
+
194
+ @property
195
+ def manifest_path(self) -> Path:
196
+ return self.root / _CODEX_MARKETPLACE_MANIFEST
197
+
198
+ def verify(self) -> None:
199
+ """Verify bytes and the small manifest projection consumed at launch."""
200
+
201
+ try:
202
+ observed_digest = codex_marketplace_tree_digest(self.root)
203
+ except ValueError as exc:
204
+ raise CodexPluginBootstrapError("Codex plugin marketplace cannot be verified") from exc
205
+ if observed_digest != self.snapshot_digest:
206
+ raise CodexPluginBootstrapError(
207
+ "Codex plugin marketplace digest mismatch: "
208
+ f"expected {self.snapshot_digest}, observed {observed_digest}"
209
+ )
210
+ try:
211
+ raw = self.manifest_path.read_bytes()
212
+ except OSError as exc:
213
+ raise CodexPluginBootstrapError(
214
+ "Codex plugin marketplace manifest cannot be read"
215
+ ) from exc
216
+ if len(raw) > _CODEX_MARKETPLACE_MAX_MANIFEST_BYTES:
217
+ raise CodexPluginBootstrapError("Codex plugin marketplace manifest is too large")
218
+ try:
219
+ payload = json.loads(raw)
220
+ except (UnicodeDecodeError, json.JSONDecodeError) as exc:
221
+ raise CodexPluginBootstrapError(
222
+ "Codex plugin marketplace manifest is not valid UTF-8 JSON"
223
+ ) from exc
224
+ if not isinstance(payload, dict) or payload.get("name") != self.marketplace_name:
225
+ raise CodexPluginBootstrapError(
226
+ "Codex plugin marketplace manifest name does not match launch config"
227
+ )
228
+ raw_plugins = payload.get("plugins")
229
+ if not isinstance(raw_plugins, list):
230
+ raise CodexPluginBootstrapError(
231
+ "Codex plugin marketplace manifest plugins must be an array"
232
+ )
233
+ manifest_names = [item.get("name") for item in raw_plugins if isinstance(item, dict)]
234
+ missing = [name for name in self.plugin_names if manifest_names.count(name) != 1]
235
+ if missing:
236
+ raise CodexPluginBootstrapError(
237
+ "Codex plugin marketplace does not contain each pinned plugin exactly once: "
238
+ + ", ".join(missing)
239
+ )
240
+
241
+
49
242
  @dataclass(frozen=True)
50
243
  class _CapabilityRoute:
51
244
  use_proxy: bool
@@ -167,6 +360,19 @@ def _probe_requires_proxy(model: str, base: str, key: str) -> bool:
167
360
  class CodexClient(ABC):
168
361
  """codex 后端(thread/turn 生命周期)的最小接口(对齐真实 SDK 线程模型)。"""
169
362
 
363
+ async def bootstrap_plugins(self, config: CodexPluginBootstrap) -> None:
364
+ """Install one admitted plugin set before creating the first thread.
365
+
366
+ Custom clients must opt into this capability explicitly. Failing
367
+ closed prevents a plugin-bearing launch from silently running without
368
+ its locked native Codex capabilities.
369
+ """
370
+
371
+ del config
372
+ raise CodexPluginBootstrapError(
373
+ "connected Codex client does not support native plugin bootstrap"
374
+ )
375
+
170
376
  @abstractmethod
171
377
  async def start_thread(self, config: Optional[dict[str, Any]] = None) -> str:
172
378
  """新建 thread(真实 SDK ``thread_start``),返回 thread_id。"""
@@ -184,6 +390,9 @@ class CodexClient(ABC):
184
390
  产出规范化事件 dict(``{"method": ..., "params": ...}``)。"""
185
391
  raise NotImplementedError
186
392
 
393
+ async def compact_thread(self, thread_id: str) -> dict[str, Any]:
394
+ raise RuntimeError("connected Codex client does not support context compaction")
395
+
187
396
  def run_goal(
188
397
  self,
189
398
  thread_id: str,
@@ -294,6 +503,7 @@ class AsyncCodexClient(CodexClient):
294
503
  self._codex = AsyncCodex(config=config)
295
504
  self.sdk_version = sdk_version
296
505
  self._threads: dict[str, Any] = {} # thread_id -> AsyncThread
506
+ self._thread_approval_configs: dict[str, dict[str, Any]] = {}
297
507
  self._active_handles: dict[str, Any] = {} # thread_id -> 活跃 AsyncTurnHandle
298
508
  self._goal_states: dict[str, Any] = {}
299
509
  self._approval_queues: dict[str, queue.Queue[Any]] = {}
@@ -302,6 +512,109 @@ class AsyncCodexClient(CodexClient):
302
512
  self._approval_lock = threading.Lock()
303
513
  self._install_approval_bridge()
304
514
 
515
+ async def bootstrap_plugins(self, config: CodexPluginBootstrap) -> None:
516
+ """Install a pinned local marketplace on this client's App Server.
517
+
518
+ This intentionally uses the ``AsyncCodex`` object's already-owned
519
+ low-level transport. Spawning a second bridge process would install
520
+ into a different host lifecycle and would not guarantee that the
521
+ thread started below observes the same plugin inventory.
522
+ """
523
+
524
+ config.verify()
525
+ try:
526
+ from openai_codex.generated.v2_all import ( # type: ignore[import-not-found]
527
+ MarketplaceAddResponse,
528
+ PluginInstallResponse,
529
+ PluginListResponse,
530
+ )
531
+ except ImportError as exc: # pragma: no cover - guarded by __init__
532
+ raise _missing_codex_error() from exc
533
+
534
+ await self._codex._ensure_initialized()
535
+ transport = getattr(self._codex, "_client", None)
536
+ if transport is None or not callable(getattr(transport, "request", None)):
537
+ raise CodexPluginBootstrapError(
538
+ f"openai-codex {self.sdk_version} lacks the App Server request transport"
539
+ )
540
+
541
+ receipt = await transport.request(
542
+ "marketplace/add",
543
+ {
544
+ "source": str(config.root),
545
+ "refName": None,
546
+ "sparsePaths": None,
547
+ },
548
+ response_model=MarketplaceAddResponse,
549
+ )
550
+ if str(receipt.marketplace_name) != config.marketplace_name:
551
+ raise CodexPluginBootstrapError(
552
+ "Codex App Server added an unexpected marketplace: "
553
+ f"expected {config.marketplace_name!r}, got {receipt.marketplace_name!r}"
554
+ )
555
+ installed_root_value = getattr(receipt.installed_root, "root", receipt.installed_root)
556
+ try:
557
+ installed_root = Path(str(installed_root_value)).resolve(strict=True)
558
+ expected_root = config.root.resolve(strict=True)
559
+ except OSError as exc:
560
+ raise CodexPluginBootstrapError(
561
+ "Codex App Server marketplace receipt names an unavailable root"
562
+ ) from exc
563
+ if installed_root != expected_root:
564
+ raise CodexPluginBootstrapError(
565
+ "Codex App Server marketplace receipt does not match the pinned root"
566
+ )
567
+
568
+ marketplace_manifest = str(config.manifest_path.resolve(strict=True))
569
+ for plugin_name in config.plugin_names:
570
+ await transport.request(
571
+ "plugin/install",
572
+ {
573
+ "pluginName": plugin_name,
574
+ "marketplacePath": marketplace_manifest,
575
+ "remoteMarketplaceName": None,
576
+ },
577
+ response_model=PluginInstallResponse,
578
+ )
579
+
580
+ inventory = await transport.request(
581
+ "plugin/list",
582
+ {"forceRefetch": True, "cwds": None, "marketplaceKinds": None},
583
+ response_model=PluginListResponse,
584
+ )
585
+ marketplaces = [
586
+ marketplace
587
+ for marketplace in inventory.marketplaces
588
+ if str(marketplace.name) == config.marketplace_name
589
+ ]
590
+ if len(marketplaces) != 1:
591
+ raise CodexPluginBootstrapError(
592
+ "Codex App Server did not report exactly one pinned marketplace"
593
+ )
594
+ marketplace = marketplaces[0]
595
+ reported_path_value = getattr(marketplace.path, "root", marketplace.path)
596
+ if reported_path_value is None:
597
+ raise CodexPluginBootstrapError(
598
+ "Codex App Server reported the pinned marketplace as remote"
599
+ )
600
+ try:
601
+ reported_path = Path(str(reported_path_value)).resolve(strict=True)
602
+ except OSError as exc:
603
+ raise CodexPluginBootstrapError(
604
+ "Codex App Server reported an unavailable marketplace manifest"
605
+ ) from exc
606
+ if reported_path != Path(marketplace_manifest):
607
+ raise CodexPluginBootstrapError(
608
+ "Codex App Server inventory does not match the pinned marketplace path"
609
+ )
610
+ for plugin_name in config.plugin_names:
611
+ matches = [plugin for plugin in marketplace.plugins if plugin.name == plugin_name]
612
+ if len(matches) != 1 or not matches[0].installed or not matches[0].enabled:
613
+ raise CodexPluginBootstrapError(
614
+ "Codex App Server did not reconcile pinned plugin as installed and enabled: "
615
+ + plugin_name
616
+ )
617
+
305
618
  def _install_approval_bridge(self) -> None:
306
619
  """Replace the SDK's unconditional accept handler with a HITL bridge.
307
620
 
@@ -339,7 +652,7 @@ class AsyncCodexClient(CodexClient):
339
652
  "item/fileChange/requestApproval",
340
653
  }:
341
654
  return self._handle_approval_request(method, params)
342
- if method == "item/tool/requestUserInput":
655
+ if method in {"item/tool/requestUserInput", "mcpServer/elicitation/request"}:
343
656
  return self._handle_user_input_request(method, params)
344
657
  return {}
345
658
 
@@ -402,6 +715,22 @@ class AsyncCodexClient(CodexClient):
402
715
  ) -> dict[str, Any]:
403
716
  raw = dict(params or {})
404
717
  thread_id, request_queue = self._active_request_queue(raw)
718
+ policy = getattr(self, "_thread_approval_configs", {}).get(thread_id, {})
719
+ metadata = raw.get("_meta") or {}
720
+ # Full access authorizes tool execution, never OAuth login or arbitrary
721
+ # server forms. Only Codex's native, empty tool-approval form qualifies.
722
+ schema = raw.get("requestedSchema") or {}
723
+ if (
724
+ method == "mcpServer/elicitation/request"
725
+ and request_queue is not None
726
+ and isinstance(metadata, dict)
727
+ and metadata.get("codex_approval_kind") == "mcp_tool_call"
728
+ and raw.get("mode") == "form"
729
+ and schema == {"type": "object", "properties": {}}
730
+ and policy.get("sandbox") == "full-access"
731
+ and policy.get("approval_mode") == "deny_all"
732
+ ):
733
+ return {"action": "accept", "content": {}}
405
734
  interaction_id = str(
406
735
  raw.get("itemId")
407
736
  or raw.get("item_id")
@@ -416,104 +745,24 @@ class AsyncCodexClient(CodexClient):
416
745
  method=method,
417
746
  params=raw,
418
747
  )
419
- if request_queue is None:
420
- return {"answers": {}}
421
-
422
- surface_id = f"input-{interaction_id}"
423
- components: list[dict[str, Any]] = []
424
- question_components: list[dict[str, Any]] = []
425
- input_schema: dict[str, Any] = {"type": "object", "properties": {}}
426
- questions = raw.get("questions") if isinstance(raw.get("questions"), list) else []
427
- for index, raw_question in enumerate(questions):
428
- if not isinstance(raw_question, dict):
429
- continue
430
- question_id = str(raw_question.get("id") or f"question_{index + 1}")
431
- raw_options = raw_question.get("options")
432
- options = (
433
- [dict(option) for option in raw_options if isinstance(option, dict)]
434
- if isinstance(raw_options, list)
435
- else []
436
- )
437
- multiple = bool(
438
- raw_question.get("multiple")
439
- or raw_question.get("isMultiple")
440
- or raw_question.get("is_multiple")
441
- or raw_question.get("isMultiSelect")
442
- or raw_question.get("is_multi_select")
443
- )
444
- question_components.append(
445
- {
446
- "id": question_id,
447
- "component": "MultipleChoice",
448
- "props": {
449
- "name": question_id,
450
- "label": str(
451
- raw_question.get("header")
452
- or raw_question.get("question")
453
- or question_id
454
- ),
455
- "description": str(raw_question.get("question") or ""),
456
- "options": options,
457
- "multiple": multiple,
458
- "allow_other": bool(
459
- raw_question.get("isOther") or raw_question.get("is_other")
460
- ),
461
- "secret": bool(
462
- raw_question.get("isSecret") or raw_question.get("is_secret")
463
- ),
464
- },
465
- }
466
- )
467
- option_labels = [
468
- str(option.get("label") or "") for option in options if option.get("label")
469
- ]
470
- input_schema["properties"][question_id] = (
471
- {
472
- "type": "array",
473
- "items": {"type": "string", "enum": option_labels},
474
- }
475
- if multiple
476
- else {"type": "string", "enum": option_labels}
477
- )
478
- components.append(
479
- {
480
- "id": "form",
481
- "component": "Form",
482
- "props": {"title": "需要你的反馈", "submit_label": "提交"},
483
- "children": question_components,
484
- }
748
+ default_response = (
749
+ {"action": "cancel"} if method == "mcpServer/elicitation/request" else {"answers": {}}
485
750
  )
751
+ if request_queue is None:
752
+ return default_response
753
+
754
+ # Preserve the native question contract (including multiple choice and
755
+ # custom answers) for the canonical interaction mapper. Legacy A2UI
756
+ # forms cannot provide the native continuation/response correlation.
486
757
  with self._approval_lock:
487
758
  self._pending_interactions[interaction_id] = pending
488
- request_queue.put(
489
- {
490
- "method": "a2ui/surface",
491
- "params": {
492
- "surface_id": surface_id,
493
- "surface": {
494
- "catalog_id": "https://a2ui.org/specification/v0_9/basic_catalog.json",
495
- "components": components,
496
- "data_model": {},
497
- },
498
- },
499
- }
500
- )
501
- request_queue.put(
502
- {
503
- "method": "a2ui/interaction",
504
- "params": {
505
- "surface_id": surface_id,
506
- "interaction_id": interaction_id,
507
- "kind": "form",
508
- "input_schema": input_schema,
509
- "is_blocking": bool(raw.get("isBlocking", raw.get("is_blocking", True))),
510
- },
511
- }
512
- )
759
+ request_queue.put({"id": interaction_id, "method": method, "params": raw})
513
760
  pending.resolved.wait()
514
761
  with self._approval_lock:
515
762
  self._pending_interactions.pop(interaction_id, None)
516
- return pending.response or {"answers": {}}
763
+ response = pending.response or default_response
764
+ request_queue.put({"id": interaction_id, "result": dict(response)})
765
+ return response
517
766
 
518
767
  @staticmethod
519
768
  def _maybe_apply_proxy(
@@ -714,6 +963,55 @@ class AsyncCodexClient(CodexClient):
714
963
  self._threads[thread.id] = thread
715
964
  return str(thread.id)
716
965
 
966
+ async def compact_thread(self, thread_id: str) -> dict[str, Any]:
967
+ """Wait for native compaction completion, not just request admission.
968
+
969
+ The caller owns an idle, dedicated client and closes it on timeout.
970
+ No model prompt or shell command is used to emulate compaction.
971
+ """
972
+ thread = self._threads[thread_id]
973
+ low_level = self._codex._client
974
+ turn_id = None
975
+ compacted = False
976
+ usage: dict[str, Any] = {}
977
+ try:
978
+ async with asyncio.timeout(120):
979
+ before = await thread.read(include_turns=True)
980
+ previous_ids = {turn.id for turn in before.thread.turns}
981
+ await thread.compact()
982
+ # compact/start returns no turn id. The SDK buffers scoped
983
+ # notifications until their turn is registered; global reads
984
+ # deliberately exclude them. Discover the new turn first.
985
+ while turn_id is None:
986
+ current = await thread.read(include_turns=True)
987
+ new_turns = [
988
+ turn for turn in current.thread.turns if turn.id not in previous_ids
989
+ ]
990
+ if new_turns:
991
+ turn_id = new_turns[-1].id
992
+ low_level.register_turn_notifications(turn_id)
993
+ break
994
+ await asyncio.sleep(0.25)
995
+ while True:
996
+ notification = await low_level.next_turn_notification(turn_id)
997
+ event = self._notification_to_event_dict(notification) or {}
998
+ params = event.get("params") or {}
999
+ if params.get("threadId") != thread_id:
1000
+ continue
1001
+ method = event.get("method")
1002
+ if method == "item/completed":
1003
+ compacted |= (params.get("item") or {}).get("type") == "contextCompaction"
1004
+ elif method == "thread/tokenUsage/updated":
1005
+ usage = dict(params.get("tokenUsage") or {})
1006
+ elif method == "turn/completed":
1007
+ turn = params["turn"]
1008
+ if turn.get("status") != "completed" or not compacted:
1009
+ raise RuntimeError("Codex context compaction did not complete")
1010
+ return usage
1011
+ finally:
1012
+ if turn_id is not None:
1013
+ low_level.unregister_turn_notifications(turn_id)
1014
+
717
1015
  async def resume_thread(self, thread_id: str, config: Optional[dict[str, Any]] = None) -> str:
718
1016
  # An ephemeral thread has no rollout on disk, so SDK thread_resume would
719
1017
  # fail with -32600. Reuse its live AsyncThread for same-process resume.
@@ -834,6 +1132,7 @@ class AsyncCodexClient(CodexClient):
834
1132
  approval_queue: queue.Queue[Any] = queue.Queue()
835
1133
  with self._approval_lock:
836
1134
  self._approval_queues[thread_id] = approval_queue
1135
+ self._thread_approval_configs[thread_id] = dict(config or {})
837
1136
  handle = await self._start_turn(thread, self._coerce_input(prompt), config)
838
1137
  self._active_handles[thread_id] = handle
839
1138
  notifications = handle.stream()
@@ -890,6 +1189,7 @@ class AsyncCodexClient(CodexClient):
890
1189
  approval_queue: queue.Queue[Any] = queue.Queue()
891
1190
  with self._approval_lock:
892
1191
  self._approval_queues[thread_id] = approval_queue
1192
+ self._thread_approval_configs[thread_id] = dict(config or {})
893
1193
  state, _logical_turn_id = await low_level.start_goal_operation(thread_id, objective)
894
1194
  self._goal_states[thread_id] = state
895
1195
  notifications = _AsyncGoalNotificationStream(
@@ -1040,7 +1340,25 @@ class AsyncCodexClient(CodexClient):
1040
1340
  pending = self._pending_interactions.get(interaction_id)
1041
1341
  if pending is None:
1042
1342
  return False
1043
- pending.response = {"answers": answers}
1343
+ if pending.method == "mcpServer/elicitation/request":
1344
+ action = data.get("action") or {
1345
+ "cancel": "cancel",
1346
+ "skip": "decline",
1347
+ "reject": "decline",
1348
+ "deny": "decline",
1349
+ "decline": "decline",
1350
+ }.get(str(data.get("decision") or ""), "accept")
1351
+ if action not in {"accept", "decline", "cancel"}:
1352
+ raise ValueError("MCP elicitation action must be accept, decline, or cancel")
1353
+ pending.response = {"action": action}
1354
+ if action == "accept":
1355
+ pending.response["content"] = {
1356
+ key: value
1357
+ for key, value in data.items()
1358
+ if key not in {"action", "decision"}
1359
+ }
1360
+ else:
1361
+ pending.response = {"answers": answers}
1044
1362
  pending.resolved.set()
1045
1363
  return True
1046
1364
 
@@ -1060,7 +1378,11 @@ class AsyncCodexClient(CodexClient):
1060
1378
  with approval_lock:
1061
1379
  interactions = list(getattr(self, "_pending_interactions", {}).values())
1062
1380
  for interaction in interactions:
1063
- interaction.response = {"answers": {}}
1381
+ interaction.response = (
1382
+ {"action": "cancel"}
1383
+ if interaction.method == "mcpServer/elicitation/request"
1384
+ else {"answers": {}}
1385
+ )
1064
1386
  interaction.resolved.set()
1065
1387
  for thread_id, state in list(getattr(self, "_goal_states", {}).items()):
1066
1388
  try:
@@ -1189,4 +1511,10 @@ def _coerce_enum(enum_type: Any, value: Any) -> Any:
1189
1511
  ) from exc
1190
1512
 
1191
1513
 
1192
- __all__ = ["AsyncCodexClient", "CodexClient"]
1514
+ __all__ = [
1515
+ "AsyncCodexClient",
1516
+ "CodexClient",
1517
+ "CodexPluginBootstrap",
1518
+ "CodexPluginBootstrapError",
1519
+ "codex_marketplace_tree_digest",
1520
+ ]