agentengine-sdk-python 0.8.0__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 (494) hide show
  1. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/METADATA +43 -7
  2. agentengine_sdk_python-0.8.2.dist-info/RECORD +778 -0
  3. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +2 -0
  5. ksadk/a2a/_space_client_events.py +381 -0
  6. ksadk/a2a/bootstrap.py +0 -2
  7. ksadk/a2a/card.py +6 -111
  8. ksadk/a2a/control_plane.py +239 -1
  9. ksadk/a2a/event_adapter.py +156 -64
  10. ksadk/a2a/executor.py +195 -172
  11. ksadk/a2a/routes.py +12 -5
  12. ksadk/a2a/server.py +1 -8
  13. ksadk/a2a/service_env.py +33 -0
  14. ksadk/a2a/space_client.py +43 -349
  15. ksadk/a2a_card.py +101 -0
  16. ksadk/a2ui/core.py +222 -53
  17. ksadk/agui/_agent_helpers.py +243 -0
  18. ksadk/agui/a2ui_projection.py +12 -5
  19. ksadk/agui/agent.py +474 -275
  20. ksadk/agui/config.py +11 -5
  21. ksadk/agui/routes.py +7 -15
  22. ksadk/api/client.py +530 -40
  23. ksadk/api/environment.py +27 -0
  24. ksadk/builders/code_builder.py +352 -53
  25. ksadk/builders/container_builder.py +71 -44
  26. ksadk/builders/framework_requirements.py +2 -1
  27. ksadk/builders/ks3_uploader.py +2 -2
  28. ksadk/builders/managed_runtime_builder.py +60 -28
  29. ksadk/cli/__init__.py +25 -0
  30. ksadk/cli/cmd_a2a.py +18 -31
  31. ksadk/cli/cmd_create.py +13 -26
  32. ksadk/cli/cmd_dashboard.py +15 -1
  33. ksadk/cli/cmd_deploy.py +28 -3
  34. ksadk/cli/cmd_eval.py +443 -0
  35. ksadk/cli/cmd_evalset.py +284 -0
  36. ksadk/cli/cmd_files.py +5 -1
  37. ksadk/cli/cmd_hermes.py +137 -163
  38. ksadk/cli/cmd_invoke.py +28 -38
  39. ksadk/cli/cmd_launch.py +12 -0
  40. ksadk/cli/cmd_managed_runtime.py +95 -0
  41. ksadk/cli/cmd_observe.py +85 -0
  42. ksadk/cli/cmd_openclaw.py +85 -479
  43. ksadk/cli/cmd_replay.py +28 -4
  44. ksadk/cli/cmd_run.py +29 -67
  45. ksadk/cli/cmd_studio.py +201 -0
  46. ksadk/cli/cmd_web.py +15 -6
  47. ksadk/cli/dry_run.py +2 -1
  48. ksadk/cli/env_options.py +83 -0
  49. ksadk/cli/global_options.py +3 -1
  50. ksadk/cli/hermes_env.py +151 -0
  51. ksadk/cli/invoke_payload.py +49 -0
  52. ksadk/cli/network_options.py +7 -5
  53. ksadk/cli/openclaw_env.py +458 -0
  54. ksadk/cli/runtime_bootstrap.py +51 -0
  55. ksadk/cli/ui.py +6 -0
  56. ksadk/cli/workflow_common.py +5 -5
  57. ksadk/codex/__init__.py +3 -3
  58. ksadk/codex/client.py +833 -49
  59. ksadk/codex/phase.py +1 -1
  60. ksadk/codex/runtime.py +720 -127
  61. ksadk/common/kop_client.py +232 -0
  62. ksadk/configs/__init__.py +1 -3
  63. ksadk/configs/env_registry.py +244 -45
  64. ksadk/configs/env_registry_pcm.py +181 -0
  65. ksadk/configs/env_var_spec.py +18 -0
  66. ksadk/configs/global_config.py +6 -1
  67. ksadk/configs/settings.py +5 -108
  68. ksadk/context_engine/__init__.py +98 -0
  69. ksadk/context_engine/assembler.py +176 -0
  70. ksadk/context_engine/baseline.py +419 -0
  71. ksadk/context_engine/cache_observability.py +228 -0
  72. ksadk/context_engine/capabilities.py +443 -0
  73. ksadk/context_engine/contributors.py +344 -0
  74. ksadk/context_engine/hosted_pipeline.py +417 -0
  75. ksadk/context_engine/models.py +117 -0
  76. ksadk/context_engine/planner.py +698 -0
  77. ksadk/context_engine/policies.py +319 -0
  78. ksadk/context_engine/projection.py +31 -0
  79. ksadk/context_engine/shadow_plan.py +266 -0
  80. ksadk/context_engine/tokenizer.py +164 -0
  81. ksadk/conversations/__init__.py +85 -94
  82. ksadk/conversations/context.py +126 -6
  83. ksadk/conversations/message_projection.py +292 -28
  84. ksadk/conversations/model_context.py +49 -3
  85. ksadk/conversations/runtime_compaction.py +207 -5
  86. ksadk/conversations/runtime_input.py +193 -3
  87. ksadk/conversations/runtime_invocation.py +81 -3
  88. ksadk/conversations/runtime_observability.py +157 -4
  89. ksadk/conversations/runtime_payloads.py +42 -0
  90. ksadk/conversations/runtime_preparation.py +280 -2
  91. ksadk/conversations/runtime_resume.py +71 -32
  92. ksadk/conversations/runtime_stream_events.py +94 -9
  93. ksadk/conversations/runtime_streaming.py +175 -22
  94. ksadk/conversations/semantic_summary.py +311 -1
  95. ksadk/conversations/session_lock.py +51 -0
  96. ksadk/deployment/env_forward.py +72 -0
  97. ksadk/deployment/managed_runtime.py +38 -0
  98. ksadk/deployment/manager.py +24 -8
  99. ksadk/deployment/providers/serverless.py +228 -92
  100. ksadk/evaluation/__init__.py +116 -0
  101. ksadk/evaluation/a2a_adapter.py +452 -0
  102. ksadk/evaluation/adapters.py +67 -0
  103. ksadk/evaluation/agent_eval_client.py +395 -0
  104. ksadk/evaluation/cloud_binding.py +80 -0
  105. ksadk/evaluation/cloud_converter.py +194 -0
  106. ksadk/evaluation/cloud_service.py +199 -0
  107. ksadk/evaluation/contracts.py +478 -0
  108. ksadk/evaluation/evalset.py +351 -0
  109. ksadk/evaluation/evaluators.py +627 -0
  110. ksadk/evaluation/evidence.py +258 -0
  111. ksadk/evaluation/executor.py +143 -0
  112. ksadk/evaluation/local_adapter.py +550 -0
  113. ksadk/evaluation/service_env.py +27 -0
  114. ksadk/evaluation/storage.py +68 -0
  115. ksadk/evaluation/studio_build_adapter.py +253 -0
  116. ksadk/evaluation/target.py +82 -0
  117. ksadk/events/__init__.py +13 -13
  118. ksadk/events/_v1_compat/__init__.py +1 -0
  119. ksadk/events/_v1_compat/models.py +299 -0
  120. ksadk/events/_v1_compat/parser.py +247 -0
  121. ksadk/events/_v1_compat/projection.py +753 -0
  122. ksadk/events/adapters/__init__.py +34 -0
  123. ksadk/events/adapters/_a2a_snapshot.py +622 -0
  124. ksadk/events/adapters/_a2a_support.py +275 -0
  125. ksadk/events/adapters/_codex_interactions.py +375 -0
  126. ksadk/events/adapters/_codex_items.py +801 -0
  127. ksadk/events/adapters/_codex_validators.py +311 -0
  128. ksadk/events/adapters/_langgraph_support.py +785 -0
  129. ksadk/events/adapters/a2a.py +841 -0
  130. ksadk/events/adapters/adk.py +503 -0
  131. ksadk/events/adapters/codex.py +717 -0
  132. ksadk/events/adapters/langgraph.py +745 -0
  133. ksadk/events/canonical.py +440 -0
  134. ksadk/events/canonical_replay.py +497 -0
  135. ksadk/events/canonical_store.py +468 -0
  136. ksadk/events/cold_recovery.py +257 -0
  137. ksadk/events/content.py +89 -0
  138. ksadk/events/identity.py +86 -0
  139. ksadk/events/pipeline.py +455 -0
  140. ksadk/events/projections.py +66 -0
  141. ksadk/events/reducer.py +661 -0
  142. ksadk/events/replay.py +3 -36
  143. ksadk/events/runtime_event.py +20 -256
  144. ksadk/events/session_event.py +324 -0
  145. ksadk/events/store.py +3 -316
  146. ksadk/events/v1_compat.py +41 -0
  147. ksadk/harness/__init__.py +3 -2
  148. ksadk/harness/app.py +114 -123
  149. ksadk/harness/config.py +1 -1
  150. ksadk/harness/runtime.py +467 -0
  151. ksadk/hermes_terminal.py +5 -0
  152. ksadk/identity/resolver.py +4 -3
  153. ksadk/interaction/__init__.py +28 -0
  154. ksadk/interaction/contracts.py +136 -0
  155. ksadk/interaction/ledger.py +189 -0
  156. ksadk/interaction/provider.py +122 -0
  157. ksadk/interaction/providers/__init__.py +52 -0
  158. ksadk/interaction/providers/adk.py +40 -0
  159. ksadk/interaction/providers/codex.py +94 -0
  160. ksadk/interaction/providers/langgraph.py +58 -0
  161. ksadk/kernel/__init__.py +117 -0
  162. ksadk/kernel/authorization.py +258 -0
  163. ksadk/kernel/bootstrap.py +1074 -0
  164. ksadk/kernel/contract_fingerprints.py +61 -0
  165. ksadk/kernel/contracts.py +362 -0
  166. ksadk/kernel/control.py +219 -0
  167. ksadk/kernel/errors.py +79 -0
  168. ksadk/kernel/ingress.py +1102 -0
  169. ksadk/kernel/mapping.py +111 -0
  170. ksadk/kernel/memory_store.py +1133 -0
  171. ksadk/kernel/postgres_store.py +1756 -0
  172. ksadk/kernel/recovery.py +452 -0
  173. ksadk/kernel/runtime_identity.py +103 -0
  174. ksadk/kernel/sql/001_agent_kernel.sql +120 -0
  175. ksadk/kernel/sqlite_store.py +1410 -0
  176. ksadk/kernel/state.py +145 -0
  177. ksadk/kernel/store.py +232 -0
  178. ksadk/kernel/worker.py +953 -0
  179. ksadk/knowledge_base/client.py +22 -4
  180. ksadk/knowledge_base/service.py +32 -5
  181. ksadk/managed_a2a_card.py +160 -0
  182. ksadk/managed_runtime.py +16 -9
  183. ksadk/memory/__init__.py +61 -0
  184. ksadk/memory/adk/backends/base_ltm_backend.py +96 -1
  185. ksadk/memory/adk/backends/http_ltm_backend.py +14 -5
  186. ksadk/memory/adk/backends/inmemory_ltm_backend.py +136 -3
  187. ksadk/memory/adk/backends/sdk_ltm_backend.py +394 -5
  188. ksadk/memory/adk/backends/sqlite_ltm_backend.py +95 -0
  189. ksadk/memory/adk/long_term_memory.py +3 -2
  190. ksadk/memory/coordinator.py +461 -0
  191. ksadk/memory/events.py +202 -0
  192. ksadk/memory/extraction.py +228 -0
  193. ksadk/memory/ltm_backend_factory.py +16 -3
  194. ksadk/memory/models.py +316 -0
  195. ksadk/memory/policy.py +215 -0
  196. ksadk/memory/provider.py +47 -0
  197. ksadk/memory/provider_adapter.py +159 -0
  198. ksadk/memory/provider_resolver.py +71 -0
  199. ksadk/memory/providers/__init__.py +5 -0
  200. ksadk/memory/providers/local_sqlite.py +490 -0
  201. ksadk/memory/resolved_policy.py +145 -0
  202. ksadk/memory/service.py +198 -8
  203. ksadk/memory/tool.py +4 -0
  204. ksadk/model_proxy/bootstrap.py +16 -9
  205. ksadk/model_proxy/config.py +22 -1
  206. ksadk/model_proxy/detect.py +202 -9
  207. ksadk/model_proxy/namespace.py +67 -15
  208. ksadk/model_proxy/server.py +168 -6
  209. ksadk/model_proxy/transform.py +105 -3
  210. ksadk/observability/__init__.py +25 -0
  211. ksadk/observability/session_log.py +420 -0
  212. ksadk/observability/trajectory.py +105 -0
  213. ksadk/prompts/__init__.py +71 -0
  214. ksadk/prompts/compiler.py +215 -0
  215. ksadk/prompts/models.py +82 -0
  216. ksadk/prompts/projection.py +89 -0
  217. ksadk/prompts/resolved.py +137 -0
  218. ksadk/prompts/sources.py +233 -0
  219. ksadk/runners/_langgraph_runner_streams.py +822 -0
  220. ksadk/runners/adk_runner.py +14 -31
  221. ksadk/runners/base_runner.py +44 -3
  222. ksadk/runners/factory.py +3 -3
  223. ksadk/runners/langgraph_runner.py +252 -433
  224. ksadk/runners/utils/__init__.py +0 -10
  225. ksadk/runners/utils/loader.py +16 -0
  226. ksadk/runtime/__init__.py +67 -41
  227. ksadk/runtime/_runner_adapter/__init__.py +1 -0
  228. ksadk/runtime/_runner_adapter/stream_mapping.py +788 -0
  229. ksadk/runtime/adapter.py +199 -16
  230. ksadk/runtime/conversation_execution.py +687 -0
  231. ksadk/runtime/executor.py +392 -0
  232. ksadk/runtime/factory.py +342 -0
  233. ksadk/runtime/framework_adapters.py +6 -12
  234. ksadk/runtime/hosted_finalizer.py +268 -0
  235. ksadk/runtime/launch.py +61 -0
  236. ksadk/runtime/preprocessing.py +49 -14
  237. ksadk/runtime/runner_adapter.py +330 -391
  238. ksadk/runtime/runner_loading.py +36 -0
  239. ksadk/runtime/usage.py +33 -0
  240. ksadk/sandbox/backends/e2b.py +36 -3
  241. ksadk/server/__init__.py +39 -4
  242. ksadk/server/app.py +18 -492
  243. ksadk/server/composition.py +36 -2
  244. ksadk/server/factory.py +210 -149
  245. ksadk/server/routes/common.py +15 -46
  246. ksadk/server/routes/control.py +13 -9
  247. ksadk/server/routes/kernel_ingress.py +258 -0
  248. ksadk/server/routes/misc.py +10 -33
  249. ksadk/server/routes/models.py +14 -6
  250. ksadk/server/routes/openai_compat.py +129 -27
  251. ksadk/server/routes/projection.py +84 -16
  252. ksadk/server/routes/run.py +347 -460
  253. ksadk/server/routes/sessions.py +37 -40
  254. ksadk/server/routes/streaming.py +52 -7
  255. ksadk/server/routes/workspace.py +54 -21
  256. ksadk/server/static/assets/{ArtifactsPanel-Cjnqt-8W.js → ArtifactsPanel-DSU1sWD_.js} +1 -1
  257. ksadk/server/static/assets/{CodeBlock-BqyqZfuB.js → CodeBlock-DOH6MVcn.js} +4 -4
  258. ksadk/server/static/assets/{MathMessageMarkdown-BpH7jiFM.js → MathMessageMarkdown-BL8my1R2.js} +4 -4
  259. ksadk/server/static/assets/MathMessageMarkdown-BorAY7qD.css +1 -0
  260. ksadk/server/static/assets/MermaidBlock-Dz4IP-Tx.js +312 -0
  261. ksadk/server/static/assets/NativeTerminalPanel-DUrK0JpZ.js +1 -0
  262. ksadk/server/static/assets/abnfDiagram-VCTEODGH-g20pFzNV.js +1 -0
  263. ksadk/server/static/assets/arc-C4FzinUA.js +1 -0
  264. ksadk/server/static/assets/architecture-7GRP2DOG-DjKratdf.js +1 -0
  265. ksadk/server/static/assets/architectureDiagram-5GKGNRK7-DpIqL5h4.js +36 -0
  266. ksadk/server/static/assets/blockDiagram-NRAW4CY4-BjkljTNz.js +129 -0
  267. ksadk/server/static/assets/c4Diagram-UCG6FXSJ-Dk_ieq2X.js +38 -0
  268. ksadk/server/static/assets/channel-4cQHKtx1.js +1 -0
  269. ksadk/server/static/assets/chunk-2Q5K7J3B-DmgWkESh.js +1 -0
  270. ksadk/server/static/assets/{chunk-FMBD7UC4-BGhvzDYt.js → chunk-5VM5RSS4-BVHAchFb.js} +1 -1
  271. ksadk/server/static/assets/{chunk-ND2GUHAM-D98vPd-E.js → chunk-F27PBJKO-C-ipQzuS.js} +1 -1
  272. ksadk/server/static/assets/chunk-G27WJ6UU-C2EyJbIK.js +231 -0
  273. ksadk/server/static/assets/{chunk-4BX2VUAB-CsWIQRhc.js → chunk-JWPE2WC7-vYvVJb_M.js} +1 -1
  274. ksadk/server/static/assets/chunk-LCL6LL3I-BcI6ysPT.js +206 -0
  275. ksadk/server/static/assets/chunk-POPQ4Y6H-C030x_Z1.js +1 -0
  276. ksadk/server/static/assets/chunk-RHFEMEQ7-yyGpsz4n.js +168 -0
  277. ksadk/server/static/assets/chunk-SVP7TREG-BLTlmMU7.js +88 -0
  278. ksadk/server/static/assets/chunk-XXDRQBXY-C_32ArgP.js +1 -0
  279. ksadk/server/static/assets/classDiagram-DTDB5LWJ-DLFd9Xi0.js +1 -0
  280. ksadk/server/static/assets/classDiagram-v2-JRS7N3AN-DLFd9Xi0.js +1 -0
  281. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-CX3yotHq.js → cose-bilkent-JH36ORCC-9YQYwdl0.js} +1 -1
  282. ksadk/server/static/assets/cynefin-OW5HDTMX-DjEM48Qp.js +1 -0
  283. ksadk/server/static/assets/cynefinDiagram-5FMLGOSQ-ErLF5N13.js +62 -0
  284. ksadk/server/static/assets/cytoscape.esm-CyCl8rPi.js +321 -0
  285. ksadk/server/static/assets/dagre-3AP2YEHR-DFiQF-6f.js +4 -0
  286. ksadk/server/static/assets/dagre-BuhGnRI1.js +1 -0
  287. ksadk/server/static/assets/diagram-S7CK7UJ4-Bt1v8-GC.js +30 -0
  288. ksadk/server/static/assets/diagram-UQ7AKVKN-DSCxJdBK.js +41 -0
  289. ksadk/server/static/assets/diagram-VSXAHHWV-DHfYwp_9.js +3 -0
  290. ksadk/server/static/assets/diagram-VX7I27RA-DdzD-4Le.js +24 -0
  291. ksadk/server/static/assets/diagram-Z3DM3KII-Du-nAJ9F.js +24 -0
  292. ksadk/server/static/assets/{dist-D82mtD2s.js → dist-8hqcx0sU.js} +1 -1
  293. ksadk/server/static/assets/dist-B7seoj3d.js +1 -0
  294. ksadk/server/static/assets/{dist-DHn6nBzr.js → dist-BE7bu-DL.js} +1 -1
  295. ksadk/server/static/assets/{dist-eoW6tZXA.js → dist-BVDffZ0U.js} +1 -1
  296. ksadk/server/static/assets/{dist-C2xjE7cO.js → dist-BX8z72IC.js} +1 -1
  297. ksadk/server/static/assets/{dist-CgF3fj15.js → dist-Bf2M8m3N.js} +1 -1
  298. ksadk/server/static/assets/{dist-Bs-jQcRX.js → dist-BjU6y-A2.js} +1 -1
  299. ksadk/server/static/assets/{dist-Djgl2wVZ.js → dist-BytlxIDT.js} +1 -1
  300. ksadk/server/static/assets/{dist-CVQRZjPu.js → dist-CSh_DE14.js} +1 -1
  301. ksadk/server/static/assets/{dist-6CVKuTAe.js → dist-CXYYBw3_.js} +1 -1
  302. ksadk/server/static/assets/{dist-DlzCRy0S.js → dist-C_wsv-Qd.js} +1 -1
  303. ksadk/server/static/assets/{dist-DF06ORQo.js → dist-ClxGviKw.js} +1 -1
  304. ksadk/server/static/assets/{dist-Cf23NY4L.js → dist-CttYUqzS.js} +1 -1
  305. ksadk/server/static/assets/{dist-ivOya1LD.js → dist-DNp6rLRA.js} +1 -1
  306. ksadk/server/static/assets/{dist-BibcG1V9.js → dist-DUX-id_F.js} +1 -1
  307. ksadk/server/static/assets/{dist-BUHRxvDG.js → dist-DmldrHd_.js} +1 -1
  308. ksadk/server/static/assets/{dist-BZ9n9AjO.js → dist-DnfXs8Vn.js} +2 -2
  309. ksadk/server/static/assets/{dist-DqNnNFrw.js → dist-Dq9gLD7L.js} +1 -1
  310. ksadk/server/static/assets/{dist-CGcp2ex8.js → dist-W-TIVntx.js} +1 -1
  311. ksadk/server/static/assets/{dist-Cwt7koer.js → dist-dDdADKFA.js} +1 -1
  312. ksadk/server/static/assets/{dist-C7-3jInC.js → dist-dydu68Fl.js} +1 -1
  313. ksadk/server/static/assets/{dist-C99THtIA.js → dist-ngtN0DJB.js} +1 -1
  314. ksadk/server/static/assets/ebnfDiagram-PWID7BFC-Da9C9NO1.js +1 -0
  315. ksadk/server/static/assets/erDiagram-SSCWMZ5O-EAGqqR79.js +99 -0
  316. ksadk/server/static/assets/eventmodeling-NTZA5JFV-CMgMaJrC.js +1 -0
  317. ksadk/server/static/assets/flowDiagram-A5DVABFB-BBKL0x3P.js +1 -0
  318. ksadk/server/static/assets/ganttDiagram-EL5Y4UJY-DqJsKb59.js +292 -0
  319. ksadk/server/static/assets/gitGraph-4MIJSDKK-Dw63mrhw.js +1 -0
  320. ksadk/server/static/assets/gitGraphDiagram-WWUBYQGX-B6g4dtDi.js +106 -0
  321. ksadk/server/static/assets/index-8ipRcQ-M.js +240 -0
  322. ksadk/server/static/assets/index-ByFCqjlh.css +2 -0
  323. ksadk/server/static/assets/info-A6RAGUB7-B6iAblII.js +1 -0
  324. ksadk/server/static/assets/infoDiagram-RXCK75RN-Djm_nbd5.js +2 -0
  325. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-DLOHGvWw.js → ishikawaDiagram-5VMMS53U-DWya9SG2.js} +6 -6
  326. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-BIzKeejT.js → journeyDiagram-EYS64GPL-DutxhSNI.js} +6 -6
  327. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-BWHoFSw2.js → kanban-definition-3QL26DDD-DJdOF8Fm.js} +10 -10
  328. ksadk/server/static/assets/katex-vFWytM5c.js +257 -0
  329. ksadk/server/static/assets/{linear-CvMBw9cA.js → linear-BHjG8b-J.js} +1 -1
  330. ksadk/server/static/assets/mermaid-parser.core-KGSy4jWT.js +166 -0
  331. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-CSAQxEAe.js → mindmap-definition-FBJOCRG2-9-HC88D4.js} +29 -29
  332. ksadk/server/static/assets/packet-AYTQ26CC-BOYAipuq.js +1 -0
  333. ksadk/server/static/assets/pegDiagram-XKGWAZYB-DrEZd4fD.js +1 -0
  334. ksadk/server/static/assets/pie-WAS4IAKB-Ctq0Kbku.js +1 -0
  335. ksadk/server/static/assets/pieDiagram-E7YTZNPT-DpjqOFFp.js +39 -0
  336. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-CxIR4JXI.js → quadrantDiagram-AXDQQJYC-BiNhgOXX.js} +6 -6
  337. ksadk/server/static/assets/radar-RG4KPBEZ-DN0-ul_0.js +1 -0
  338. ksadk/server/static/assets/railroad-74A4TZTK-C6cC_to0.js +1 -0
  339. ksadk/server/static/assets/railroad-abnf-HS5TGJTU-BimjIuRc.js +1 -0
  340. ksadk/server/static/assets/railroad-ebnf-LZEXJU2U-CvY65ABq.js +1 -0
  341. ksadk/server/static/assets/railroad-peg-WCYAUIDC-D72Iq_Tv.js +1 -0
  342. ksadk/server/static/assets/railroadDiagram-O6MQD6OU-_Y3Ojg6G.js +1 -0
  343. ksadk/server/static/assets/requirementDiagram-EFPCY7ZU-DeCFdg9K.js +84 -0
  344. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-DpGa6EAV.js → sankeyDiagram-P5KCCOFB-CPH75rhw.js} +7 -7
  345. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-NTKNGGe5.js → sequenceDiagram-WJ2MYXX4-OEpQQdr4.js} +10 -10
  346. ksadk/server/static/assets/sizeCapture-X5ZJPWSS-heUErzhI.js +1 -0
  347. ksadk/server/static/assets/stateDiagram-HBIQ2CUA-DvA3jSMB.js +1 -0
  348. ksadk/server/static/assets/stateDiagram-v2-4QOOHH4V-BgQY03nz.js +1 -0
  349. ksadk/server/static/assets/swimlanes-XN3QIQJK-CR-dfN_t.js +1 -0
  350. ksadk/server/static/assets/swimlanesDiagram-VK2B7HYN-DLVw3q5Q.js +8 -0
  351. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-jqoYs3jQ.js → timeline-definition-24CTP7MA-DAVJf1TX.js} +7 -7
  352. ksadk/server/static/assets/treeView-Q6P3EWNA-BMpO0wsB.js +1 -0
  353. ksadk/server/static/assets/treemap-WGGIJYW6-Et0aqzU3.js +1 -0
  354. ksadk/server/static/assets/vennDiagram-4TSXK5OY-DwM8eDkh.js +34 -0
  355. ksadk/server/static/assets/wardley-WFR3VGLG-CbY0mhpl.js +1 -0
  356. ksadk/server/static/assets/wardleyDiagram-VM6X3IG4-DZL-Zz2t.js +78 -0
  357. ksadk/server/static/assets/xychartDiagram-S5SC5T6Z-Dy6Yh_hu.js +7 -0
  358. ksadk/server/static/index.html +2 -2
  359. ksadk/sessions/__init__.py +26 -9
  360. ksadk/sessions/_local_service_sync.py +688 -0
  361. ksadk/sessions/_local_tables.py +21 -0
  362. ksadk/sessions/_postgres_schema.py +305 -0
  363. ksadk/sessions/_postgres_tables.py +15 -0
  364. ksadk/sessions/base.py +80 -1
  365. ksadk/sessions/in_memory.py +53 -2
  366. ksadk/sessions/local_service.py +63 -604
  367. ksadk/sessions/postgres_service.py +58 -148
  368. ksadk/sessions/resilient.py +35 -1
  369. ksadk/skills/runtime/backends/e2b.py +1 -1
  370. ksadk/skills/service_client.py +13 -3
  371. ksadk/studio/__init__.py +5 -0
  372. ksadk/studio/agent_avatar_assets.py +120 -0
  373. ksadk/studio/agent_lifecycle.py +51 -0
  374. ksadk/studio/api.py +1598 -0
  375. ksadk/studio/api_catalog_routes.py +324 -0
  376. ksadk/studio/api_contracts.py +286 -0
  377. ksadk/studio/api_helpers.py +132 -0
  378. ksadk/studio/api_memory_routes.py +82 -0
  379. ksadk/studio/authoring.py +749 -0
  380. ksadk/studio/authoring_coordinator.py +1017 -0
  381. ksadk/studio/builder.py +397 -0
  382. ksadk/studio/capabilities.py +368 -0
  383. ksadk/studio/cloud.py +2099 -0
  384. ksadk/studio/codex_agent_service.py +694 -0
  385. ksadk/studio/codex_authoring.py +469 -0
  386. ksadk/studio/codex_builder.py +437 -0
  387. ksadk/studio/codex_manifest.py +307 -0
  388. ksadk/studio/codex_run.py +395 -0
  389. ksadk/studio/compiler.py +190 -0
  390. ksadk/studio/contracts.py +755 -0
  391. ksadk/studio/errors.py +47 -0
  392. ksadk/studio/event_store.py +214 -0
  393. ksadk/studio/framework_run.py +342 -0
  394. ksadk/studio/hosted_kernel.py +317 -0
  395. ksadk/studio/identifiers.py +33 -0
  396. ksadk/studio/manifest_resolver.py +131 -0
  397. ksadk/studio/mcp_runtime.py +229 -0
  398. ksadk/studio/model_client.py +629 -0
  399. ksadk/studio/model_profile_service.py +214 -0
  400. ksadk/studio/operations.py +275 -0
  401. ksadk/studio/otel_trace.py +1060 -0
  402. ksadk/studio/pagination.py +182 -0
  403. ksadk/studio/pcm_memory.py +85 -0
  404. ksadk/studio/python_tool_inspection.py +183 -0
  405. ksadk/studio/repository.py +327 -0
  406. ksadk/studio/resource_catalog.py +1260 -0
  407. ksadk/studio/run_service.py +1133 -0
  408. ksadk/studio/runtime_catalog.py +74 -0
  409. ksadk/studio/runtime_source.py +365 -0
  410. ksadk/studio/service.py +2249 -0
  411. ksadk/studio/shared_web.py +1004 -0
  412. ksadk/studio/skill_discovery.py +628 -0
  413. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  414. ksadk/studio/static/assets/index-BLpcdrgW.css +1 -0
  415. ksadk/studio/static/assets/index-CYekR2Xv.js +260 -0
  416. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  417. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  418. ksadk/studio/static/index.html +15 -0
  419. ksadk/studio/templates.py +722 -0
  420. ksadk/studio/validator.py +265 -0
  421. ksadk/studio/workspace.py +135 -0
  422. ksadk/tools/gateway.py +9 -0
  423. ksadk/toolsets/__init__.py +27 -1
  424. ksadk/toolsets/a2a.py +426 -0
  425. ksadk/tracing/__init__.py +19 -21
  426. ksadk/tracing/setup.py +317 -403
  427. ksadk/tracing/span_utils.py +0 -44
  428. ksadk/version.py +1 -1
  429. ksadk_runtime_common/memory_backend/registry.py +56 -56
  430. ksadk_runtime_common/schemas/runtime_event_v1.json +37 -0
  431. ksadk_runtime_common/schemas/runtime_event_v2.json +271 -0
  432. ksadk_runtime_common/workspace_files/router.py +8 -2
  433. agentengine_sdk_python-0.8.0.dist-info/RECORD +0 -578
  434. ksadk/a2a/card_builder.py +0 -64
  435. ksadk/a2a/client.py +0 -309
  436. ksadk/events/parser.py +0 -191
  437. ksadk/harness/runner.py +0 -211
  438. ksadk/runners/codex_runner.py +0 -132
  439. ksadk/runners/utils/langfuse.py +0 -230
  440. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +0 -1
  441. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +0 -303
  442. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +0 -1
  443. ksadk/server/static/assets/arc-CFKwSk_B.js +0 -1
  444. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +0 -1
  445. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-Dej8jX8c.js +0 -36
  446. ksadk/server/static/assets/blockDiagram-GPEHLZMM-1F64jqvy.js +0 -132
  447. ksadk/server/static/assets/c4Diagram-AAUBKEIU-9q7AUAKb.js +0 -10
  448. ksadk/server/static/assets/channel-iUGv2N24.js +0 -1
  449. ksadk/server/static/assets/chunk-2J33WTMH-6qgwJm7Q.js +0 -1
  450. ksadk/server/static/assets/chunk-55IACEB6-BK8paA20.js +0 -1
  451. ksadk/server/static/assets/chunk-727SXJPM-B-JEhy7h.js +0 -206
  452. ksadk/server/static/assets/chunk-AQP2D5EJ-DYBvMHAa.js +0 -231
  453. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +0 -1
  454. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +0 -1
  455. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +0 -1
  456. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +0 -321
  457. ksadk/server/static/assets/dagre-BM42HDAG-C7TguAWo.js +0 -4
  458. ksadk/server/static/assets/dagre-Bx709z4p.js +0 -1
  459. ksadk/server/static/assets/diagram-2AECGRRQ-Dd17_kws.js +0 -43
  460. ksadk/server/static/assets/diagram-5GNKFQAL-DVIClIil.js +0 -10
  461. ksadk/server/static/assets/diagram-KO2AKTUF-Df_3gYQa.js +0 -3
  462. ksadk/server/static/assets/diagram-LMA3HP47-BhLk6ZtA.js +0 -24
  463. ksadk/server/static/assets/diagram-OG6HWLK6-D4GNGvuu.js +0 -24
  464. ksadk/server/static/assets/dist-DyvYLMW9.js +0 -1
  465. ksadk/server/static/assets/erDiagram-TEJ5UH35-CnfRcY2M.js +0 -85
  466. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +0 -1
  467. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DGaJjGNJ.js +0 -162
  468. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-DpCoB2g9.js +0 -292
  469. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +0 -1
  470. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-9IKVFBVT.js +0 -106
  471. ksadk/server/static/assets/graphlib-B8gBHxth.js +0 -1
  472. ksadk/server/static/assets/index-QSwCHuB8.js +0 -177
  473. ksadk/server/static/assets/index-jOPmTOZH.css +0 -2
  474. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +0 -1
  475. ksadk/server/static/assets/infoDiagram-5YYISTIA-CYIIsb8y.js +0 -2
  476. ksadk/server/static/assets/katex-DATssjp1.js +0 -265
  477. ksadk/server/static/assets/mermaid-parser.core-mGAcEwcq.js +0 -161
  478. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +0 -1
  479. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +0 -1
  480. ksadk/server/static/assets/pieDiagram-4H26LBE5-By-ra07M.js +0 -30
  481. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +0 -1
  482. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-DpW90iu3.js +0 -84
  483. ksadk/server/static/assets/stateDiagram-AJRCARHV-DGpd9yFG.js +0 -1
  484. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +0 -1
  485. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +0 -1
  486. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +0 -1
  487. ksadk/server/static/assets/vennDiagram-CIIHVFJN-l3Z7-wbP.js +0 -34
  488. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +0 -1
  489. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-BR54GPmr.js +0 -78
  490. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-SkiH8GsK.js +0 -7
  491. ksadk/tracing/exporters/langfuse_exporter.py +0 -460
  492. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/entry_points.txt +0 -0
  493. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/licenses/LICENSE +0 -0
  494. {agentengine_sdk_python-0.8.0.dist-info → agentengine_sdk_python-0.8.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,753 @@
1
+ """canonical-v2 to legacy v1 wire projection."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ from typing import Any
8
+
9
+ from ksadk.events._v1_compat.models import (
10
+ A2ATaskProjectionRef,
11
+ A2UIInteractionProjectionRef,
12
+ A2UISurfaceProjectionRef,
13
+ EventTypeV1,
14
+ RuntimeEventV1,
15
+ RuntimeEventV1ProjectionContext,
16
+ RuntimeEventV1ProjectionMode,
17
+ V1ProjectionContextRequiredError,
18
+ )
19
+ from ksadk.events.canonical import (
20
+ ContextCompactionCompleted,
21
+ ContextCompactionStarted,
22
+ ContinuationCreated,
23
+ ContinuationResumed,
24
+ EventPhase,
25
+ InteractionRequested,
26
+ InteractionResolved,
27
+ ItemCompleted,
28
+ ItemFailed,
29
+ ItemSnapshotReplaced,
30
+ ItemStarted,
31
+ ItemUpdated,
32
+ RunCanceled,
33
+ RunCompleted,
34
+ RunFailed,
35
+ RunInterrupted,
36
+ RunProgress,
37
+ RunStarted,
38
+ RuntimeEvent,
39
+ UsageReported,
40
+ )
41
+ from ksadk.events.content import (
42
+ ArtifactContent,
43
+ DataContent,
44
+ TextContent,
45
+ ToolCallContent,
46
+ ToolResultContent,
47
+ )
48
+
49
+
50
+ def _phase_for_item(
51
+ event: ItemStarted | ItemUpdated | ItemCompleted,
52
+ context: RuntimeEventV1ProjectionContext | None,
53
+ ) -> EventPhase:
54
+ if event.item_kind == "reasoning":
55
+ return "commentary"
56
+ if event.item_kind != "message":
57
+ raise ValueError(f"item kind {event.item_kind!r} has no v1 text phase")
58
+ if isinstance(event, ItemStarted) and event.phase is not None:
59
+ return event.phase
60
+ item = context.item(event.scope_id, event.item_id) if context else None
61
+ phase = item.phase if item is not None else None
62
+ if phase is None:
63
+ raise V1ProjectionContextRequiredError(
64
+ "message phase requires RuntimeEventV1ProjectionContext"
65
+ )
66
+ return phase
67
+
68
+
69
+ def _source_event_id(event: RuntimeEvent) -> str:
70
+ return event.source.native_event_id or event.event_id
71
+
72
+
73
+ def _identity_payload(
74
+ event: RuntimeEvent,
75
+ *,
76
+ item_id: str | None = None,
77
+ part_id: str | None = None,
78
+ ) -> dict[str, Any]:
79
+ payload: dict[str, Any] = {
80
+ "scope_id": event.scope_id,
81
+ "source_event_id": _source_event_id(event),
82
+ }
83
+ if item_id is not None:
84
+ payload["item_id"] = item_id
85
+ if part_id is not None:
86
+ payload["part_id"] = part_id
87
+ return payload
88
+
89
+
90
+ def _artifact_payload(
91
+ event: ItemStarted | ItemUpdated | ItemCompleted,
92
+ part: ArtifactContent,
93
+ context: RuntimeEventV1ProjectionContext | None,
94
+ ) -> dict[str, Any]:
95
+ if context is None:
96
+ raise V1ProjectionContextRequiredError(
97
+ "artifact version requires RuntimeEventV1ProjectionContext"
98
+ )
99
+ return {
100
+ "name": part.name,
101
+ "version": context.artifact_version(event.scope_id, event.item_id, part.artifact_id),
102
+ "uri": part.uri,
103
+ "mime": part.mime_type,
104
+ "data": part.data,
105
+ **_identity_payload(event, item_id=event.item_id, part_id=part.part_id),
106
+ }
107
+
108
+
109
+ def _a2a_task_ref(
110
+ event: RuntimeEvent,
111
+ context: RuntimeEventV1ProjectionContext | None,
112
+ ) -> A2ATaskProjectionRef | None:
113
+ if event.source.framework != "a2a":
114
+ return None
115
+ ref = context.a2a_tasks.get((event.run_id, event.scope_id)) if context else None
116
+ if ref is None or not ref.task_id.strip() or not ref.origin.strip():
117
+ raise V1ProjectionContextRequiredError(
118
+ "A2A task projection requires nonempty task_id and origin"
119
+ )
120
+ return ref
121
+
122
+
123
+ def _a2ui_surface_ref(
124
+ event: ItemStarted | ItemUpdated | ItemSnapshotReplaced | ItemCompleted,
125
+ context: RuntimeEventV1ProjectionContext | None,
126
+ ) -> A2UISurfaceProjectionRef | None:
127
+ ref = context.a2ui_surfaces.get((event.scope_id, event.item_id)) if context else None
128
+ if ref is not None and not ref.surface_id.strip():
129
+ raise V1ProjectionContextRequiredError(
130
+ "A2UI surface projection requires a nonempty surface_id"
131
+ )
132
+ return ref
133
+
134
+
135
+ def _a2ui_interaction_ref(
136
+ event: InteractionRequested | InteractionResolved,
137
+ context: RuntimeEventV1ProjectionContext | None,
138
+ ) -> A2UIInteractionProjectionRef | None:
139
+ ref = context.a2ui_interactions.get((event.scope_id, event.interaction_id)) if context else None
140
+ if ref is not None and not ref.surface_id.strip():
141
+ raise V1ProjectionContextRequiredError(
142
+ "A2UI interaction projection requires a nonempty surface_id"
143
+ )
144
+ return ref
145
+
146
+
147
+ def _project_artifact_parts(
148
+ event: ItemStarted | ItemUpdated | ItemCompleted,
149
+ parts: tuple[ArtifactContent, ...],
150
+ *,
151
+ generic_event_type: str,
152
+ context: RuntimeEventV1ProjectionContext | None,
153
+ ) -> tuple[RuntimeEventV1, ...]:
154
+ a2a_ref = _a2a_task_ref(event, context)
155
+ event_type = EventTypeV1.A2A_TASK_ARTIFACT if a2a_ref is not None else generic_event_type
156
+ projected: list[RuntimeEventV1] = []
157
+ for ordinal, part in enumerate(parts):
158
+ artifact = _artifact_payload(event, part, context)
159
+ payload = (
160
+ {
161
+ "task_id": a2a_ref.task_id,
162
+ "origin": a2a_ref.origin,
163
+ "artifact": artifact,
164
+ **_identity_payload(event, item_id=event.item_id, part_id=part.part_id),
165
+ }
166
+ if a2a_ref is not None
167
+ else artifact
168
+ )
169
+ projected.append(
170
+ _v1_event(
171
+ event,
172
+ event_type,
173
+ payload,
174
+ context=context,
175
+ ordinal=ordinal,
176
+ )
177
+ )
178
+ return tuple(projected)
179
+
180
+
181
+ def _v1_event(
182
+ event: RuntimeEvent,
183
+ event_type: str,
184
+ payload: dict[str, Any],
185
+ *,
186
+ context: RuntimeEventV1ProjectionContext | None,
187
+ phase: EventPhase | None = None,
188
+ ordinal: int = 0,
189
+ identity_item_id: str | None = None,
190
+ identity_part_id: str | None = None,
191
+ ) -> RuntimeEventV1:
192
+ if context is None or not all(
193
+ value.strip() for value in (context.agent_id, context.user_id, context.session_id)
194
+ ):
195
+ raise V1ProjectionContextRequiredError(
196
+ "v1 output requires a complete nonempty envelope context"
197
+ )
198
+ if context.projection is not None and context.projection.run_id != event.run_id:
199
+ raise V1ProjectionContextRequiredError(
200
+ "RuntimeEventV1ProjectionContext projection run_id must match event run_id"
201
+ )
202
+ item_id = identity_item_id or payload.get("item_id") or ""
203
+ part_id = identity_part_id or payload.get("part_id") or ""
204
+ identity = json.dumps(
205
+ [event.event_id, ordinal, item_id, part_id, event_type],
206
+ ensure_ascii=False,
207
+ separators=(",", ":"),
208
+ ).encode("utf-8")
209
+ legacy_event_id = f"evt_v1_{hashlib.sha256(identity).hexdigest()[:32]}"
210
+ projected = RuntimeEventV1(
211
+ event_id=legacy_event_id,
212
+ event_type=event_type,
213
+ timestamp=event.timestamp,
214
+ agent_id=context.agent_id,
215
+ user_id=context.user_id,
216
+ session_id=context.session_id,
217
+ invocation_id=event.run_id,
218
+ seq_id=event.seq,
219
+ phase=phase,
220
+ payload=payload,
221
+ )
222
+ projected.validate_conformance()
223
+ return projected
224
+
225
+
226
+ def _project_text_item(
227
+ event: ItemStarted | ItemUpdated | ItemCompleted,
228
+ *,
229
+ mode: RuntimeEventV1ProjectionMode,
230
+ context: RuntimeEventV1ProjectionContext | None,
231
+ ) -> tuple[RuntimeEventV1, ...]:
232
+ if event.item_kind not in {"message", "reasoning"}:
233
+ return ()
234
+ if mode == "snapshot_only":
235
+ return ()
236
+ parts: tuple[TextContent, ...]
237
+ if isinstance(event, ItemUpdated):
238
+ if not isinstance(event.update, TextContent):
239
+ return ()
240
+ parts = (event.update,)
241
+ completed = False
242
+ operation = event.op
243
+ elif isinstance(event, ItemCompleted):
244
+ parts = tuple(part for part in event.snapshot.parts if isinstance(part, TextContent))
245
+ completed = True
246
+ operation = "replace"
247
+ else:
248
+ if event.initial is None:
249
+ return ()
250
+ parts = tuple(part for part in event.initial.parts if isinstance(part, TextContent))
251
+ completed = False
252
+ operation = "replace"
253
+ if not parts:
254
+ return ()
255
+ phase = _phase_for_item(event, context)
256
+ prefix = "reasoning" if event.item_kind == "reasoning" else "text"
257
+ event_type = f"{prefix}.completed" if completed else f"{prefix}.delta"
258
+ projected: list[RuntimeEventV1] = []
259
+ for ordinal, part in enumerate(parts):
260
+ payload = {
261
+ "text": part.text,
262
+ **_identity_payload(event, item_id=event.item_id, part_id=part.part_id),
263
+ "operation": operation,
264
+ }
265
+ projected.append(
266
+ _v1_event(
267
+ event,
268
+ event_type,
269
+ payload,
270
+ context=context,
271
+ phase=phase,
272
+ ordinal=ordinal,
273
+ )
274
+ )
275
+ return tuple(projected)
276
+
277
+
278
+ def _project_item_started(
279
+ event: ItemStarted,
280
+ *,
281
+ mode: RuntimeEventV1ProjectionMode,
282
+ context: RuntimeEventV1ProjectionContext | None,
283
+ ) -> tuple[RuntimeEventV1, ...]:
284
+ text_projection = _project_text_item(event, mode=mode, context=context)
285
+ if text_projection or event.item_kind in {"message", "reasoning"}:
286
+ return text_projection
287
+ if event.item_kind == "data":
288
+ ref = _a2ui_surface_ref(event, context)
289
+ if ref is None:
290
+ return ()
291
+ data_parts = (
292
+ tuple(part for part in event.initial.parts if isinstance(part, DataContent))
293
+ if event.initial is not None
294
+ else ()
295
+ )
296
+ payload = {
297
+ "surface_id": ref.surface_id,
298
+ "catalog": ref.catalog,
299
+ "data": [part.data for part in data_parts],
300
+ **_identity_payload(event, item_id=event.item_id),
301
+ }
302
+ return (_v1_event(event, EventTypeV1.A2UI_SURFACE_BEGIN, payload, context=context),)
303
+ if event.item_kind == "artifact" and event.initial is not None:
304
+ artifact_parts = tuple(
305
+ part for part in event.initial.parts if isinstance(part, ArtifactContent)
306
+ )
307
+ return _project_artifact_parts(
308
+ event,
309
+ artifact_parts,
310
+ generic_event_type=EventTypeV1.ARTIFACT_CREATED,
311
+ context=context,
312
+ )
313
+ if event.item_kind != "tool_call" or event.initial is None:
314
+ return ()
315
+ tool_parts = tuple(part for part in event.initial.parts if isinstance(part, ToolCallContent))
316
+ return tuple(
317
+ _v1_event(
318
+ event,
319
+ EventTypeV1.TOOL_CALL_BEGIN,
320
+ {
321
+ "call_id": part.call_id,
322
+ "name": part.name,
323
+ "args": part.arguments,
324
+ **_identity_payload(event, item_id=event.item_id, part_id=part.part_id),
325
+ },
326
+ context=context,
327
+ ordinal=ordinal,
328
+ )
329
+ for ordinal, part in enumerate(tool_parts)
330
+ )
331
+
332
+
333
+ def _project_item_updated(
334
+ event: ItemUpdated,
335
+ *,
336
+ mode: RuntimeEventV1ProjectionMode,
337
+ context: RuntimeEventV1ProjectionContext | None,
338
+ ) -> tuple[RuntimeEventV1, ...]:
339
+ text_projection = _project_text_item(event, mode=mode, context=context)
340
+ if text_projection or event.item_kind in {"message", "reasoning"}:
341
+ return text_projection
342
+ if event.item_kind == "data":
343
+ ref = _a2ui_surface_ref(event, context)
344
+ if ref is None or not isinstance(event.update, DataContent):
345
+ return ()
346
+ payload = {
347
+ "surface_id": ref.surface_id,
348
+ "catalog": ref.catalog,
349
+ "data": event.update.data,
350
+ **_identity_payload(event, item_id=event.item_id, part_id=event.update.part_id),
351
+ }
352
+ return (_v1_event(event, EventTypeV1.A2UI_SURFACE_UPDATE, payload, context=context),)
353
+ if event.item_kind != "artifact" or not isinstance(event.update, ArtifactContent):
354
+ return ()
355
+ return _project_artifact_parts(
356
+ event,
357
+ (event.update,),
358
+ generic_event_type=EventTypeV1.ARTIFACT_UPDATED,
359
+ context=context,
360
+ )
361
+
362
+
363
+ def _project_item_completed(
364
+ event: ItemCompleted,
365
+ *,
366
+ mode: RuntimeEventV1ProjectionMode,
367
+ context: RuntimeEventV1ProjectionContext | None,
368
+ ) -> tuple[RuntimeEventV1, ...]:
369
+ text_projection = _project_text_item(event, mode=mode, context=context)
370
+ if text_projection or event.item_kind in {"message", "reasoning"}:
371
+ return text_projection
372
+ if event.item_kind == "data":
373
+ ref = _a2ui_surface_ref(event, context)
374
+ if ref is None:
375
+ return ()
376
+ parts = tuple(part for part in event.snapshot.parts if isinstance(part, DataContent))
377
+ payload = {
378
+ "surface_id": ref.surface_id,
379
+ "catalog": ref.catalog,
380
+ "data": [part.data for part in parts],
381
+ **_identity_payload(event, item_id=event.item_id),
382
+ }
383
+ return (_v1_event(event, EventTypeV1.A2UI_SURFACE_END, payload, context=context),)
384
+ if event.item_kind == "tool_result":
385
+ tool_result_parts = tuple(
386
+ part for part in event.snapshot.parts if isinstance(part, ToolResultContent)
387
+ )
388
+ return tuple(
389
+ _v1_event(
390
+ event,
391
+ EventTypeV1.TOOL_CALL_END,
392
+ {
393
+ "call_id": part.call_id,
394
+ "name": (context.tool_name(event.scope_id, part.call_id) if context else ""),
395
+ "result": part.result,
396
+ "error": part.result if part.is_error else None,
397
+ **_identity_payload(event, item_id=event.item_id, part_id=part.part_id),
398
+ },
399
+ context=context,
400
+ ordinal=ordinal,
401
+ )
402
+ for ordinal, part in enumerate(tool_result_parts)
403
+ )
404
+ if event.item_kind == "artifact":
405
+ artifact_parts = tuple(
406
+ part for part in event.snapshot.parts if isinstance(part, ArtifactContent)
407
+ )
408
+ return _project_artifact_parts(
409
+ event,
410
+ artifact_parts,
411
+ generic_event_type=EventTypeV1.ARTIFACT_UPDATED,
412
+ context=context,
413
+ )
414
+ return ()
415
+
416
+
417
+ def _project_item_snapshot_replaced(
418
+ event: ItemSnapshotReplaced,
419
+ *,
420
+ mode: RuntimeEventV1ProjectionMode,
421
+ context: RuntimeEventV1ProjectionContext | None,
422
+ ) -> tuple[RuntimeEventV1, ...]:
423
+ """Project only snapshots with an existing lossless v1 item-level meaning."""
424
+
425
+ if event.item_kind in {"message", "reasoning"}:
426
+ if mode == "snapshot_only":
427
+ return ()
428
+ raise V1ProjectionContextRequiredError(
429
+ "identity_replace cannot represent an item-level snapshot replacement "
430
+ "without leaving stale or reordered v1 text parts"
431
+ )
432
+
433
+ if event.item_kind == "data" and event.source.protocol == "a2ui":
434
+ ref = _a2ui_surface_ref(event, context)
435
+ if ref is None:
436
+ raise V1ProjectionContextRequiredError(
437
+ "A2UI item-level snapshot requires a typed surface projection ref"
438
+ )
439
+ raise V1ProjectionContextRequiredError(
440
+ "v1 A2UI updates cannot represent an item-level snapshot replacement atomically"
441
+ )
442
+
443
+ # A2A and artifact projection identities must still be validated before the
444
+ # legacy boundary rejects a snapshot it cannot express atomically.
445
+ _a2a_task_ref(event, context)
446
+ if event.item_kind == "artifact":
447
+ if context is None:
448
+ raise V1ProjectionContextRequiredError(
449
+ "artifact item-level snapshot requires typed projection context"
450
+ )
451
+ for part in event.snapshot.parts:
452
+ if not isinstance(part, ArtifactContent):
453
+ raise V1ProjectionContextRequiredError(
454
+ "artifact item-level snapshot contains incompatible content"
455
+ )
456
+ context.artifact_version(event.scope_id, event.item_id, part.artifact_id)
457
+ raise V1ProjectionContextRequiredError(
458
+ "v1 artifact events cannot represent an item-level snapshot replacement atomically"
459
+ )
460
+
461
+ if mode == "identity_replace":
462
+ raise V1ProjectionContextRequiredError(
463
+ f"v1 cannot represent an item-level snapshot replacement for {event.item_kind!r}"
464
+ )
465
+ return ()
466
+
467
+
468
+ def _snapshot_output_events(
469
+ event: RunCompleted,
470
+ context: RuntimeEventV1ProjectionContext | None,
471
+ ) -> tuple[RuntimeEventV1, ...]:
472
+ if context is None or context.projection is None:
473
+ raise V1ProjectionContextRequiredError(
474
+ "snapshot_only run completion requires reducer RunProjection"
475
+ )
476
+ if context.projection.run_id != event.run_id:
477
+ raise V1ProjectionContextRequiredError(
478
+ "RunProjection run_id must match run.completed run_id"
479
+ )
480
+ if context.projection.status != "completed":
481
+ raise V1ProjectionContextRequiredError(
482
+ "RunProjection status must be completed for snapshot_only output"
483
+ )
484
+ if context.projection.output_refs != event.output_refs:
485
+ raise V1ProjectionContextRequiredError(
486
+ "RunProjection output_refs must match run.completed output_refs"
487
+ )
488
+ projected: list[RuntimeEventV1] = []
489
+ ordinal = 0
490
+ for output_ref in event.output_refs:
491
+ item = context.item(output_ref.scope_id, output_ref.item_id)
492
+ if item is None:
493
+ raise V1ProjectionContextRequiredError(
494
+ "RunProjection is missing a run.completed output_ref item"
495
+ )
496
+ if item.item_kind not in {"message", "reasoning"}:
497
+ continue
498
+ if item.item_kind == "reasoning":
499
+ phase: EventPhase = "commentary"
500
+ event_type = EventTypeV1.REASONING_COMPLETED
501
+ else:
502
+ if item.phase is None:
503
+ raise V1ProjectionContextRequiredError(
504
+ "message phase is missing from reducer RunProjection"
505
+ )
506
+ phase = item.phase
507
+ event_type = EventTypeV1.TEXT_COMPLETED
508
+ parts = tuple(part for part in item.parts if isinstance(part, TextContent))
509
+ if output_ref.part_id is not None:
510
+ parts = tuple(part for part in parts if part.part_id == output_ref.part_id)
511
+ if not parts:
512
+ raise V1ProjectionContextRequiredError(
513
+ "RunProjection is missing a run.completed output_ref part"
514
+ )
515
+ for part in parts:
516
+ projected.append(
517
+ _v1_event(
518
+ event,
519
+ event_type,
520
+ {"text": part.text},
521
+ context=context,
522
+ phase=phase,
523
+ ordinal=ordinal,
524
+ identity_item_id=item.item_id,
525
+ identity_part_id=part.part_id,
526
+ )
527
+ )
528
+ ordinal += 1
529
+ return tuple(projected)
530
+
531
+
532
+ def _project_run_event(
533
+ event: RuntimeEvent,
534
+ *,
535
+ mode: RuntimeEventV1ProjectionMode,
536
+ context: RuntimeEventV1ProjectionContext | None,
537
+ ) -> tuple[RuntimeEventV1, ...] | None:
538
+ event_type: str
539
+ payload: dict[str, Any]
540
+ a2a_ref = _a2a_task_ref(event, context)
541
+ snapshot_events: tuple[RuntimeEventV1, ...] = ()
542
+ if isinstance(event, RunCompleted) and mode == "snapshot_only":
543
+ snapshot_events = _snapshot_output_events(event, context)
544
+ if a2a_ref is not None:
545
+ if isinstance(event, RunStarted):
546
+ event_type = EventTypeV1.A2A_TASK_CREATED
547
+ payload = {
548
+ "task_id": a2a_ref.task_id,
549
+ "origin": a2a_ref.origin,
550
+ "status": event.status,
551
+ }
552
+ elif isinstance(
553
+ event,
554
+ (RunProgress, RunInterrupted, RunCompleted, RunFailed, RunCanceled),
555
+ ):
556
+ event_type = EventTypeV1.A2A_TASK_STATUS
557
+ payload = {
558
+ "task_id": a2a_ref.task_id,
559
+ "origin": a2a_ref.origin,
560
+ "status": event.status,
561
+ }
562
+ if isinstance(event, RunFailed):
563
+ payload["error"] = event.error.model_dump(mode="json")
564
+ else:
565
+ return None
566
+ payload.update(_identity_payload(event))
567
+ lifecycle = _v1_event(
568
+ event,
569
+ event_type,
570
+ payload,
571
+ context=context,
572
+ ordinal=len(snapshot_events),
573
+ )
574
+ return (*snapshot_events, lifecycle)
575
+ if isinstance(event, RunStarted):
576
+ event_type, payload = EventTypeV1.RUN_STARTED, {"status": event.status}
577
+ elif isinstance(event, RunProgress):
578
+ event_type = EventTypeV1.RUN_PROGRESS
579
+ payload = {"status": event.status, "progress": event.progress, "message": event.message}
580
+ elif isinstance(event, RunInterrupted):
581
+ event_type = EventTypeV1.RUN_INTERRUPTED
582
+ payload = {
583
+ "status": event.status,
584
+ "reason": event.reason,
585
+ "interaction_id": event.interaction_id,
586
+ "continuation_id": event.continuation_id,
587
+ }
588
+ elif isinstance(event, RunCompleted):
589
+ event_type = EventTypeV1.RUN_COMPLETED
590
+ payload = {
591
+ "status": event.status,
592
+ "output_refs": [
593
+ ref.model_dump(mode="json", exclude_none=True) for ref in event.output_refs
594
+ ],
595
+ }
596
+ elif isinstance(event, RunFailed):
597
+ event_type = EventTypeV1.RUN_FAILED
598
+ payload = {"status": event.status, "error": event.error.model_dump(mode="json")}
599
+ elif isinstance(event, RunCanceled):
600
+ event_type = EventTypeV1.RUN_CANCELED
601
+ payload = {"status": event.status, "reason": event.reason}
602
+ else:
603
+ return None
604
+ payload.update(_identity_payload(event))
605
+ lifecycle = _v1_event(
606
+ event,
607
+ event_type,
608
+ payload,
609
+ context=context,
610
+ ordinal=len(snapshot_events),
611
+ )
612
+ return (*snapshot_events, lifecycle)
613
+
614
+
615
+ def project_to_v1(
616
+ event: RuntimeEvent,
617
+ *,
618
+ mode: RuntimeEventV1ProjectionMode = "snapshot_only",
619
+ context: RuntimeEventV1ProjectionContext | None = None,
620
+ ) -> tuple[RuntimeEventV1, ...]:
621
+ """Project one canonical event to zero or more legacy v1 wire events.
622
+
623
+ 公开承诺字段(契约声明见 ``ksadk/events/projections.py``,执行形态为
624
+ ``tests/protocol/test_cross_projection_golden.py``):
625
+ - RuntimeEventV1 事件类型与各类型 payload(approval_id/call_id/kind/detail、
626
+ surface_id/block_id/data、output_refs、status/error/reason 等);
627
+ - 身份字段 run_id/scope_id/item_id。
628
+
629
+ 内部不保证字段:seq/run_seq 的具体数值(仅保序)、source.native_* 游标、
630
+ source.metadata 原始键值。消费方不得依赖未列出的 payload 附加键。
631
+ """
632
+
633
+ if mode not in {"snapshot_only", "identity_replace"}:
634
+ raise ValueError(f"unknown RuntimeEvent v1 projection mode: {mode!r}")
635
+ if (
636
+ context is not None
637
+ and context.projection is not None
638
+ and context.projection.run_id != event.run_id
639
+ ):
640
+ raise V1ProjectionContextRequiredError(
641
+ "RuntimeEventV1ProjectionContext projection run_id must match event run_id"
642
+ )
643
+
644
+ run_projection = _project_run_event(event, mode=mode, context=context)
645
+ if run_projection is not None:
646
+ return run_projection
647
+ if isinstance(event, ItemStarted):
648
+ return _project_item_started(event, mode=mode, context=context)
649
+ if isinstance(event, ItemUpdated):
650
+ return _project_item_updated(event, mode=mode, context=context)
651
+ if isinstance(event, ItemSnapshotReplaced):
652
+ return _project_item_snapshot_replaced(event, mode=mode, context=context)
653
+ if isinstance(event, ItemCompleted):
654
+ return _project_item_completed(event, mode=mode, context=context)
655
+ if isinstance(event, ItemFailed):
656
+ return ()
657
+ if isinstance(event, InteractionRequested):
658
+ a2ui_ref = _a2ui_interaction_ref(event, context)
659
+ if a2ui_ref is not None:
660
+ payload = {
661
+ "surface_id": a2ui_ref.surface_id,
662
+ "block_id": a2ui_ref.block_id,
663
+ "data": event.request.model_dump(mode="json", by_alias=True),
664
+ **_identity_payload(event, item_id=event.interaction_id),
665
+ }
666
+ return (_v1_event(event, EventTypeV1.A2UI_INTERACTION, payload, context=context),)
667
+ if event.interaction_kind != "approval" or event.request.request_type != "approval":
668
+ return ()
669
+ call_id = event.request.call_id or (
670
+ context.interaction_call_id(event.scope_id, event.interaction_id) if context else ""
671
+ )
672
+ payload = {
673
+ "approval_id": event.interaction_id,
674
+ "call_id": call_id,
675
+ "kind": event.request.kind,
676
+ "detail": event.request.detail,
677
+ **_identity_payload(event, item_id=event.interaction_id),
678
+ }
679
+ return (_v1_event(event, EventTypeV1.APPROVAL_REQUESTED, payload, context=context),)
680
+ if isinstance(event, InteractionResolved):
681
+ a2ui_ref = _a2ui_interaction_ref(event, context)
682
+ if a2ui_ref is not None:
683
+ payload = {
684
+ "surface_id": a2ui_ref.surface_id,
685
+ "block_id": a2ui_ref.block_id,
686
+ "data": event.response.model_dump(mode="json", by_alias=True),
687
+ **_identity_payload(event, item_id=event.interaction_id),
688
+ }
689
+ return (_v1_event(event, EventTypeV1.A2UI_ACTION, payload, context=context),)
690
+ if event.interaction_kind != "approval" or event.response.response_type != "approval":
691
+ return ()
692
+ call_id = (
693
+ context.interaction_call_id(event.scope_id, event.interaction_id) if context else ""
694
+ )
695
+ payload = {
696
+ "approval_id": event.interaction_id,
697
+ "call_id": call_id,
698
+ "decision": event.response.decision,
699
+ "data": event.response.data,
700
+ **_identity_payload(event, item_id=event.interaction_id),
701
+ }
702
+ return (_v1_event(event, EventTypeV1.APPROVAL_RESOLVED, payload, context=context),)
703
+ if isinstance(event, ContinuationCreated):
704
+ if event.continuation_kind != "graph_checkpoint":
705
+ return ()
706
+ payload = {
707
+ "checkpoint_id": event.continuation_id,
708
+ "granularity": event.ref.get("granularity", "snapshot"),
709
+ "resume_target": event.ref,
710
+ "resumable": event.resumable,
711
+ **_identity_payload(event, item_id=event.continuation_id),
712
+ }
713
+ return (_v1_event(event, EventTypeV1.CHECKPOINT_CREATED, payload, context=context),)
714
+ if isinstance(event, ContinuationResumed):
715
+ if event.continuation_kind != "graph_checkpoint":
716
+ return ()
717
+ payload = {
718
+ "checkpoint_id": event.continuation_id,
719
+ "resume_attempt_id": event.resume_attempt_id,
720
+ **_identity_payload(event, item_id=event.continuation_id),
721
+ }
722
+ return (_v1_event(event, EventTypeV1.CHECKPOINT_RESUMED, payload, context=context),)
723
+ if isinstance(event, ContextCompactionStarted):
724
+ payload = {
725
+ "phase": context.compaction_phase if context else "runtime",
726
+ "trigger": event.trigger,
727
+ **_identity_payload(event),
728
+ }
729
+ return (_v1_event(event, EventTypeV1.CONTEXT_COMPACTION_STARTED, payload, context=context),)
730
+ if isinstance(event, ContextCompactionCompleted):
731
+ payload = {
732
+ "phase": context.compaction_phase if context else "runtime",
733
+ "trigger": event.trigger,
734
+ "compacted_until_seq_id": event.compacted_until_seq,
735
+ **_identity_payload(event),
736
+ }
737
+ return (
738
+ _v1_event(event, EventTypeV1.CONTEXT_COMPACTION_COMPLETED, payload, context=context),
739
+ )
740
+ if isinstance(event, UsageReported):
741
+ payload = {
742
+ "input_tokens": event.input_tokens,
743
+ "output_tokens": event.output_tokens,
744
+ "total_tokens": event.total_tokens,
745
+ "cached_tokens": event.cached_tokens,
746
+ "reasoning_tokens": event.reasoning_tokens,
747
+ **_identity_payload(event),
748
+ }
749
+ return (_v1_event(event, EventTypeV1.USAGE_REPORTED, payload, context=context),)
750
+ raise TypeError(f"unsupported canonical RuntimeEvent: {type(event).__name__}")
751
+
752
+
753
+ __all__ = ["project_to_v1"]