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,253 @@
1
+ """Evaluation adapter for immutable Studio Build artifacts."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ from collections.abc import Callable
7
+ from dataclasses import dataclass
8
+ from typing import Any, Protocol
9
+
10
+ from ksadk.events.canonical import RuntimeEvent, parse_runtime_event
11
+
12
+ from .adapters import TargetAdapterError
13
+ from .contracts import (
14
+ EvalCase,
15
+ EvalRunSpec,
16
+ TargetKind,
17
+ TargetRef,
18
+ TargetRun,
19
+ TargetRunStatus,
20
+ TargetSnapshot,
21
+ ToolCallEvidence,
22
+ TraceRef,
23
+ UsageSnapshot,
24
+ )
25
+ from .evidence import EvidenceStore, project_tool_calls
26
+
27
+
28
+ class _StudioRunService(Protocol):
29
+ event_store: Any
30
+
31
+ async def run(
32
+ self,
33
+ spec: Any,
34
+ user_input: str,
35
+ *,
36
+ session_id: str,
37
+ on_event: Any = None,
38
+ ) -> Any: ...
39
+
40
+ async def events(self, run_id: str, *, after: int = 0) -> list[Any]: ...
41
+
42
+
43
+ @dataclass(frozen=True)
44
+ class StudioBuildResolution:
45
+ """Frozen Studio-owned build identity and executable run specification."""
46
+
47
+ build_id: str
48
+ agent_id: str
49
+ revision_digest: str
50
+ runtime: str
51
+ model: str | None
52
+ run_spec: Any
53
+ metadata: dict[str, Any]
54
+
55
+
56
+ class StudioBuildTargetError(TargetAdapterError):
57
+ """Classified failure resolving or executing a Studio Build."""
58
+
59
+
60
+ class StudioBuildTargetAdapter:
61
+ """Execute EvalCases through Studio's immutable Build runtime path."""
62
+
63
+ kind = TargetKind.STUDIO_BUILD
64
+
65
+ def __init__(
66
+ self,
67
+ *,
68
+ timeout_seconds: int,
69
+ resolve_build: Callable[[str], StudioBuildResolution],
70
+ run_service: _StudioRunService,
71
+ evidence_store: EvidenceStore | None = None,
72
+ ) -> None:
73
+ self._timeout_seconds = timeout_seconds
74
+ self._resolve_build = resolve_build
75
+ self._run_service = run_service
76
+ self._evidence_store = evidence_store
77
+ self._resolved: StudioBuildResolution | None = None
78
+ self._snapshot: TargetSnapshot | None = None
79
+
80
+ def _resolve(self, build_id: str) -> StudioBuildResolution:
81
+ try:
82
+ resolved = self._resolve_build(build_id)
83
+ except StudioBuildTargetError:
84
+ raise
85
+ except Exception as exc:
86
+ raise StudioBuildTargetError(
87
+ "STUDIO_BUILD_RESOLUTION_FAILED",
88
+ "Studio Build could not be resolved",
89
+ ) from exc
90
+ if resolved.build_id != build_id:
91
+ raise StudioBuildTargetError(
92
+ "STUDIO_BUILD_MISMATCH",
93
+ "Studio Build resolver returned a different immutable Build",
94
+ )
95
+ if not resolved.revision_digest or not resolved.runtime:
96
+ raise StudioBuildTargetError(
97
+ "STUDIO_BUILD_INVALID",
98
+ "Studio Build is missing immutable runtime identity",
99
+ )
100
+ return resolved
101
+
102
+ async def snapshot(self, target: TargetRef) -> TargetSnapshot:
103
+ if target.kind is not self.kind:
104
+ raise StudioBuildTargetError(
105
+ "STUDIO_BUILD_KIND_INVALID",
106
+ "Studio Build adapter received a non-Build target",
107
+ )
108
+ resolved = self._resolve(target.locator)
109
+ metadata = {
110
+ "buildId": resolved.build_id,
111
+ "agentId": resolved.agent_id,
112
+ **dict(resolved.metadata),
113
+ }
114
+ if resolved.model:
115
+ metadata["model"] = resolved.model
116
+ snapshot = TargetSnapshot(
117
+ kind=self.kind,
118
+ entrypoint=f"build:{resolved.build_id}",
119
+ revision_digest=resolved.revision_digest,
120
+ runtime=resolved.runtime,
121
+ metadata=metadata,
122
+ )
123
+ self._resolved = resolved
124
+ self._snapshot = snapshot
125
+ return snapshot
126
+
127
+ async def run_case(
128
+ self,
129
+ spec: EvalRunSpec,
130
+ case: EvalCase,
131
+ *,
132
+ attempt: int,
133
+ ) -> TargetRun:
134
+ resolved = self._resolved
135
+ snapshot = self._snapshot
136
+ if resolved is None or snapshot is None:
137
+ raise RuntimeError("Studio Build target must be snapshotted before execution")
138
+ if spec.target != snapshot:
139
+ raise RuntimeError("EvalRunSpec target does not match the Studio Build snapshot")
140
+
141
+ session_id = _scoped_id("eval-build-session", spec.id, case.id, str(attempt))
142
+ output = ""
143
+ duration_ms = 0
144
+ usage = UsageSnapshot()
145
+ trace_ref: TraceRef | None = None
146
+ trace_refs: list[TraceRef] = []
147
+ tool_calls: list[ToolCallEvidence] = []
148
+ for turn in case.turns:
149
+ record = await self._run_service.run(
150
+ resolved.run_spec,
151
+ turn.input,
152
+ session_id=session_id,
153
+ )
154
+ events = _runtime_events(await self._run_service.events(record.id))
155
+ if events:
156
+ tool_calls.extend(project_tool_calls(events))
157
+ trace_ref = _trace_ref(spec.id, record, events)
158
+ if self._evidence_store is not None and events:
159
+ persisted_ref = self._evidence_store.write_trace(
160
+ spec.id,
161
+ events,
162
+ session_id=session_id,
163
+ policy=spec.config.data_policy,
164
+ )
165
+ trace_ref = persisted_ref.model_copy(
166
+ update={"trace_id": str(getattr(record, "trace_id", "") or "") or None}
167
+ )
168
+ trace_refs.append(trace_ref)
169
+ duration_ms += max(0, int(getattr(record, "duration_ms", 0) or 0))
170
+ usage = _add_usage(usage, getattr(record, "usage", None))
171
+ status = _status_value(getattr(record, "status", ""))
172
+ if status != "COMPLETED":
173
+ error = getattr(record, "error", None) or {}
174
+ return TargetRun(
175
+ status=(
176
+ TargetRunStatus.CANCELLED
177
+ if status in {"CANCELLED", "INTERRUPTED"}
178
+ else TargetRunStatus.ERROR
179
+ ),
180
+ duration_ms=duration_ms,
181
+ usage=usage,
182
+ error_code=str(error.get("code") or "STUDIO_BUILD_RUN_FAILED"),
183
+ error_message="Studio Build runtime failed",
184
+ trace_ref=trace_ref,
185
+ trace_refs=trace_refs,
186
+ tool_calls=tool_calls,
187
+ metadata={"runtime": resolved.runtime, "turnCount": len(tool_calls)},
188
+ )
189
+ output = str(getattr(record, "output", "") or "")
190
+
191
+ return TargetRun(
192
+ status=TargetRunStatus.PASSED if output else TargetRunStatus.UNAVAILABLE,
193
+ output=output,
194
+ duration_ms=duration_ms,
195
+ usage=usage,
196
+ error_code=None if output else "STUDIO_BUILD_OUTPUT_UNAVAILABLE",
197
+ error_message=None if output else "Studio Build did not provide evaluable text output",
198
+ trace_ref=trace_ref,
199
+ trace_refs=trace_refs,
200
+ tool_calls=tool_calls,
201
+ metadata={"runtime": resolved.runtime, "turnCount": len(case.turns)},
202
+ )
203
+
204
+
205
+ def _runtime_events(stored_events: list[Any]) -> list[RuntimeEvent]:
206
+ events: list[RuntimeEvent] = []
207
+ for stored in stored_events:
208
+ data = getattr(stored, "data", None)
209
+ payload = data.get("runtimeEvent") if isinstance(data, dict) else None
210
+ if not isinstance(payload, dict):
211
+ continue
212
+ try:
213
+ events.append(parse_runtime_event(payload))
214
+ except ValueError:
215
+ continue
216
+ return sorted(events, key=lambda event: event.seq)
217
+
218
+
219
+ def _trace_ref(run_id: str, record: Any, events: list[RuntimeEvent]) -> TraceRef:
220
+ return TraceRef(
221
+ run_id=run_id,
222
+ trace_id=str(getattr(record, "trace_id", "") or "") or None,
223
+ session_id=str(getattr(record, "session_id", "") or "") or None,
224
+ invocation_id=str(getattr(record, "id", "") or "") or None,
225
+ seq_start=events[0].seq if events else None,
226
+ seq_end=events[-1].seq if events else None,
227
+ )
228
+
229
+
230
+ def _add_usage(total: UsageSnapshot, raw: Any) -> UsageSnapshot:
231
+ return UsageSnapshot(
232
+ input_tokens=total.input_tokens + max(0, int(getattr(raw, "input_tokens", 0) or 0)),
233
+ output_tokens=total.output_tokens + max(0, int(getattr(raw, "output_tokens", 0) or 0)),
234
+ total_tokens=total.total_tokens + max(0, int(getattr(raw, "total_tokens", 0) or 0)),
235
+ reported=total.reported or bool(getattr(raw, "reported", False)),
236
+ )
237
+
238
+
239
+ def _status_value(raw: Any) -> str:
240
+ value = getattr(raw, "value", raw)
241
+ return str(value or "").upper()
242
+
243
+
244
+ def _scoped_id(prefix: str, *parts: str) -> str:
245
+ payload = "\0".join(parts).encode("utf-8")
246
+ return f"{prefix}-{hashlib.sha256(payload).hexdigest()[:24]}"
247
+
248
+
249
+ __all__ = [
250
+ "StudioBuildResolution",
251
+ "StudioBuildTargetAdapter",
252
+ "StudioBuildTargetError",
253
+ ]
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ from typing import TYPE_CHECKING
6
7
 
7
8
  from .adapters import (
8
9
  EvaluationNotImplementedError,
@@ -20,6 +21,9 @@ from .contracts import (
20
21
  TargetSnapshot,
21
22
  )
22
23
 
24
+ if TYPE_CHECKING:
25
+ from .evidence import EvidenceStore
26
+
23
27
 
24
28
  class EvaluationExecutionError(RuntimeError):
25
29
  """A classified failure from the common target execution boundary."""
@@ -28,11 +32,18 @@ class EvaluationExecutionError(RuntimeError):
28
32
  class EvaluationTarget:
29
33
  """Own target lifecycle; protocol details stay in the selected adapter."""
30
34
 
31
- def __init__(self, target: TargetRef, config: EvaluationConfig) -> None:
35
+ def __init__(
36
+ self,
37
+ target: TargetRef,
38
+ config: EvaluationConfig,
39
+ *,
40
+ evidence_store: EvidenceStore | None = None,
41
+ adapter: TargetAdapter | None = None,
42
+ ) -> None:
32
43
  self.reference = target
33
44
  self._timeout_seconds = config.timeout_seconds
34
- self._adapter: TargetAdapter = create_target_adapter(
35
- target, timeout_seconds=config.timeout_seconds
45
+ self._adapter: TargetAdapter = adapter or create_target_adapter(
46
+ target, timeout_seconds=config.timeout_seconds, evidence_store=evidence_store
36
47
  )
37
48
 
38
49
  async def snapshot(self) -> TargetSnapshot:
@@ -42,9 +53,7 @@ class EvaluationTarget:
42
53
  timeout=self._timeout_seconds,
43
54
  )
44
55
  except TimeoutError as exc:
45
- raise EvaluationExecutionError(
46
- f"{self.reference.kind.value} Target 快照超时"
47
- ) from exc
56
+ raise EvaluationExecutionError(f"{self.reference.kind.value} Target 快照超时") from exc
48
57
  except TargetAdapterError as exc:
49
58
  raise EvaluationExecutionError(f"{exc.code}: {exc}") from exc
50
59
 
ksadk/events/__init__.py CHANGED
@@ -1,25 +1,25 @@
1
- """RuntimeEvent schema (goal-02)。见 :mod:`ksadk.events.runtime_event`。"""
1
+ """Canonical RuntimeEvent public API."""
2
2
 
3
- from ksadk.events.parser import RuntimeEventParser
4
- from ksadk.events.replay import replay_transcript
5
- from ksadk.events.runtime_event import (
3
+ from ksadk.events.canonical import (
6
4
  ALL_EVENT_TYPES,
7
- EVENT_PAYLOAD_REQUIRED_KEYS,
8
- SCHEMA_VERSION,
9
5
  EventPhase,
10
- EventType,
11
6
  RuntimeEvent,
7
+ dump_runtime_event,
8
+ parse_runtime_event,
12
9
  )
13
- from ksadk.events.store import RuntimeEventStore
10
+ from ksadk.events.canonical_replay import replay_projection
11
+ from ksadk.events.canonical_store import RuntimeEventStore
12
+ from ksadk.events.reducer import ProjectionPatch, RunProjection, StreamReducer
14
13
 
15
14
  __all__ = [
16
15
  "ALL_EVENT_TYPES",
17
- "EVENT_PAYLOAD_REQUIRED_KEYS",
18
16
  "EventPhase",
19
- "EventType",
17
+ "ProjectionPatch",
18
+ "RunProjection",
20
19
  "RuntimeEvent",
21
- "RuntimeEventParser",
22
20
  "RuntimeEventStore",
23
- "replay_transcript",
24
- "SCHEMA_VERSION",
21
+ "StreamReducer",
22
+ "dump_runtime_event",
23
+ "parse_runtime_event",
24
+ "replay_projection",
25
25
  ]
@@ -0,0 +1 @@
1
+ """Internal v1_compat implementation subpackage; stable API lives in ksadk.events.v1_compat."""
@@ -0,0 +1,299 @@
1
+ """v1 wire models: envelope, event-type registry, and projection context."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import time
6
+ import uuid
7
+ from dataclasses import dataclass, field
8
+ from typing import Any, Literal, Mapping, TypeAlias
9
+
10
+ from pydantic import BaseModel, ConfigDict, Field
11
+
12
+ from ksadk.events.content import ToolCallContent
13
+ from ksadk.events.reducer import ItemProjection, RunProjection
14
+
15
+ RuntimeEventV1ProjectionMode: TypeAlias = Literal["snapshot_only", "identity_replace"]
16
+
17
+
18
+ class V1ProjectionContextRequiredError(ValueError):
19
+ """Raised when a lossless v1 projection needs compat-local context."""
20
+
21
+
22
+ @dataclass(frozen=True)
23
+ class A2UISurfaceProjectionRef:
24
+ surface_id: str
25
+ catalog: str | None = None
26
+
27
+
28
+ @dataclass(frozen=True)
29
+ class A2UIInteractionProjectionRef:
30
+ surface_id: str
31
+ block_id: str | None = None
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class A2ATaskProjectionRef:
36
+ task_id: str
37
+ origin: str
38
+
39
+
40
+ @dataclass(frozen=True)
41
+ class RuntimeEventV1ProjectionContext:
42
+ """Ephemeral values absent from the canonical event envelope.
43
+
44
+ These values are supplied by the v1 read boundary. Framework adapters and
45
+ the canonical store must not manufacture or persist them for this module.
46
+ """
47
+
48
+ agent_id: str
49
+ user_id: str
50
+ session_id: str
51
+ projection: RunProjection | None
52
+ a2ui_surfaces: Mapping[tuple[str, str], A2UISurfaceProjectionRef] = field(default_factory=dict)
53
+ a2ui_interactions: Mapping[tuple[str, str], A2UIInteractionProjectionRef] = field(
54
+ default_factory=dict
55
+ )
56
+ a2a_tasks: Mapping[tuple[str, str], A2ATaskProjectionRef] = field(default_factory=dict)
57
+ artifact_versions: Mapping[tuple[str, str, str], int] = field(default_factory=dict)
58
+ compaction_phase: str = "runtime"
59
+
60
+ @classmethod
61
+ def from_projection(
62
+ cls,
63
+ projection: RunProjection | None,
64
+ *,
65
+ agent_id: str,
66
+ user_id: str,
67
+ session_id: str,
68
+ a2ui_surfaces: Mapping[tuple[str, str], A2UISurfaceProjectionRef] | None = None,
69
+ a2ui_interactions: Mapping[tuple[str, str], A2UIInteractionProjectionRef] | None = None,
70
+ a2a_tasks: Mapping[tuple[str, str], A2ATaskProjectionRef] | None = None,
71
+ artifact_versions: Mapping[tuple[str, str, str], int] | None = None,
72
+ compaction_phase: str = "runtime",
73
+ ) -> RuntimeEventV1ProjectionContext:
74
+ return cls(
75
+ agent_id=agent_id,
76
+ user_id=user_id,
77
+ session_id=session_id,
78
+ projection=projection,
79
+ a2ui_surfaces=a2ui_surfaces or {},
80
+ a2ui_interactions=a2ui_interactions or {},
81
+ a2a_tasks=a2a_tasks or {},
82
+ artifact_versions=artifact_versions or {},
83
+ compaction_phase=compaction_phase,
84
+ )
85
+
86
+ def item(self, scope_id: str, item_id: str) -> ItemProjection | None:
87
+ if self.projection is None:
88
+ return None
89
+ return next(
90
+ (
91
+ item
92
+ for item in self.projection.items
93
+ if item.scope_id == scope_id and item.item_id == item_id
94
+ ),
95
+ None,
96
+ )
97
+
98
+ def tool_name(self, scope_id: str, call_id: str) -> str:
99
+ if self.projection is None:
100
+ return ""
101
+ for item in self.projection.items:
102
+ if item.scope_id != scope_id:
103
+ continue
104
+ for part in item.parts:
105
+ if isinstance(part, ToolCallContent) and part.call_id == call_id:
106
+ return part.name
107
+ return ""
108
+
109
+ def interaction_call_id(self, scope_id: str, interaction_id: str) -> str:
110
+ if self.projection is None:
111
+ return ""
112
+ for interaction in self.projection.interactions:
113
+ if (
114
+ interaction.scope_id == scope_id
115
+ and interaction.interaction_id == interaction_id
116
+ and interaction.request.request_type == "approval"
117
+ ):
118
+ return interaction.request.call_id or ""
119
+ return ""
120
+
121
+ def artifact_version(self, scope_id: str, item_id: str, artifact_id: str) -> int:
122
+ version = self.artifact_versions.get((scope_id, item_id, artifact_id))
123
+ if isinstance(version, bool) or not isinstance(version, int) or version <= 0:
124
+ raise V1ProjectionContextRequiredError(
125
+ "artifact version must be an explicit positive integer"
126
+ )
127
+ return version
128
+
129
+
130
+ class EventTypeV1:
131
+ TEXT_DELTA = "text.delta"
132
+ TEXT_COMPLETED = "text.completed"
133
+ REASONING_DELTA = "reasoning.delta"
134
+ REASONING_COMPLETED = "reasoning.completed"
135
+ TOOL_CALL_BEGIN = "tool.call.begin"
136
+ TOOL_CALL_END = "tool.call.end"
137
+ ARTIFACT_CREATED = "artifact.created"
138
+ ARTIFACT_UPDATED = "artifact.updated"
139
+ APPROVAL_REQUESTED = "approval.requested"
140
+ APPROVAL_RESOLVED = "approval.resolved"
141
+ RUN_STARTED = "run.started"
142
+ RUN_PROGRESS = "run.progress"
143
+ RUN_INTERRUPTED = "run.interrupted"
144
+ RUN_COMPLETED = "run.completed"
145
+ RUN_FAILED = "run.failed"
146
+ RUN_CANCELED = "run.canceled"
147
+ CONTEXT_COMPACTION_STARTED = "context.compaction.started"
148
+ CONTEXT_COMPACTION_COMPLETED = "context.compaction.completed"
149
+ CHECKPOINT_CREATED = "checkpoint.created"
150
+ CHECKPOINT_RESUMED = "checkpoint.resumed"
151
+ USAGE_REPORTED = "usage.reported"
152
+ A2UI_SURFACE_BEGIN = "a2ui.surface.begin"
153
+ A2UI_SURFACE_UPDATE = "a2ui.surface.update"
154
+ A2UI_SURFACE_END = "a2ui.surface.end"
155
+ A2UI_INTERACTION = "a2ui.interaction"
156
+ A2UI_ACTION = "a2ui.action"
157
+ A2A_TASK_CREATED = "a2a.task.created"
158
+ A2A_TASK_STATUS = "a2a.task.status"
159
+ A2A_TASK_ARTIFACT = "a2a.task.artifact"
160
+
161
+
162
+ ALL_V1_EVENT_TYPES = frozenset(
163
+ value for name, value in vars(EventTypeV1).items() if name.isupper() and isinstance(value, str)
164
+ )
165
+
166
+ V1_EVENT_PAYLOAD_REQUIRED_KEYS: dict[str, frozenset[str]] = {
167
+ EventTypeV1.TEXT_DELTA: frozenset({"text"}),
168
+ EventTypeV1.TEXT_COMPLETED: frozenset({"text"}),
169
+ EventTypeV1.REASONING_DELTA: frozenset({"text"}),
170
+ EventTypeV1.REASONING_COMPLETED: frozenset({"text"}),
171
+ EventTypeV1.TOOL_CALL_BEGIN: frozenset({"call_id", "name"}),
172
+ EventTypeV1.TOOL_CALL_END: frozenset({"call_id", "name"}),
173
+ EventTypeV1.ARTIFACT_CREATED: frozenset({"name", "version"}),
174
+ EventTypeV1.ARTIFACT_UPDATED: frozenset({"name", "version"}),
175
+ EventTypeV1.APPROVAL_REQUESTED: frozenset({"approval_id", "call_id", "kind"}),
176
+ EventTypeV1.APPROVAL_RESOLVED: frozenset({"approval_id", "call_id", "decision"}),
177
+ EventTypeV1.RUN_STARTED: frozenset({"status"}),
178
+ EventTypeV1.RUN_PROGRESS: frozenset({"status"}),
179
+ EventTypeV1.RUN_INTERRUPTED: frozenset({"status"}),
180
+ EventTypeV1.RUN_COMPLETED: frozenset({"status"}),
181
+ EventTypeV1.RUN_FAILED: frozenset({"status", "error"}),
182
+ EventTypeV1.RUN_CANCELED: frozenset({"status"}),
183
+ EventTypeV1.CONTEXT_COMPACTION_STARTED: frozenset({"phase", "trigger"}),
184
+ EventTypeV1.CONTEXT_COMPACTION_COMPLETED: frozenset(
185
+ {"phase", "trigger", "compacted_until_seq_id"}
186
+ ),
187
+ EventTypeV1.CHECKPOINT_CREATED: frozenset({"checkpoint_id", "granularity"}),
188
+ EventTypeV1.CHECKPOINT_RESUMED: frozenset({"checkpoint_id"}),
189
+ EventTypeV1.USAGE_REPORTED: frozenset({"input_tokens", "output_tokens", "total_tokens"}),
190
+ EventTypeV1.A2UI_SURFACE_BEGIN: frozenset({"surface_id"}),
191
+ EventTypeV1.A2UI_SURFACE_UPDATE: frozenset({"surface_id"}),
192
+ EventTypeV1.A2UI_SURFACE_END: frozenset({"surface_id"}),
193
+ EventTypeV1.A2UI_INTERACTION: frozenset({"surface_id"}),
194
+ EventTypeV1.A2UI_ACTION: frozenset({"surface_id"}),
195
+ EventTypeV1.A2A_TASK_CREATED: frozenset({"task_id", "origin"}),
196
+ EventTypeV1.A2A_TASK_STATUS: frozenset({"task_id", "origin", "status"}),
197
+ EventTypeV1.A2A_TASK_ARTIFACT: frozenset({"task_id", "origin"}),
198
+ }
199
+
200
+ _V1_PHASE_AWARE_TYPES = frozenset(
201
+ {
202
+ EventTypeV1.TEXT_DELTA,
203
+ EventTypeV1.TEXT_COMPLETED,
204
+ EventTypeV1.REASONING_DELTA,
205
+ EventTypeV1.REASONING_COMPLETED,
206
+ }
207
+ )
208
+
209
+
210
+ class RuntimeEventV1(BaseModel):
211
+ """Frozen RuntimeEvent v1 JSON envelope."""
212
+
213
+ model_config = ConfigDict(extra="forbid")
214
+
215
+ schema_version: Literal[1] = 1
216
+ event_id: str
217
+ event_type: str
218
+ timestamp: float
219
+ agent_id: str
220
+ user_id: str
221
+ session_id: str
222
+ invocation_id: str
223
+ seq_id: int
224
+ phase: Literal["commentary", "final_answer"] | None = None
225
+ payload: dict[str, Any] = Field(default_factory=dict)
226
+
227
+ @classmethod
228
+ def create(
229
+ cls,
230
+ event_type: str,
231
+ *,
232
+ agent_id: str,
233
+ user_id: str,
234
+ session_id: str,
235
+ invocation_id: str,
236
+ seq_id: int,
237
+ payload: dict[str, Any] | None = None,
238
+ phase: str | None = None,
239
+ event_id: str | None = None,
240
+ timestamp: float | None = None,
241
+ ) -> RuntimeEventV1:
242
+ event = cls(
243
+ event_id=event_id or f"evt_{uuid.uuid4().hex}",
244
+ event_type=event_type,
245
+ timestamp=time.time() if timestamp is None else timestamp,
246
+ agent_id=agent_id,
247
+ user_id=user_id,
248
+ session_id=session_id,
249
+ invocation_id=invocation_id,
250
+ seq_id=seq_id,
251
+ phase=phase, # type: ignore[arg-type]
252
+ payload=payload or {},
253
+ )
254
+ event.validate_conformance()
255
+ return event
256
+
257
+ def validate_conformance(self) -> None:
258
+ if self.event_type not in ALL_V1_EVENT_TYPES:
259
+ raise ValueError(f"unknown event_type: {self.event_type!r} (v1 event family)")
260
+ if self.phase is not None and self.event_type not in _V1_PHASE_AWARE_TYPES:
261
+ raise ValueError(f"phase is only valid for v1 text/reasoning events: {self.event_type}")
262
+ required = V1_EVENT_PAYLOAD_REQUIRED_KEYS.get(self.event_type, frozenset())
263
+ missing = required - self.payload.keys()
264
+ if missing:
265
+ raise ValueError(
266
+ f"event_type {self.event_type!r} payload missing required keys: {sorted(missing)}"
267
+ )
268
+
269
+ def to_dict(self) -> dict[str, Any]:
270
+ return self.model_dump(mode="json", exclude_none=True)
271
+
272
+ def to_json(self) -> str:
273
+ return self.model_dump_json(exclude_none=True)
274
+
275
+ @classmethod
276
+ def from_dict(cls, data: dict[str, Any]) -> RuntimeEventV1:
277
+ event = cls.model_validate(data)
278
+ event.validate_conformance()
279
+ return event
280
+
281
+ @classmethod
282
+ def from_json(cls, raw: str) -> RuntimeEventV1:
283
+ event = cls.model_validate_json(raw)
284
+ event.validate_conformance()
285
+ return event
286
+
287
+
288
+ __all__ = [
289
+ "ALL_V1_EVENT_TYPES",
290
+ "A2ATaskProjectionRef",
291
+ "A2UIInteractionProjectionRef",
292
+ "A2UISurfaceProjectionRef",
293
+ "EventTypeV1",
294
+ "RuntimeEventV1",
295
+ "RuntimeEventV1ProjectionContext",
296
+ "RuntimeEventV1ProjectionMode",
297
+ "V1ProjectionContextRequiredError",
298
+ "V1_EVENT_PAYLOAD_REQUIRED_KEYS",
299
+ ]