agentengine-sdk-python 0.8.3__py3-none-any.whl → 0.8.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (509) hide show
  1. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/METADATA +9 -8
  2. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/RECORD +482 -245
  3. ksadk/_build_provenance.json +1 -1
  4. ksadk/api/client.py +105 -91
  5. ksadk/builders/code_builder.py +36 -9
  6. ksadk/builders/framework_requirements.py +2 -1
  7. ksadk/builders/ks3_uploader.py +36 -7
  8. ksadk/builders/managed_runtime_builder.py +1 -0
  9. ksadk/cli/__init__.py +32 -3
  10. ksadk/cli/cmd_managed_runtime.py +13 -1
  11. ksadk/cli/cmd_plugin.py +6 -1
  12. ksadk/cli/cmd_web.py +2 -5
  13. ksadk/cli/runtime_bootstrap.py +23 -1
  14. ksadk/codex/client.py +424 -96
  15. ksadk/codex/projection.py +24 -0
  16. ksadk/codex/runtime.py +56 -298
  17. ksadk/common/auth.py +16 -10
  18. ksadk/configs/env_registry.py +29 -1
  19. ksadk/conversations/message_projection.py +135 -14
  20. ksadk/conversations/projector.py +4 -6
  21. ksadk/conversations/runtime_invocation.py +5 -0
  22. ksadk/conversations/runtime_payloads.py +1 -0
  23. ksadk/conversations/runtime_preparation.py +30 -27
  24. ksadk/conversations/runtime_resume.py +50 -2
  25. ksadk/conversations/runtime_stream_events.py +5 -0
  26. ksadk/conversations/runtime_streaming.py +25 -7
  27. ksadk/deployment/env_forward.py +2 -2
  28. ksadk/deployment/providers/serverless.py +1 -1
  29. ksadk/events/adapters/_codex_validators.py +18 -7
  30. ksadk/events/adapters/langgraph.py +15 -1
  31. ksadk/events/canonical_store.py +3 -1
  32. ksadk/events/projections.py +1 -1
  33. ksadk/harness/config.py +2 -2
  34. ksadk/harness/runtime.py +27 -27
  35. ksadk/harness/tools.py +38 -13
  36. ksadk/interaction/provider.py +1 -0
  37. ksadk/interaction/providers/langgraph.py +1 -0
  38. ksadk/kernel/bootstrap.py +28 -4
  39. ksadk/kernel/ingress.py +15 -2
  40. ksadk/kernel/sqlite_store.py +27 -0
  41. ksadk/kernel/store.py +3 -0
  42. ksadk/kernel/worker.py +65 -10
  43. ksadk/knowledge_base/client.py +57 -27
  44. ksadk/mcp_runtime/__init__.py +12 -4
  45. ksadk/memory/adk/backends/sdk_ltm_backend.py +161 -41
  46. ksadk/memory/adk/resilient_session_service.py +25 -17
  47. ksadk/memory/adk/short_term_memory.py +26 -9
  48. ksadk/memory/models.py +7 -4
  49. ksadk/memory/provider_resolver.py +3 -0
  50. ksadk/model_proxy/server.py +10 -5
  51. ksadk/plugins/__init__.py +4 -0
  52. ksadk/plugins/artifacts.py +275 -0
  53. ksadk/plugins/bridges/__init__.py +4 -2
  54. ksadk/plugins/bridges/codex.py +120 -13
  55. ksadk/plugins/bridges/dsh.py +340 -156
  56. ksadk/plugins/builtins.py +35 -36
  57. ksadk/plugins/bundle_security.py +28 -4
  58. ksadk/plugins/codex_manifest.py +983 -0
  59. ksadk/plugins/composition.py +8 -0
  60. ksadk/plugins/contracts.py +118 -0
  61. ksadk/plugins/delivery.py +153 -0
  62. ksadk/plugins/dsh_installation_digest.py +71 -0
  63. ksadk/plugins/dsh_toolchain.py +110 -21
  64. ksadk/plugins/ecosystem_probe.py +6 -6
  65. ksadk/plugins/host.py +102 -39
  66. ksadk/plugins/kernel_adapter.py +205 -0
  67. ksadk/plugins/providers/__init__.py +23 -0
  68. ksadk/plugins/providers/bundles/dsh-knowledge/cordis.patch.yml +3 -0
  69. ksadk/plugins/providers/bundles/dsh-knowledge/index.mjs +53 -0
  70. ksadk/plugins/providers/bundles/dsh-knowledge/package.json +16 -0
  71. ksadk/plugins/providers/bundles/dsh-memory/cordis.patch.yml +3 -0
  72. ksadk/plugins/providers/bundles/dsh-memory/index.mjs +175 -0
  73. ksadk/plugins/providers/bundles/dsh-memory/package.json +16 -0
  74. ksadk/plugins/providers/bundles/dsh-platform-resources/client.mjs +166 -0
  75. ksadk/plugins/providers/bundles/dsh-platform-resources/cordis.patch.yml +3 -0
  76. ksadk/plugins/providers/bundles/dsh-platform-resources/index.mjs +9 -0
  77. ksadk/plugins/providers/bundles/dsh-platform-resources/package.json +12 -0
  78. ksadk/plugins/providers/bundles/dsh-skill-center/cordis.patch.yml +3 -0
  79. ksadk/plugins/providers/bundles/dsh-skill-center/index.mjs +125 -0
  80. ksadk/plugins/providers/bundles/dsh-skill-center/package.json +16 -0
  81. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/cordis.patch.yml +3 -0
  82. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/index.mjs +870 -0
  83. ksadk/plugins/providers/bundles/ksadk-dsh-capability-host/package.json +27 -0
  84. ksadk/plugins/providers/bundles/ksadk-dsh-studio/client.js +92 -0
  85. ksadk/plugins/providers/bundles/ksadk-dsh-studio/index.mjs +15 -0
  86. ksadk/plugins/providers/bundles/ksadk-dsh-studio/package.json +7 -0
  87. ksadk/plugins/providers/codex.py +335 -69
  88. ksadk/plugins/providers/codex_native.py +368 -0
  89. ksadk/plugins/providers/codex_turn.py +301 -0
  90. ksadk/plugins/providers/dsh_capabilities.py +1389 -0
  91. ksadk/plugins/providers/dsh_mcp.py +467 -0
  92. ksadk/plugins/providers/harness.py +118 -113
  93. ksadk/plugins/providers/mcp_projection.py +150 -0
  94. ksadk/plugins/providers/platform_resources.py +657 -0
  95. ksadk/plugins/resolver.py +8 -1
  96. ksadk/resource_runtime/__init__.py +4 -0
  97. ksadk/resource_runtime/broker.py +616 -0
  98. ksadk/resource_runtime/build_artifacts.py +165 -0
  99. ksadk/resource_runtime/contracts.py +138 -0
  100. ksadk/resource_runtime/discovery_receipts.py +100 -0
  101. ksadk/resource_runtime/discovery_skills.py +172 -0
  102. ksadk/resource_runtime/errors.py +6 -0
  103. ksadk/resource_runtime/ipc.py +142 -0
  104. ksadk/resource_runtime/kernel_approval.py +165 -0
  105. ksadk/resource_runtime/knowledge.py +114 -0
  106. ksadk/resource_runtime/langgraph.py +94 -0
  107. ksadk/resource_runtime/leases.py +191 -0
  108. ksadk/resource_runtime/managed_projection.py +186 -0
  109. ksadk/resource_runtime/mcp_server.py +138 -0
  110. ksadk/resource_runtime/memory_provider.py +318 -0
  111. ksadk/resource_runtime/memory_receipts.py +34 -0
  112. ksadk/resource_runtime/operation_ledger.py +211 -0
  113. ksadk/resource_runtime/plugin_config.py +48 -0
  114. ksadk/resource_runtime/policy_authorization.py +54 -0
  115. ksadk/resource_runtime/process.py +110 -0
  116. ksadk/resource_runtime/skill_artifacts.py +153 -0
  117. ksadk/resource_runtime/skill_runtime.py +42 -0
  118. ksadk/resource_runtime/skill_workspace.py +118 -0
  119. ksadk/resource_runtime/skills.py +215 -0
  120. ksadk/resource_runtime/snapshots.py +180 -0
  121. ksadk/resource_runtime/socket_server.py +103 -0
  122. ksadk/resource_runtime/supervisor.py +380 -0
  123. ksadk/resource_runtime/worker.py +504 -0
  124. ksadk/runners/_langgraph_runner_streams.py +74 -6
  125. ksadk/runners/adk_runner.py +149 -11
  126. ksadk/runners/base_runner.py +29 -1
  127. ksadk/runners/langgraph_runner.py +475 -145
  128. ksadk/runtime/_runner_adapter/stream_mapping.py +142 -18
  129. ksadk/runtime/adapter.py +2 -0
  130. ksadk/runtime/conversation_execution.py +92 -16
  131. ksadk/runtime/executor.py +78 -2
  132. ksadk/runtime/factory.py +29 -273
  133. ksadk/runtime/framework_adapters.py +23 -0
  134. ksadk/runtime/preprocessing.py +10 -2
  135. ksadk/runtime/runner_adapter.py +73 -14
  136. ksadk/runtime_context.py +40 -2
  137. ksadk/sandbox/backends/e2b.py +52 -11
  138. ksadk/sandbox/backends/local_process.py +9 -0
  139. ksadk/sandbox/base.py +2 -0
  140. ksadk/sandbox/e2b_connection.py +66 -0
  141. ksadk/scheduler/sqlite_store.py +18 -0
  142. ksadk/server/composition.py +2 -0
  143. ksadk/server/factory.py +5 -0
  144. ksadk/server/persistence_capability.py +516 -0
  145. ksadk/server/routes/control.py +210 -46
  146. ksadk/server/routes/dependencies.py +15 -0
  147. ksadk/server/routes/models.py +47 -4
  148. ksadk/server/routes/projection.py +252 -12
  149. ksadk/server/routes/sessions.py +284 -107
  150. ksadk/server/routes/streaming.py +43 -9
  151. ksadk/server/static/assets/{ArtifactsPanel-10GPXIJ6.js → ArtifactsPanel-CGbWlMNh.js} +1 -1
  152. ksadk/server/static/assets/{CodeBlock-BXk1l-G1.js → CodeBlock-b4C7upmO.js} +3 -3
  153. ksadk/server/static/assets/{MathMessageMarkdown-D9uB55Oh.js → MathMessageMarkdown-DbdW5A4_.js} +4 -4
  154. ksadk/server/static/assets/{MermaidBlock--OEYoXIJ.js → MermaidBlock-BEBN4Ksz.js} +6 -6
  155. ksadk/server/static/assets/{NativeTerminalPanel-DrEe1syq.js → NativeTerminalPanel-zvL-WpAn.js} +1 -1
  156. ksadk/server/static/assets/{abnfDiagram-VCTEODGH-eeTFJLvo.js → abnfDiagram-VCTEODGH-BYafW7Za.js} +1 -1
  157. ksadk/server/static/assets/{arc-S3ZNbIAd.js → arc-bTohInsS.js} +1 -1
  158. ksadk/server/static/assets/architecture-7GRP2DOG-BW5UtSnx.js +1 -0
  159. ksadk/server/static/assets/{architectureDiagram-5GKGNRK7-CRjgEJDX.js → architectureDiagram-5GKGNRK7-Ch5Lbzsi.js} +1 -1
  160. ksadk/server/static/assets/{blockDiagram-NRAW4CY4-C7bsBoNH.js → blockDiagram-NRAW4CY4-kqF4MDOG.js} +1 -1
  161. ksadk/server/static/assets/{c4Diagram-UCG6FXSJ-BX3c33Ob.js → c4Diagram-UCG6FXSJ-8uSRIODv.js} +1 -1
  162. ksadk/server/static/assets/channel-CF5Up3hQ.js +1 -0
  163. ksadk/server/static/assets/chunk-2Q5K7J3B-KkXX47WI.js +1 -0
  164. ksadk/server/static/assets/{chunk-5VM5RSS4-bZ7ws-8m.js → chunk-5VM5RSS4-DkhehZDr.js} +1 -1
  165. ksadk/server/static/assets/{chunk-F27PBJKO-D2r0pvhY.js → chunk-F27PBJKO-BdXhtPe9.js} +1 -1
  166. ksadk/server/static/assets/{chunk-G27WJ6UU-CZwF3oUP.js → chunk-G27WJ6UU-DPTpvpwi.js} +1 -1
  167. ksadk/server/static/assets/{chunk-JWPE2WC7-DigFYCML.js → chunk-JWPE2WC7-Pqoh38el.js} +1 -1
  168. ksadk/server/static/assets/{chunk-LCL6LL3I-CnorGV5q.js → chunk-LCL6LL3I-DeU00qC-.js} +1 -1
  169. ksadk/server/static/assets/{chunk-POPQ4Y6H-CexntQA-.js → chunk-POPQ4Y6H-CzxScFkr.js} +1 -1
  170. ksadk/server/static/assets/{chunk-RHFEMEQ7-CHTC7UxA.js → chunk-RHFEMEQ7-DpqMx-ux.js} +1 -1
  171. ksadk/server/static/assets/{chunk-SVP7TREG-BC1EWt_-.js → chunk-SVP7TREG-C6t0SypQ.js} +1 -1
  172. ksadk/server/static/assets/{chunk-XXDRQBXY-BTG24xN0.js → chunk-XXDRQBXY-DVaeafZk.js} +1 -1
  173. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Cz81acRQ.js +1 -0
  174. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Cz81acRQ.js +1 -0
  175. ksadk/server/static/assets/{cose-bilkent-JH36ORCC-CkonRdAS.js → cose-bilkent-JH36ORCC-Bf9D3tzJ.js} +1 -1
  176. ksadk/server/static/assets/cynefin-OW5HDTMX-DVWs8a2t.js +1 -0
  177. ksadk/server/static/assets/{cynefinDiagram-5FMLGOSQ-DEOCBe15.js → cynefinDiagram-5FMLGOSQ-B9cY3iTz.js} +1 -1
  178. ksadk/server/static/assets/{dagre-3AP2YEHR-DBThPuLa.js → dagre-3AP2YEHR-CSwlx3CB.js} +1 -1
  179. ksadk/server/static/assets/{dagre-ClTPrTht.js → dagre-UBpgon5q.js} +1 -1
  180. ksadk/server/static/assets/{diagram-S7CK7UJ4-DsZHrnpJ.js → diagram-S7CK7UJ4-C9akhN9a.js} +1 -1
  181. ksadk/server/static/assets/{diagram-UQ7AKVKN-BJR4nhVr.js → diagram-UQ7AKVKN-CgedhTPI.js} +1 -1
  182. ksadk/server/static/assets/{diagram-VSXAHHWV-xzcERX0a.js → diagram-VSXAHHWV-Cjucz5BY.js} +1 -1
  183. ksadk/server/static/assets/{diagram-VX7I27RA-tn2xM1xu.js → diagram-VX7I27RA-Dd4Vleyn.js} +1 -1
  184. ksadk/server/static/assets/{diagram-Z3DM3KII-BZPGBkw5.js → diagram-Z3DM3KII-CZ2jGtYW.js} +1 -1
  185. ksadk/server/static/assets/{dist-DdRBIceA.js → dist-B2_CVgKv.js} +1 -1
  186. ksadk/server/static/assets/{dist-Cq4OL6nO.js → dist-B3FR1SKK.js} +1 -1
  187. ksadk/server/static/assets/{dist-M67Hwu0n.js → dist-BIr4DSRq.js} +1 -1
  188. ksadk/server/static/assets/{dist-B1oWRmrH.js → dist-BgV_owcB.js} +1 -1
  189. ksadk/server/static/assets/{dist-DyqV4fL4.js → dist-Bj730Ib4.js} +1 -1
  190. ksadk/server/static/assets/{dist-DfGFrb0v.js → dist-BnaTiyzN.js} +1 -1
  191. ksadk/server/static/assets/{dist-C71CsujO.js → dist-C1NMAY5a.js} +1 -1
  192. ksadk/server/static/assets/{dist-CXpH_Rdd.js → dist-C5_ZAZsG.js} +1 -1
  193. ksadk/server/static/assets/{dist-DJmCPRVB.js → dist-CB9iJrvg.js} +1 -1
  194. ksadk/server/static/assets/{dist-DjhwGUgZ.js → dist-CFzsn6BG.js} +1 -1
  195. ksadk/server/static/assets/{dist-BI1qQH4n.js → dist-Cf125P_m.js} +1 -1
  196. ksadk/server/static/assets/{dist-8VWI-2bZ.js → dist-ClYUxfeK.js} +1 -1
  197. ksadk/server/static/assets/{dist-DUwKa_l6.js → dist-DFD6Qa6T.js} +1 -1
  198. ksadk/server/static/assets/{dist-B-46q3Hk.js → dist-DVCOWtha.js} +1 -1
  199. ksadk/server/static/assets/{dist-BJLUwH6W.js → dist-D_ctSS2i.js} +1 -1
  200. ksadk/server/static/assets/{dist-4zN1_tq5.js → dist-DiixqL0J.js} +1 -1
  201. ksadk/server/static/assets/{dist-B0gdk4rl.js → dist-DoVSwoDb.js} +1 -1
  202. ksadk/server/static/assets/{dist-Bbwqa8TG.js → dist-DvFK7p5S.js} +1 -1
  203. ksadk/server/static/assets/{dist-D1V3f1B4.js → dist-QfkEHOlb.js} +1 -1
  204. ksadk/server/static/assets/{dist-Btyo4vX4.js → dist-btbmmX5O.js} +1 -1
  205. ksadk/server/static/assets/{dist-u8tVH5Ak.js → dist-fBO2v5Kt.js} +1 -1
  206. ksadk/server/static/assets/{dist-DQAB0qn_.js → dist-ufY3F5p6.js} +1 -1
  207. ksadk/server/static/assets/{ebnfDiagram-PWID7BFC-DVfMsLge.js → ebnfDiagram-PWID7BFC-Ci8NqqZu.js} +1 -1
  208. ksadk/server/static/assets/{erDiagram-SSCWMZ5O-CWEZSYaw.js → erDiagram-SSCWMZ5O-CCIOhLZG.js} +1 -1
  209. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CQqR2hg3.js +1 -0
  210. ksadk/server/static/assets/flowDiagram-A5DVABFB-DDRRbGPm.js +1 -0
  211. ksadk/server/static/assets/{ganttDiagram-EL5Y4UJY-TWIxoyYL.js → ganttDiagram-EL5Y4UJY-Cp_r9Hb6.js} +1 -1
  212. ksadk/server/static/assets/gitGraph-4MIJSDKK-fgWEf7UD.js +1 -0
  213. ksadk/server/static/assets/{gitGraphDiagram-WWUBYQGX-DDh2hd2S.js → gitGraphDiagram-WWUBYQGX-Dlhc8Wr8.js} +1 -1
  214. ksadk/server/static/assets/index-DcTML1Up.css +2 -0
  215. ksadk/server/static/assets/index-Dh2XHqPK.js +244 -0
  216. ksadk/server/static/assets/info-A6RAGUB7-BUecLTdt.js +1 -0
  217. ksadk/server/static/assets/{infoDiagram-RXCK75RN-CgoyWiDR.js → infoDiagram-RXCK75RN-CO0rRTRA.js} +1 -1
  218. ksadk/server/static/assets/{ishikawaDiagram-5VMMS53U-CyRIu_om.js → ishikawaDiagram-5VMMS53U-CHiaedSS.js} +1 -1
  219. ksadk/server/static/assets/{journeyDiagram-EYS64GPL-DN5JXHzN.js → journeyDiagram-EYS64GPL-CHcCIB09.js} +1 -1
  220. ksadk/server/static/assets/{kanban-definition-3QL26DDD-CNP3ui66.js → kanban-definition-3QL26DDD-CJ_ebBZf.js} +1 -1
  221. ksadk/server/static/assets/{katex-DWEzQy1d.js → katex-B4weu383.js} +1 -1
  222. ksadk/server/static/assets/{linear-C-qHp7d2.js → linear-V-MgYHW1.js} +1 -1
  223. ksadk/server/static/assets/{mermaid-parser.core-Cl-K943T.js → mermaid-parser.core-CBijEX_c.js} +2 -2
  224. ksadk/server/static/assets/{mindmap-definition-FBJOCRG2-D5DB5mYm.js → mindmap-definition-FBJOCRG2-Bc-pQvpp.js} +1 -1
  225. ksadk/server/static/assets/packet-AYTQ26CC-BeW-btFv.js +1 -0
  226. ksadk/server/static/assets/{pegDiagram-XKGWAZYB-BQVc9ia_.js → pegDiagram-XKGWAZYB-D7genGLl.js} +1 -1
  227. ksadk/server/static/assets/pie-WAS4IAKB-X0xh4SaT.js +1 -0
  228. ksadk/server/static/assets/{pieDiagram-E7YTZNPT-B6UCAvtY.js → pieDiagram-E7YTZNPT-Bxj32zwD.js} +1 -1
  229. ksadk/server/static/assets/{quadrantDiagram-AXDQQJYC-mIr2d3eb.js → quadrantDiagram-AXDQQJYC-BURv2mGh.js} +1 -1
  230. ksadk/server/static/assets/radar-RG4KPBEZ-DzRMSqjd.js +1 -0
  231. ksadk/server/static/assets/railroad-74A4TZTK-Cc44icX-.js +1 -0
  232. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-D6S4BdV-.js +1 -0
  233. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-vD3aVE2o.js +1 -0
  234. ksadk/server/static/assets/railroad-peg-WCYAUIDC-CYbW_b4T.js +1 -0
  235. ksadk/server/static/assets/{railroadDiagram-O6MQD6OU-Dt3FFDmK.js → railroadDiagram-O6MQD6OU-CCsh3avW.js} +1 -1
  236. ksadk/server/static/assets/{requirementDiagram-EFPCY7ZU-Cz_vQtgF.js → requirementDiagram-EFPCY7ZU-_FRRBKEd.js} +1 -1
  237. ksadk/server/static/assets/{sankeyDiagram-P5KCCOFB-wlO1TsH5.js → sankeyDiagram-P5KCCOFB-C-gr2o9M.js} +1 -1
  238. ksadk/server/static/assets/{sequenceDiagram-WJ2MYXX4-CHRbElYq.js → sequenceDiagram-WJ2MYXX4-D97NmfKg.js} +1 -1
  239. ksadk/server/static/assets/{sizeCapture-X5ZJPWSS-DXX54iyO.js → sizeCapture-X5ZJPWSS-DjrPC5FX.js} +1 -1
  240. ksadk/server/static/assets/{stateDiagram-HBIQ2CUA-Dp_lw9II.js → stateDiagram-HBIQ2CUA-DzMNg1hh.js} +1 -1
  241. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BIcjKFhF.js +1 -0
  242. ksadk/server/static/assets/{swimlanes-XN3QIQJK-D8O5UlLG.js → swimlanes-XN3QIQJK-Cssf_CsU.js} +1 -1
  243. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-tq3K3Ybl.js +8 -0
  244. ksadk/server/static/assets/{timeline-definition-24CTP7MA-8mfKcxvG.js → timeline-definition-24CTP7MA-BWTHzyS1.js} +1 -1
  245. ksadk/server/static/assets/treeView-Q6P3EWNA-DBXt3GdU.js +1 -0
  246. ksadk/server/static/assets/treemap-WGGIJYW6-DrCy4E_l.js +1 -0
  247. ksadk/server/static/assets/{vennDiagram-4TSXK5OY-EnNl0DE7.js → vennDiagram-4TSXK5OY-BSKgJsmR.js} +1 -1
  248. ksadk/server/static/assets/wardley-WFR3VGLG-CefhOliM.js +1 -0
  249. ksadk/server/static/assets/{wardleyDiagram-VM6X3IG4-DBu5fbYr.js → wardleyDiagram-VM6X3IG4-eflHNoaZ.js} +1 -1
  250. ksadk/server/static/assets/{xychartDiagram-S5SC5T6Z-BSVXs4IY.js → xychartDiagram-S5SC5T6Z-eYqrQ-v4.js} +1 -1
  251. ksadk/server/static/index.html +2 -2
  252. ksadk/session_context.py +66 -0
  253. ksadk/sessions/__init__.py +11 -21
  254. ksadk/sessions/_local_service_sync.py +263 -1
  255. ksadk/sessions/base.py +176 -0
  256. ksadk/sessions/errors.py +4 -0
  257. ksadk/sessions/in_memory.py +309 -19
  258. ksadk/sessions/local_service.py +83 -1
  259. ksadk/sessions/persistence.py +275 -0
  260. ksadk/sessions/postgres_service.py +358 -0
  261. ksadk/sessions/resilience.py +8 -0
  262. ksadk/sessions/resilient.py +362 -4
  263. ksadk/sessions/topology.py +135 -0
  264. ksadk/skills/models.py +26 -4
  265. ksadk/skills/package_store.py +186 -38
  266. ksadk/skills/runtime/agent.py +31 -6
  267. ksadk/skills/runtime/artifact_delivery.py +139 -0
  268. ksadk/skills/runtime/backends/e2b.py +98 -6
  269. ksadk/skills/runtime/backends/local.py +73 -8
  270. ksadk/skills/runtime/base.py +3 -0
  271. ksadk/skills/runtime/executor.py +2 -0
  272. ksadk/skills/runtime/loader.py +10 -2
  273. ksadk/skills/runtime/pinned.py +114 -0
  274. ksadk/skills/runtime/request.py +31 -0
  275. ksadk/skills/service_client.py +167 -28
  276. ksadk/studio/api.py +224 -42
  277. ksadk/studio/api_catalog_routes.py +18 -0
  278. ksadk/studio/api_plugin_routes.py +526 -95
  279. ksadk/studio/api_resource_connections.py +183 -0
  280. ksadk/studio/authoring_coordinator.py +19 -14
  281. ksadk/studio/builder.py +76 -0
  282. ksadk/studio/cloud.py +342 -104
  283. ksadk/studio/cloud_shared_web.py +565 -0
  284. ksadk/studio/codex_agent_service.py +128 -26
  285. ksadk/studio/codex_builder.py +241 -2
  286. ksadk/studio/codex_credentials.py +90 -0
  287. ksadk/studio/codex_manifest.py +31 -4
  288. ksadk/studio/codex_plugin_store.py +746 -0
  289. ksadk/studio/codex_provider_build.py +231 -0
  290. ksadk/studio/codex_run.py +184 -25
  291. ksadk/studio/compatibility_report.py +12 -1
  292. ksadk/studio/compiler.py +78 -14
  293. ksadk/studio/contracts.py +132 -6
  294. ksadk/studio/dsh_application.py +137 -0
  295. ksadk/studio/dsh_capability_service.py +1107 -0
  296. ksadk/studio/dsh_models.py +59 -0
  297. ksadk/studio/dsh_provider_registration.py +320 -13
  298. ksadk/studio/hosted_kernel.py +88 -13
  299. ksadk/studio/mcp_runtime.py +11 -3
  300. ksadk/studio/model_client.py +2 -2
  301. ksadk/studio/plugin_composition.py +190 -23
  302. ksadk/studio/plugin_kernel_adapter.py +12 -112
  303. ksadk/studio/plugin_runtime.py +224 -45
  304. ksadk/studio/resource_authority.py +637 -0
  305. ksadk/studio/resource_binding_validation.py +77 -0
  306. ksadk/studio/resource_build_admission.py +196 -0
  307. ksadk/studio/resource_build_materializer.py +149 -0
  308. ksadk/studio/resource_catalog.py +143 -2
  309. ksadk/studio/resource_connections.py +220 -0
  310. ksadk/studio/run_service.py +462 -52
  311. ksadk/studio/runtime_source.py +15 -7
  312. ksadk/studio/scheduler_assistant.py +317 -0
  313. ksadk/studio/scheduler_runtime.py +9 -0
  314. ksadk/studio/scheduler_service.py +3 -0
  315. ksadk/studio/service.py +490 -44
  316. ksadk/studio/shared_web.py +446 -62
  317. ksadk/studio/static/assets/CodeBlock-DCUUY0PL-BLjA7kbS.js +41 -0
  318. ksadk/studio/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  319. ksadk/studio/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  320. ksadk/studio/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  321. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  322. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  323. ksadk/studio/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  324. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  325. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  326. ksadk/studio/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  327. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  328. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  329. ksadk/studio/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  330. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  331. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  332. ksadk/studio/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  333. ksadk/studio/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  334. ksadk/studio/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  335. ksadk/studio/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  336. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  337. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  338. ksadk/studio/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  339. ksadk/studio/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  340. ksadk/studio/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  341. ksadk/studio/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  342. ksadk/studio/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  343. ksadk/studio/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  344. ksadk/studio/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  345. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  346. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  347. ksadk/studio/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  348. ksadk/studio/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  349. ksadk/studio/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  350. ksadk/studio/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  351. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  352. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  353. ksadk/studio/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  354. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  355. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  356. ksadk/studio/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  357. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  358. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  359. ksadk/studio/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  360. ksadk/studio/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  361. ksadk/studio/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  362. ksadk/studio/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  363. ksadk/studio/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  364. ksadk/studio/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  365. ksadk/studio/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  366. ksadk/studio/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  367. ksadk/studio/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  368. ksadk/studio/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  369. ksadk/studio/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  370. ksadk/studio/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  371. ksadk/studio/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  372. ksadk/studio/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  373. ksadk/studio/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  374. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  375. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  376. ksadk/studio/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  377. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--BEOyPC3w.css +1 -0
  378. ksadk/studio/static/assets/MathMessageMarkdown-CBcDrAw--CUYIXwgI.js +8 -0
  379. ksadk/studio/static/assets/MermaidBlock-DBFTztfQ-BTYKWEbD.js +44 -0
  380. ksadk/studio/static/assets/PrismRenderer-wiXRHURw.js +3 -0
  381. ksadk/studio/static/assets/abnfDiagram-VCTEODGH-CLETGjKq.js +1 -0
  382. ksadk/studio/static/assets/arc-Pry-7G1_.js +1 -0
  383. ksadk/studio/static/assets/architecture-7GRP2DOG-hXMiO_AU.js +1 -0
  384. ksadk/studio/static/assets/architectureDiagram-5GKGNRK7-B5EQysk6.js +36 -0
  385. ksadk/studio/static/assets/array-BifhSqXX.js +1 -0
  386. ksadk/studio/static/assets/blockDiagram-I7D4REHJ-CFmPl1de.js +129 -0
  387. ksadk/studio/static/assets/c4Diagram-7LVT6UL2-BRrGu8qt.js +38 -0
  388. ksadk/studio/static/assets/channel-BqO-gtEw.js +1 -0
  389. ksadk/studio/static/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  390. ksadk/studio/static/assets/chunk-4HAMMTFA-D220vUtq.js +62 -0
  391. ksadk/studio/static/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  392. ksadk/studio/static/assets/chunk-75Z2AOVW-C8lLv_qc.js +2 -0
  393. ksadk/studio/static/assets/chunk-DU6HZSFF-C4DtVpCu.js +128 -0
  394. ksadk/studio/static/assets/chunk-F27PBJKO-Cpw14SNG.js +1 -0
  395. ksadk/studio/static/assets/chunk-FOHPRMQF-DHwB1DNv.js +161 -0
  396. ksadk/studio/static/assets/chunk-GMAD6QVW-DiQA-u2N.js +72 -0
  397. ksadk/studio/static/assets/chunk-GVQU2GXP-DUdNBUCi.js +1 -0
  398. ksadk/studio/static/assets/chunk-IMKFNOWR-BSlbjT_b.js +231 -0
  399. ksadk/studio/static/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  400. ksadk/studio/static/assets/chunk-L3NEJ4N5-Db8Ab22W.js +1 -0
  401. ksadk/studio/static/assets/chunk-OSK3NFVY-M2m6G3j4.js +10 -0
  402. ksadk/studio/static/assets/chunk-P2QGCYS3-DezaQxiK.js +1 -0
  403. ksadk/studio/static/assets/chunk-POPQ4Y6H-DOpufJ3t.js +1 -0
  404. ksadk/studio/static/assets/chunk-PWAF6VOD-CfLb1gSc.js +1 -0
  405. ksadk/studio/static/assets/chunk-SHT3W25Y-DAyIVp5H.js +168 -0
  406. ksadk/studio/static/assets/chunk-SVP7TREG-DulomOrS.js +88 -0
  407. ksadk/studio/static/assets/chunk-TICWLB2K-bHJYoflj.js +206 -0
  408. ksadk/studio/static/assets/chunk-XXDRQBXY-7PcdR2B1.js +1 -0
  409. ksadk/studio/static/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  410. ksadk/studio/static/assets/classDiagram-ZZMXUADV-D_bW8JjA.js +1 -0
  411. ksadk/studio/static/assets/classDiagram-v2-VYDZK3BY-D_bW8JjA.js +1 -0
  412. ksadk/studio/static/assets/cose-bilkent-JH36ORCC-snL88wkX.js +1 -0
  413. ksadk/studio/static/assets/cynefin-OW5HDTMX-Bd1YhRo1.js +1 -0
  414. ksadk/studio/static/assets/cynefinDiagram-5FMLGOSQ-BBrIG_mI.js +62 -0
  415. ksadk/studio/static/assets/cytoscape.esm-CGd-uY3x.js +321 -0
  416. ksadk/studio/static/assets/dagre-GXQ25YYZ-DtF1nGdY.js +4 -0
  417. ksadk/studio/static/assets/dagre-PrKaheQc.js +1 -0
  418. ksadk/studio/static/assets/defaultLocale-BFoDCU3G.js +1 -0
  419. ksadk/studio/static/assets/diagram-S7CK7UJ4-0BZ98mya.js +30 -0
  420. ksadk/studio/static/assets/diagram-UQ7AKVKN-6mLKEo6L.js +41 -0
  421. ksadk/studio/static/assets/diagram-VSXAHHWV-CJBIaiZ2.js +3 -0
  422. ksadk/studio/static/assets/diagram-VX7I27RA-BohLEE1C.js +24 -0
  423. ksadk/studio/static/assets/diagram-Z3DM3KII-D8KIGonG.js +24 -0
  424. ksadk/studio/static/assets/dist-v5Q1xZ2K.js +1 -0
  425. ksadk/studio/static/assets/ebnfDiagram-PWID7BFC-C99HU61t.js +1 -0
  426. ksadk/studio/static/assets/erDiagram-RLTQ6QDP-DLGry2Ap.js +99 -0
  427. ksadk/studio/static/assets/eventmodeling-NTZA5JFV-B1_5Ac8j.js +1 -0
  428. ksadk/studio/static/assets/flowDiagram-HODETNUW-DD5hmicn.js +1 -0
  429. ksadk/studio/static/assets/ganttDiagram-EL5Y4UJY-BPJrVLSG.js +292 -0
  430. ksadk/studio/static/assets/gitGraph-4MIJSDKK-Cy_ZQBGi.js +1 -0
  431. ksadk/studio/static/assets/gitGraphDiagram-WWUBYQGX-CZCUz4MT.js +106 -0
  432. ksadk/studio/static/assets/graphlib-DS17s2tU.js +1 -0
  433. ksadk/studio/static/assets/index-CeHL9ARV.css +2 -0
  434. ksadk/studio/static/assets/index-D9QEcVpL.js +320 -0
  435. ksadk/studio/static/assets/info-A6RAGUB7-DBzDQB_I.js +1 -0
  436. ksadk/studio/static/assets/infoDiagram-27XIBGKW-B-sq07Hi.js +2 -0
  437. ksadk/studio/static/assets/init-C-OQMol4.js +1 -0
  438. ksadk/studio/static/assets/ishikawaDiagram-5VMMS53U-CljI2wyf.js +70 -0
  439. ksadk/studio/static/assets/journeyDiagram-3NMN7TZE-D50Fo2sL.js +139 -0
  440. ksadk/studio/static/assets/kanban-definition-UXKFOSKX-DimfOTam.js +89 -0
  441. ksadk/studio/static/assets/katex-DhON-x74.js +257 -0
  442. ksadk/studio/static/assets/line-CX5BOOUP.js +1 -0
  443. ksadk/studio/static/assets/linear-BCxN9JLv.js +1 -0
  444. ksadk/studio/static/assets/mermaid-parser.core-BdCz8fkS.js +7 -0
  445. ksadk/studio/static/assets/mindmap-definition-YA3MSWOX-Bizzqy5R.js +96 -0
  446. ksadk/studio/static/assets/ordinal-BDEzSJ7C.js +1 -0
  447. ksadk/studio/static/assets/packet-AYTQ26CC-gPln-_kG.js +1 -0
  448. ksadk/studio/static/assets/path-fybaL0A-.js +1 -0
  449. ksadk/studio/static/assets/pegDiagram-XKGWAZYB-Dy3fB-gW.js +1 -0
  450. ksadk/studio/static/assets/pie-WAS4IAKB-qZdHMr7B.js +1 -0
  451. ksadk/studio/static/assets/pieDiagram-E7YTZNPT-B9mrFSDF.js +39 -0
  452. ksadk/studio/static/assets/quadrantDiagram-AXDQQJYC-NzUfCbMR.js +7 -0
  453. ksadk/studio/static/assets/radar-RG4KPBEZ-BZlnaea9.js +1 -0
  454. ksadk/studio/static/assets/railroad-74A4TZTK-Ce3__H9c.js +1 -0
  455. ksadk/studio/static/assets/railroad-abnf-HS5TGJTU-DqQn7EzD.js +1 -0
  456. ksadk/studio/static/assets/railroad-ebnf-LZEXJU2U-B55kCA8F.js +1 -0
  457. ksadk/studio/static/assets/railroad-peg-WCYAUIDC-DfQnvkHd.js +1 -0
  458. ksadk/studio/static/assets/railroadDiagram-O6MQD6OU-DnhMjZCk.js +1 -0
  459. ksadk/studio/static/assets/requirementDiagram-BXWQKSXE-BF3d103U.js +84 -0
  460. ksadk/studio/static/assets/rolldown-runtime-Dy4uBu1J-DK3Fl9T5.js +1 -0
  461. ksadk/studio/static/assets/rough.esm-Dy-Kn_BL.js +1 -0
  462. ksadk/studio/static/assets/sankeyDiagram-P5KCCOFB-Bo-JTwt0.js +40 -0
  463. ksadk/studio/static/assets/sequenceDiagram-WJ2MYXX4-Dh4wZtUm.js +162 -0
  464. ksadk/studio/static/assets/sizeCapture-INFHLROL-B0uUizjq.js +1 -0
  465. ksadk/studio/static/assets/src-SFn9St9H.js +1 -0
  466. ksadk/studio/static/assets/stateDiagram-D77RDMKH-DH774G6d.js +1 -0
  467. ksadk/studio/static/assets/stateDiagram-v2-MP3YSRHH-DZvVWPBo.js +1 -0
  468. ksadk/studio/static/assets/swimlanes-42K2YHIH-Bl13OvTX.js +1 -0
  469. ksadk/studio/static/assets/swimlanesDiagram-VR7AAH4N-BnFOTALJ.js +8 -0
  470. ksadk/studio/static/assets/timeline-definition-24CTP7MA-DxmSSjRB.js +120 -0
  471. ksadk/studio/static/assets/treeView-Q6P3EWNA-D5Nn9Swz.js +1 -0
  472. ksadk/studio/static/assets/treemap-WGGIJYW6-CgHgnQhE.js +1 -0
  473. ksadk/studio/static/assets/vennDiagram-4TSXK5OY-B9QEXcJq.js +34 -0
  474. ksadk/studio/static/assets/wardley-WFR3VGLG-DXrK2RRY.js +1 -0
  475. ksadk/studio/static/assets/wardleyDiagram-VM6X3IG4-Ba1AOWoe.js +78 -0
  476. ksadk/studio/static/assets/xychartDiagram-S5SC5T6Z-Cr5pt5Y-.js +7 -0
  477. ksadk/studio/static/index.html +2 -2
  478. ksadk/version.py +1 -1
  479. ksadk/server/static/assets/architecture-7GRP2DOG-Dk9nRQ6-.js +0 -1
  480. ksadk/server/static/assets/channel-s354Yo6o.js +0 -1
  481. ksadk/server/static/assets/chunk-2Q5K7J3B-CDpPpKR5.js +0 -1
  482. ksadk/server/static/assets/classDiagram-DTDB5LWJ-Dd0nucl9.js +0 -1
  483. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-Dd0nucl9.js +0 -1
  484. ksadk/server/static/assets/cynefin-OW5HDTMX-BBlT4uMf.js +0 -1
  485. ksadk/server/static/assets/eventmodeling-NTZA5JFV-Dr5okd8V.js +0 -1
  486. ksadk/server/static/assets/flowDiagram-A5DVABFB-VEO-cVcO.js +0 -1
  487. ksadk/server/static/assets/gitGraph-4MIJSDKK-CKiKY9Cf.js +0 -1
  488. ksadk/server/static/assets/index-B2k_urY8.js +0 -241
  489. ksadk/server/static/assets/index-ILPt6IWF.css +0 -2
  490. ksadk/server/static/assets/info-A6RAGUB7-ubA4Nm_p.js +0 -1
  491. ksadk/server/static/assets/packet-AYTQ26CC-C7R3NUlK.js +0 -1
  492. ksadk/server/static/assets/pie-WAS4IAKB-BIT6qjr3.js +0 -1
  493. ksadk/server/static/assets/radar-RG4KPBEZ-l5noef9X.js +0 -1
  494. ksadk/server/static/assets/railroad-74A4TZTK-Baea6ZvM.js +0 -1
  495. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-OKn8zZnU.js +0 -1
  496. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-DdKAKC4l.js +0 -1
  497. ksadk/server/static/assets/railroad-peg-WCYAUIDC-Bds8udlG.js +0 -1
  498. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-5b-8o2iS.js +0 -1
  499. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-uf6WPRA4.js +0 -8
  500. ksadk/server/static/assets/treeView-Q6P3EWNA-CK5CSrSO.js +0 -1
  501. ksadk/server/static/assets/treemap-WGGIJYW6-Ch2BKgAM.js +0 -1
  502. ksadk/server/static/assets/wardley-WFR3VGLG-YW3Q0ml_.js +0 -1
  503. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +0 -3
  504. ksadk/studio/static/assets/index-DXs1Eq4M.css +0 -1
  505. ksadk/studio/static/assets/index-DeDqwTsD.js +0 -283
  506. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/WHEEL +0 -0
  507. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/entry_points.txt +0 -0
  508. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/licenses/LICENSE +0 -0
  509. {agentengine_sdk_python-0.8.3.dist-info → agentengine_sdk_python-0.8.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,368 @@
1
+ """Official Codex provider's native assembly; no PluginHost or default-registry recursion.
2
+
3
+ Both the legacy runtime registration and the admitted AgentProvider use this
4
+ factory. Policy and input projection belong here; native lifecycle and events
5
+ remain in CodexRuntimeAdapter.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import dataclasses
10
+ import hashlib
11
+ import json
12
+ import os
13
+ import re
14
+ import shutil
15
+ import tempfile
16
+ from collections.abc import Mapping
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ from ksadk.codex.client import AsyncCodexClient, CodexPluginBootstrap
21
+ from ksadk.plugins.providers.codex_turn import CodexTurnProjector
22
+ from ksadk.resource_runtime.managed_projection import native_codex_plugin_bindings
23
+ from ksadk.runtime.adapter import RuntimeAdapter, RuntimeRegistry
24
+ from ksadk.runtime.launch import RuntimeLaunchContext
25
+
26
+
27
+ def codex_request_config(context: RuntimeLaunchContext) -> dict[str, Any]:
28
+ """Project admitted Codex policy into native turn defaults."""
29
+ config = dict(context.config)
30
+ prompt = str(config.get("prompt") or "").strip()
31
+ task_prompt = str(config.get("task_prompt") or "").strip()
32
+ base_instructions = prompt
33
+ if task_prompt:
34
+ base_instructions = f"{prompt}\n\n{task_prompt}" if prompt else task_prompt
35
+
36
+ raw_sandbox = str(config.get("sandbox") or "read_only").strip().lower()
37
+ raw_approval = str(config.get("approval_mode") or "").strip().lower()
38
+ approval_profiles = {
39
+ "ask": ("workspace-write", "manual"),
40
+ "risk": ("workspace-write", "auto_review"),
41
+ "full": ("full-access", "deny_all"),
42
+ }
43
+ sandbox_profiles = {
44
+ "read_only": ("read-only", "deny_all"),
45
+ "read-only": ("read-only", "deny_all"),
46
+ "workspace_write": ("workspace-write", "deny_all"),
47
+ "workspace-write": ("workspace-write", "deny_all"),
48
+ "workspace_write_auto": ("workspace-write", "auto_review"),
49
+ "workspace-write-auto": ("workspace-write", "auto_review"),
50
+ "full_access": ("full-access", "deny_all"),
51
+ "full-access": ("full-access", "deny_all"),
52
+ }
53
+ if raw_approval in approval_profiles:
54
+ sandbox, approval = approval_profiles[raw_approval]
55
+ else:
56
+ sandbox, default_approval = sandbox_profiles.get(raw_sandbox, ("read-only", "deny_all"))
57
+ approval = raw_approval or default_approval
58
+
59
+ request_config: dict[str, Any] = {
60
+ "sandbox_read_only": sandbox == "read-only",
61
+ "sandbox": sandbox,
62
+ "approval_mode": approval,
63
+ "cwd": str(context.project_dir),
64
+ "summary": "auto",
65
+ "ephemeral": False,
66
+ }
67
+ if base_instructions:
68
+ request_config["base_instructions"] = base_instructions
69
+ collaboration_mode = str(config.get("collaboration_mode") or "").strip().lower()
70
+ if collaboration_mode:
71
+ if collaboration_mode not in {"default", "plan"}:
72
+ raise ValueError("Codex collaboration_mode must be default or plan")
73
+ request_config["collaboration_mode"] = collaboration_mode
74
+ goal_objective = str(config.get("goal_objective") or "").strip()
75
+ if goal_objective:
76
+ request_config["goal_objective"] = goal_objective
77
+ raw_skills = config.get("skills")
78
+ if isinstance(raw_skills, (list, tuple)):
79
+ request_config["skills"] = [dict(item) for item in raw_skills if isinstance(item, dict)]
80
+ return request_config
81
+
82
+
83
+ def _manifest_mcp_overrides(config: dict[str, Any]) -> list[str]:
84
+ """Translate declarative MCP bindings into native Codex config keys."""
85
+
86
+ overrides: list[str] = []
87
+ servers = config.get("mcp_servers") or []
88
+ if not isinstance(servers, (list, tuple)):
89
+ return overrides
90
+ for server in servers:
91
+ if not isinstance(server, dict):
92
+ continue
93
+ name = str(server.get("name") or "").strip()
94
+ transport = str(server.get("transport") or ("http" if server.get("url") else "")).lower()
95
+ url = str(server.get("url") or "").strip()
96
+ if not name:
97
+ continue
98
+ if transport == "stdio":
99
+ command = str(server.get("command") or "").strip()
100
+ if not command:
101
+ continue
102
+ args = [str(argument) for argument in (server.get("args") or [])]
103
+ overrides.append(f"mcp_servers.{name}.command={json.dumps(command)}")
104
+ overrides.append(f"mcp_servers.{name}.args={json.dumps(args)}")
105
+ env_refs = server.get("env_refs") or {}
106
+ if isinstance(env_refs, dict) and env_refs:
107
+ overrides.append(
108
+ f"mcp_servers.{name}.env_vars="
109
+ f"{json.dumps(sorted(str(key) for key in env_refs))}"
110
+ )
111
+ elif transport in {"http", "sse"} and url:
112
+ overrides.append(f"mcp_servers.{name}.url={url}")
113
+ env_key = str(server.get("env_key") or "").strip()
114
+ if env_key:
115
+ overrides.append(f"mcp_servers.{name}.bearer_token_env_var={env_key}")
116
+ return overrides
117
+
118
+
119
+ def _manifest_has_network_mcp(config: Mapping[str, Any]) -> bool:
120
+ """Whether a projected Codex MCP binding genuinely needs network access."""
121
+
122
+ servers = config.get("mcp_servers") or []
123
+ if not isinstance(servers, (list, tuple)):
124
+ return False
125
+ for server in servers:
126
+ if not isinstance(server, dict):
127
+ continue
128
+ name = str(server.get("name") or "").strip()
129
+ url = str(server.get("url") or "").strip()
130
+ transport = str(server.get("transport") or ("http" if url else "")).lower()
131
+ if name and url and transport in {"http", "sse"}:
132
+ return True
133
+ return False
134
+
135
+
136
+ def _codex_plugin_bootstrap(config: Mapping[str, Any]) -> CodexPluginBootstrap | None:
137
+ """Read the closed, digest-pinned plugin bootstrap launch contract."""
138
+
139
+ raw = config.get("codex_plugin_bootstrap")
140
+ if raw is None:
141
+ if native_codex_plugin_bindings(config):
142
+ raise ValueError(
143
+ "原生插件绑定缺少可验证的交付快照;当前启动只收到 plugins 声明,"
144
+ "无法恢复插件。请提供完整插件交付配置后再启动。"
145
+ )
146
+ return None
147
+ if not isinstance(raw, Mapping):
148
+ raise ValueError("codex_plugin_bootstrap must be an object")
149
+ return CodexPluginBootstrap.from_mapping(raw)
150
+
151
+
152
+ _CODEX_HOME_KEY = re.compile(r"^build_[0-9a-f]{8,64}$")
153
+
154
+
155
+ def _codex_home_key(
156
+ config: Mapping[str, Any],
157
+ plugin_bootstrap: CodexPluginBootstrap | None,
158
+ ) -> str:
159
+ raw = config.get("codex_home_key")
160
+ if raw is None:
161
+ if plugin_bootstrap is not None:
162
+ raise ValueError("plugin-bearing Codex launches require codex_home_key")
163
+ return "unscoped"
164
+ value = str(raw).strip()
165
+ if _CODEX_HOME_KEY.fullmatch(value) is None:
166
+ raise ValueError("codex_home_key must match build_[0-9a-f]{8,64}")
167
+ return value
168
+
169
+
170
+ def create_codex_adapter(context: RuntimeLaunchContext) -> RuntimeAdapter:
171
+ from ksadk.codex.runtime import CodexRuntimeAdapter
172
+
173
+ client_factory = context.services.codex_client_factory or AsyncCodexClient
174
+ config = dict(context.config)
175
+ plugin_bootstrap = _codex_plugin_bootstrap(config)
176
+ codex_home_key = _codex_home_key(config, plugin_bootstrap)
177
+ bound_skill_paths: dict[str, str] = {}
178
+ overrides = list(config.get("codex_overrides") or [])
179
+ manifest_mcp_overrides = _manifest_mcp_overrides(config)
180
+ overrides.extend(item for item in manifest_mcp_overrides if item not in overrides)
181
+ projected_config = codex_request_config(context)
182
+ if _manifest_has_network_mcp(config) and projected_config.get("sandbox") == "workspace-write":
183
+ network_override = "sandbox_workspace_write.network_access=true"
184
+ if network_override not in overrides:
185
+ overrides.append(network_override)
186
+ # Studio's default collaboration mode must expose Codex's structured
187
+ # request_user_input tool; the upstream feature is intentionally off by
188
+ # default outside Plan mode. This stays process-local to the isolated
189
+ # runtime and does not mutate the user's global Codex configuration.
190
+ interaction_override = "features.default_mode_request_user_input=true"
191
+ if interaction_override not in overrides:
192
+ overrides.append(interaction_override)
193
+ try:
194
+ from openai_codex import CodexConfig
195
+
196
+ base_cfg = CodexConfig()
197
+ if overrides:
198
+ base_cfg = dataclasses.replace(
199
+ base_cfg,
200
+ config_overrides=tuple(getattr(base_cfg, "config_overrides", ()) or ())
201
+ + tuple(str(o) for o in overrides),
202
+ )
203
+ env = dict(getattr(base_cfg, "env", None) or {})
204
+ isolated_home = _isolated_codex_home(context.project_dir, codex_home_key)
205
+ bound_skill_paths = _materialize_bound_codex_skills(isolated_home, config.get("skills"))
206
+ env.setdefault("CODEX_HOME", str(isolated_home))
207
+ # HOME 级隔离:codex app-server 还会按约定扫 ~/.agents/skills、
208
+ # ~/.claude/skills 等宿主目录,仅设 CODEX_HOME 挡不住。隔离 HOME 后这些
209
+ # 路径全部落在工作区内,宿主 skills/MCP/凭证不再进入 Agent 上下文。
210
+ # 设 KSADK_CODEX_ISOLATE_HOME=0 可关闭(调试用)。
211
+ if os.environ.get("KSADK_CODEX_ISOLATE_HOME", "1") != "0":
212
+ env.setdefault("HOME", str(isolated_home))
213
+ # 运行期解析出的凭证值(如 MCP bearer_token_env_var 所需)注入子进程环境
214
+ env.update({str(k): str(v) for k, v in (context.config.get("env") or {}).items()})
215
+ base_cfg = dataclasses.replace(base_cfg, env=env)
216
+ try:
217
+ client: Any = client_factory(config=base_cfg)
218
+ except TypeError:
219
+ # 自定义/测试工厂可能不接受 config 参数:退化为无参构造,
220
+ # config_overrides 事后注入(自定义工厂自行承担 env 隔离)。
221
+ client = client_factory()
222
+ if overrides:
223
+ _apply_codex_overrides(client, overrides)
224
+ except ImportError:
225
+ client: Any = client_factory()
226
+ if overrides:
227
+ _apply_codex_overrides(client, overrides)
228
+ timeout = context.config.get("turn_timeout_seconds")
229
+ request_config = codex_request_config(context)
230
+ sandbox_read_only = (
231
+ bool(context.config["sandbox_read_only"])
232
+ if "sandbox_read_only" in context.config
233
+ else bool(request_config.get("sandbox_read_only", True))
234
+ )
235
+ return CodexRuntimeAdapter(
236
+ client,
237
+ sandbox_read_only=sandbox_read_only,
238
+ turn_timeout_seconds=float(timeout) if timeout is not None else None,
239
+ turn_projector=CodexTurnProjector(
240
+ bound_skill_paths=bound_skill_paths,
241
+ enforce_bound_skills=bool(config.get("enforce_bound_skills")),
242
+ ),
243
+ plugin_bootstrap=plugin_bootstrap,
244
+ )
245
+
246
+
247
+ def _isolated_codex_home(project_dir: Any, codex_home_key: str = "unscoped") -> Path:
248
+ """Use one CODEX_HOME partition per immutable Codex build.
249
+
250
+ ``KSADK_CODEX_HOME`` is a base directory, not the final home: every build
251
+ is placed under ``builds/<key>``. Workspace and managed-runtime fallbacks
252
+ use the same separation, so two build digests cannot observe each other's
253
+ App Server plugin cache.
254
+ """
255
+
256
+ if codex_home_key != "unscoped" and _CODEX_HOME_KEY.fullmatch(codex_home_key) is None:
257
+ raise ValueError("codex_home_key must match build_[0-9a-f]{8,64}")
258
+ override = os.environ.get("KSADK_CODEX_HOME")
259
+ if override:
260
+ home = Path(override).expanduser() / "builds" / codex_home_key
261
+ home.mkdir(parents=True, exist_ok=True)
262
+ return home
263
+
264
+ # Source bundles are deliberately mounted read-only in managed runtimes.
265
+ # Keep the preferred workspace-local isolation for local development, but
266
+ # never make a Codex turn depend on being able to mutate that bundle.
267
+ workspace_home = Path(str(project_dir)) / ".agentkit" / "codex-homes" / codex_home_key
268
+ try:
269
+ workspace_home.mkdir(parents=True, exist_ok=True)
270
+ return workspace_home
271
+ except OSError:
272
+ pass
273
+
274
+ # The managed runtime already provides a per-workload writable state
275
+ # volume. Derive from its explicit directory first, then from the
276
+ # session-store path for backward-compatible images. /tmp is a final
277
+ # process-local fallback for custom read-only launchers.
278
+ state_dir = os.environ.get("KSADK_RUNTIME_STATE_DIR")
279
+ session_path = os.environ.get("KSADK_SESSION_PATH")
280
+ fallback_root = (
281
+ Path(state_dir)
282
+ if state_dir
283
+ else Path(session_path).expanduser().parent
284
+ if session_path
285
+ else Path(tempfile.gettempdir()) / "ksadk-runtime-state"
286
+ )
287
+ fallback_home = fallback_root / "codex-homes" / codex_home_key
288
+ fallback_home.mkdir(parents=True, exist_ok=True)
289
+ return fallback_home
290
+
291
+
292
+ def _materialize_bound_codex_skills(codex_home: Path, value: Any) -> dict[str, str]:
293
+ """Expose immutable Bundle Skills through Codex's native skill catalog.
294
+
295
+ Passing an arbitrary ``SkillInput`` path is accepted by the Python SDK but
296
+ ignored by the real App Server unless the Skill is discoverable by the
297
+ native host. Copy each content-addressed Bundle Skill into the isolated
298
+ CODEX_HOME so the host owns discovery while the Bundle remains read-only.
299
+ Content-addressed directory names avoid overwriting user-managed Skills
300
+ when an explicit KSADK_CODEX_HOME is used.
301
+ """
302
+
303
+ if not isinstance(value, (list, tuple)):
304
+ return {}
305
+ skills_root = codex_home / "skills"
306
+ skills_root.mkdir(parents=True, exist_ok=True)
307
+ installed: dict[str, str] = {}
308
+ for item in value:
309
+ if not isinstance(item, dict):
310
+ continue
311
+ name = str(item.get("name") or "").strip()
312
+ raw_path = str(item.get("path") or "").strip()
313
+ if not name or not raw_path:
314
+ continue
315
+ skill_file = Path(raw_path).resolve()
316
+ if skill_file.name != "SKILL.md" or not skill_file.is_file():
317
+ continue
318
+ source_dir = skill_file.parent
319
+ digest = hashlib.sha256()
320
+ for source in sorted(path for path in source_dir.rglob("*") if path.is_file()):
321
+ digest.update(source.relative_to(source_dir).as_posix().encode("utf-8"))
322
+ digest.update(b"\0")
323
+ digest.update(source.read_bytes())
324
+ digest.update(b"\0")
325
+ safe_name = re.sub(r"[^A-Za-z0-9._-]+", "-", name).strip(".-") or "skill"
326
+ target = skills_root / f"ksadk-{digest.hexdigest()[:16]}-{safe_name}"
327
+ if target.is_dir():
328
+ installed[name] = str(target / "SKILL.md")
329
+ continue
330
+ staging = Path(tempfile.mkdtemp(prefix=".ksadk-skill-", dir=skills_root))
331
+ try:
332
+ shutil.copytree(source_dir, staging, dirs_exist_ok=True)
333
+ try:
334
+ staging.replace(target)
335
+ except FileExistsError:
336
+ pass
337
+ finally:
338
+ if staging.exists():
339
+ shutil.rmtree(staging)
340
+ installed[name] = str(target / "SKILL.md")
341
+ return installed
342
+
343
+
344
+ def _apply_codex_overrides(client: Any, overrides: Any) -> None:
345
+ """Append MCP server --config overrides to the client's CodexConfig."""
346
+ try:
347
+ from openai_codex import CodexConfig
348
+ except ImportError:
349
+ return
350
+ # ksadk AsyncCodexClient -> AsyncCodex -> inner AsyncCodexClient.config
351
+ inner_codex = getattr(client, "_codex", None)
352
+ inner_client = getattr(inner_codex, "_client", None) or inner_codex
353
+ cfg = getattr(inner_client, "config", None)
354
+ if cfg is None or not isinstance(cfg, CodexConfig):
355
+ return
356
+ base_overrides = tuple(getattr(cfg, "config_overrides", ()) or ())
357
+ new_overrides = tuple(str(o) for o in overrides if o not in base_overrides)
358
+ if not new_overrides:
359
+ return
360
+ new_cfg = dataclasses.replace(cfg, config_overrides=base_overrides + new_overrides)
361
+ setattr(inner_client, "config", new_cfg)
362
+
363
+
364
+ def codex_runtime_registry() -> RuntimeRegistry:
365
+ """Private native registry for the provider, never a provider resolver."""
366
+ registry = RuntimeRegistry()
367
+ registry.register("codex", create_codex_adapter)
368
+ return registry
@@ -0,0 +1,301 @@
1
+ """Provider-owned projection of bound capabilities and canonical input into Codex.
2
+
3
+ One projector belongs to one native adapter. Attachment persistence retains the
4
+ existing native-thread continuation contract; adapter close is not session close.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import base64
9
+ import binascii
10
+ import hashlib
11
+ import json
12
+ import re
13
+ from collections.abc import Mapping
14
+ from pathlib import Path
15
+ from typing import Any, Optional
16
+
17
+ from ksadk.codex.projection import ProjectedCodexTurn
18
+ from ksadk.runtime.adapter import ResumePayload, StartRequest
19
+
20
+
21
+ class CodexTurnProjector:
22
+ def __init__(
23
+ self, *, bound_skill_paths: Mapping[str, str] | None = None,
24
+ enforce_bound_skills: bool = False,
25
+ ) -> None:
26
+ self._skills = dict(bound_skill_paths or {})
27
+ self._enforce_bound_skills = enforce_bound_skills
28
+ self._closed = False
29
+
30
+ def prepare(self, request: StartRequest) -> StartRequest:
31
+ """Project admitted native Skill paths without mutating a caller request."""
32
+ self._require_open()
33
+ skills = request.config.get("skills")
34
+ if self._enforce_bound_skills:
35
+ if skills is not None and (not isinstance(skills, list) or any(
36
+ not isinstance(item, dict)
37
+ or str(item.get("name") or "").strip() not in self._skills
38
+ for item in skills
39
+ )):
40
+ raise ValueError("Codex request contains a Skill absent from the immutable Bundle")
41
+ return request.model_copy(update={"config": {
42
+ **request.config,
43
+ "skills": [{"name": name, "path": path} for name, path in self._skills.items()],
44
+ }})
45
+ if not self._skills or not isinstance(skills, list):
46
+ return request
47
+ projected = [
48
+ {**item, "path": self._skills.get(
49
+ str(item.get("name") or "").strip(), str(item.get("path") or ""),
50
+ )}
51
+ for item in skills if isinstance(item, dict)
52
+ ]
53
+ return request.model_copy(update={"config": {**request.config, "skills": projected}})
54
+
55
+ def project(
56
+ self, request: StartRequest | None, payload: ResumePayload | None,
57
+ ) -> ProjectedCodexTurn:
58
+ self._require_open()
59
+ prompt = _request_prompt(request) if request is not None else _resume_prompt(payload)
60
+ return ProjectedCodexTurn(_build_run_input(request, prompt, self._materialize_file))
61
+
62
+ def close(self) -> None:
63
+ self._closed = True
64
+
65
+ def _require_open(self) -> None:
66
+ if self._closed:
67
+ raise RuntimeError("Codex turn projector is closed")
68
+
69
+ def _materialize_file(self, data_url: str, filename: str) -> Path | None:
70
+ """Materialize a bounded Studio inline attachment for native Codex."""
71
+
72
+ match = re.fullmatch(r"data:([^;,]+)?;base64,([A-Za-z0-9+/=\s]+)", data_url)
73
+ encoded = match.group(2) if match is not None else data_url.strip()
74
+ try:
75
+ payload = base64.b64decode(encoded, validate=True)
76
+ except (ValueError, binascii.Error):
77
+ return None
78
+ if not payload or len(payload) > 10 * 1024 * 1024:
79
+ return None
80
+ safe_name = re.sub(r"[^A-Za-z0-9._-]+", "-", Path(filename).name).strip(".-")
81
+ safe_name = safe_name[:120] or "attachment"
82
+ digest = hashlib.sha256(payload).hexdigest()
83
+ # Native thread continuation can outlive this adapter. Keep the existing
84
+ # content-addressed storage until the session owner supplies retention.
85
+ path = Path("/tmp/ksadk-codex-attachments") / digest / safe_name
86
+ path.parent.mkdir(parents=True, exist_ok=True)
87
+ if not path.exists():
88
+ path.write_bytes(payload)
89
+ return path
90
+
91
+
92
+ def _resume_prompt(payload: Optional[ResumePayload]) -> Any:
93
+ if payload is None:
94
+ return ""
95
+ if isinstance(payload.data, str):
96
+ return payload.data
97
+ return json.dumps(payload.data, ensure_ascii=False, sort_keys=True)
98
+
99
+
100
+ def _coerce_prompt_text(value: Any) -> Any:
101
+ """把 canonical message 形态的 input 压成 SDK 可接受的文本。
102
+
103
+ ``openai-codex`` 0.147 的 run input 只接受 TextInput/str;请求侧没有
104
+ conversation preprocessing 时 ``request.input`` 可能是
105
+ ``[{role, content}]`` 历史列表,直接透传会 ``unsupported input item``。
106
+ """
107
+ if isinstance(value, str) or value is None:
108
+ return value
109
+ if isinstance(value, dict):
110
+ content = value.get("content") if "role" in value else value.get("text")
111
+ if isinstance(content, str):
112
+ return content
113
+ if isinstance(content, dict):
114
+ text = content.get("text") or content.get("content")
115
+ if isinstance(text, str):
116
+ return text
117
+ return str(value)
118
+ if isinstance(value, list):
119
+ texts = [
120
+ text
121
+ for text in (_coerce_prompt_text(item) for item in value)
122
+ if isinstance(text, str) and text
123
+ ]
124
+ return "\n".join(texts) if texts else str(value)
125
+ return str(value)
126
+
127
+
128
+ def _request_prompt(request: StartRequest) -> Any:
129
+ """Render canonical conversation history for a native Codex turn.
130
+
131
+ 只传 user 消息历史 + 当前 input,不传 assistant 的完整回复(避免 codex 复述历史)。
132
+ assistant 回复用简短摘要代替,仅维持对话结构。
133
+ """
134
+ # A resumed Codex thread already owns its transcript. Re-sending Studio's
135
+ # transport-neutral history would duplicate every prior turn after refresh.
136
+ if str(request.metadata.get("thread_id") or "").strip():
137
+ return (
138
+ request.input
139
+ if _is_structured_turn_input(request.input)
140
+ else _coerce_prompt_text(request.input)
141
+ )
142
+
143
+ conversation = request.conversation_preprocessing()
144
+ if conversation is None or not conversation.messages:
145
+ # Keep native text/image/mention parts intact for _build_run_input().
146
+ # Flattening this list turns an image dict into user-visible text.
147
+ return (
148
+ request.input
149
+ if _is_structured_turn_input(request.input)
150
+ else _coerce_prompt_text(request.input)
151
+ )
152
+
153
+ lines: list[str] = []
154
+ for message in conversation.messages:
155
+ content = message.get("content")
156
+ if not isinstance(content, str):
157
+ continue
158
+ role = str(message.get("role") or "user").strip().lower()
159
+ if role == "assistant":
160
+ # 不传完整回复,只标注"已回复",避免 codex 复述
161
+ summary = content[:80] + ("..." if len(content) > 80 else "")
162
+ lines.append(f"[上一轮已回复: {summary}]")
163
+ elif role == "user":
164
+ lines.append(f"User: {content}")
165
+ return "\n".join(lines) or request.input
166
+
167
+
168
+ def _is_structured_turn_input(value: Any) -> bool:
169
+ return isinstance(value, list) and any(
170
+ isinstance(item, dict) and isinstance(item.get("type"), str) for item in value
171
+ )
172
+
173
+
174
+ def _build_run_input(
175
+ request: Optional[StartRequest], prompt: Any, materialize_file: Any
176
+ ) -> Any:
177
+ """Compose Codex skills and native text/image/mention turn input."""
178
+ try:
179
+ from openai_codex import ImageInput, LocalImageInput, MentionInput, SkillInput, TextInput
180
+ except ImportError:
181
+ return prompt
182
+ skills: list[SkillInput] = []
183
+ if request is not None:
184
+ raw = request.config.get("skills") if request.config else None
185
+ if isinstance(raw, list):
186
+ for item in raw:
187
+ if not isinstance(item, dict):
188
+ continue
189
+ name = str(item.get("name") or "").strip()
190
+ path = str(item.get("path") or "").strip()
191
+ if name and path:
192
+ skills.append(SkillInput(name=name, path=path))
193
+ native_items: list[Any] = []
194
+ raw_input = request.input if request is not None else prompt
195
+ if isinstance(raw_input, list):
196
+ text_replaced = False
197
+ for item in raw_input:
198
+ if not isinstance(item, dict):
199
+ continue
200
+ kind = str(item.get("type") or "")
201
+ if not kind and "role" in item:
202
+ # canonical conversation message({role, content});当前 input
203
+ # 已由 prompt(或 conversation preprocessing)承载,跳过历史项。
204
+ continue
205
+ if kind in {"text", "input_text"}:
206
+ text = str(
207
+ prompt
208
+ if not text_replaced and isinstance(prompt, str)
209
+ else item.get("text") or ""
210
+ )
211
+ text_replaced = True
212
+ if text:
213
+ native_items.append(TextInput(text=text))
214
+ elif kind in {"image", "input_image"} and (item.get("url") or item.get("image_url")):
215
+ native_items.append(ImageInput(url=str(item.get("url") or item.get("image_url"))))
216
+ elif kind == "localImage" and item.get("path"):
217
+ native_items.append(LocalImageInput(path=str(item["path"])))
218
+ elif kind == "input_file" and (
219
+ item.get("file_data") or str(item.get("file_url") or "").startswith("data:")
220
+ ):
221
+ file_path = materialize_file(
222
+ str(item.get("file_data") or item.get("file_url")),
223
+ str(item.get("filename") or "attachment"),
224
+ )
225
+ if file_path is not None:
226
+ # App Server's ``mention`` input is presentation metadata:
227
+ # current Codex versions do not include it in the model's
228
+ # user message. Always add an explicit model-visible
229
+ # attachment context as well. Small textual files are
230
+ # inlined deterministically; binary/large files expose a
231
+ # sandbox-readable path that Codex can inspect with tools.
232
+ native_items.append(TextInput(text=_attachment_context_text(file_path, item)))
233
+ native_items.append(MentionInput(name=file_path.name, path=str(file_path)))
234
+ elif kind == "mention" and item.get("path"):
235
+ native_items.append(
236
+ MentionInput(
237
+ name=str(item.get("name") or item["path"]),
238
+ path=str(item["path"]),
239
+ )
240
+ )
241
+ else:
242
+ text = prompt if isinstance(prompt, str) else str(prompt or "")
243
+ if text:
244
+ native_items.append(TextInput(text=text))
245
+ combined = [*skills, *native_items]
246
+ if not combined:
247
+ return prompt
248
+ if len(combined) == 1 and isinstance(combined[0], TextInput) and not skills:
249
+ return combined[0].text
250
+ return combined
251
+
252
+
253
+
254
+
255
+ _MAX_INLINE_ATTACHMENT_TEXT_BYTES = 64 * 1024
256
+ _TEXT_ATTACHMENT_SUFFIXES = {
257
+ ".csv",
258
+ ".html",
259
+ ".htm",
260
+ ".ini",
261
+ ".json",
262
+ ".jsonl",
263
+ ".log",
264
+ ".md",
265
+ ".py",
266
+ ".rst",
267
+ ".toml",
268
+ ".tsv",
269
+ ".txt",
270
+ ".xml",
271
+ ".yaml",
272
+ ".yml",
273
+ }
274
+
275
+
276
+ def _attachment_context_text(path: Path, item: Mapping[str, Any]) -> str:
277
+ """Build model-visible context for a materialized Responses input file."""
278
+
279
+ name = str(item.get("filename") or path.name).replace('"', "'")
280
+ inline_data = item.get("inlineData")
281
+ inline_mime = inline_data.get("mimeType") if isinstance(inline_data, Mapping) else None
282
+ mime_type = str(item.get("mime_type") or inline_mime or "").strip().lower()
283
+ source = str(item.get("file_data") or item.get("file_url") or "")
284
+ data_url_match = re.match(r"data:([^;,]+)", source)
285
+ if not mime_type and data_url_match is not None:
286
+ mime_type = data_url_match.group(1).strip().lower()
287
+ is_text = mime_type.startswith("text/") or path.suffix.lower() in _TEXT_ATTACHMENT_SUFFIXES
288
+ header = f'<uploaded_attachment name="{name}" path="{path}">'
289
+ if not is_text:
290
+ return (
291
+ f"{header}\n"
292
+ "The uploaded file is available at the path above. Read it with an appropriate "
293
+ "tool before answering questions about its contents.\n"
294
+ "</uploaded_attachment>"
295
+ )
296
+
297
+ raw = path.read_bytes()
298
+ truncated = len(raw) > _MAX_INLINE_ATTACHMENT_TEXT_BYTES
299
+ text = raw[:_MAX_INLINE_ATTACHMENT_TEXT_BYTES].decode("utf-8", errors="replace")
300
+ suffix = "\n[attachment content truncated]" if truncated else ""
301
+ return f"{header}\n{text}{suffix}\n</uploaded_attachment>"