agentengine-sdk-python 0.8.1__py3-none-any.whl → 0.8.2__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 (411) hide show
  1. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +22 -2
  2. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/RECORD +356 -222
  3. ksadk/a2a/_space_client_events.py +381 -0
  4. ksadk/a2a/event_adapter.py +156 -64
  5. ksadk/a2a/executor.py +179 -63
  6. ksadk/a2a/space_client.py +6 -333
  7. ksadk/a2ui/core.py +222 -53
  8. ksadk/agui/_agent_helpers.py +243 -0
  9. ksadk/agui/a2ui_projection.py +12 -5
  10. ksadk/agui/agent.py +443 -259
  11. ksadk/api/client.py +525 -27
  12. ksadk/builders/code_builder.py +284 -8
  13. ksadk/builders/container_builder.py +8 -1
  14. ksadk/builders/managed_runtime_builder.py +39 -35
  15. ksadk/cli/__init__.py +17 -0
  16. ksadk/cli/cmd_dashboard.py +15 -1
  17. ksadk/cli/cmd_deploy.py +10 -2
  18. ksadk/cli/cmd_eval.py +66 -9
  19. ksadk/cli/cmd_evalset.py +284 -0
  20. ksadk/cli/cmd_files.py +5 -1
  21. ksadk/cli/cmd_hermes.py +1 -126
  22. ksadk/cli/cmd_invoke.py +28 -38
  23. ksadk/cli/cmd_managed_runtime.py +95 -0
  24. ksadk/cli/cmd_observe.py +85 -0
  25. ksadk/cli/cmd_openclaw.py +1 -435
  26. ksadk/cli/cmd_replay.py +28 -4
  27. ksadk/cli/cmd_studio.py +99 -8
  28. ksadk/cli/cmd_web.py +10 -2
  29. ksadk/cli/hermes_env.py +151 -0
  30. ksadk/cli/invoke_payload.py +49 -0
  31. ksadk/cli/openclaw_env.py +458 -0
  32. ksadk/codex/client.py +180 -30
  33. ksadk/codex/runtime.py +428 -326
  34. ksadk/configs/env_registry.py +66 -12
  35. ksadk/configs/env_registry_pcm.py +181 -0
  36. ksadk/configs/env_var_spec.py +18 -0
  37. ksadk/configs/global_config.py +5 -0
  38. ksadk/context_engine/__init__.py +98 -0
  39. ksadk/context_engine/assembler.py +176 -0
  40. ksadk/context_engine/baseline.py +419 -0
  41. ksadk/context_engine/cache_observability.py +228 -0
  42. ksadk/context_engine/capabilities.py +443 -0
  43. ksadk/context_engine/contributors.py +344 -0
  44. ksadk/context_engine/hosted_pipeline.py +417 -0
  45. ksadk/context_engine/models.py +117 -0
  46. ksadk/context_engine/planner.py +698 -0
  47. ksadk/context_engine/policies.py +319 -0
  48. ksadk/context_engine/projection.py +31 -0
  49. ksadk/context_engine/shadow_plan.py +266 -0
  50. ksadk/context_engine/tokenizer.py +164 -0
  51. ksadk/conversations/context.py +126 -6
  52. ksadk/conversations/message_projection.py +292 -28
  53. ksadk/conversations/model_context.py +49 -3
  54. ksadk/conversations/runtime_compaction.py +207 -5
  55. ksadk/conversations/runtime_input.py +184 -2
  56. ksadk/conversations/runtime_invocation.py +81 -3
  57. ksadk/conversations/runtime_observability.py +141 -0
  58. ksadk/conversations/runtime_payloads.py +42 -0
  59. ksadk/conversations/runtime_preparation.py +272 -2
  60. ksadk/conversations/runtime_resume.py +20 -1
  61. ksadk/conversations/runtime_stream_events.py +94 -9
  62. ksadk/conversations/semantic_summary.py +311 -1
  63. ksadk/conversations/session_lock.py +51 -0
  64. ksadk/deployment/env_forward.py +72 -0
  65. ksadk/deployment/managed_runtime.py +5 -0
  66. ksadk/deployment/providers/serverless.py +143 -69
  67. ksadk/evaluation/__init__.py +32 -0
  68. ksadk/evaluation/a2a_adapter.py +9 -1
  69. ksadk/evaluation/adapters.py +18 -5
  70. ksadk/evaluation/agent_eval_client.py +395 -0
  71. ksadk/evaluation/cloud_binding.py +80 -0
  72. ksadk/evaluation/cloud_converter.py +194 -0
  73. ksadk/evaluation/cloud_service.py +199 -0
  74. ksadk/evaluation/contracts.py +73 -4
  75. ksadk/evaluation/evaluators.py +183 -17
  76. ksadk/evaluation/evidence.py +258 -0
  77. ksadk/evaluation/executor.py +31 -6
  78. ksadk/evaluation/local_adapter.py +550 -0
  79. ksadk/evaluation/service_env.py +27 -0
  80. ksadk/evaluation/studio_build_adapter.py +253 -0
  81. ksadk/evaluation/target.py +15 -6
  82. ksadk/events/__init__.py +13 -13
  83. ksadk/events/_v1_compat/__init__.py +1 -0
  84. ksadk/events/_v1_compat/models.py +299 -0
  85. ksadk/events/_v1_compat/parser.py +247 -0
  86. ksadk/events/_v1_compat/projection.py +753 -0
  87. ksadk/events/adapters/__init__.py +34 -0
  88. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  89. ksadk/events/adapters/_a2a_support.py +275 -0
  90. ksadk/events/adapters/_codex_interactions.py +375 -0
  91. ksadk/events/adapters/_codex_items.py +801 -0
  92. ksadk/events/adapters/_codex_validators.py +311 -0
  93. ksadk/events/adapters/_langgraph_support.py +785 -0
  94. ksadk/events/adapters/a2a.py +841 -0
  95. ksadk/events/adapters/adk.py +503 -0
  96. ksadk/events/adapters/codex.py +717 -0
  97. ksadk/events/adapters/langgraph.py +745 -0
  98. ksadk/events/canonical.py +440 -0
  99. ksadk/events/canonical_replay.py +497 -0
  100. ksadk/events/canonical_store.py +468 -0
  101. ksadk/events/cold_recovery.py +257 -0
  102. ksadk/events/content.py +89 -0
  103. ksadk/events/identity.py +86 -0
  104. ksadk/events/pipeline.py +455 -0
  105. ksadk/events/projections.py +66 -0
  106. ksadk/events/reducer.py +661 -0
  107. ksadk/events/replay.py +3 -36
  108. ksadk/events/runtime_event.py +20 -265
  109. ksadk/events/session_event.py +324 -0
  110. ksadk/events/store.py +3 -316
  111. ksadk/events/v1_compat.py +41 -0
  112. ksadk/harness/runtime.py +160 -57
  113. ksadk/identity/resolver.py +4 -3
  114. ksadk/interaction/__init__.py +28 -0
  115. ksadk/interaction/contracts.py +136 -0
  116. ksadk/interaction/ledger.py +189 -0
  117. ksadk/interaction/provider.py +122 -0
  118. ksadk/interaction/providers/__init__.py +52 -0
  119. ksadk/interaction/providers/adk.py +40 -0
  120. ksadk/interaction/providers/codex.py +94 -0
  121. ksadk/interaction/providers/langgraph.py +58 -0
  122. ksadk/kernel/__init__.py +117 -0
  123. ksadk/kernel/authorization.py +258 -0
  124. ksadk/kernel/bootstrap.py +1074 -0
  125. ksadk/kernel/contract_fingerprints.py +61 -0
  126. ksadk/kernel/contracts.py +362 -0
  127. ksadk/kernel/control.py +219 -0
  128. ksadk/kernel/errors.py +79 -0
  129. ksadk/kernel/ingress.py +1102 -0
  130. ksadk/kernel/mapping.py +111 -0
  131. ksadk/kernel/memory_store.py +1133 -0
  132. ksadk/kernel/postgres_store.py +1756 -0
  133. ksadk/kernel/recovery.py +452 -0
  134. ksadk/kernel/runtime_identity.py +103 -0
  135. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  136. ksadk/kernel/sqlite_store.py +1410 -0
  137. ksadk/kernel/state.py +145 -0
  138. ksadk/kernel/store.py +232 -0
  139. ksadk/kernel/worker.py +953 -0
  140. ksadk/knowledge_base/client.py +7 -0
  141. ksadk/knowledge_base/service.py +32 -5
  142. ksadk/memory/__init__.py +61 -0
  143. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  144. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  145. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  146. ksadk/memory/adk/backends/sdk_ltm_backend.py +384 -2
  147. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  148. ksadk/memory/coordinator.py +461 -0
  149. ksadk/memory/events.py +202 -0
  150. ksadk/memory/extraction.py +228 -0
  151. ksadk/memory/ltm_backend_factory.py +16 -3
  152. ksadk/memory/models.py +316 -0
  153. ksadk/memory/policy.py +215 -0
  154. ksadk/memory/provider.py +47 -0
  155. ksadk/memory/provider_adapter.py +159 -0
  156. ksadk/memory/provider_resolver.py +71 -0
  157. ksadk/memory/providers/__init__.py +5 -0
  158. ksadk/memory/providers/local_sqlite.py +490 -0
  159. ksadk/memory/resolved_policy.py +145 -0
  160. ksadk/memory/service.py +188 -6
  161. ksadk/model_proxy/bootstrap.py +16 -9
  162. ksadk/model_proxy/detect.py +202 -9
  163. ksadk/model_proxy/namespace.py +39 -15
  164. ksadk/model_proxy/server.py +24 -5
  165. ksadk/model_proxy/transform.py +60 -2
  166. ksadk/observability/__init__.py +25 -0
  167. ksadk/observability/session_log.py +420 -0
  168. ksadk/observability/trajectory.py +105 -0
  169. ksadk/prompts/__init__.py +71 -0
  170. ksadk/prompts/compiler.py +215 -0
  171. ksadk/prompts/models.py +82 -0
  172. ksadk/prompts/projection.py +89 -0
  173. ksadk/prompts/resolved.py +137 -0
  174. ksadk/prompts/sources.py +233 -0
  175. ksadk/runners/_langgraph_runner_streams.py +822 -0
  176. ksadk/runners/adk_runner.py +5 -5
  177. ksadk/runners/base_runner.py +16 -0
  178. ksadk/runners/factory.py +1 -2
  179. ksadk/runners/langgraph_runner.py +198 -437
  180. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  181. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  182. ksadk/runtime/adapter.py +118 -2
  183. ksadk/runtime/conversation_execution.py +316 -182
  184. ksadk/runtime/executor.py +144 -3
  185. ksadk/runtime/factory.py +193 -7
  186. ksadk/runtime/hosted_finalizer.py +268 -0
  187. ksadk/runtime/launch.py +14 -1
  188. ksadk/runtime/preprocessing.py +25 -3
  189. ksadk/runtime/runner_adapter.py +288 -508
  190. ksadk/runtime/usage.py +33 -0
  191. ksadk/sandbox/backends/e2b.py +35 -2
  192. ksadk/server/composition.py +8 -0
  193. ksadk/server/factory.py +69 -6
  194. ksadk/server/routes/kernel_ingress.py +258 -0
  195. ksadk/server/routes/openai_compat.py +88 -8
  196. ksadk/server/routes/projection.py +35 -20
  197. ksadk/server/routes/run.py +94 -0
  198. ksadk/server/routes/sessions.py +2 -0
  199. ksadk/server/routes/streaming.py +5 -2
  200. ksadk/server/static/assets/{ArtifactsPanel-CakCqxEN.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  201. ksadk/server/static/assets/{CodeBlock-CynLknyO.js → CodeBlock-DOH6MVcn.js} +4 -4
  202. ksadk/server/static/assets/{MathMessageMarkdown-3sQdOysS.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  203. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  204. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  205. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  206. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  207. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  208. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  209. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  210. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  211. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  212. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  213. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  214. ksadk/server/static/assets/{chunk-FMBD7UC4-B_fH2YuH.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  215. ksadk/server/static/assets/{chunk-ND2GUHAM-D6rFLaVV.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  216. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  217. ksadk/server/static/assets/{chunk-4BX2VUAB-B9drTgOW.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  218. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  219. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  220. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  221. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  222. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  223. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  224. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  225. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-ChNs_Mdk.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  226. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  227. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  228. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  229. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  230. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  231. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  232. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  233. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  234. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  235. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  236. ksadk/server/static/assets/{dist-Dli7qW-B.js → dist-8hqcx0sU.js} +1 -1
  237. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  238. ksadk/server/static/assets/{dist-C1sz5Eo3.js → dist-BE7bu-DL.js} +1 -1
  239. ksadk/server/static/assets/{dist-fhOuWds5.js → dist-BVDffZ0U.js} +1 -1
  240. ksadk/server/static/assets/{dist-BjOdlDjj.js → dist-BX8z72IC.js} +1 -1
  241. ksadk/server/static/assets/{dist-DsHPdk3W.js → dist-Bf2M8m3N.js} +1 -1
  242. ksadk/server/static/assets/{dist-o2OVmKvt.js → dist-BjU6y-A2.js} +1 -1
  243. ksadk/server/static/assets/{dist-DWKByxWV.js → dist-BytlxIDT.js} +1 -1
  244. ksadk/server/static/assets/{dist-DJN_6Y39.js → dist-CSh_DE14.js} +1 -1
  245. ksadk/server/static/assets/{dist-DQU9EWw-.js → dist-CXYYBw3_.js} +1 -1
  246. ksadk/server/static/assets/{dist-4N2NMVYg.js → dist-C_wsv-Qd.js} +1 -1
  247. ksadk/server/static/assets/{dist-gLnrGsoU.js → dist-ClxGviKw.js} +1 -1
  248. ksadk/server/static/assets/{dist-j6Dxmf_j.js → dist-CttYUqzS.js} +1 -1
  249. ksadk/server/static/assets/{dist-D6MpCZtz.js → dist-DNp6rLRA.js} +1 -1
  250. ksadk/server/static/assets/{dist-BB3-OwTQ.js → dist-DUX-id_F.js} +1 -1
  251. ksadk/server/static/assets/{dist-_pHPTyZ-.js → dist-DmldrHd_.js} +1 -1
  252. ksadk/server/static/assets/{dist-CWV4lDr1.js → dist-DnfXs8Vn.js} +2 -2
  253. ksadk/server/static/assets/{dist-B5oS1zcj.js → dist-Dq9gLD7L.js} +1 -1
  254. ksadk/server/static/assets/{dist-B-jNR6Vn.js → dist-W-TIVntx.js} +1 -1
  255. ksadk/server/static/assets/{dist-BIlKoW0k.js → dist-dDdADKFA.js} +1 -1
  256. ksadk/server/static/assets/{dist-X4TnqwOK.js → dist-dydu68Fl.js} +1 -1
  257. ksadk/server/static/assets/{dist-CmZHzlwZ.js → dist-ngtN0DJB.js} +1 -1
  258. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  259. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  260. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  261. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  262. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  263. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  264. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  265. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  266. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  267. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  268. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  269. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-K0OOfVna.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  270. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-8LeOJaZp.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  271. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-C6uCgZrW.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  272. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  273. ksadk/server/static/assets/{linear-hdBcYzM8.js → linear-BHjG8b-J.js} +1 -1
  274. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  275. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-Bjy_2v4_.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  276. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  277. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  278. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  279. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  280. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-BmkRbwCg.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  281. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  282. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  283. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  284. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  285. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  286. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  287. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  288. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-l6iXmU65.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  289. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-Cq6UBeQB.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  290. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  291. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  292. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  293. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  294. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  295. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-DEz24vV0.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  296. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  297. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  298. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  299. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  300. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  301. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  302. ksadk/server/static/index.html +2 -2
  303. ksadk/sessions/__init__.py +26 -9
  304. ksadk/sessions/_local_service_sync.py +688 -0
  305. ksadk/sessions/_local_tables.py +21 -0
  306. ksadk/sessions/_postgres_schema.py +305 -0
  307. ksadk/sessions/_postgres_tables.py +15 -0
  308. ksadk/sessions/base.py +80 -1
  309. ksadk/sessions/in_memory.py +53 -2
  310. ksadk/sessions/local_service.py +63 -604
  311. ksadk/sessions/postgres_service.py +58 -148
  312. ksadk/sessions/resilient.py +35 -1
  313. ksadk/studio/api.py +577 -25
  314. ksadk/studio/api_contracts.py +114 -5
  315. ksadk/studio/api_memory_routes.py +82 -0
  316. ksadk/studio/authoring.py +252 -27
  317. ksadk/studio/authoring_coordinator.py +799 -67
  318. ksadk/studio/builder.py +88 -11
  319. ksadk/studio/capabilities.py +17 -0
  320. ksadk/studio/cloud.py +1916 -95
  321. ksadk/studio/codex_agent_service.py +125 -14
  322. ksadk/studio/codex_authoring.py +469 -0
  323. ksadk/studio/codex_builder.py +138 -25
  324. ksadk/studio/codex_manifest.py +51 -22
  325. ksadk/studio/codex_run.py +46 -3
  326. ksadk/studio/compiler.py +1 -0
  327. ksadk/studio/contracts.py +114 -3
  328. ksadk/studio/event_store.py +25 -95
  329. ksadk/studio/framework_run.py +231 -3
  330. ksadk/studio/hosted_kernel.py +317 -0
  331. ksadk/studio/manifest_resolver.py +131 -0
  332. ksadk/studio/model_client.py +95 -9
  333. ksadk/studio/model_profile_service.py +1 -1
  334. ksadk/studio/operations.py +37 -5
  335. ksadk/studio/otel_trace.py +348 -42
  336. ksadk/studio/pcm_memory.py +85 -0
  337. ksadk/studio/repository.py +23 -2
  338. ksadk/studio/resource_catalog.py +43 -0
  339. ksadk/studio/run_service.py +563 -137
  340. ksadk/studio/runtime_source.py +42 -16
  341. ksadk/studio/service.py +1180 -72
  342. ksadk/studio/shared_web.py +32 -22
  343. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  344. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  345. ksadk/studio/static/index.html +2 -2
  346. ksadk/studio/templates.py +100 -8
  347. ksadk/studio/validator.py +19 -0
  348. ksadk/studio/workspace.py +30 -32
  349. ksadk/tracing/setup.py +304 -3
  350. ksadk/version.py +1 -1
  351. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  352. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  353. ksadk/events/parser.py +0 -191
  354. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  355. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +0 -303
  356. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +0 -1
  357. ksadk/server/static/assets/arc-DrgjcKhl.js +0 -1
  358. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +0 -1
  359. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-BXoVRbQ6.js +0 -36
  360. ksadk/server/static/assets/blockDiagram-GPEHLZMM-BnaB3Ywv.js +0 -132
  361. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dw4weZcp.js +0 -10
  362. ksadk/server/static/assets/channel-Dt3rQTFI.js +0 -1
  363. ksadk/server/static/assets/chunk-2J33WTMH-ChjpLK7j.js +0 -1
  364. ksadk/server/static/assets/chunk-55IACEB6-CK4ROATy.js +0 -1
  365. ksadk/server/static/assets/chunk-727SXJPM-B9KtTTgw.js +0 -206
  366. ksadk/server/static/assets/chunk-AQP2D5EJ-1O1mki3m.js +0 -231
  367. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +0 -1
  368. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +0 -1
  369. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +0 -1
  370. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  371. ksadk/server/static/assets/dagre-BM42HDAG-D0QXg_MQ.js +0 -4
  372. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  373. ksadk/server/static/assets/diagram-2AECGRRQ-DBDDKwBQ.js +0 -43
  374. ksadk/server/static/assets/diagram-5GNKFQAL-BkwDOxmO.js +0 -10
  375. ksadk/server/static/assets/diagram-KO2AKTUF-Bv8waYvY.js +0 -3
  376. ksadk/server/static/assets/diagram-LMA3HP47-e1VECDdu.js +0 -24
  377. ksadk/server/static/assets/diagram-OG6HWLK6-Ds9adfRl.js +0 -24
  378. ksadk/server/static/assets/dist-B5J2uhNk.js +0 -1
  379. ksadk/server/static/assets/erDiagram-TEJ5UH35-BPItFKH6.js +0 -85
  380. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +0 -1
  381. ksadk/server/static/assets/flowDiagram-I6XJVG4X-BbYB9w5Y.js +0 -162
  382. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-TQXa0KXv.js +0 -292
  383. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +0 -1
  384. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-bKblCnpa.js +0 -106
  385. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  386. ksadk/server/static/assets/index-R52pJJvg.js +0 -177
  387. ksadk/server/static/assets/index-jJr3_955.css +0 -2
  388. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +0 -1
  389. ksadk/server/static/assets/infoDiagram-5YYISTIA-BGVT7J_i.js +0 -2
  390. ksadk/server/static/assets/katex-CYWseY5E.js +0 -265
  391. ksadk/server/static/assets/mermaid-parser.core-BWrDjSZM.js +0 -161
  392. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +0 -1
  393. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +0 -1
  394. ksadk/server/static/assets/pieDiagram-4H26LBE5-GmmqNiVH.js +0 -30
  395. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +0 -1
  396. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DSWFqL7c.js +0 -84
  397. ksadk/server/static/assets/stateDiagram-AJRCARHV-qzTQpg3Y.js +0 -1
  398. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +0 -1
  399. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +0 -1
  400. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +0 -1
  401. ksadk/server/static/assets/vennDiagram-CIIHVFJN-CMCixki2.js +0 -34
  402. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +0 -1
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-CVzB8F9K.js +0 -78
  404. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-BFBqBLc1.js +0 -7
  405. ksadk/studio/evaluation.py +0 -192
  406. ksadk/studio/static/assets/index-CaEN0eTR.css +0 -1
  407. ksadk/studio/static/assets/index-DI2eY_NH.js +0 -252
  408. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +0 -0
  409. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  410. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  411. {agentengine_sdk_python-0.8.1.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,497 @@
1
+ """Canonical replay plus the temporary mixed-schema legacy read boundary."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ from collections.abc import AsyncIterator
7
+ from dataclasses import dataclass
8
+ from typing import Any, Protocol
9
+
10
+ from ksadk.events.canonical import (
11
+ InteractionRequested,
12
+ InteractionResolved,
13
+ ItemCompleted,
14
+ ItemSnapshotReplaced,
15
+ ItemStarted,
16
+ ItemUpdated,
17
+ RunCompleted,
18
+ RuntimeEvent,
19
+ )
20
+ from ksadk.events.canonical_store import RuntimeEventStore, session_event_to_runtime_event
21
+ from ksadk.events.content import ArtifactContent, TextContent
22
+ from ksadk.events.reducer import RunProjection, StreamReducer
23
+ from ksadk.events.v1_compat import (
24
+ EventTypeV1,
25
+ RuntimeEventV1,
26
+ RuntimeEventV1Parser,
27
+ RuntimeEventV1ProjectionContext,
28
+ V1ProjectionContextRequiredError,
29
+ project_to_v1,
30
+ )
31
+ from ksadk.sessions.base import Session, SessionEvent
32
+
33
+
34
+ class LegacyRunNotResumableError(RuntimeError):
35
+ status_code = 409
36
+ code = "legacy_run_not_resumable"
37
+
38
+ def __init__(self, run_id: str) -> None:
39
+ super().__init__(f"legacy run {run_id!r} cannot resume as a canonical run")
40
+ self.run_id = run_id
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class LegacySessionEventGroup:
45
+ """One indivisible public delivery group sharing a canonical session seq."""
46
+
47
+ seq: int
48
+ events: tuple[dict[str, Any], ...]
49
+
50
+
51
+ class RuntimeEventV1ContextProvider(Protocol):
52
+ """Supply protocol-specific v1 refs at the temporary legacy read boundary."""
53
+
54
+ def __call__(
55
+ self,
56
+ session: Session,
57
+ event: RuntimeEvent,
58
+ projection: RunProjection,
59
+ ) -> RuntimeEventV1ProjectionContext: ...
60
+
61
+
62
+ class _LegacySessionProjector:
63
+ """Session-scoped reducer/parser state shared by hydrate and incremental tail."""
64
+
65
+ def __init__(
66
+ self,
67
+ session: Session,
68
+ context_provider: RuntimeEventV1ContextProvider | None,
69
+ ) -> None:
70
+ self.session = session
71
+ self.context_provider = context_provider
72
+ self.reducers: dict[str, StreamReducer] = {}
73
+ self.parser = RuntimeEventV1Parser()
74
+
75
+ def project(self, raw: SessionEvent) -> list[dict[str, Any]]:
76
+ canonical = session_event_to_runtime_event(raw)
77
+ if canonical is None:
78
+ return [_legacy_raw_payload(raw)]
79
+ reducer = self.reducers.setdefault(canonical.run_id, StreamReducer())
80
+ reducer.apply(canonical)
81
+ projection = reducer.snapshot()
82
+ context = _legacy_projection_context(
83
+ self.session,
84
+ canonical,
85
+ projection,
86
+ provider=self.context_provider,
87
+ )
88
+ v1_events = project_to_v1(canonical, context=context)
89
+ for event in v1_events:
90
+ self.parser.feed(event)
91
+ return _canonical_legacy_payloads(
92
+ canonical,
93
+ v1_events,
94
+ projection=projection,
95
+ )
96
+
97
+
98
+ async def replay_projection(
99
+ store: RuntimeEventStore,
100
+ session_id: str,
101
+ *,
102
+ run_id: str,
103
+ through_seq: int | None = None,
104
+ settle_open: bool = False,
105
+ ) -> RunProjection:
106
+ """Rebuild one run exclusively through the live ``StreamReducer.apply`` path.
107
+
108
+ With ``settle_open`` the projection never exposes an unfinished stream to a
109
+ cold reader: an open run at the read boundary is completed in-memory with
110
+ the same deterministic outcomes :func:`ksadk.events.cold_recovery.settle_finding`
111
+ would persist, so live readers (run still executing) and cold readers
112
+ (process gone) both observe a conformant projection without consumers
113
+ special-casing a dangling stream. The synthesized events are applied to the
114
+ in-memory reducer only; persisting them is :func:`cold_recovery.recover_session`'s
115
+ job.
116
+ """
117
+
118
+ reducer = StreamReducer()
119
+ for event in await store.list(session_id, run_id=run_id):
120
+ if through_seq is not None and event.seq > through_seq:
121
+ break
122
+ reducer.apply(event)
123
+ if settle_open and (snapshot := reducer.snapshot()).status in (None, "running"):
124
+ from ksadk.events.cold_recovery import OpenItem, RecoveryFinding, settle_finding
125
+
126
+ finding = RecoveryFinding(
127
+ run_id=run_id,
128
+ scope_id=_root_scope_for(run_id),
129
+ resumable=any(c.resumable for c in snapshot.continuations),
130
+ continuation_id=(
131
+ snapshot.continuations[-1].continuation_id
132
+ if snapshot.continuations
133
+ else None
134
+ ),
135
+ open_items=[
136
+ OpenItem(
137
+ scope_id=item.scope_id,
138
+ item_id=item.item_id,
139
+ item_kind=item.item_kind,
140
+ )
141
+ for item in snapshot.items
142
+ if item.status == "open"
143
+ ],
144
+ last_seq=snapshot.last_seq or 0,
145
+ )
146
+ # 冷读者默认不允许接管执行(resume 裁决属执行层),只做确定性结算。
147
+ for event in settle_finding(
148
+ finding, session_id, allow_resume=False, timestamp=0.0
149
+ ):
150
+ reducer.apply(event)
151
+ return reducer.snapshot()
152
+
153
+
154
+ def _root_scope_for(run_id: str) -> str:
155
+ return f"run:{run_id}"
156
+
157
+
158
+ async def list_legacy_session_events(
159
+ store: RuntimeEventStore,
160
+ session_id: str,
161
+ *,
162
+ session_service: Any | None = None,
163
+ after_seq: int = 0,
164
+ before_seq: int | None = None,
165
+ limit: int | None = None,
166
+ context_provider: RuntimeEventV1ContextProvider | None = None,
167
+ ) -> list[dict[str, Any]]:
168
+ """Merge historical rows and v2 read projections in one physical seq space.
169
+
170
+ One canonical event may project to several public rows. Rows with the same
171
+ physical seq are selected as one atomic pagination/delivery group.
172
+ """
173
+
174
+ service = session_service or store.session_service
175
+ session = await service.get_session_metadata(session_id)
176
+ if session is None:
177
+ return []
178
+ raw_events = await service.get_events(session_id, before_seq_id=before_seq)
179
+ raw_events.sort(key=lambda item: item.seq_id)
180
+ projector = _LegacySessionProjector(session, context_provider)
181
+ groups: list[tuple[int, list[dict[str, Any]]]] = []
182
+
183
+ for raw in raw_events:
184
+ projected = projector.project(raw)
185
+ if projected:
186
+ groups.append((raw.seq_id, projected))
187
+
188
+ groups = [
189
+ group
190
+ for group in groups
191
+ if group[0] > after_seq and (before_seq is None or group[0] < before_seq)
192
+ ]
193
+ if limit is not None:
194
+ if limit < 1:
195
+ raise ValueError("limit must be positive")
196
+ selected: list[tuple[int, list[dict[str, Any]]]] = []
197
+ selected_size = 0
198
+ for group in reversed(groups):
199
+ selected.append(group)
200
+ selected_size += len(group[1])
201
+ if selected_size >= limit:
202
+ break
203
+ groups = list(reversed(selected))
204
+ return [payload for _seq, group in groups for payload in group]
205
+
206
+
207
+ async def subscribe_legacy_session_events(
208
+ store: RuntimeEventStore,
209
+ session_id: str,
210
+ *,
211
+ session_service: Any | None = None,
212
+ after_seq: int = 0,
213
+ poll_interval: float = 0.25,
214
+ timeout: float = 5 * 60,
215
+ context_provider: RuntimeEventV1ContextProvider | None = None,
216
+ ) -> AsyncIterator[LegacySessionEventGroup]:
217
+ """Yield whole projection groups and advance only after each group delivery."""
218
+
219
+ service = session_service or store.session_service
220
+ session = await service.get_session_metadata(session_id)
221
+ if session is None:
222
+ return
223
+ cursor = int(after_seq or 0)
224
+ projector = _LegacySessionProjector(session, context_provider)
225
+ if cursor > 0:
226
+ prefix = await service.get_events(session_id, before_seq_id=cursor + 1)
227
+ prefix.sort(key=lambda item: item.seq_id)
228
+ for raw in prefix:
229
+ projector.project(raw)
230
+
231
+ deadline = asyncio.get_running_loop().time() + timeout
232
+ while True:
233
+ rows = await service.get_events(session_id, after_seq_id=cursor)
234
+ rows.sort(key=lambda item: item.seq_id)
235
+ for raw in rows:
236
+ projected = projector.project(raw)
237
+ if projected:
238
+ yield LegacySessionEventGroup(seq=raw.seq_id, events=tuple(projected))
239
+ cursor = raw.seq_id
240
+ if asyncio.get_running_loop().time() >= deadline:
241
+ return
242
+ await asyncio.sleep(poll_interval)
243
+
244
+
245
+ async def ensure_canonical_resume_allowed(
246
+ store: RuntimeEventStore,
247
+ session_id: str,
248
+ run_id: str,
249
+ *,
250
+ session_service: Any | None = None,
251
+ ) -> None:
252
+ """Reject v1-only run resume instead of silently producing an empty v2 run."""
253
+
254
+ if await store.list(session_id, run_id=run_id):
255
+ return
256
+ service = session_service or store.session_service
257
+ for event in await service.get_events_by_invocation_id(session_id, run_id):
258
+ if session_event_to_runtime_event(event) is None:
259
+ raise LegacyRunNotResumableError(run_id)
260
+
261
+
262
+ def _legacy_raw_payload(event: SessionEvent) -> dict[str, Any]:
263
+ payload: dict[str, Any] = {
264
+ "EventId": event.id,
265
+ "SessionId": event.session_id,
266
+ "Author": event.author,
267
+ "EventType": event.event_type,
268
+ "Content": event.content,
269
+ "Timestamp": event.timestamp,
270
+ "SeqId": event.seq_id,
271
+ "Metadata": event.metadata,
272
+ }
273
+ if event.invocation_id:
274
+ payload["InvocationId"] = event.invocation_id
275
+ if event.state_delta:
276
+ payload["StateDelta"] = event.state_delta
277
+ return payload
278
+
279
+
280
+ def _legacy_projection_context(
281
+ session: Session,
282
+ event: RuntimeEvent,
283
+ projection: RunProjection,
284
+ *,
285
+ provider: RuntimeEventV1ContextProvider | None,
286
+ ) -> RuntimeEventV1ProjectionContext:
287
+ requirement = _protocol_context_requirement(event)
288
+ if provider is None:
289
+ if requirement is not None:
290
+ raise V1ProjectionContextRequiredError(
291
+ f"{requirement} requires a RuntimeEvent v1 context provider"
292
+ )
293
+ return RuntimeEventV1ProjectionContext.from_projection(
294
+ projection,
295
+ agent_id=session.agent_id,
296
+ user_id=session.user_id,
297
+ session_id=session.id,
298
+ )
299
+
300
+ context = provider(session, event, projection)
301
+ if not isinstance(context, RuntimeEventV1ProjectionContext):
302
+ raise TypeError("RuntimeEvent v1 context provider returned an invalid context")
303
+ if (
304
+ context.agent_id != session.agent_id
305
+ or context.user_id != session.user_id
306
+ or context.session_id != session.id
307
+ or context.projection != projection
308
+ ):
309
+ raise V1ProjectionContextRequiredError(
310
+ "RuntimeEvent v1 context provider must preserve session and current projection"
311
+ )
312
+ _validate_protocol_context(event, context)
313
+ return context
314
+
315
+
316
+ def _protocol_context_requirement(event: RuntimeEvent) -> str | None:
317
+ if event.source.framework == "a2a":
318
+ return "A2A task projection"
319
+ if isinstance(event, (ItemStarted, ItemUpdated, ItemSnapshotReplaced, ItemCompleted)):
320
+ if event.item_kind == "artifact":
321
+ return "artifact projection"
322
+ if event.item_kind == "data" and event.source.protocol == "a2ui":
323
+ return "A2UI surface projection"
324
+ if (
325
+ isinstance(event, (InteractionRequested, InteractionResolved))
326
+ and event.source.protocol == "a2ui"
327
+ ):
328
+ return "A2UI interaction projection"
329
+ return None
330
+
331
+
332
+ def _validate_protocol_context(
333
+ event: RuntimeEvent,
334
+ context: RuntimeEventV1ProjectionContext,
335
+ ) -> None:
336
+ if event.source.framework == "a2a":
337
+ a2a_ref = context.a2a_tasks.get((event.run_id, event.scope_id))
338
+ if a2a_ref is None or not a2a_ref.task_id.strip() or not a2a_ref.origin.strip():
339
+ raise V1ProjectionContextRequiredError(
340
+ "A2A task projection requires a context provider task ref"
341
+ )
342
+ if isinstance(event, (ItemStarted, ItemUpdated, ItemSnapshotReplaced, ItemCompleted)):
343
+ if event.item_kind == "artifact":
344
+ for part in _artifact_parts(event):
345
+ context.artifact_version(event.scope_id, event.item_id, part.artifact_id)
346
+ if event.item_kind == "data" and event.source.protocol == "a2ui":
347
+ surface_ref = context.a2ui_surfaces.get((event.scope_id, event.item_id))
348
+ if surface_ref is None or not surface_ref.surface_id.strip():
349
+ raise V1ProjectionContextRequiredError(
350
+ "A2UI surface projection requires a context provider surface ref"
351
+ )
352
+ if (
353
+ isinstance(event, (InteractionRequested, InteractionResolved))
354
+ and event.source.protocol == "a2ui"
355
+ ):
356
+ interaction_ref = context.a2ui_interactions.get((event.scope_id, event.interaction_id))
357
+ if interaction_ref is None or not interaction_ref.surface_id.strip():
358
+ raise V1ProjectionContextRequiredError(
359
+ "A2UI interaction projection requires a context provider interaction ref"
360
+ )
361
+
362
+
363
+ def _artifact_parts(
364
+ event: ItemStarted | ItemUpdated | ItemSnapshotReplaced | ItemCompleted,
365
+ ) -> tuple[ArtifactContent, ...]:
366
+ if isinstance(event, ItemStarted):
367
+ parts = event.initial.parts if event.initial is not None else ()
368
+ elif isinstance(event, ItemUpdated):
369
+ parts = (event.update,)
370
+ else:
371
+ parts = event.snapshot.parts
372
+ return tuple(part for part in parts if isinstance(part, ArtifactContent))
373
+
374
+
375
+ def _canonical_legacy_payloads(
376
+ canonical: RuntimeEvent,
377
+ events: tuple[RuntimeEventV1, ...],
378
+ *,
379
+ projection: RunProjection,
380
+ ) -> list[dict[str, Any]]:
381
+ runtime_identities = _projected_runtime_identities(canonical, events, projection=projection)
382
+ return [
383
+ _v1_to_session_payload(event, runtime_item=runtime_identities.get(index))
384
+ for index, event in enumerate(events)
385
+ ]
386
+
387
+
388
+ def _projected_runtime_identities(
389
+ canonical: RuntimeEvent,
390
+ events: tuple[RuntimeEventV1, ...],
391
+ *,
392
+ projection: RunProjection,
393
+ ) -> dict[int, dict[str, Any]]:
394
+ identities: dict[int, dict[str, Any]] = {}
395
+ if isinstance(canonical, RunCompleted):
396
+ text_indexes = [
397
+ index
398
+ for index, event in enumerate(events)
399
+ if event.event_type in {EventTypeV1.TEXT_COMPLETED, EventTypeV1.REASONING_COMPLETED}
400
+ ]
401
+ selected_parts: list[tuple[Any, str]] = []
402
+ for ref in canonical.output_refs:
403
+ item = next(
404
+ (
405
+ candidate
406
+ for candidate in projection.items
407
+ if candidate.scope_id == ref.scope_id and candidate.item_id == ref.item_id
408
+ ),
409
+ None,
410
+ )
411
+ if item is None:
412
+ continue
413
+ parts = [part for part in item.parts if isinstance(part, TextContent)]
414
+ if ref.part_id is not None:
415
+ parts = [part for part in parts if part.part_id == ref.part_id]
416
+ selected_parts.extend((ref, part.part_id) for part in parts)
417
+ for index, (ref, output_part_id) in zip(text_indexes, selected_parts):
418
+ identities[index] = {
419
+ "RunId": canonical.run_id,
420
+ "ScopeId": ref.scope_id,
421
+ "ItemId": ref.item_id,
422
+ "PartId": output_part_id,
423
+ "Operation": "replace",
424
+ "SourceEventId": canonical.source.native_event_id or canonical.event_id,
425
+ }
426
+ for index, event in enumerate(events):
427
+ if index in identities:
428
+ continue
429
+ item_id = event.payload.get("item_id")
430
+ payload_part_id = event.payload.get("part_id")
431
+ if item_id:
432
+ identities[index] = {
433
+ "RunId": canonical.run_id,
434
+ "ScopeId": event.payload.get("scope_id"),
435
+ "ItemId": item_id,
436
+ "PartId": payload_part_id,
437
+ "Operation": event.payload.get("operation"),
438
+ "SourceEventId": event.payload.get("source_event_id") or canonical.event_id,
439
+ }
440
+ return identities
441
+
442
+
443
+ def _v1_to_session_payload(
444
+ event: RuntimeEventV1, *, runtime_item: dict[str, Any] | None
445
+ ) -> dict[str, Any]:
446
+ content: dict[str, Any]
447
+ if event.event_type in {EventTypeV1.TEXT_COMPLETED, EventTypeV1.TEXT_DELTA}:
448
+ event_type = (
449
+ "assistant_message"
450
+ if event.event_type == EventTypeV1.TEXT_COMPLETED
451
+ else "assistant_stream_delta"
452
+ )
453
+ content = {"role": "model", "parts": [{"text": event.payload.get("text", "")}]}
454
+ elif event.event_type in {EventTypeV1.REASONING_COMPLETED, EventTypeV1.REASONING_DELTA}:
455
+ event_type = "reasoning"
456
+ content = {"role": "model", "parts": [{"text": event.payload.get("text", "")}]}
457
+ elif event.event_type in {
458
+ EventTypeV1.RUN_STARTED,
459
+ EventTypeV1.RUN_PROGRESS,
460
+ EventTypeV1.RUN_INTERRUPTED,
461
+ EventTypeV1.RUN_COMPLETED,
462
+ EventTypeV1.RUN_FAILED,
463
+ EventTypeV1.RUN_CANCELED,
464
+ }:
465
+ event_type = "run_status"
466
+ content = {"status": event.payload.get("status")}
467
+ else:
468
+ event_type = event.event_type
469
+ content = dict(event.payload)
470
+ metadata: dict[str, Any] = {
471
+ "schema_version": 1,
472
+ "RuntimeEventV1": dict(event.payload),
473
+ }
474
+ if runtime_item is not None:
475
+ metadata["RuntimeItem"] = runtime_item
476
+ return {
477
+ "EventId": event.event_id,
478
+ "SessionId": event.session_id,
479
+ "Author": event.agent_id,
480
+ "EventType": event_type,
481
+ "Content": content,
482
+ "Timestamp": event.timestamp,
483
+ "SeqId": event.seq_id,
484
+ "InvocationId": event.invocation_id,
485
+ "Metadata": metadata,
486
+ }
487
+
488
+
489
+ __all__ = [
490
+ "LegacyRunNotResumableError",
491
+ "LegacySessionEventGroup",
492
+ "RuntimeEventV1ContextProvider",
493
+ "ensure_canonical_resume_allowed",
494
+ "list_legacy_session_events",
495
+ "replay_projection",
496
+ "subscribe_legacy_session_events",
497
+ ]