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
@@ -18,8 +18,13 @@ from ksadk.conversations.contracts import (
18
18
  ConversationTextPart,
19
19
  validate_conversation_input,
20
20
  )
21
+ from ksadk.conversations.message_projection import project_session_messages
22
+ from ksadk.events.canonical import parse_runtime_event
23
+ from ksadk.events.canonical_store import session_event_to_runtime_event
24
+ from ksadk.sessions.base import Session
21
25
  from ksadk.studio.contracts import OperationStatus, RunRecord, RunStatus
22
26
  from ksadk.studio.errors import StudioError, not_found
27
+ from ksadk.studio.run_service import project_runtime_event
23
28
  from ksadk.studio.service import StudioService
24
29
  from ksadk.tools.gateway import tool_approval_capability
25
30
 
@@ -89,10 +94,12 @@ class StudioSharedWebBridge:
89
94
  "CheckpointResumePreview": False,
90
95
  },
91
96
  "ApprovalPolicy": tool_approval_capability(),
97
+ "InteractionV1": True,
92
98
  "WorkspaceFiles": {"Enabled": False},
93
99
  "NativeDashboard": {"Enabled": False},
94
100
  "NativeTerminal": {"Enabled": False},
95
101
  "Thinking": False,
102
+ "ContextCompaction": self.studio.is_codex_agent(agent_id),
96
103
  },
97
104
  }
98
105
 
@@ -110,14 +117,14 @@ class StudioSharedWebBridge:
110
117
 
111
118
  return self._select_model(agent_id, str(requested or ""))
112
119
 
113
- def list_sessions(
120
+ async def list_sessions(
114
121
  self,
115
122
  agent_id: str,
116
123
  *,
117
124
  page: int = 1,
118
125
  page_size: int = 30,
119
126
  ) -> dict[str, Any]:
120
- sessions = self._sessions(agent_id)
127
+ sessions = await self._sessions(agent_id)
121
128
  safe_page = max(1, page)
122
129
  safe_size = min(100, max(1, page_size))
123
130
  start = (safe_page - 1) * safe_size
@@ -128,29 +135,79 @@ class StudioSharedWebBridge:
128
135
  "PageSize": safe_size,
129
136
  }
130
137
 
131
- def create_session(self, agent_id: str) -> dict[str, Any]:
138
+ async def create_session(self, agent_id: str) -> dict[str, Any]:
132
139
  self._draft(agent_id)
133
140
  session_id = f"ses_{uuid4().hex}"
134
- now = datetime.now(timezone.utc).isoformat()
135
- return {
136
- "Session": {
137
- "SessionId": session_id,
138
- "AgentId": agent_id,
139
- "UserId": "local-user",
140
- "Title": "新会话",
141
- "CreatedAt": now,
142
- "UpdatedAt": now,
143
- }
144
- }
141
+ session = await self.studio.session_service.create_session(
142
+ agent_id,
143
+ "local-user",
144
+ session_id,
145
+ )
146
+ return {"Session": self._session_metadata_record(session)}
145
147
 
146
- def get_session(self, session_id: str) -> dict[str, Any]:
148
+ async def get_session(self, session_id: str) -> dict[str, Any]:
147
149
  runs = self.studio.event_store.list_runs(session_id=session_id)
150
+ if runs:
151
+ return {"Session": self._session_record(runs)}
152
+ session = await self.studio.session_service.get_session_metadata(session_id)
153
+ if session is None:
154
+ raise not_found("session", session_id)
155
+ return {"Session": self._session_metadata_record(session)}
156
+
157
+ async def compact_session(self, agent_id: str, session_id: str) -> dict[str, Any]:
158
+ from ksadk.codex.runtime import CodexRuntimeAdapter
159
+
160
+ runs = self.studio.event_store.list_runs(session_id=session_id, agent_id=agent_id)
148
161
  if not runs:
149
162
  raise not_found("session", session_id)
150
- return {"Session": self._session_record(runs)}
163
+ latest = runs[-1]
164
+ if latest.runtime_type != "codex":
165
+ raise StudioError("COMPACTION_UNSUPPORTED", "此运行时尚未提供手动压缩", status_code=409)
166
+ key = (agent_id, session_id)
167
+ service = self.studio.run_service
168
+ if key in service._active_sessions or any(self._active_status(run.status) for run in runs):
169
+ raise StudioError(
170
+ "SESSION_RUN_ACTIVE", "请等待当前运行完成后压缩上下文", status_code=409
171
+ )
172
+ thread_id = str((latest.runtime_handle.get("native_ref") or {}).get("thread_id") or "")
173
+ if not thread_id:
174
+ raise StudioError(
175
+ "CONTEXT_UNAVAILABLE", "此会话尚无可压缩的原生上下文", status_code=409
176
+ )
177
+ service._active_sessions.add(key)
178
+ adapter = None
179
+ try:
180
+ spec = self.studio.resolve_run_spec(latest.build_id, model=latest.model or None)
181
+ adapter = self.studio.runtime_executor.create_adapter(spec.launch_context)
182
+ if not isinstance(adapter, CodexRuntimeAdapter):
183
+ raise StudioError(
184
+ "COMPACTION_UNSUPPORTED", "此运行时尚未提供手动压缩", status_code=409
185
+ )
186
+ usage = await adapter.compact_session(thread_id, dict(spec.request_config))
187
+ last = usage.get("last") or {}
188
+ context_usage = {
189
+ "used_tokens": last.get("totalTokens"),
190
+ "source": "runtime",
191
+ "model": latest.model,
192
+ }
193
+ self.studio.event_store.append(
194
+ latest.id,
195
+ "context.compaction.completed",
196
+ {
197
+ "trigger": "manual",
198
+ "contextUsage": context_usage,
199
+ },
200
+ )
201
+ return {"Status": "completed", "ContextUsage": context_usage}
202
+ finally:
203
+ try:
204
+ if adapter is not None:
205
+ await adapter.close_all()
206
+ finally:
207
+ service._active_sessions.discard(key)
151
208
 
152
- def delete_session(self, session_id: str) -> dict[str, Any]:
153
- self.studio.event_store.delete_session(session_id)
209
+ async def delete_session(self, session_id: str) -> dict[str, Any]:
210
+ await self.studio.delete_session(session_id)
154
211
  return {}
155
212
 
156
213
  async def list_messages(
@@ -181,7 +238,14 @@ class StudioSharedWebBridge:
181
238
  {
182
239
  "MessageId": f"{run.id}:assistant",
183
240
  "Role": "assistant",
184
- "Content": {"text": self._run_output(run)},
241
+ "Content": {
242
+ # Run status is metadata, not an assistant reply. An
243
+ # empty pending reply lets canonical reasoning/tools
244
+ # restore without a synthetic status text shadowing them.
245
+ "text": (
246
+ run.output if self._active_status(run.status) else self._run_output(run)
247
+ )
248
+ },
185
249
  "Timestamp": self._timestamp(run.completed_at or run.started_at),
186
250
  "SeqId": sequence,
187
251
  "InvocationId": run.id,
@@ -189,6 +253,16 @@ class StudioSharedWebBridge:
189
253
  }
190
254
  )
191
255
 
256
+ extra_events = await self._untracked_runtime_events(session_id, runs)
257
+ if extra_events:
258
+ messages.extend(project_session_messages(extra_events))
259
+ messages.sort(key=lambda item: self._timestamp_value(item["Timestamp"]))
260
+ for sequence, message in enumerate(messages, 1):
261
+ message["SeqId"] = sequence
262
+ if isinstance(message["Timestamp"], (int, float)):
263
+ message["Timestamp"] = self._timestamp(message["Timestamp"])
264
+ message.pop("StartSeqId", None)
265
+
192
266
  latest_seq_id = sequence
193
267
  if after_seq_id is not None:
194
268
  messages = [item for item in messages if item["SeqId"] > after_seq_id]
@@ -214,12 +288,31 @@ class StudioSharedWebBridge:
214
288
  events.append(
215
289
  {
216
290
  "SeqId": sequence,
217
- "EventType": event.type,
291
+ "EventType": self._shared_event_type(event.type, event.data),
218
292
  "InvocationId": run.id,
219
- "Content": event.data,
293
+ "Content": self._shared_event_content(event.data, run.id),
220
294
  "Timestamp": self._timestamp(event.created_at),
221
295
  }
222
296
  )
297
+ extra_events = await self._untracked_runtime_events(session_id, runs)
298
+ for event in extra_events:
299
+ native = event["Content"]["runtime_event"]
300
+ event_type, content = project_runtime_event(
301
+ parse_runtime_event(native), session_id=session_id
302
+ )
303
+ events.append(
304
+ {
305
+ "SeqId": 0,
306
+ "EventType": self._shared_event_type(event_type, content),
307
+ "InvocationId": event["InvocationId"],
308
+ "Content": content,
309
+ "Timestamp": self._timestamp(event["Timestamp"]),
310
+ }
311
+ )
312
+ if extra_events:
313
+ events.sort(key=lambda item: self._timestamp_value(item["Timestamp"]))
314
+ for sequence, event in enumerate(events, 1):
315
+ event["SeqId"] = sequence
223
316
  return {
224
317
  "Events": events,
225
318
  "Total": len(events),
@@ -227,6 +320,147 @@ class StudioSharedWebBridge:
227
320
  "Limit": len(events),
228
321
  }
229
322
 
323
+ async def _untracked_runtime_events(
324
+ self, session_id: str, runs: list[RunRecord]
325
+ ) -> list[dict[str, Any]]:
326
+ """Read Kernel-owned runs absent from Studio's foreground run index.
327
+
328
+ Scheduled runs already have a durable canonical transcript. Project
329
+ that log through the shared message contract, including in sessions
330
+ that also contain foreground turns, without manufacturing RunRecords.
331
+ """
332
+ tracked = {run.id for run in runs}
333
+ for run in runs:
334
+ tracked.add(str(run.runtime_handle.get("run_id") or ""))
335
+ for event in await self.studio.run_service.events(run.id):
336
+ native = event.data.get("runtimeEvent")
337
+ if isinstance(native, dict):
338
+ tracked.add(str(native.get("run_id") or ""))
339
+ result = []
340
+ for row in await self.studio.session_service.get_events(session_id):
341
+ native = session_event_to_runtime_event(row)
342
+ if native is None or native.run_id in tracked:
343
+ continue
344
+ result.append(
345
+ {
346
+ "EventId": native.event_id,
347
+ "SessionId": session_id,
348
+ "SeqId": row.seq_id,
349
+ "EventType": native.event_type,
350
+ "InvocationId": native.run_id,
351
+ "Timestamp": row.timestamp,
352
+ "Content": {"runtime_event": native.model_dump(mode="json")},
353
+ "Metadata": {"ksadk_canonical_runtime_event": True},
354
+ }
355
+ )
356
+ return result
357
+
358
+ @staticmethod
359
+ def _timestamp_value(value: str | float) -> float:
360
+ if isinstance(value, (float, int)):
361
+ return value
362
+ return datetime.fromisoformat(value.replace("Z", "+00:00")).timestamp() if value else 0
363
+
364
+ @staticmethod
365
+ def _shared_event_type(event_type: str, data: dict[str, Any]) -> str:
366
+ native = data.get("runtimeEvent")
367
+ if (
368
+ event_type == "run.interrupted"
369
+ and isinstance(native, dict)
370
+ and native.get("interaction_id")
371
+ ):
372
+ # A resumable interaction is waiting, not a terminal interruption.
373
+ return "run.waiting"
374
+ return event_type
375
+
376
+ @staticmethod
377
+ def _shared_event_content(data: dict[str, Any], run_id: str) -> dict[str, Any]:
378
+ """Use the public Studio run identity in shared-Web history projections.
379
+
380
+ The persisted canonical event retains the adapter's native run ID.
381
+ ListSessionMessages uses the Studio ID, so its event projection must
382
+ use the same ID or hydration retains both copies of the answer.
383
+ """
384
+ native = data.get("runtimeEvent")
385
+ if not isinstance(native, dict):
386
+ return data
387
+ return {**data, "runtimeEvent": {**native, "run_id": run_id}}
388
+
389
+ async def subscription_run_id(self, session_id: str, invocation_id: str) -> str:
390
+ run_id = self._run_ids_by_invocation.get(invocation_id, invocation_id)
391
+ try:
392
+ run = self.studio.event_store.get(run_id)
393
+ except StudioError as error:
394
+ if error.code != "RUN_NOT_FOUND":
395
+ raise
396
+ else:
397
+ if run.session_id != session_id:
398
+ raise not_found("run", invocation_id)
399
+ return run_id
400
+ for row in await self.studio.session_service.get_events(session_id):
401
+ native = session_event_to_runtime_event(row)
402
+ if native is not None and native.run_id == run_id:
403
+ return run_id
404
+ raise not_found("run", invocation_id)
405
+
406
+ async def subscribe_run_events(
407
+ self,
408
+ session_id: str,
409
+ invocation_id: str,
410
+ *,
411
+ after_seq_id: int = 0,
412
+ ) -> AsyncIterator[str]:
413
+ run_id = await self.subscription_run_id(session_id, invocation_id)
414
+ runs = self.studio.event_store.list_runs(session_id=session_id)
415
+ if await self._untracked_runtime_events(session_id, runs):
416
+ cursor = after_seq_id
417
+ while True:
418
+ history = await self.list_session_events(session_id)
419
+ run_events = [
420
+ event for event in history["Events"] if event["InvocationId"] == run_id
421
+ ]
422
+ for event in run_events:
423
+ if event["SeqId"] > cursor:
424
+ yield self._sse("message", {**event, "SessionId": session_id})
425
+ cursor = event["SeqId"]
426
+ if any(
427
+ event["EventType"]
428
+ in {"run.completed", "run.failed", "run.cancelled", "run.interrupted"}
429
+ for event in run_events
430
+ ):
431
+ yield "event: done\ndata: [DONE]\n\n"
432
+ return
433
+ yield ": ping\n\n"
434
+ await asyncio.sleep(0.25)
435
+ # Match ListSessionEvents' session cursor without rereading every old
436
+ # run on every live poll. Only the subscribed run can still grow.
437
+ offset = 0
438
+ for record in self.studio.event_store.list_runs(session_id=session_id):
439
+ if record.id == run_id:
440
+ break
441
+ offset += len(self.studio.event_store.events(record.id))
442
+ cursor = max(0, after_seq_id - offset)
443
+ while True:
444
+ for event in await self.studio.run_service.events(run_id, after=cursor):
445
+ cursor = max(cursor, event.id)
446
+ yield self._sse(
447
+ "message",
448
+ {
449
+ "SeqId": offset + event.id,
450
+ "SessionId": session_id,
451
+ "InvocationId": invocation_id,
452
+ "EventType": self._shared_event_type(event.type, event.data),
453
+ "Content": self._shared_event_content(event.data, run_id),
454
+ "Timestamp": self._timestamp(event.created_at),
455
+ },
456
+ )
457
+ record = self.studio.event_store.get(run_id)
458
+ if not self._active_status(record.status):
459
+ yield "event: done\ndata: [DONE]\n\n"
460
+ return
461
+ yield ": ping\n\n"
462
+ await asyncio.sleep(0.25)
463
+
230
464
  def cancel_run(self, invocation_id: str) -> dict[str, Any]:
231
465
  operation_id = self._operations_by_invocation.get(invocation_id)
232
466
  if operation_id:
@@ -249,7 +483,9 @@ class StudioSharedWebBridge:
249
483
  run_id = self._response_runs.get(response_id, response_id)
250
484
  return self.studio.event_store.get(run_id).session_id
251
485
 
252
- async def stream_run(self, payload: dict[str, Any]) -> AsyncIterator[str]:
486
+ async def stream_run(
487
+ self, payload: dict[str, Any], *, shared_ui: bool = False
488
+ ) -> AsyncIterator[str]:
253
489
  agent_id = self.resolve_agent_id(str(payload.get("AgentId") or "") or None)
254
490
  session_id = str(payload.get("SessionId") or f"ses_{uuid4().hex}")
255
491
  invocation_id = str(payload.get("InvocationId") or f"resp_{uuid4().hex}")
@@ -257,10 +493,9 @@ class StudioSharedWebBridge:
257
493
  runtime_input = self._runtime_input(payload)
258
494
  model = self._select_model(agent_id, str(payload.get("Model") or ""))
259
495
  model_explicit = bool(payload.get("ModelExplicit", str(payload.get("Model") or "")))
260
- approval_mode = str(payload.get("ApprovalMode") or "")
261
- collaboration_mode = str(payload.get("CollaborationMode") or "")
262
- goal_objective = str(payload.get("GoalObjective") or "")
263
- reasoning_effort = str(payload.get("ReasoningEffort") or "")
496
+ approval_mode, collaboration_mode, goal_objective, reasoning_effort = (
497
+ self._request_controls(payload)
498
+ )
264
499
  try:
265
500
  build = await self._ensure_build(agent_id)
266
501
  self._validate_conversation_turn(
@@ -339,6 +574,15 @@ class StudioSharedWebBridge:
339
574
  if event_name == "response.output_text.delta":
340
575
  emitted_text += str(event_payload.get("delta") or "")
341
576
  yield self._sse(event_name, event_payload)
577
+ if (
578
+ shared_ui
579
+ and event_name == "a2ui.interaction"
580
+ and event_payload.get("kind") in {"form", "structured_input"}
581
+ ):
582
+ # The shared UI restores the durable Interaction/v1
583
+ # request, then subscribes to this same live run.
584
+ # Leave the execution attached while input is pending.
585
+ return
342
586
  else:
343
587
  idle_polls += 1
344
588
  if idle_polls >= 20:
@@ -391,10 +635,9 @@ class StudioSharedWebBridge:
391
635
  invocation_id = str(payload.get("InvocationId") or f"resp_{uuid4().hex}")
392
636
  model = self._select_model(agent_id, str(payload.get("Model") or ""))
393
637
  model_explicit = bool(payload.get("ModelExplicit", str(payload.get("Model") or "")))
394
- approval_mode = str(payload.get("ApprovalMode") or "")
395
- collaboration_mode = str(payload.get("CollaborationMode") or "")
396
- goal_objective = str(payload.get("GoalObjective") or "")
397
- reasoning_effort = str(payload.get("ReasoningEffort") or "")
638
+ approval_mode, collaboration_mode, goal_objective, reasoning_effort = (
639
+ self._request_controls(payload)
640
+ )
398
641
  build = await self._ensure_build(agent_id)
399
642
  prompt = self._input_text(payload)
400
643
  runtime_input = self._runtime_input(payload)
@@ -449,9 +692,7 @@ class StudioSharedWebBridge:
449
692
  ) -> RunRecord:
450
693
  if build is None:
451
694
  build = await self._ensure_build(agent_id)
452
- bound_agent = str(
453
- getattr(build, "agent_name", None) or getattr(build, "agent_id", "")
454
- )
695
+ bound_agent = str(getattr(build, "agent_name", None) or getattr(build, "agent_id", ""))
455
696
  if bound_agent != agent_id:
456
697
  raise StudioError(
457
698
  "CONVERSATION_BUILD_MISMATCH",
@@ -585,6 +826,23 @@ class StudioSharedWebBridge:
585
826
  )
586
827
  )
587
828
  continue
829
+ if event.type == "approval.resolved":
830
+ projected.append(
831
+ (
832
+ "response.ksadk.approval_resolved",
833
+ {
834
+ "type": "response.ksadk.approval_resolved",
835
+ "approvalRequestId": event.data.get("approvalId")
836
+ or event.data.get("interactionId"),
837
+ "decision": event.data.get("decision")
838
+ or event.data.get("name")
839
+ or "approved",
840
+ "revision": event.data.get("revision") or 2,
841
+ "runId": run.id,
842
+ },
843
+ )
844
+ )
845
+ continue
588
846
  item_event = self._response_item_event(event.type, event.data, starts)
589
847
  if item_event is not None:
590
848
  projected.append(item_event)
@@ -613,7 +871,9 @@ class StudioSharedWebBridge:
613
871
  "status": (
614
872
  "failed"
615
873
  if event_type.endswith("failed") or data.get("exitCode") not in {None, 0}
616
- else "completed" if done else "in_progress"
874
+ else "completed"
875
+ if done
876
+ else "in_progress"
617
877
  ),
618
878
  "action": {
619
879
  "commands": [command],
@@ -634,17 +894,24 @@ class StudioSharedWebBridge:
634
894
  "status": (
635
895
  "failed"
636
896
  if event_type.endswith("failed")
637
- else "completed" if done else "in_progress"
897
+ else "completed"
898
+ if done
899
+ else "in_progress"
638
900
  ),
639
901
  "output": data.get("output") or data.get("result") or "",
640
902
  }
641
903
  elif event_type == "approval.requested":
904
+ approval_id = str(data.get("approvalId") or data.get("interactionId") or call_id or "")
905
+ detail = data.get("detail")
906
+ arguments = detail if isinstance(detail, dict) else {"detail": detail}
642
907
  item = {
643
- "id": call_id or f"approval_{uuid4().hex}",
908
+ "id": approval_id or f"approval_{uuid4().hex}",
644
909
  "call_id": call_id,
645
- "type": "approval_request",
910
+ "type": "mcp_approval_request",
911
+ "name": str(data.get("kind") or started.get("tool") or "人工确认"),
912
+ "arguments": json.dumps(arguments, ensure_ascii=False),
913
+ "run_id": str(data.get("runId") or ""),
646
914
  "status": "in_progress",
647
- "action": data,
648
915
  }
649
916
  else:
650
917
  return None
@@ -811,15 +1078,49 @@ class StudioSharedWebBridge:
811
1078
  return media_type
812
1079
  return fallback
813
1080
 
814
- def _sessions(self, agent_id: str) -> list[dict[str, Any]]:
1081
+ async def _sessions(self, agent_id: str) -> list[dict[str, Any]]:
1082
+ persisted = await self.studio.session_service.list_session_metadata(
1083
+ agent_id=agent_id,
1084
+ )
1085
+ records = {
1086
+ session.id: self._session_metadata_record(session)
1087
+ for session in persisted
1088
+ if session.user_id in {"local-user", "local-studio"}
1089
+ }
815
1090
  grouped: dict[str, list[RunRecord]] = {}
816
1091
  for run in self.studio.event_store.list_runs():
817
1092
  if run.agent_id != agent_id:
818
1093
  continue
819
1094
  grouped.setdefault(run.session_id, []).append(run)
820
- records = [self._session_record(runs) for runs in grouped.values()]
821
- records.sort(key=lambda item: item["UpdatedAt"], reverse=True)
822
- return records
1095
+ for session_id, runs in grouped.items():
1096
+ records[session_id] = self._session_record(runs)
1097
+ ordered = list(records.values())
1098
+ ordered.sort(key=lambda item: item["UpdatedAt"], reverse=True)
1099
+ return ordered
1100
+
1101
+ def _session_metadata_record(self, session: Session) -> dict[str, Any]:
1102
+ title = session.title
1103
+ if not title and session.first_prompt:
1104
+ title = self._short_title(session.first_prompt)
1105
+ return {
1106
+ "SessionId": session.id,
1107
+ "AgentId": session.agent_id,
1108
+ "UserId": session.user_id or "local-user",
1109
+ "Title": title or "新会话",
1110
+ "FirstPrompt": session.first_prompt,
1111
+ "LastPrompt": session.last_prompt,
1112
+ "CreatedAt": self._timestamp(session.created_at),
1113
+ "UpdatedAt": self._timestamp(session.updated_at),
1114
+ "ActiveRunStatus": "",
1115
+ "ActiveInvocationId": "",
1116
+ "TokenUsage": {
1117
+ "input_tokens": 0,
1118
+ "output_tokens": 0,
1119
+ "total_tokens": 0,
1120
+ "turns": 0,
1121
+ "last_response_id": "",
1122
+ },
1123
+ }
823
1124
 
824
1125
  def _session_record(self, runs: list[RunRecord]) -> dict[str, Any]:
825
1126
  ordered = sorted(
@@ -830,6 +1131,7 @@ class StudioSharedWebBridge:
830
1131
  )
831
1132
  first = ordered[0]
832
1133
  latest = ordered[-1]
1134
+ active = next((run for run in reversed(ordered) if self._active_status(run.status)), None)
833
1135
  usage = {
834
1136
  "input_tokens": sum(run.usage.input_tokens for run in ordered),
835
1137
  "output_tokens": sum(run.usage.output_tokens for run in ordered),
@@ -846,11 +1148,26 @@ class StudioSharedWebBridge:
846
1148
  "LastPrompt": latest.input,
847
1149
  "CreatedAt": self._timestamp(first.started_at),
848
1150
  "UpdatedAt": self._timestamp(latest.completed_at or latest.started_at),
849
- "ActiveRunStatus": self._active_status(latest.status),
850
- "ActiveInvocationId": latest.id if latest.status == RunStatus.RUNNING else "",
1151
+ "ActiveRunStatus": self._active_status(active.status) if active else "",
1152
+ "ActiveInvocationId": active.id if active else "",
851
1153
  "TokenUsage": usage,
1154
+ "ContextUsage": self._context_usage(latest),
852
1155
  }
853
1156
 
1157
+ def _context_usage(self, latest: RunRecord) -> dict[str, Any] | None:
1158
+ if latest.runtime_type != "codex":
1159
+ return None
1160
+ for event in reversed(self.studio.event_store.events(latest.id)):
1161
+ if event.type == "context.compaction.completed":
1162
+ return event.data.get("contextUsage")
1163
+ if latest.runtime_type == "codex" and latest.usage.input_tokens > 0:
1164
+ return {
1165
+ "used_tokens": latest.usage.input_tokens,
1166
+ "source": "last_request",
1167
+ "model": latest.model,
1168
+ }
1169
+ return None
1170
+
854
1171
  def _model_descriptor(
855
1172
  self, agent_id: str, models: list[dict[str, Any]] | None = None
856
1173
  ) -> dict[str, Any]:
@@ -927,7 +1244,7 @@ class StudioSharedWebBridge:
927
1244
  "id": model_name,
928
1245
  "display_name": model_name,
929
1246
  "source": "agentkit-studio",
930
- "context_window_tokens": draft.spec.context.max_input_tokens,
1247
+ "input_budget_tokens": draft.spec.context.max_input_tokens,
931
1248
  "max_output_tokens": 2048,
932
1249
  "capabilities": {
933
1250
  "function_calling": True,
@@ -952,8 +1269,8 @@ class StudioSharedWebBridge:
952
1269
  "id": model_id,
953
1270
  "display_name": resolved_display_name,
954
1271
  "source": "agentkit-studio",
955
- "context_window_tokens": metadata.get("context_window_tokens")
956
- or draft.spec.context.max_input_tokens,
1272
+ "context_window_tokens": metadata.get("context_window_tokens"),
1273
+ "input_budget_tokens": draft.spec.context.max_input_tokens,
957
1274
  "max_output_tokens": max_output_tokens,
958
1275
  "capabilities": {
959
1276
  **dict(metadata.get("capabilities") or {}),
@@ -971,7 +1288,7 @@ class StudioSharedWebBridge:
971
1288
  "id": model_id,
972
1289
  "display_name": model_id if model_id != "unconfigured-model" else "未配置模型",
973
1290
  "source": "agentkit-studio",
974
- "context_window_tokens": draft.spec.context.max_input_tokens,
1291
+ "input_budget_tokens": draft.spec.context.max_input_tokens,
975
1292
  "max_output_tokens": 2048,
976
1293
  "capabilities": {
977
1294
  "function_calling": True,
@@ -997,7 +1314,7 @@ class StudioSharedWebBridge:
997
1314
  return self.studio.agent_detail(agent_id)["draft"]
998
1315
 
999
1316
  async def _run_activities(self, run: RunRecord) -> list[dict[str, Any]]:
1000
- activities: list[dict[str, Any]] = []
1317
+ activities: dict[str, dict[str, Any]] = {}
1001
1318
  for event in await self.studio.run_service.events(run.id):
1002
1319
  operations = (
1003
1320
  event.data.get("a2uiOperations")
@@ -1009,16 +1326,78 @@ class StudioSharedWebBridge:
1009
1326
  surface_id = str(
1010
1327
  event.data.get("surfaceId") or event.data.get("surface_id") or f"{run.id}-surface"
1011
1328
  )
1012
- activities.append(
1013
- {
1014
- "SeqId": event.id,
1015
- "Type": event.type,
1016
- "MessageId": f"{run.id}:assistant",
1017
- "SurfaceId": surface_id,
1018
- "Content": {"a2ui_operations": operations},
1019
- }
1329
+ previous = activities.get(surface_id)
1330
+ # Snapshot updates may repeat createSurface; only the latest full
1331
+ # snapshot should become a history row. Delta-only batches append.
1332
+ reset = any(isinstance(op, dict) and "createSurface" in op for op in operations)
1333
+ previous_operations = (
1334
+ previous["Content"]["a2ui_operations"] if previous and not reset else []
1335
+ )
1336
+ activities[surface_id] = {
1337
+ "SeqId": event.id,
1338
+ "Type": event.type,
1339
+ "MessageId": f"{run.id}:assistant",
1340
+ "SurfaceId": surface_id,
1341
+ "Content": {"a2ui_operations": [*previous_operations, *operations]},
1342
+ }
1343
+ return list(activities.values())
1344
+
1345
+ @staticmethod
1346
+ def _request_controls(payload: dict[str, Any]) -> tuple[str, str, str, str]:
1347
+ """Read turn controls from both legacy and shared-Web request shapes."""
1348
+
1349
+ metadata = payload.get("Metadata") or payload.get("metadata")
1350
+ metadata = metadata if isinstance(metadata, dict) else {}
1351
+ agentengine = metadata.get("agentengine")
1352
+ agentengine = agentengine if isinstance(agentengine, dict) else {}
1353
+ model_options = payload.get("ModelOptions") or payload.get("model_options")
1354
+ model_options = model_options if isinstance(model_options, dict) else {}
1355
+
1356
+ approval_mode = (
1357
+ str(
1358
+ payload.get("ApprovalMode")
1359
+ or payload.get("approval_mode")
1360
+ or metadata.get("approval_mode")
1361
+ or metadata.get("approvalMode")
1362
+ or agentengine.get("tool_approval_mode")
1363
+ or agentengine.get("approval_mode")
1364
+ or ""
1020
1365
  )
1021
- return activities
1366
+ .strip()
1367
+ .lower()
1368
+ )
1369
+ collaboration_mode = (
1370
+ str(
1371
+ payload.get("CollaborationMode")
1372
+ or payload.get("collaboration_mode")
1373
+ or metadata.get("collaboration_mode")
1374
+ or metadata.get("collaborationMode")
1375
+ or agentengine.get("collaboration_mode")
1376
+ or ""
1377
+ )
1378
+ .strip()
1379
+ .lower()
1380
+ )
1381
+ goal_objective = str(
1382
+ payload.get("GoalObjective")
1383
+ or payload.get("goal_objective")
1384
+ or metadata.get("goal_objective")
1385
+ or metadata.get("goalObjective")
1386
+ or agentengine.get("goal_objective")
1387
+ or ""
1388
+ ).strip()
1389
+ reasoning_effort = (
1390
+ str(
1391
+ payload.get("ReasoningEffort")
1392
+ or payload.get("reasoning_effort")
1393
+ or model_options.get("reasoning_effort")
1394
+ or model_options.get("reasoningEffort")
1395
+ or ""
1396
+ )
1397
+ .strip()
1398
+ .lower()
1399
+ )
1400
+ return approval_mode, collaboration_mode, goal_objective, reasoning_effort
1022
1401
 
1023
1402
  @staticmethod
1024
1403
  def _input_text(payload: dict[str, Any]) -> str:
@@ -1100,7 +1479,7 @@ class StudioSharedWebBridge:
1100
1479
 
1101
1480
  @staticmethod
1102
1481
  def _active_status(status: RunStatus) -> str:
1103
- return "running" if status == RunStatus.RUNNING else ""
1482
+ return "running" if status in {RunStatus.RUNNING, RunStatus.WAITING_INPUT} else ""
1104
1483
 
1105
1484
  @staticmethod
1106
1485
  def _run_output(run: RunRecord) -> str:
@@ -1108,7 +1487,8 @@ class StudioSharedWebBridge:
1108
1487
  return run.output
1109
1488
  if run.error:
1110
1489
  return str(run.error.get("message") or "Agent 运行失败")
1111
- return f"运行状态:{run.status.value}"
1490
+ status = run.status.value if isinstance(run.status, RunStatus) else str(run.status)
1491
+ return f"运行状态:{status}"
1112
1492
 
1113
1493
  @staticmethod
1114
1494
  def _short_title(value: str, limit: int = 36) -> str:
@@ -1116,8 +1496,12 @@ class StudioSharedWebBridge:
1116
1496
  return text if len(text) <= limit else f"{text[:limit]}..."
1117
1497
 
1118
1498
  @staticmethod
1119
- def _timestamp(value: datetime | None) -> str:
1120
- return (value or datetime.now(timezone.utc)).isoformat()
1499
+ def _timestamp(value: datetime | float | int | None) -> str:
1500
+ if isinstance(value, datetime):
1501
+ return value.isoformat()
1502
+ if isinstance(value, (float, int)):
1503
+ return datetime.fromtimestamp(value, tz=timezone.utc).isoformat()
1504
+ return datetime.now(timezone.utc).isoformat()
1121
1505
 
1122
1506
  @staticmethod
1123
1507
  def _sse(event: str, payload: dict[str, Any]) -> str: