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,788 @@
1
+ """RunnerRuntimeAdapter 的 dict-chunk 退化路径:runner 流竞速与 chunk→canonical 事件映射。
2
+
3
+ 从 ``ksadk.runtime.runner_adapter`` 按职责拆出(纯移动,行为不变)。以 mixin 形式
4
+ 被 :class:`RunnerRuntimeAdapter` 继承,依赖宿主提供 ``_active_runs`` /
5
+ ``_runtime_type`` / ``_runner`` / ``_next_seq`` / ``_canonical_kwargs`` /
6
+ ``_interaction_requested_from_approval`` / ``_coerce``。
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import inspect
13
+ import json
14
+ import logging
15
+ import time
16
+ from collections.abc import Mapping
17
+ from contextlib import nullcontext
18
+ from typing import TYPE_CHECKING, Any, AsyncIterator, Optional, cast
19
+
20
+ from pydantic import JsonValue
21
+
22
+ from ksadk.conversations.runtime_input import _runner_name
23
+ from ksadk.conversations.runtime_observability import (
24
+ _set_conversation_input_attributes,
25
+ _set_conversation_output_attributes,
26
+ _set_conversation_span_attributes,
27
+ _set_conversation_usage_attributes,
28
+ )
29
+ from ksadk.events.canonical import (
30
+ ApprovalRequest,
31
+ ContentSnapshot,
32
+ ContinuationCreated,
33
+ ErrorInfo,
34
+ EventEnvelope,
35
+ InteractionRequested,
36
+ ItemCompleted,
37
+ ItemStarted,
38
+ ItemUpdated,
39
+ RunFailed,
40
+ RunProgress,
41
+ RuntimeEvent,
42
+ SourceRef,
43
+ UsageReported,
44
+ )
45
+ from ksadk.events.content import DataContent, TextContent, ToolCallContent, ToolResultContent
46
+ from ksadk.events.identity import stable_event_id, stable_item_id, stable_scope_id
47
+ from ksadk.runtime.adapter import RunHandle
48
+ from ksadk.runtime.preprocessing import PreparedRuntimeStart
49
+ from ksadk.runtime_context import platform_invocation_scope
50
+ from ksadk.tools.gateway import approval_interrupt_info_from_result
51
+
52
+ if TYPE_CHECKING:
53
+ from ksadk.runtime.runner_adapter import _ActiveRun
54
+
55
+ logger = logging.getLogger(__name__)
56
+
57
+ _STREAM_STOP = object()
58
+
59
+
60
+ async def _anext_or_stop(gen: AsyncIterator[Any]) -> Any:
61
+ """取下一个 chunk;流结束返回 _STREAM_STOP sentinel(便于竞速)。"""
62
+ try:
63
+ return await gen.__anext__()
64
+ except StopAsyncIteration:
65
+ return _STREAM_STOP
66
+
67
+
68
+ def _a2ui_surface_event(
69
+ self: Any,
70
+ handle: RunHandle,
71
+ chunk: Any,
72
+ ) -> RuntimeEvent | None:
73
+ """Recognize a validated A2UI tool envelope and emit a canonical data-item event.
74
+
75
+ The dynamic ``generate_a2ui`` tool returns official v0.9 operations as a
76
+ JSON tool result. Tool results are otherwise opaque to the runtime, which
77
+ would leave AG-UI with nothing to project until a page reload reconstructs
78
+ history. Convert exactly that envelope at the runtime boundary so it is
79
+ streamed, persisted, and replayed like every other A2UI surface.
80
+
81
+ In the canonical schema, A2UI surfaces are modeled as ``item_kind="data"``
82
+ items with ``source.protocol="a2ui"``.
83
+ """
84
+
85
+ if not isinstance(chunk, dict):
86
+ return None
87
+ value = chunk.get("tool_output", chunk.get("output"))
88
+ if value is not None and hasattr(value, "content"):
89
+ value = value.content
90
+ if isinstance(value, str):
91
+ try:
92
+ value = json.loads(value)
93
+ except (TypeError, ValueError):
94
+ return None
95
+ if not isinstance(value, Mapping):
96
+ return None
97
+ operations_raw = value.get("a2ui_operations")
98
+ if not isinstance(operations_raw, list) or not operations_raw:
99
+ return None
100
+ operations = [dict(operation) for operation in operations_raw if isinstance(operation, Mapping)]
101
+ if not operations:
102
+ return None
103
+
104
+ known: list[tuple[str, str]] = [] # (surface_id, lifecycle)
105
+ for operation in operations:
106
+ for key, lifecycle in (
107
+ ("createSurface", "begin"),
108
+ ("updateComponents", "update"),
109
+ ("updateDataModel", "update"),
110
+ ("deleteSurface", "end"),
111
+ ):
112
+ detail = operation.get(key)
113
+ if isinstance(detail, Mapping) and isinstance(detail.get("surfaceId"), str):
114
+ surface_id = detail["surfaceId"].strip()
115
+ if surface_id:
116
+ known.append((surface_id, lifecycle))
117
+ break
118
+ if not known:
119
+ return None
120
+ surface_ids = {surface_id for surface_id, _lifecycle in known}
121
+ if len(surface_ids) != 1:
122
+ logger.warning("ignoring A2UI tool result with multiple surfaces")
123
+ return None
124
+ surface_id = known[0][0]
125
+ lifecycle = "begin" if any(lc == "begin" for _, lc in known) else known[0][1]
126
+
127
+ framework = self._runtime_type
128
+ run_id = handle.run_id
129
+ scope_id = stable_scope_id(framework, run_id)
130
+ item_id = stable_item_id(framework, run_id, "a2ui", surface_id)
131
+ source = SourceRef(
132
+ framework=framework,
133
+ protocol="a2ui",
134
+ native_run_id=run_id,
135
+ metadata={"surface_id": surface_id},
136
+ )
137
+ # TODO(runtime-event-v2): dict chunk 退化路径,chunk_ordinal 用 seq counter;
138
+ # LangGraph/Codex 切 stream_canonical_events 后清理
139
+ n = self._next_seq()
140
+ timestamp = time.time()
141
+ if lifecycle == "begin":
142
+ return ItemStarted(
143
+ schema_version=2,
144
+ event_id=stable_event_id(
145
+ framework, scope_id, item_id, "item.started", "a2ui", run_id, n
146
+ ),
147
+ seq=n,
148
+ timestamp=timestamp,
149
+ run_id=run_id,
150
+ scope_id=scope_id,
151
+ source=source,
152
+ item_id=item_id,
153
+ item_kind="data",
154
+ initial=ContentSnapshot(parts=(DataContent(part_id="a2ui-ops", data=operations),)),
155
+ )
156
+ if lifecycle == "update":
157
+ return ItemUpdated(
158
+ schema_version=2,
159
+ event_id=stable_event_id(
160
+ framework, scope_id, item_id, "item.updated", "a2ui", run_id, n
161
+ ),
162
+ seq=n,
163
+ timestamp=timestamp,
164
+ run_id=run_id,
165
+ scope_id=scope_id,
166
+ source=source,
167
+ item_id=item_id,
168
+ item_kind="data",
169
+ op="replace",
170
+ update=DataContent(part_id="a2ui-ops", data=operations),
171
+ )
172
+ # lifecycle == "end"
173
+ return ItemCompleted(
174
+ schema_version=2,
175
+ event_id=stable_event_id(framework, scope_id, item_id, "item.completed", "a2ui", run_id, n),
176
+ seq=n,
177
+ timestamp=timestamp,
178
+ run_id=run_id,
179
+ scope_id=scope_id,
180
+ source=source,
181
+ item_id=item_id,
182
+ item_kind="data",
183
+ snapshot=ContentSnapshot(parts=()),
184
+ )
185
+
186
+
187
+ class _RunnerStreamMappingMixin:
188
+ """``_map_runner_stream`` / ``_chunk_to_event`` 的实现载体(纯移动自 runner_adapter)。"""
189
+
190
+ async def _map_runner_stream(
191
+ self, handle: RunHandle, runner_input: dict
192
+ ) -> AsyncIterator[RuntimeEvent]:
193
+ run: Optional[_ActiveRun] = self._active_runs.get(handle.run_id) # type: ignore[attr-defined]
194
+ interrupt = run.interrupt_event if run is not None else None
195
+ prepared_start = run.__dict__.get("_prepared_start") if run is not None else None
196
+ invocation_context = (
197
+ prepared_start.context if isinstance(prepared_start, PreparedRuntimeStart) else None
198
+ )
199
+ scope = (
200
+ platform_invocation_scope(invocation_context)
201
+ if invocation_context is not None
202
+ else nullcontext()
203
+ )
204
+ runner_name = _runner_name(self._runner) # type: ignore[attr-defined]
205
+ accumulated_output = ""
206
+ usage: dict[str, Any] = {}
207
+ runner_gen: Optional[AsyncIterator[Any]] = None
208
+ # span scope 经 runner_adapter 模块属性间接解析,保持既有 monkeypatch
209
+ # patch 点(tests/agui/test_runtime_preprocessing.py)继续生效。
210
+ from ksadk.runtime import runner_adapter as _runner_adapter_module
211
+
212
+ async with _runner_adapter_module._conversation_span_scope(runner_name) as span:
213
+ if isinstance(prepared_start, PreparedRuntimeStart):
214
+ _set_conversation_span_attributes(
215
+ span,
216
+ agent_id=str(handle.native_ref.get("agent_id") or "agent"),
217
+ user_id=str(handle.native_ref.get("user_id") or "user"),
218
+ session_id=handle.session_id,
219
+ invocation_id=handle.run_id,
220
+ runner_name=runner_name,
221
+ model=prepared_start.context.model,
222
+ response_id=prepared_start.response_id,
223
+ )
224
+ _set_conversation_input_attributes(span, prepared_start.input_text)
225
+ try:
226
+ with scope:
227
+ canonical_stream = getattr(self._runner, "stream_canonical_events", None) # type: ignore[attr-defined]
228
+ # ToolGateway 语义续跑 runner(gateway approval 可能出现在终态
229
+ # tool result 之后)仍走 chunk 路径:approval 识别逻辑在
230
+ # _chunk_to_events 的 tool_result 分支,canonical 快速路径
231
+ # (stream_canonical_events)不覆盖该语义。
232
+ if getattr(
233
+ self._runner, "supports_gateway_approval_semantic_resume", False # type: ignore[attr-defined]
234
+ ):
235
+ canonical_stream = None
236
+ stream_result = (
237
+ canonical_stream(runner_input)
238
+ if callable(canonical_stream)
239
+ else self._runner.stream(runner_input) # type: ignore[attr-defined]
240
+ )
241
+ if inspect.iscoroutine(stream_result):
242
+ # runner.stream 若声明为 async def -> AsyncIterator(非 async generator),
243
+ # 调用返回 coroutine,需 await 得到迭代器。
244
+ stream_result = await stream_result
245
+ runner_gen = cast(AsyncIterator[Any], stream_result)
246
+ while True:
247
+ # 竞速:下一个 runner chunk vs cancel 中断事件。
248
+ chunk_task = asyncio.ensure_future(_anext_or_stop(runner_gen))
249
+ if run is not None:
250
+ run.chunk_task = chunk_task
251
+ wait_set = {chunk_task}
252
+ interrupt_task = (
253
+ asyncio.ensure_future(interrupt.wait())
254
+ if interrupt is not None
255
+ else None
256
+ )
257
+ if interrupt_task is not None:
258
+ wait_set.add(interrupt_task)
259
+ done, pending = await asyncio.wait(
260
+ wait_set, return_when=asyncio.FIRST_COMPLETED
261
+ )
262
+ for task in pending:
263
+ task.cancel()
264
+ if pending:
265
+ await asyncio.gather(*pending, return_exceptions=True)
266
+ if interrupt_task is not None and interrupt_task in done:
267
+ # cancel 中断:安全关闭 runner 流(同一 task)并停止。
268
+ chunk_task.cancel()
269
+ await asyncio.gather(chunk_task, return_exceptions=True)
270
+ return
271
+ try:
272
+ chunk = chunk_task.result()
273
+ except asyncio.CancelledError:
274
+ if interrupt is not None and interrupt.is_set():
275
+ return
276
+ raise
277
+ finally:
278
+ if run is not None:
279
+ run.chunk_task = None
280
+ if chunk is _STREAM_STOP:
281
+ return
282
+ if isinstance(chunk, EventEnvelope):
283
+ # canonical 事件(来自 stream_canonical_events):直接转发,
284
+ # 追踪 output/usage 供 span 属性。
285
+ if isinstance(chunk, ItemCompleted) and chunk.item_kind == "message":
286
+ accumulated_output = "".join(
287
+ part.text
288
+ for part in chunk.snapshot.parts
289
+ if isinstance(part, TextContent)
290
+ )
291
+ elif isinstance(chunk, UsageReported):
292
+ usage.update(
293
+ {
294
+ "input_tokens": chunk.input_tokens,
295
+ "output_tokens": chunk.output_tokens,
296
+ "total_tokens": chunk.total_tokens,
297
+ "cached_tokens": chunk.cached_tokens,
298
+ "reasoning_tokens": chunk.reasoning_tokens,
299
+ }
300
+ )
301
+ if isinstance(chunk, dict):
302
+ chunk_type = str(chunk.get("type") or "")
303
+ if chunk_type == "final" and run is not None:
304
+ for source_key, target_key in (
305
+ ("duration_ms", "duration_ms"),
306
+ ("started_at", "started_at"),
307
+ ("completed_at", "completed_at"),
308
+ ("metrics_source", "source"),
309
+ ):
310
+ if chunk.get(source_key) is not None:
311
+ run.completion_metrics[target_key] = chunk[source_key]
312
+ if chunk_type in {"final", "text", "text_delta"}:
313
+ text = self._coerce( # type: ignore[attr-defined]
314
+ chunk.get("delta") or chunk.get("output") or chunk.get("data")
315
+ )
316
+ if text:
317
+ if chunk_type == "final" or chunk.get("replace"):
318
+ accumulated_output = text
319
+ else:
320
+ accumulated_output += text
321
+ raw_usage = chunk.get("usage")
322
+ if isinstance(raw_usage, dict):
323
+ usage.update(raw_usage)
324
+ for event in self._chunk_to_event(handle, run, chunk): # type: ignore[attr-defined]
325
+ yield event
326
+ a2ui_surface = _a2ui_surface_event(self, handle, chunk)
327
+ if a2ui_surface is not None:
328
+ yield a2ui_surface
329
+ finally:
330
+ if accumulated_output:
331
+ _set_conversation_output_attributes(span, accumulated_output)
332
+ _set_conversation_usage_attributes(span, usage)
333
+ if runner_gen is not None:
334
+ aclose = getattr(runner_gen, "aclose", None)
335
+ if callable(aclose):
336
+ try:
337
+ await aclose()
338
+ except Exception: # noqa: BLE001
339
+ pass
340
+ if run is not None:
341
+ run.cancellation_ack.set()
342
+
343
+ def _chunk_to_event(
344
+ self, handle: RunHandle, run: Optional[_ActiveRun], chunk: Any
345
+ ) -> list[RuntimeEvent]:
346
+ if isinstance(chunk, EventEnvelope):
347
+ # canonical 事件(来自 stream_canonical_events):直接转发,
348
+ # 抑制 runner 自己的 run.started(adapter 已发自己的)。
349
+ if chunk.event_type == "run.started":
350
+ return []
351
+ return [chunk]
352
+ if not isinstance(chunk, dict):
353
+ chunk = {"type": "text", "delta": str(chunk)}
354
+
355
+ framework = self._runtime_type # type: ignore[attr-defined]
356
+ run_id = handle.run_id
357
+ scope_id = stable_scope_id(framework, run_id)
358
+ started = run.started_items if run is not None else set()
359
+
360
+ def ensure_started(
361
+ *,
362
+ item_id: str,
363
+ item_kind: str,
364
+ phase: str | None = None,
365
+ initial: ContentSnapshot | None = None,
366
+ ) -> list[RuntimeEvent]:
367
+ key = (scope_id, item_id)
368
+ if key in started:
369
+ return []
370
+ started.add(key)
371
+ return [
372
+ ItemStarted(
373
+ **self._canonical_kwargs( # type: ignore[attr-defined]
374
+ handle,
375
+ scope_id=scope_id,
376
+ item_id=item_id,
377
+ event_type="item.started",
378
+ part_id="item",
379
+ ),
380
+ item_id=item_id,
381
+ item_kind=item_kind,
382
+ phase=phase,
383
+ initial=initial,
384
+ )
385
+ ]
386
+
387
+ chunk_type = chunk.get("type")
388
+
389
+ # ---- reasoning ----
390
+ if chunk_type in ("reasoning", "reasoning_delta", "thinking"):
391
+ text = self._coerce( # type: ignore[attr-defined]
392
+ chunk.get("delta")
393
+ or chunk.get("content")
394
+ or chunk.get("output")
395
+ or chunk.get("data")
396
+ )
397
+ if not text:
398
+ return []
399
+ item_id = stable_item_id(framework, run_id, "reasoning")
400
+ events: list[RuntimeEvent] = ensure_started(
401
+ item_id=item_id, item_kind="reasoning", phase="commentary"
402
+ )
403
+ if chunk.get("status") in ("completed", "done"):
404
+ events.append(
405
+ ItemCompleted(
406
+ **self._canonical_kwargs( # type: ignore[attr-defined]
407
+ handle,
408
+ scope_id=scope_id,
409
+ item_id=item_id,
410
+ event_type="item.completed",
411
+ part_id="reasoning-text",
412
+ ),
413
+ item_id=item_id,
414
+ item_kind="reasoning",
415
+ snapshot=ContentSnapshot(
416
+ parts=(TextContent(part_id="reasoning-text", text=text),)
417
+ ),
418
+ )
419
+ )
420
+ else:
421
+ events.append(
422
+ ItemUpdated(
423
+ **self._canonical_kwargs( # type: ignore[attr-defined]
424
+ handle,
425
+ scope_id=scope_id,
426
+ item_id=item_id,
427
+ event_type="item.updated",
428
+ part_id="reasoning-text",
429
+ ),
430
+ item_id=item_id,
431
+ item_kind="reasoning",
432
+ op="append",
433
+ update=TextContent(part_id="reasoning-text", text=text),
434
+ )
435
+ )
436
+ return events
437
+
438
+ # ---- tool_call ----
439
+ if chunk_type in ("tool_call", "tool_start"):
440
+ call_id = str(
441
+ chunk.get("tool_call_id")
442
+ or chunk.get("call_id")
443
+ or chunk.get("run_id")
444
+ or chunk.get("id")
445
+ or ""
446
+ )
447
+ name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
448
+ effective_call_id = call_id or name
449
+ item_id = stable_item_id(framework, run_id, effective_call_id, "tool_call")
450
+ part_id = "tool_call"
451
+ tc_content = ToolCallContent(
452
+ part_id=part_id,
453
+ call_id=effective_call_id,
454
+ name=name,
455
+ arguments=cast(JsonValue, chunk.get("tool_args", chunk.get("args")) or {}),
456
+ )
457
+ return [
458
+ ItemStarted(
459
+ **self._canonical_kwargs( # type: ignore[attr-defined]
460
+ handle,
461
+ scope_id=scope_id,
462
+ item_id=item_id,
463
+ event_type="item.started",
464
+ part_id=part_id,
465
+ ),
466
+ item_id=item_id,
467
+ item_kind="tool_call",
468
+ phase="commentary",
469
+ initial=ContentSnapshot(parts=(tc_content,)),
470
+ ),
471
+ ItemCompleted(
472
+ **self._canonical_kwargs( # type: ignore[attr-defined]
473
+ handle,
474
+ scope_id=scope_id,
475
+ item_id=item_id,
476
+ event_type="item.completed",
477
+ part_id=part_id,
478
+ ),
479
+ item_id=item_id,
480
+ item_kind="tool_call",
481
+ snapshot=ContentSnapshot(parts=(tc_content,)),
482
+ ),
483
+ ]
484
+
485
+ # ---- tool_result ----
486
+ if chunk_type in ("tool_result", "tool_end"):
487
+ call_id = str(
488
+ chunk.get("tool_call_id")
489
+ or chunk.get("call_id")
490
+ or chunk.get("run_id")
491
+ or chunk.get("id")
492
+ or ""
493
+ )
494
+ name = str(chunk.get("tool_name") or chunk.get("name") or "tool")
495
+ effective_call_id = call_id or name
496
+ item_id = stable_item_id(framework, run_id, effective_call_id, "tool_result")
497
+ part_id = "tool_result"
498
+ result_data = chunk.get("tool_output", chunk.get("output"))
499
+ # ToolGateway 审批可能出现在"本已终态"的 tool result 里;识别后转为
500
+ # canonical InteractionRequested(语义续跑由 runner 的
501
+ # supports_gateway_approval_semantic_resume 决定)。
502
+ tool_args = chunk.get("tool_args", chunk.get("args"))
503
+ approval_detail = approval_interrupt_info_from_result(
504
+ result_data,
505
+ fallback_tool_name=name,
506
+ tool_args=tool_args,
507
+ run_id=call_id or None,
508
+ )
509
+ if approval_detail is not None:
510
+ return self._interaction_requested_from_approval( # type: ignore[attr-defined]
511
+ handle,
512
+ run,
513
+ detail=approval_detail,
514
+ call_id=call_id,
515
+ )
516
+ tr_content = ToolResultContent(
517
+ part_id=part_id,
518
+ call_id=effective_call_id,
519
+ result=cast(JsonValue, result_data if result_data is not None else {}),
520
+ is_error=bool(chunk.get("error")),
521
+ )
522
+ return [
523
+ ItemStarted(
524
+ **self._canonical_kwargs( # type: ignore[attr-defined]
525
+ handle,
526
+ scope_id=scope_id,
527
+ item_id=item_id,
528
+ event_type="item.started",
529
+ part_id=part_id,
530
+ ),
531
+ item_id=item_id,
532
+ item_kind="tool_result",
533
+ phase="commentary",
534
+ ),
535
+ ItemCompleted(
536
+ **self._canonical_kwargs( # type: ignore[attr-defined]
537
+ handle,
538
+ scope_id=scope_id,
539
+ item_id=item_id,
540
+ event_type="item.completed",
541
+ part_id=part_id,
542
+ ),
543
+ item_id=item_id,
544
+ item_kind="tool_result",
545
+ snapshot=ContentSnapshot(parts=(tr_content,)),
546
+ ),
547
+ ]
548
+
549
+ # ---- interrupt / approval ----
550
+ if chunk_type in ("interrupt", "approval", "approval_required"):
551
+ detail = chunk.get("interrupt_info") or chunk.get("detail") or {}
552
+ detail_id = detail.get("approval_request_id") if isinstance(detail, dict) else None
553
+ call_id = str(
554
+ chunk.get("call_id")
555
+ or chunk.get("approval_id")
556
+ or chunk.get("id")
557
+ or detail_id
558
+ or ""
559
+ )
560
+ if run is not None and call_id:
561
+ run.pending_approvals.add(call_id)
562
+ if call_id:
563
+ pending_approval_ids = handle.native_ref.setdefault("pending_approval_ids", [])
564
+ if call_id not in pending_approval_ids:
565
+ pending_approval_ids.append(call_id)
566
+ interaction_id = call_id or stable_item_id(framework, run_id, "interaction")
567
+ item_id = stable_item_id(framework, run_id, "interaction")
568
+ detail_value: JsonValue = (
569
+ cast(JsonValue, detail)
570
+ if isinstance(detail, (dict, list, str, int, float, bool, type(None)))
571
+ else None
572
+ )
573
+ return [
574
+ InteractionRequested(
575
+ **self._canonical_kwargs( # type: ignore[attr-defined]
576
+ handle,
577
+ scope_id=scope_id,
578
+ item_id=item_id,
579
+ event_type="interaction.requested",
580
+ part_id="interaction",
581
+ ),
582
+ interaction_id=interaction_id,
583
+ interaction_kind="approval",
584
+ request=ApprovalRequest(
585
+ call_id=call_id or None,
586
+ kind="tool",
587
+ detail=detail_value,
588
+ ),
589
+ )
590
+ ]
591
+
592
+ # ---- checkpoint ----
593
+ if chunk_type == "checkpoint":
594
+ raw_metadata = chunk.get("metadata")
595
+ metadata: dict[str, Any] = raw_metadata if isinstance(raw_metadata, dict) else {}
596
+ raw_agentengine = metadata.get("agentengine")
597
+ agentengine: dict[str, Any] = (
598
+ raw_agentengine if isinstance(raw_agentengine, dict) else {}
599
+ )
600
+ ckpt_framework = str(agentengine.get("framework") or self._runtime_type) # type: ignore[attr-defined]
601
+ framework_ref = agentengine.get("framework_ref") or {}
602
+ runtime_ref = (
603
+ framework_ref.get(ckpt_framework) if isinstance(framework_ref, dict) else {}
604
+ ) or {}
605
+ checkpoint_id = str(
606
+ runtime_ref.get("checkpoint_id") if isinstance(runtime_ref, dict) else ""
607
+ )
608
+ if not checkpoint_id:
609
+ return []
610
+ handle.native_ref["checkpoint_id"] = checkpoint_id
611
+ known_checkpoint_ids = handle.native_ref.setdefault("known_checkpoint_ids", [])
612
+ if checkpoint_id not in known_checkpoint_ids:
613
+ known_checkpoint_ids.append(checkpoint_id)
614
+ handle.native_ref["framework_ref"] = framework_ref
615
+ if isinstance(runtime_ref, dict):
616
+ handle.native_ref.update(runtime_ref)
617
+ item_id = stable_item_id(framework, run_id, "$run")
618
+ ref_value = cast(
619
+ JsonValue,
620
+ framework_ref if isinstance(framework_ref, dict) else {},
621
+ )
622
+ return [
623
+ ContinuationCreated(
624
+ **self._canonical_kwargs( # type: ignore[attr-defined]
625
+ handle,
626
+ scope_id=scope_id,
627
+ item_id=item_id,
628
+ event_type="continuation.created",
629
+ part_id="continuation",
630
+ ),
631
+ continuation_id=checkpoint_id,
632
+ continuation_kind="graph_checkpoint",
633
+ resumable=True,
634
+ ref={
635
+ "framework": ckpt_framework,
636
+ "framework_ref": ref_value,
637
+ "resume_target": ref_value,
638
+ },
639
+ )
640
+ ]
641
+
642
+ # ---- graph_update ----
643
+ if chunk_type == "graph_update":
644
+ item_id = stable_item_id(framework, run_id, "$run")
645
+ return [
646
+ RunProgress(
647
+ **self._canonical_kwargs( # type: ignore[attr-defined]
648
+ handle,
649
+ scope_id=scope_id,
650
+ item_id=item_id,
651
+ event_type="run.progress",
652
+ part_id="run",
653
+ ),
654
+ status="running",
655
+ message=str(chunk.get("node") or ""),
656
+ )
657
+ ]
658
+
659
+ # ---- usage ----
660
+ if chunk_type == "usage":
661
+ raw_usage = chunk.get("usage")
662
+ usage_dict: dict[str, Any] = raw_usage if isinstance(raw_usage, dict) else {}
663
+ item_id = stable_item_id(framework, run_id, "$run")
664
+ return [
665
+ UsageReported(
666
+ **self._canonical_kwargs( # type: ignore[attr-defined]
667
+ handle,
668
+ scope_id=scope_id,
669
+ item_id=item_id,
670
+ event_type="usage.reported",
671
+ part_id="usage",
672
+ ),
673
+ input_tokens=int(usage_dict.get("input_tokens") or 0),
674
+ output_tokens=int(usage_dict.get("output_tokens") or 0),
675
+ total_tokens=int(usage_dict.get("total_tokens") or 0),
676
+ cached_tokens=int(usage_dict.get("cached_tokens") or 0),
677
+ reasoning_tokens=int(usage_dict.get("reasoning_tokens") or 0),
678
+ )
679
+ ]
680
+
681
+ # ---- error ----
682
+ if chunk_type == "error":
683
+ error = self._coerce(chunk.get("message") or chunk.get("error")) # type: ignore[attr-defined]
684
+ item_id = stable_item_id(framework, run_id, "$run")
685
+ return [
686
+ RunFailed(
687
+ **self._canonical_kwargs( # type: ignore[attr-defined]
688
+ handle,
689
+ scope_id=scope_id,
690
+ item_id=item_id,
691
+ event_type="run.failed",
692
+ part_id="run",
693
+ ),
694
+ status="failed",
695
+ error=ErrorInfo(
696
+ code="runner_failed",
697
+ message=error or "runner failed",
698
+ source=framework,
699
+ scope_id=scope_id,
700
+ ),
701
+ )
702
+ ]
703
+
704
+ # ---- final ----
705
+ if chunk_type == "final":
706
+ output = self._coerce(chunk.get("output")) # type: ignore[attr-defined]
707
+ item_id = stable_item_id(framework, run_id, "message", "final_answer")
708
+ if run is not None:
709
+ run.final_answer_item_id = item_id
710
+ text_content = TextContent(part_id="text-0", text=output)
711
+ # Auto-close any open commentary/reasoning item before emitting final_answer.
712
+ # Text/thinking deltas create items that are never ItemCompleted;
713
+ # without this, RunCompleted fails _ensure_no_open_items.
714
+ #
715
+ # Close them *before* allocating the final-answer item. Event
716
+ # constructors allocate ``seq`` eagerly, so inserting a later
717
+ # completion at index zero would otherwise return an event list
718
+ # whose physical order disagrees with its sequence numbers.
719
+ events: list[RuntimeEvent] = []
720
+ for close_kind, close_part_id, close_components in (
721
+ ("message", "text-0", ("message", "commentary")),
722
+ ("reasoning", "reasoning-text", ("reasoning",)),
723
+ ):
724
+ close_item_id = stable_item_id(framework, run_id, *close_components)
725
+ close_key = (scope_id, close_item_id)
726
+ if close_key in started:
727
+ started.discard(close_key)
728
+ events.append(
729
+ ItemCompleted(
730
+ **self._canonical_kwargs( # type: ignore[attr-defined]
731
+ handle,
732
+ scope_id=scope_id,
733
+ item_id=close_item_id,
734
+ event_type="item.completed",
735
+ part_id=close_part_id,
736
+ ),
737
+ item_id=close_item_id,
738
+ item_kind=close_kind,
739
+ snapshot=ContentSnapshot(
740
+ parts=(TextContent(part_id=close_part_id, text=""),)
741
+ ),
742
+ ),
743
+ )
744
+ events.extend(
745
+ ensure_started(item_id=item_id, item_kind="message", phase="final_answer")
746
+ )
747
+ events.append(
748
+ ItemCompleted(
749
+ **self._canonical_kwargs( # type: ignore[attr-defined]
750
+ handle,
751
+ scope_id=scope_id,
752
+ item_id=item_id,
753
+ event_type="item.completed",
754
+ part_id="text-0",
755
+ ),
756
+ item_id=item_id,
757
+ item_kind="message",
758
+ snapshot=ContentSnapshot(parts=(text_content,)),
759
+ )
760
+ )
761
+ return events
762
+
763
+ # ---- default: text delta ----
764
+ text = self._coerce(chunk.get("delta") or chunk.get("output") or chunk.get("data")) # type: ignore[attr-defined]
765
+ if not text:
766
+ return []
767
+ item_id = stable_item_id(framework, run_id, "message", "commentary")
768
+ op: str = "replace" if chunk.get("replace") else "append"
769
+ events = ensure_started(item_id=item_id, item_kind="message", phase="commentary")
770
+ events.append(
771
+ ItemUpdated(
772
+ **self._canonical_kwargs( # type: ignore[attr-defined]
773
+ handle,
774
+ scope_id=scope_id,
775
+ item_id=item_id,
776
+ event_type="item.updated",
777
+ part_id="text-0",
778
+ ),
779
+ item_id=item_id,
780
+ item_kind="message",
781
+ op=op,
782
+ update=TextContent(part_id="text-0", text=text),
783
+ )
784
+ )
785
+ return events
786
+
787
+
788
+ __all__ = ["_RunnerStreamMappingMixin", "_a2ui_surface_event", "_anext_or_stop", "_STREAM_STOP"]