agentengine-sdk-python 0.7.0__py3-none-any.whl → 0.8.1__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 (450) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/METADATA +52 -20
  2. agentengine_sdk_python-0.8.1.dist-info/RECORD +644 -0
  3. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/WHEEL +1 -1
  4. ksadk/a2a/__init__.py +180 -11
  5. ksadk/a2a/bootstrap.py +332 -0
  6. ksadk/a2a/card.py +15 -0
  7. ksadk/a2a/context_store.py +203 -0
  8. ksadk/a2a/control_plane.py +1056 -0
  9. ksadk/a2a/credential.py +99 -0
  10. ksadk/a2a/event_adapter.py +149 -0
  11. ksadk/a2a/executor.py +361 -137
  12. ksadk/a2a/external_transport.py +516 -0
  13. ksadk/a2a/identity.py +304 -0
  14. ksadk/a2a/ids.py +22 -0
  15. ksadk/a2a/langgraph.py +285 -0
  16. ksadk/a2a/resume_store.py +201 -0
  17. ksadk/a2a/routes.py +112 -0
  18. ksadk/a2a/server.py +102 -62
  19. ksadk/a2a/service_env.py +33 -0
  20. ksadk/a2a/space_client.py +1122 -0
  21. ksadk/a2a/task_adapter.py +423 -0
  22. ksadk/a2a/task_event_dispatcher.py +167 -0
  23. ksadk/a2a/task_event_outbox.py +326 -0
  24. ksadk/a2a/task_store.py +206 -0
  25. ksadk/a2a_card.py +101 -0
  26. ksadk/a2ui/__init__.py +27 -0
  27. ksadk/a2ui/core.py +186 -0
  28. ksadk/a2ui/models.py +166 -0
  29. ksadk/a2ui/renderer.py +198 -0
  30. ksadk/agui/__init__.py +9 -0
  31. ksadk/agui/a2ui_projection.py +92 -0
  32. ksadk/agui/agent.py +872 -0
  33. ksadk/agui/config.py +92 -0
  34. ksadk/agui/routes.py +47 -0
  35. ksadk/api/client.py +238 -204
  36. ksadk/api/environment.py +27 -0
  37. ksadk/builders/__init__.py +2 -0
  38. ksadk/builders/base.py +16 -14
  39. ksadk/builders/code_builder.py +375 -270
  40. ksadk/builders/container_builder.py +240 -200
  41. ksadk/builders/framework_requirements.py +31 -12
  42. ksadk/builders/ks3_uploader.py +60 -29
  43. ksadk/builders/managed_runtime_builder.py +173 -0
  44. ksadk/builders/mcp_builder.py +91 -92
  45. ksadk/builders/requirements_utils.py +1 -5
  46. ksadk/cli/__init__.py +97 -171
  47. ksadk/cli/cmd_a2a.py +255 -84
  48. ksadk/cli/cmd_agent.py +19 -5
  49. ksadk/cli/cmd_build.py +158 -29
  50. ksadk/cli/cmd_completion.py +47 -35
  51. ksadk/cli/cmd_config.py +267 -198
  52. ksadk/cli/cmd_create.py +507 -740
  53. ksadk/cli/cmd_dashboard.py +120 -45
  54. ksadk/cli/cmd_deploy.py +135 -59
  55. ksadk/cli/cmd_destroy.py +44 -14
  56. ksadk/cli/cmd_eval.py +386 -0
  57. ksadk/cli/cmd_files.py +63 -24
  58. ksadk/cli/cmd_hermes.py +313 -135
  59. ksadk/cli/cmd_invoke.py +184 -122
  60. ksadk/cli/cmd_launch.py +76 -28
  61. ksadk/cli/cmd_mcp.py +98 -64
  62. ksadk/cli/cmd_model.py +14 -5
  63. ksadk/cli/cmd_openclaw.py +564 -268
  64. ksadk/cli/cmd_replay.py +71 -0
  65. ksadk/cli/cmd_run.py +58 -73
  66. ksadk/cli/cmd_status.py +80 -31
  67. ksadk/cli/cmd_studio.py +110 -0
  68. ksadk/cli/cmd_version.py +20 -13
  69. ksadk/cli/cmd_web.py +95 -18
  70. ksadk/cli/deploy_utils.py +20 -20
  71. ksadk/cli/dry_run.py +7 -4
  72. ksadk/cli/env_options.py +83 -0
  73. ksadk/cli/error_utils.py +37 -12
  74. ksadk/cli/global_options.py +4 -3
  75. ksadk/cli/local_runtime.py +1 -2
  76. ksadk/cli/model_catalog.py +6 -2
  77. ksadk/cli/network_options.py +41 -19
  78. ksadk/cli/resource_common.py +6 -2
  79. ksadk/cli/runtime_bootstrap.py +51 -0
  80. ksadk/cli/storage.py +0 -1
  81. ksadk/cli/ui.py +11 -3
  82. ksadk/cli/workflow_common.py +52 -18
  83. ksadk/codex/__init__.py +12 -0
  84. ksadk/codex/client.py +1042 -0
  85. ksadk/codex/phase.py +143 -0
  86. ksadk/codex/runtime.py +940 -0
  87. ksadk/common/aicp_env.py +0 -1
  88. ksadk/common/auth.py +2 -2
  89. ksadk/common/constants.py +1 -3
  90. ksadk/common/kop_client.py +232 -0
  91. ksadk/common/llm_utils.py +17 -13
  92. ksadk/compat/__init__.py +5 -0
  93. ksadk/compat/adk_compat.py +200 -0
  94. ksadk/compat/copilotkit_a2ui.py +330 -0
  95. ksadk/configs/__init__.py +12 -14
  96. ksadk/configs/env_registry.py +661 -116
  97. ksadk/configs/global_config.py +3 -2
  98. ksadk/configs/settings.py +133 -209
  99. ksadk/conversations/__init__.py +85 -92
  100. ksadk/conversations/attachment_storage.py +16 -11
  101. ksadk/conversations/attachments.py +44 -36
  102. ksadk/conversations/compaction_pipeline.py +12 -12
  103. ksadk/conversations/compaction_prompt.py +9 -5
  104. ksadk/conversations/context.py +221 -6
  105. ksadk/conversations/message_projection.py +438 -51
  106. ksadk/conversations/model_context.py +12 -6
  107. ksadk/conversations/model_options.py +0 -1
  108. ksadk/conversations/normalize.py +20 -16
  109. ksadk/conversations/reasoning_markup.py +1 -1
  110. ksadk/conversations/runtime.py +339 -5255
  111. ksadk/conversations/runtime_compaction.py +333 -0
  112. ksadk/conversations/runtime_constants.py +27 -0
  113. ksadk/conversations/runtime_governance.py +185 -0
  114. ksadk/conversations/runtime_input.py +660 -0
  115. ksadk/conversations/runtime_invocation.py +395 -0
  116. ksadk/conversations/runtime_metadata.py +475 -0
  117. ksadk/conversations/runtime_observability.py +367 -0
  118. ksadk/conversations/runtime_payloads.py +272 -0
  119. ksadk/conversations/runtime_persistence.py +440 -0
  120. ksadk/conversations/runtime_preparation.py +426 -0
  121. ksadk/conversations/runtime_resume.py +836 -0
  122. ksadk/conversations/runtime_stream_events.py +902 -0
  123. ksadk/conversations/runtime_streaming.py +700 -0
  124. ksadk/conversations/semantic_summary.py +17 -5
  125. ksadk/conversations/session_title.py +6 -3
  126. ksadk/deployment/__init__.py +15 -16
  127. ksadk/deployment/agent_access.py +12 -23
  128. ksadk/deployment/base.py +51 -38
  129. ksadk/deployment/managed_runtime.py +33 -0
  130. ksadk/deployment/manager.py +85 -71
  131. ksadk/deployment/providers/serverless.py +379 -210
  132. ksadk/deployment/registry.py +38 -32
  133. ksadk/deployment/state.py +11 -11
  134. ksadk/deployment/ui_config.py +1 -1
  135. ksadk/detection/__init__.py +1 -1
  136. ksadk/detection/detector.py +146 -83
  137. ksadk/detection/mcp_detector.py +9 -6
  138. ksadk/evaluation/__init__.py +84 -0
  139. ksadk/evaluation/a2a_adapter.py +444 -0
  140. ksadk/evaluation/adapters.py +54 -0
  141. ksadk/evaluation/contracts.py +409 -0
  142. ksadk/evaluation/evalset.py +351 -0
  143. ksadk/evaluation/evaluators.py +461 -0
  144. ksadk/evaluation/executor.py +118 -0
  145. ksadk/evaluation/storage.py +68 -0
  146. ksadk/evaluation/target.py +73 -0
  147. ksadk/events/__init__.py +25 -0
  148. ksadk/events/parser.py +191 -0
  149. ksadk/events/replay.py +37 -0
  150. ksadk/events/runtime_event.py +273 -0
  151. ksadk/events/store.py +317 -0
  152. ksadk/harness/__init__.py +35 -0
  153. ksadk/harness/app.py +269 -0
  154. ksadk/harness/config.py +181 -0
  155. ksadk/harness/reasoner.py +105 -0
  156. ksadk/harness/runtime.py +364 -0
  157. ksadk/harness/sandbox.py +141 -0
  158. ksadk/harness/tools.py +222 -0
  159. ksadk/hermes_terminal.py +28 -12
  160. ksadk/identity/resolver.py +15 -9
  161. ksadk/ids.py +32 -0
  162. ksadk/knowledge_base/adk_tool.py +1 -1
  163. ksadk/knowledge_base/client.py +38 -33
  164. ksadk/managed_a2a_card.py +160 -0
  165. ksadk/managed_runtime.py +195 -0
  166. ksadk/markdown.py +5 -2
  167. ksadk/mcp_runtime/__init__.py +9 -6
  168. ksadk/memory/__init__.py +1 -1
  169. ksadk/memory/adk/__init__.py +2 -0
  170. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  171. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  172. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  173. ksadk/memory/adk/backends/sdk_ltm_backend.py +36 -36
  174. ksadk/memory/adk/long_term_memory.py +34 -37
  175. ksadk/memory/adk/resilient_session_service.py +4 -5
  176. ksadk/memory/adk/short_term_memory.py +12 -21
  177. ksadk/memory/adk_tool.py +3 -2
  178. ksadk/memory/backends/base.py +19 -19
  179. ksadk/memory/backends/memory.py +24 -25
  180. ksadk/memory/backends/redis.py +31 -30
  181. ksadk/memory/langchain_tool.py +2 -1
  182. ksadk/memory/manager.py +52 -47
  183. ksadk/memory/service.py +16 -6
  184. ksadk/memory/tool.py +4 -0
  185. ksadk/model_policy.py +15 -7
  186. ksadk/model_proxy/__init__.py +51 -0
  187. ksadk/model_proxy/bootstrap.py +80 -0
  188. ksadk/model_proxy/cache.py +165 -0
  189. ksadk/model_proxy/config.py +66 -0
  190. ksadk/model_proxy/demo_webui.py +115 -0
  191. ksadk/model_proxy/detect.py +145 -0
  192. ksadk/model_proxy/gate.py +68 -0
  193. ksadk/model_proxy/namespace.py +201 -0
  194. ksadk/model_proxy/protocol_proxy.py +22 -0
  195. ksadk/model_proxy/server.py +443 -0
  196. ksadk/model_proxy/transform.py +735 -0
  197. ksadk/openclaw_gateway.py +29 -14
  198. ksadk/runners/adk_runner.py +354 -146
  199. ksadk/runners/base_runner.py +71 -29
  200. ksadk/runners/deepagents_runner.py +0 -1
  201. ksadk/runners/factory.py +18 -5
  202. ksadk/runners/langchain_runner.py +29 -742
  203. ksadk/runners/langgraph_runner.py +417 -97
  204. ksadk/runners/patch_langchain.py +16 -16
  205. ksadk/runners/remote_runner.py +134 -33
  206. ksadk/runners/usage_accumulator.py +1 -0
  207. ksadk/runners/utils/__init__.py +0 -10
  208. ksadk/runners/utils/loader.py +23 -7
  209. ksadk/runtime/__init__.py +67 -0
  210. ksadk/runtime/adapter.py +412 -0
  211. ksadk/runtime/conversation_execution.py +553 -0
  212. ksadk/runtime/executor.py +251 -0
  213. ksadk/runtime/factory.py +156 -0
  214. ksadk/runtime/framework_adapters.py +118 -0
  215. ksadk/runtime/launch.py +48 -0
  216. ksadk/runtime/preprocessing.py +131 -0
  217. ksadk/runtime/runner_adapter.py +1032 -0
  218. ksadk/runtime/runner_loading.py +36 -0
  219. ksadk/runtime_context.py +18 -3
  220. ksadk/runtime_state.py +0 -1
  221. ksadk/sandbox/__init__.py +4 -1
  222. ksadk/sandbox/backends/__init__.py +4 -1
  223. ksadk/sandbox/backends/e2b.py +13 -5
  224. ksadk/sandbox/backends/local_process.py +11 -3
  225. ksadk/sandbox/base.py +10 -15
  226. ksadk/sandbox/factory.py +14 -4
  227. ksadk/sandbox/registry.py +57 -6
  228. ksadk/server/__init__.py +39 -4
  229. ksadk/server/api_models.py +15 -5
  230. ksadk/server/app.py +24 -3928
  231. ksadk/server/composition.py +47 -0
  232. ksadk/server/factory.py +622 -0
  233. ksadk/server/routes/__init__.py +1 -0
  234. ksadk/server/routes/checkpoint_resolution.py +116 -0
  235. ksadk/server/routes/common.py +682 -0
  236. ksadk/server/routes/control.py +331 -0
  237. ksadk/server/routes/dependencies.py +98 -0
  238. ksadk/server/routes/misc.py +425 -0
  239. ksadk/server/routes/models.py +451 -0
  240. ksadk/server/routes/openai_compat.py +229 -0
  241. ksadk/server/routes/projection.py +848 -0
  242. ksadk/server/routes/routers.py +52 -0
  243. ksadk/server/routes/run.py +519 -0
  244. ksadk/server/routes/sessions.py +644 -0
  245. ksadk/server/routes/streaming.py +265 -0
  246. ksadk/server/routes/workspace.py +414 -0
  247. ksadk/server/static/assets/{ArtifactsPanel-D-SSn2ee.js → ArtifactsPanel-CakCqxEN.js} +1 -1
  248. ksadk/server/static/assets/CodeBlock-CynLknyO.js +9 -0
  249. ksadk/server/static/assets/MathMessageMarkdown-3sQdOysS.js +8 -0
  250. ksadk/server/static/assets/MermaidBlock-NERD_ef7.js +303 -0
  251. ksadk/server/static/assets/NativeTerminalPanel-CiHWf82q.js +1 -0
  252. ksadk/server/static/assets/{arc-BA13sHc9.js → arc-DrgjcKhl.js} +1 -1
  253. ksadk/server/static/assets/architecture-7EHR7CIX-CpZLRCcY.js +1 -0
  254. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-DzJzgVoL.js → architectureDiagram-3BPJPVTR-BXoVRbQ6.js} +1 -1
  255. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-BnaB3Ywv.js} +1 -1
  256. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-Dw4weZcp.js} +1 -1
  257. ksadk/server/static/assets/channel-Dt3rQTFI.js +1 -0
  258. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-ChjpLK7j.js} +1 -1
  259. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-B9drTgOW.js} +1 -1
  260. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-CK4ROATy.js} +1 -1
  261. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B9KtTTgw.js} +1 -1
  262. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-1O1mki3m.js} +1 -1
  263. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-B_fH2YuH.js} +1 -1
  264. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.js → chunk-ND2GUHAM-D6rFLaVV.js} +1 -1
  265. ksadk/server/static/assets/chunk-QZHKN3VN-iXEZtKQc.js +1 -0
  266. ksadk/server/static/assets/classDiagram-4FO5ZUOK-DIveV17Q.js +1 -0
  267. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-DIveV17Q.js +1 -0
  268. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-Zhy2GBnP.js → cose-bilkent-S5V4N54A-ChNs_Mdk.js} +1 -1
  269. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-D0QXg_MQ.js} +1 -1
  270. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-DBDDKwBQ.js} +1 -1
  271. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-BkwDOxmO.js} +1 -1
  272. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Bv8waYvY.js} +1 -1
  273. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-e1VECDdu.js} +1 -1
  274. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-Ds9adfRl.js} +1 -1
  275. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-4N2NMVYg.js} +1 -1
  276. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-B-jNR6Vn.js} +1 -1
  277. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-B5J2uhNk.js} +1 -1
  278. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-B5oS1zcj.js} +1 -1
  279. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BB3-OwTQ.js} +1 -1
  280. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-BIlKoW0k.js} +1 -1
  281. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-BjOdlDjj.js} +1 -1
  282. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-C1sz5Eo3.js} +1 -1
  283. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-CWV4lDr1.js} +1 -1
  284. ksadk/server/static/assets/{dist-D-xOD048.js → dist-CmZHzlwZ.js} +1 -1
  285. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-D6MpCZtz.js} +1 -1
  286. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-DJN_6Y39.js} +1 -1
  287. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-DQU9EWw-.js} +1 -1
  288. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-DWKByxWV.js} +1 -1
  289. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-Dli7qW-B.js} +1 -1
  290. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-DsHPdk3W.js} +1 -1
  291. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-X4TnqwOK.js} +1 -1
  292. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-_pHPTyZ-.js} +1 -1
  293. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-fhOuWds5.js} +1 -1
  294. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-gLnrGsoU.js} +1 -1
  295. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-j6Dxmf_j.js} +1 -1
  296. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-o2OVmKvt.js} +1 -1
  297. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.js → erDiagram-TEJ5UH35-BPItFKH6.js} +1 -1
  298. ksadk/server/static/assets/eventmodeling-FCH6USID-DYFSxbqr.js +1 -0
  299. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-BbYB9w5Y.js} +1 -1
  300. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.js → ganttDiagram-6RSMTGT7-TQXa0KXv.js} +1 -1
  301. ksadk/server/static/assets/gitGraph-WXDBUCRP-DyNYp6BN.js +1 -0
  302. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-C7Q0X-wi.js → gitGraphDiagram-PVQCEYII-bKblCnpa.js} +1 -1
  303. ksadk/server/static/assets/index-R52pJJvg.js +177 -0
  304. ksadk/server/static/assets/index-jJr3_955.css +2 -0
  305. ksadk/server/static/assets/info-J43DQDTF-WUx7qTde.js +1 -0
  306. ksadk/server/static/assets/{infoDiagram-5YYISTIA-BO_CSqq5.js → infoDiagram-5YYISTIA-BGVT7J_i.js} +1 -1
  307. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-K0OOfVna.js} +1 -1
  308. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-8LeOJaZp.js} +1 -1
  309. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-C6uCgZrW.js} +1 -1
  310. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-CYWseY5E.js} +1 -1
  311. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-hdBcYzM8.js} +1 -1
  312. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-BWrDjSZM.js} +2 -2
  313. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.js → mindmap-definition-RKZ34NQL-Bjy_2v4_.js} +1 -1
  314. ksadk/server/static/assets/packet-YPE3B663-BN13y_xl.js +1 -0
  315. ksadk/server/static/assets/pie-LRSECV5Y-ftSLXhhc.js +1 -0
  316. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPv_VstN.js → pieDiagram-4H26LBE5-GmmqNiVH.js} +1 -1
  317. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.js → quadrantDiagram-W4KKPZXB-BmkRbwCg.js} +1 -1
  318. ksadk/server/static/assets/radar-GUYGQ44K-jaICkIeO.js +1 -0
  319. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-BYVw81VC.js → requirementDiagram-4Y6WPE33-DSWFqL7c.js} +1 -1
  320. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-l6iXmU65.js} +1 -1
  321. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-Cq6UBeQB.js} +1 -1
  322. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.js → stateDiagram-AJRCARHV-qzTQpg3Y.js} +1 -1
  323. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-BYCoYGAN.js +1 -0
  324. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-FbCTGrf9.js → timeline-definition-PNZ67QCA-DEz24vV0.js} +1 -1
  325. ksadk/server/static/assets/treeView-BLDUP644-Cpib_vlz.js +1 -0
  326. ksadk/server/static/assets/treemap-LRROVOQU-DQxfmVHK.js +1 -0
  327. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-DWgwtPsJ.js → vennDiagram-CIIHVFJN-CMCixki2.js} +1 -1
  328. ksadk/server/static/assets/wardley-L42UT6IY-BQYHnnkU.js +1 -0
  329. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-CVzB8F9K.js} +1 -1
  330. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.js → xychartDiagram-2RQKCTM6-BFBqBLc1.js} +1 -1
  331. ksadk/server/static/index.html +2 -2
  332. ksadk/server/terminal_sessions.py +111 -58
  333. ksadk/sessions/__init__.py +69 -19
  334. ksadk/sessions/base.py +31 -11
  335. ksadk/sessions/continuity.py +2 -3
  336. ksadk/sessions/in_memory.py +46 -2
  337. ksadk/sessions/local_service.py +148 -17
  338. ksadk/sessions/postgres_service.py +143 -25
  339. ksadk/sessions/resilient.py +36 -8
  340. ksadk/skills/models.py +17 -5
  341. ksadk/skills/package_store.py +5 -2
  342. ksadk/skills/runtime/agent.py +20 -5
  343. ksadk/skills/runtime/artifacts.py +1 -5
  344. ksadk/skills/runtime/backends/e2b.py +10 -4
  345. ksadk/skills/runtime/backends/local.py +15 -3
  346. ksadk/skills/runtime/base.py +1 -2
  347. ksadk/skills/runtime/executor.py +10 -3
  348. ksadk/skills/runtime/factory.py +4 -2
  349. ksadk/skills/runtime/loader.py +1 -2
  350. ksadk/skills/runtime/registry.py +15 -10
  351. ksadk/skills/runtime/request.py +3 -1
  352. ksadk/skills/service_client.py +47 -16
  353. ksadk/skills/tool_defs.py +15 -10
  354. ksadk/studio/__init__.py +5 -0
  355. ksadk/studio/agent_avatar_assets.py +120 -0
  356. ksadk/studio/agent_lifecycle.py +51 -0
  357. ksadk/studio/api.py +1046 -0
  358. ksadk/studio/api_catalog_routes.py +324 -0
  359. ksadk/studio/api_contracts.py +177 -0
  360. ksadk/studio/api_helpers.py +132 -0
  361. ksadk/studio/authoring.py +524 -0
  362. ksadk/studio/authoring_coordinator.py +285 -0
  363. ksadk/studio/builder.py +320 -0
  364. ksadk/studio/capabilities.py +351 -0
  365. ksadk/studio/cloud.py +278 -0
  366. ksadk/studio/codex_agent_service.py +583 -0
  367. ksadk/studio/codex_builder.py +324 -0
  368. ksadk/studio/codex_manifest.py +278 -0
  369. ksadk/studio/codex_run.py +352 -0
  370. ksadk/studio/compiler.py +189 -0
  371. ksadk/studio/contracts.py +644 -0
  372. ksadk/studio/errors.py +47 -0
  373. ksadk/studio/evaluation.py +192 -0
  374. ksadk/studio/event_store.py +284 -0
  375. ksadk/studio/framework_run.py +114 -0
  376. ksadk/studio/identifiers.py +33 -0
  377. ksadk/studio/mcp_runtime.py +229 -0
  378. ksadk/studio/model_client.py +543 -0
  379. ksadk/studio/model_profile_service.py +214 -0
  380. ksadk/studio/operations.py +243 -0
  381. ksadk/studio/otel_trace.py +754 -0
  382. ksadk/studio/pagination.py +182 -0
  383. ksadk/studio/python_tool_inspection.py +183 -0
  384. ksadk/studio/repository.py +306 -0
  385. ksadk/studio/resource_catalog.py +1217 -0
  386. ksadk/studio/run_service.py +707 -0
  387. ksadk/studio/runtime_catalog.py +74 -0
  388. ksadk/studio/runtime_source.py +339 -0
  389. ksadk/studio/service.py +1141 -0
  390. ksadk/studio/shared_web.py +994 -0
  391. ksadk/studio/skill_discovery.py +628 -0
  392. ksadk/studio/static/assets/PrismRenderer-IYN-ffww.js +3 -0
  393. ksadk/studio/static/assets/index-CaEN0eTR.css +1 -0
  394. ksadk/studio/static/assets/index-DI2eY_NH.js +252 -0
  395. ksadk/studio/static/assets/react-vendor-BNmTiJ-I.js +9 -0
  396. ksadk/studio/static/assets/rolldown-runtime-hePW80VL.js +1 -0
  397. ksadk/studio/static/index.html +15 -0
  398. ksadk/studio/templates.py +630 -0
  399. ksadk/studio/validator.py +246 -0
  400. ksadk/studio/workspace.py +137 -0
  401. ksadk/terminal_exec_policy.py +3 -4
  402. ksadk/tools/gateway.py +101 -15
  403. ksadk/tools/result_budget.py +12 -4
  404. ksadk/toolsets/__init__.py +161 -37
  405. ksadk/toolsets/a2a.py +426 -0
  406. ksadk/toolsets/platform.py +21 -5
  407. ksadk/toolsets/sandbox.py +82 -16
  408. ksadk/toolsets/skills.py +200 -39
  409. ksadk/toolsets/web.py +123 -26
  410. ksadk/toolsets/workspace.py +212 -101
  411. ksadk/tracing/__init__.py +19 -21
  412. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  413. ksadk/tracing/setup.py +135 -506
  414. ksadk/tracing/span_utils.py +0 -41
  415. ksadk/tui/loop.py +78 -30
  416. ksadk/tui/stream_render.py +1 -0
  417. ksadk/ui_config.py +5 -3
  418. ksadk/version.py +1 -1
  419. ksadk_runtime_common/memory_backend/registry.py +56 -56
  420. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  421. ksadk_runtime_common/workspace_files/router.py +8 -2
  422. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  423. ksadk/a2a/card_builder.py +0 -64
  424. ksadk/a2a/client.py +0 -309
  425. ksadk/runners/utils/langfuse.py +0 -230
  426. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  427. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  428. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  429. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  430. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  431. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  432. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  433. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  434. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  435. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  436. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  437. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  438. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  439. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  440. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  441. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  442. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  443. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  444. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  445. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  446. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  447. ksadk/tracing/exporters/langfuse_exporter.py +0 -445
  448. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/entry_points.txt +0 -0
  449. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/licenses/LICENSE +0 -0
  450. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,902 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import time
5
+ from typing import Any, AsyncIterator, Callable, Dict, Mapping, Optional, Sequence
6
+
7
+ from ksadk.conversations.run_kinds import (
8
+ RUN_MODE_FOREGROUND,
9
+ trigger_from_resume_input,
10
+ validate_run_mode,
11
+ )
12
+ from ksadk.conversations.runtime_compaction import preview_auto_compaction
13
+ from ksadk.conversations.runtime_constants import (
14
+ ASSISTANT_STREAM_SNAPSHOT_INTERVAL_SECONDS,
15
+ ASSISTANT_STREAM_SNAPSHOT_MIN_NEW_CHARS,
16
+ PTL_RETRY_KEEP_TAIL_GROUPS,
17
+ )
18
+ from ksadk.conversations.runtime_governance import (
19
+ RuntimeCircuitOpen,
20
+ _compact_conversation_history_with_governance,
21
+ _governance_record_tool_call,
22
+ _governance_record_tool_result,
23
+ _governance_record_turn_start,
24
+ _runtime_governance_from_env,
25
+ _tool_observability_metadata,
26
+ )
27
+ from ksadk.conversations.runtime_input import (
28
+ _auto_save_ltm_turn,
29
+ _build_runner_ambient_contexts,
30
+ _build_runner_request_payload,
31
+ _inject_runner_deferred_tools_for_request,
32
+ _is_prompt_too_long_error,
33
+ _runner_name,
34
+ _runner_type_name,
35
+ )
36
+ from ksadk.conversations.runtime_metadata import _update_session_metadata_after_assistant_turn
37
+ from ksadk.conversations.runtime_observability import (
38
+ _extract_deferred_tool_names,
39
+ _get_conversation_tracer,
40
+ _normalize_usage_payload,
41
+ _set_conversation_input_attributes,
42
+ _set_conversation_output_attributes,
43
+ _set_conversation_span_attributes,
44
+ _set_conversation_usage_attributes,
45
+ _set_span_attribute,
46
+ _span_current_context,
47
+ _span_feedback_metadata,
48
+ )
49
+ from ksadk.conversations.runtime_payloads import CompactionPlan
50
+ from ksadk.conversations.runtime_persistence import (
51
+ append_conversation_event,
52
+ append_deferred_tools_event,
53
+ append_reasoning_event,
54
+ append_run_checkpoint_event,
55
+ append_run_status_event,
56
+ )
57
+ from ksadk.conversations.runtime_preparation import _refresh_history, build_run_input
58
+ from ksadk.conversations.runtime_resume import (
59
+ _checkpoint_event_args_from_agentengine_metadata,
60
+ _extract_agentengine_metadata,
61
+ _failed_status_for_resume,
62
+ _filter_responses_reasoning_output,
63
+ _is_checkpoint_resume_input,
64
+ _latest_checkpoint_metadata_for_run,
65
+ _merge_agentengine_metadata,
66
+ _model_options_disable_reasoning,
67
+ _semantic_events_from_responses_output,
68
+ _tool_receipt_metadata,
69
+ )
70
+ from ksadk.model_policy import fallback_model_for_exception, model_policy_options_for_model
71
+ from ksadk.runtime_context import (
72
+ PlatformInvocationContext,
73
+ platform_invocation_scope,
74
+ tool_execution_scope,
75
+ )
76
+ from ksadk.sessions import resolve_session_service
77
+ from ksadk.tools.gateway import (
78
+ approval_interrupt_info_from_result,
79
+ )
80
+
81
+
82
+ async def _iter_conversation_turn_events(
83
+ *,
84
+ runner: Any,
85
+ agent_id: str,
86
+ user_id: str,
87
+ session_id: Optional[str],
88
+ messages: Sequence[Dict[str, Any]],
89
+ model: Optional[str],
90
+ prepare_runner: Callable[[Any, Optional[str]], None],
91
+ model_metadata: Mapping[str, Any] | None = None,
92
+ model_options: Mapping[str, Any] | None = None,
93
+ state_delta: Optional[dict[str, Any]] = None,
94
+ instructions: Optional[str] = None,
95
+ request_metadata: Mapping[str, Any] | None = None,
96
+ custom_metadata: Mapping[str, Any] | None = None,
97
+ resume_input: Mapping[str, Any] | None = None,
98
+ response_id: str | None = None,
99
+ account_id: str | None = None,
100
+ invocation_id: Optional[str] = None,
101
+ session_service_provider: Callable[[], Any] | None = None,
102
+ run_mode: str = RUN_MODE_FOREGROUND,
103
+ ) -> AsyncIterator[dict[str, Any]]:
104
+ """Internal semantic event stream shared by protocol serializers."""
105
+ provider = session_service_provider or resolve_session_service
106
+ prepare_runner(runner, model)
107
+ governance = _runtime_governance_from_env()
108
+ _governance_record_turn_start(governance)
109
+ entry_run_mode = validate_run_mode(run_mode)
110
+ entry_run_trigger = trigger_from_resume_input(resume_input)
111
+ if resume_input is None:
112
+ compaction_preview = await preview_auto_compaction(
113
+ agent_id=agent_id,
114
+ user_id=user_id,
115
+ session_id=session_id,
116
+ messages=messages,
117
+ model=model,
118
+ model_metadata=model_metadata,
119
+ session_service_provider=provider,
120
+ )
121
+ else:
122
+ compaction_preview = CompactionPlan(
123
+ should_compact=False,
124
+ groups_to_compact=[],
125
+ total_chars=0,
126
+ total_estimated_tokens=0,
127
+ group_count=0,
128
+ tail_groups=0,
129
+ )
130
+ if compaction_preview.should_compact:
131
+ yield {
132
+ "type": "compaction",
133
+ "phase": "start",
134
+ "trigger": "auto",
135
+ "total_chars": compaction_preview.total_chars,
136
+ "total_estimated_tokens": compaction_preview.total_estimated_tokens,
137
+ "group_count": compaction_preview.group_count,
138
+ "threshold_percentage": compaction_preview.auto_compact_threshold_percentage,
139
+ }
140
+ try:
141
+ prepared = await build_run_input(
142
+ agent_id=agent_id,
143
+ user_id=user_id,
144
+ session_id=session_id,
145
+ messages=messages,
146
+ model=model,
147
+ model_metadata=model_metadata,
148
+ model_options=model_options,
149
+ state_delta=state_delta,
150
+ instructions=instructions,
151
+ request_metadata=request_metadata,
152
+ custom_metadata=custom_metadata,
153
+ resume_input=resume_input,
154
+ invocation_id=invocation_id,
155
+ governance_state=governance,
156
+ session_service_provider=provider,
157
+ run_mode=entry_run_mode,
158
+ )
159
+ # prepared 之后的 run_status 写入复用 prepared 的 mode/trigger
160
+ run_mode = prepared.run_mode
161
+ run_trigger = prepared.run_trigger
162
+ except RuntimeCircuitOpen as exc:
163
+ if session_id:
164
+ await append_run_status_event(
165
+ session_id=session_id,
166
+ author=_runner_name(runner),
167
+ status=_failed_status_for_resume(resume_input),
168
+ invocation_id=invocation_id,
169
+ detail=str(exc),
170
+ metadata={"governance": exc.metadata},
171
+ session_service_provider=provider,
172
+ run_mode=entry_run_mode,
173
+ run_trigger=entry_run_trigger,
174
+ )
175
+ yield {"type": "error", "message": str(exc) or "Agent 运行失败"}
176
+ return
177
+ _inject_runner_deferred_tools_for_request(runner, prepared)
178
+ ambient_contexts = _build_runner_ambient_contexts(
179
+ runner=runner,
180
+ user_id=user_id,
181
+ user_input=prepared.user_input,
182
+ )
183
+ runtime_context = PlatformInvocationContext(
184
+ agent_id=agent_id,
185
+ user_id=user_id,
186
+ account_id=str(account_id or ""),
187
+ session_id=prepared.session_id,
188
+ history=list(prepared.history),
189
+ input_content=list(prepared.input_content),
190
+ input_messages=list(prepared.input_messages),
191
+ input_parts=list(prepared.user_parts),
192
+ attachments=list(prepared.attachments),
193
+ attachment_results=list(prepared.attachment_results),
194
+ current_attachments=list(prepared.current_attachments),
195
+ current_attachment_results=list(prepared.current_attachment_results),
196
+ has_current_files=prepared.has_current_files,
197
+ runner_type=_runner_type_name(runner),
198
+ metadata=dict(custom_metadata or {}),
199
+ model=model,
200
+ model_options=prepared.model_options,
201
+ kb_context=ambient_contexts.get("kb_context"),
202
+ memory_context=ambient_contexts.get("memory_context"),
203
+ tool_approval_mode=str(
204
+ prepared.request_metadata.get("tool_approval_mode") or ""
205
+ ),
206
+ )
207
+ if prepared.compaction_triggered:
208
+ yield {
209
+ "type": "compaction",
210
+ "phase": "done",
211
+ "trigger": str(prepared.compaction_trigger or "auto"),
212
+ "compacted_until_seq_id": prepared.compacted_until_seq_id,
213
+ "total_chars": (
214
+ compaction_preview.total_chars if compaction_preview.should_compact else None
215
+ ),
216
+ "total_estimated_tokens": (
217
+ compaction_preview.total_estimated_tokens
218
+ if compaction_preview.should_compact
219
+ else None
220
+ ),
221
+ "group_count": (
222
+ compaction_preview.group_count if compaction_preview.should_compact else None
223
+ ),
224
+ "threshold_percentage": (
225
+ compaction_preview.auto_compact_threshold_percentage
226
+ if compaction_preview.should_compact
227
+ else None
228
+ ),
229
+ }
230
+ runner_name = _runner_name(runner)
231
+ tracer = _get_conversation_tracer()
232
+ span = tracer.start_span(runner_name) if tracer else None
233
+ span_ended = False
234
+
235
+ def _finish_span() -> None:
236
+ nonlocal span_ended
237
+ if span is None or span_ended:
238
+ return
239
+ span_ended = True
240
+ try:
241
+ span.end()
242
+ except Exception:
243
+ pass
244
+
245
+ try:
246
+ _set_conversation_span_attributes(
247
+ span,
248
+ agent_id=agent_id,
249
+ user_id=user_id,
250
+ session_id=prepared.session_id,
251
+ invocation_id=prepared.invocation_id,
252
+ runner_name=runner_name,
253
+ model=model,
254
+ response_id=response_id,
255
+ )
256
+ _set_conversation_input_attributes(span, prepared.user_input or prepared.user_display_input)
257
+ trace_metadata = _span_feedback_metadata(span)
258
+ yield {
259
+ "type": "started",
260
+ "session_id": prepared.session_id,
261
+ "metadata": {**trace_metadata, **dict(request_metadata or {})},
262
+ }
263
+ await append_run_status_event(
264
+ session_id=prepared.session_id,
265
+ author=runner_name,
266
+ status="in_progress",
267
+ invocation_id=prepared.invocation_id,
268
+ session_service_provider=provider,
269
+ run_mode=run_mode,
270
+ run_trigger=run_trigger,
271
+ )
272
+
273
+ accumulated_text = ""
274
+ last_snapshot_text = ""
275
+ last_snapshot_at = 0.0
276
+ snapshot_index = 0
277
+ accumulated_reasoning_parts: list[str] = []
278
+ emitted_anything = False
279
+ emitted_response_artifacts = False
280
+ saw_final_chunk = False
281
+ responses_output: list[Any] = []
282
+ responses_response_id: str | None = response_id
283
+ runner_agentengine_metadata: dict[str, Any] = {}
284
+ stream_usage: dict[str, Any] = {}
285
+ stream_last_usage: dict[str, Any] = {}
286
+ reasoning_disabled = _model_options_disable_reasoning(prepared.model_options)
287
+
288
+ async def _persist_accumulated_reasoning(*, before_text: bool = False) -> None:
289
+ if not accumulated_reasoning_parts:
290
+ return
291
+ reasoning = "".join(accumulated_reasoning_parts)
292
+ accumulated_reasoning_parts.clear()
293
+ await append_reasoning_event(
294
+ session_id=prepared.session_id,
295
+ author=runner_name,
296
+ text=reasoning,
297
+ invocation_id=prepared.invocation_id,
298
+ metadata={"stream_boundary": "before_text"} if before_text else None,
299
+ session_service_provider=provider,
300
+ )
301
+
302
+ async def _persist_assistant_snapshot(*, force: bool = False) -> None:
303
+ """Persist a bounded replay point for detached stream recovery."""
304
+ nonlocal last_snapshot_at, last_snapshot_text, snapshot_index
305
+ if not accumulated_text or accumulated_text == last_snapshot_text:
306
+ return
307
+ now = time.monotonic()
308
+ if (
309
+ last_snapshot_text
310
+ and not force
311
+ and len(accumulated_text) - len(last_snapshot_text)
312
+ < ASSISTANT_STREAM_SNAPSHOT_MIN_NEW_CHARS
313
+ and now - last_snapshot_at < ASSISTANT_STREAM_SNAPSHOT_INTERVAL_SECONDS
314
+ ):
315
+ return
316
+ snapshot_index += 1
317
+ await append_conversation_event(
318
+ session_id=prepared.session_id,
319
+ author=runner_name,
320
+ role="model",
321
+ text=accumulated_text,
322
+ invocation_id=prepared.invocation_id,
323
+ event_type="assistant_stream_snapshot",
324
+ metadata={"stream_snapshot": True, "snapshot_index": snapshot_index},
325
+ session_service_provider=provider,
326
+ )
327
+ last_snapshot_text = accumulated_text
328
+ last_snapshot_at = now
329
+
330
+ for attempt in range(2):
331
+ try:
332
+ runtime_context.history = list(prepared.history)
333
+ with platform_invocation_scope(runtime_context):
334
+ with tool_execution_scope(
335
+ session_id=prepared.session_id,
336
+ run_id=prepared.invocation_id,
337
+ invocation_id=prepared.invocation_id,
338
+ ):
339
+ stream = runner.stream(
340
+ _build_runner_request_payload(
341
+ prepared=prepared,
342
+ model=model,
343
+ runtime_context=runtime_context,
344
+ runner=runner,
345
+ )
346
+ )
347
+ while True:
348
+ try:
349
+ with _span_current_context(span):
350
+ chunk = await anext(stream)
351
+ except StopAsyncIteration:
352
+ break
353
+ chunk_type = chunk.get("type")
354
+ if chunk_type == "checkpoint":
355
+ emitted_anything = True
356
+ chunk_agentengine_metadata = _extract_agentengine_metadata(chunk)
357
+ if chunk_agentengine_metadata:
358
+ runner_agentengine_metadata.update(chunk_agentengine_metadata)
359
+ resume_run_id = ""
360
+ if prepared.resume_input and _is_checkpoint_resume_input(
361
+ prepared.resume_input
362
+ ):
363
+ resume_run_id = str(
364
+ prepared.resume_input.get("run_id") or ""
365
+ ).strip()
366
+ checkpoint_args = (
367
+ _checkpoint_event_args_from_agentengine_metadata(
368
+ runner_agentengine_metadata.get("agentengine"),
369
+ fallback_run_id=resume_run_id or prepared.invocation_id,
370
+ )
371
+ )
372
+ if checkpoint_args:
373
+ await append_run_checkpoint_event(
374
+ session_id=prepared.session_id,
375
+ author=runner_name,
376
+ run_id=checkpoint_args["run_id"],
377
+ checkpoint_id=checkpoint_args["checkpoint_id"],
378
+ framework=checkpoint_args["framework"],
379
+ framework_ref=checkpoint_args["framework_ref"],
380
+ phase=checkpoint_args.get("phase") or "stream",
381
+ invocation_id=prepared.invocation_id,
382
+ metadata=checkpoint_args.get("metadata"),
383
+ session_service_provider=provider,
384
+ )
385
+ continue
386
+ if chunk_type == "responses_output":
387
+ if isinstance(chunk.get("usage"), Mapping):
388
+ stream_usage = _normalize_usage_payload(chunk.get("usage"))
389
+ chunk_last = (chunk.get("metadata") or {}).get("last_usage")
390
+ if isinstance(chunk_last, Mapping):
391
+ stream_last_usage = (
392
+ _normalize_usage_payload(chunk_last) or stream_usage
393
+ )
394
+ raw_output = chunk.get("output")
395
+ responses_output = (
396
+ raw_output if isinstance(raw_output, list) else []
397
+ )
398
+ if reasoning_disabled:
399
+ responses_output = _filter_responses_reasoning_output(
400
+ responses_output
401
+ )
402
+ raw_response_id = chunk.get("response_id")
403
+ responses_response_id = (
404
+ str(raw_response_id)
405
+ if raw_response_id
406
+ else responses_response_id
407
+ )
408
+ if responses_output and not emitted_response_artifacts:
409
+ for semantic_event in _semantic_events_from_responses_output(
410
+ responses_output
411
+ ):
412
+ if semantic_event.get("type") == "thinking":
413
+ accumulated_reasoning_parts.append(
414
+ str(semantic_event.get("delta") or "")
415
+ )
416
+ emitted_anything = True
417
+ yield semantic_event
418
+ continue
419
+ if chunk_type == "thinking":
420
+ if reasoning_disabled:
421
+ continue
422
+ delta = str(chunk.get("delta", ""))
423
+ if delta:
424
+ # Close the preceding text segment before
425
+ # a new thought begins. Snapshot throttling
426
+ # must not erase this timeline boundary.
427
+ await _persist_assistant_snapshot(force=True)
428
+ accumulated_reasoning_parts.append(delta)
429
+ emitted_anything = True
430
+ emitted_response_artifacts = True
431
+ yield {"type": "thinking", "delta": delta}
432
+ continue
433
+ if chunk_type == "text":
434
+ delta = str(chunk.get("delta", ""))
435
+ if delta:
436
+ # A reasoning event must be written before
437
+ # the text snapshot it explains. Without
438
+ # this boundary, historical replay only
439
+ # sees one merged reasoning blob after all
440
+ # streamed text and cannot rebuild an
441
+ # interleaved turn.
442
+ await _persist_accumulated_reasoning(before_text=True)
443
+ replace = bool(chunk.get("replace"))
444
+ accumulated_text = (
445
+ delta if replace else accumulated_text + delta
446
+ )
447
+ emitted_anything = True
448
+ await _persist_assistant_snapshot(force=replace)
449
+ text_event: dict[str, Any] = {
450
+ "type": "text",
451
+ "delta": delta,
452
+ }
453
+ if replace:
454
+ text_event["replace"] = True
455
+ yield text_event
456
+ continue
457
+ if chunk_type == "tool_call":
458
+ await _persist_assistant_snapshot(force=True)
459
+ _governance_record_tool_call(governance)
460
+ emitted_response_artifacts = True
461
+ tool_args = chunk.get("tool_args", {})
462
+ if not isinstance(tool_args, Mapping):
463
+ tool_args = {}
464
+ tool_call_id = str(
465
+ chunk.get("call_id") or chunk.get("run_id") or ""
466
+ ).strip()
467
+ await append_conversation_event(
468
+ session_id=prepared.session_id,
469
+ author=runner_name,
470
+ role="model",
471
+ text=str(chunk.get("tool_name") or "tool"),
472
+ invocation_id=prepared.invocation_id,
473
+ event_type="tool_call",
474
+ metadata={
475
+ "tool_name": chunk.get("tool_name"),
476
+ "tool_args": dict(tool_args),
477
+ "run_id": chunk.get("run_id"),
478
+ "tool_call_id": tool_call_id,
479
+ "stage": chunk.get("stage") or tool_args.get("stage"),
480
+ "event_kind": chunk.get("event_kind"),
481
+ "display_title": chunk.get("display_title"),
482
+ "display_summary": chunk.get("display_summary"),
483
+ },
484
+ session_service_provider=provider,
485
+ )
486
+ emitted_anything = True
487
+ await _persist_accumulated_reasoning()
488
+ yield {
489
+ "type": "tool_call",
490
+ "name": chunk.get("tool_name"),
491
+ "args": dict(tool_args),
492
+ "run_id": chunk.get("run_id"),
493
+ "stage": chunk.get("stage") or tool_args.get("stage"),
494
+ "event_kind": chunk.get("event_kind"),
495
+ "display_title": chunk.get("display_title"),
496
+ "display_summary": chunk.get("display_summary"),
497
+ }
498
+ continue
499
+ if chunk_type in {"stage_tool_call", "stage_tool_result"}:
500
+ await _persist_assistant_snapshot(force=True)
501
+ emitted_response_artifacts = True
502
+ tool_name = str(
503
+ chunk.get("tool_name") or chunk.get("name") or "tool"
504
+ )
505
+ tool_args = chunk.get("tool_args", chunk.get("args", {}))
506
+ if not isinstance(tool_args, Mapping):
507
+ tool_args = {}
508
+ tool_output = chunk.get("tool_output", chunk.get("output", ""))
509
+ event_kind = str(chunk.get("event_kind") or "")
510
+ display_title = str(chunk.get("display_title") or tool_name)
511
+ display_summary = str(
512
+ chunk.get("display_summary") or chunk.get("text") or ""
513
+ )
514
+ tool_call_id = str(
515
+ chunk.get("call_id") or chunk.get("run_id") or ""
516
+ ).strip()
517
+ await append_conversation_event(
518
+ session_id=prepared.session_id,
519
+ author=runner_name,
520
+ role="model" if chunk_type == "stage_tool_call" else "user",
521
+ text=display_summary or tool_name,
522
+ invocation_id=prepared.invocation_id,
523
+ event_type=chunk_type,
524
+ metadata={
525
+ "tool_name": tool_name,
526
+ "tool_args": dict(tool_args),
527
+ "tool_output": tool_output,
528
+ "run_id": chunk.get("run_id"),
529
+ "tool_call_id": tool_call_id,
530
+ "stage": chunk.get("stage") or tool_args.get("stage"),
531
+ "event_kind": event_kind,
532
+ "display_title": display_title,
533
+ "display_summary": display_summary,
534
+ },
535
+ session_service_provider=provider,
536
+ )
537
+ emitted_anything = True
538
+ yield {
539
+ "type": chunk_type,
540
+ "name": tool_name,
541
+ "args": dict(tool_args),
542
+ "output": tool_output,
543
+ "run_id": chunk.get("run_id"),
544
+ "stage": chunk.get("stage") or tool_args.get("stage"),
545
+ "event_kind": event_kind,
546
+ "display_title": display_title,
547
+ "display_summary": display_summary,
548
+ }
549
+ continue
550
+ if chunk_type == "tool_result":
551
+ await _persist_assistant_snapshot(force=True)
552
+ emitted_response_artifacts = True
553
+ tool_name = str(chunk.get("tool_name") or "tool")
554
+ tool_args = chunk.get("tool_args", {})
555
+ if not isinstance(tool_args, Mapping):
556
+ tool_args = {}
557
+ tool_run_id = str(chunk.get("run_id") or prepared.invocation_id)
558
+ tool_call_id = str(
559
+ chunk.get("call_id") or chunk.get("run_id") or tool_run_id
560
+ ).strip()
561
+ checkpoint_metadata = _latest_checkpoint_metadata_for_run(
562
+ await provider().get_events(prepared.session_id),
563
+ tool_run_id,
564
+ )
565
+ approval_interrupt_info = approval_interrupt_info_from_result(
566
+ chunk.get("tool_output", ""),
567
+ fallback_tool_name=tool_name,
568
+ tool_args=tool_args,
569
+ run_id=tool_run_id,
570
+ )
571
+ if approval_interrupt_info:
572
+ await append_conversation_event(
573
+ session_id=prepared.session_id,
574
+ author=runner_name,
575
+ role="model",
576
+ text="approval requested",
577
+ invocation_id=prepared.invocation_id,
578
+ event_type="approval_request",
579
+ metadata={"interrupt_info": approval_interrupt_info},
580
+ session_service_provider=provider,
581
+ )
582
+ await append_run_status_event(
583
+ session_id=prepared.session_id,
584
+ author=runner_name,
585
+ status="interrupted",
586
+ invocation_id=prepared.invocation_id,
587
+ detail="approval_required",
588
+ session_service_provider=provider,
589
+ run_mode=run_mode,
590
+ run_trigger=run_trigger,
591
+ )
592
+ emitted_anything = True
593
+ await _persist_accumulated_reasoning()
594
+ yield {
595
+ "type": "interrupt",
596
+ "interrupt_info": approval_interrupt_info,
597
+ "session_id": prepared.session_id,
598
+ "metadata": {**trace_metadata, **prepared.request_metadata},
599
+ }
600
+ return
601
+ await append_conversation_event(
602
+ session_id=prepared.session_id,
603
+ author=runner_name,
604
+ role="user",
605
+ text=str(chunk.get("tool_output", "")),
606
+ invocation_id=prepared.invocation_id,
607
+ event_type="tool_result",
608
+ metadata={
609
+ "tool_name": tool_name,
610
+ "tool_output": chunk.get("tool_output", ""),
611
+ "run_id": tool_run_id,
612
+ "tool_call_id": tool_call_id,
613
+ "observability": _tool_observability_metadata(
614
+ tool_name, chunk.get("tool_output", "")
615
+ ),
616
+ "tool_receipt": _tool_receipt_metadata(
617
+ session_id=prepared.session_id,
618
+ run_id=tool_run_id,
619
+ tool_call_id=tool_call_id,
620
+ tool_name=tool_name,
621
+ tool_args=tool_args,
622
+ checkpoint_id=checkpoint_metadata.get("checkpoint_id"),
623
+ framework=checkpoint_metadata.get("framework"),
624
+ framework_ref=checkpoint_metadata.get("framework_ref"),
625
+ status=(
626
+ "failed"
627
+ if isinstance(chunk.get("tool_output"), Mapping)
628
+ and chunk.get("tool_output", {}).get("ok") is False
629
+ else "completed"
630
+ ),
631
+ ),
632
+ },
633
+ session_service_provider=provider,
634
+ )
635
+ deferred_tool_names = _extract_deferred_tool_names(
636
+ chunk.get("tool_output", "")
637
+ )
638
+ if tool_name == "tool_search" and deferred_tool_names:
639
+ await append_deferred_tools_event(
640
+ session_id=prepared.session_id,
641
+ author=runner_name,
642
+ deferred_tool_names=deferred_tool_names,
643
+ invocation_id=prepared.invocation_id,
644
+ session_service_provider=provider,
645
+ run_mode=run_mode,
646
+ run_trigger=run_trigger,
647
+ )
648
+ _governance_record_tool_result(
649
+ governance, chunk.get("tool_output", "")
650
+ )
651
+ emitted_anything = True
652
+ await _persist_accumulated_reasoning()
653
+ yield {
654
+ "type": "tool_result",
655
+ "name": chunk.get("tool_name"),
656
+ "output": chunk.get("tool_output", ""),
657
+ "run_id": chunk.get("run_id"),
658
+ }
659
+ continue
660
+ if chunk_type in ("interrupt", "approval"):
661
+ await _persist_assistant_snapshot(force=True)
662
+ # langgraph_runner 流式路径冒 `approval`(含 HITL action_requests);
663
+ # invoke 路径冒 `interrupt`。两者统一走 approval_request 通道。
664
+ interrupt_info = chunk.get("interrupt_info")
665
+ await append_conversation_event(
666
+ session_id=prepared.session_id,
667
+ author=runner_name,
668
+ role="model",
669
+ text="approval requested",
670
+ invocation_id=prepared.invocation_id,
671
+ event_type="approval_request",
672
+ metadata={"interrupt_info": interrupt_info},
673
+ session_service_provider=provider,
674
+ )
675
+ await append_run_status_event(
676
+ session_id=prepared.session_id,
677
+ author=runner_name,
678
+ status="interrupted",
679
+ invocation_id=prepared.invocation_id,
680
+ detail="approval_required",
681
+ session_service_provider=provider,
682
+ run_mode=run_mode,
683
+ run_trigger=run_trigger,
684
+ )
685
+ emitted_anything = True
686
+ yield {
687
+ "type": "interrupt",
688
+ "interrupt_info": interrupt_info,
689
+ "session_id": prepared.session_id,
690
+ "metadata": {**trace_metadata, **prepared.request_metadata},
691
+ }
692
+ return
693
+ if chunk_type == "final":
694
+ saw_final_chunk = True
695
+ final_text = str(chunk.get("output", ""))
696
+ if final_text:
697
+ accumulated_text = final_text
698
+ if isinstance(chunk.get("usage"), Mapping):
699
+ stream_usage = _normalize_usage_payload(chunk.get("usage"))
700
+ chunk_last = (chunk.get("metadata") or {}).get("last_usage")
701
+ if isinstance(chunk_last, Mapping):
702
+ stream_last_usage = (
703
+ _normalize_usage_payload(chunk_last) or stream_usage
704
+ )
705
+ break
706
+ except asyncio.CancelledError:
707
+ await _persist_accumulated_reasoning()
708
+ await append_run_status_event(
709
+ session_id=prepared.session_id,
710
+ author=runner_name,
711
+ status="cancelled",
712
+ invocation_id=prepared.invocation_id,
713
+ detail="cancel_requested",
714
+ session_service_provider=provider,
715
+ run_mode=run_mode,
716
+ run_trigger=run_trigger,
717
+ )
718
+ yield {
719
+ "type": "cancelled",
720
+ "session_id": prepared.session_id,
721
+ "metadata": {**trace_metadata, **prepared.request_metadata},
722
+ }
723
+ return
724
+ except Exception as exc:
725
+ if attempt == 0 and not emitted_anything and _is_prompt_too_long_error(exc):
726
+ yield {"type": "compaction", "phase": "start", "trigger": "prompt_too_long"}
727
+ try:
728
+ checkpoint = await _compact_conversation_history_with_governance(
729
+ governance,
730
+ session_id=prepared.session_id,
731
+ author=runner_name,
732
+ invocation_id=prepared.invocation_id,
733
+ model=model,
734
+ model_metadata=prepared.model_metadata,
735
+ force=True,
736
+ trigger="prompt_too_long",
737
+ keep_tail_groups=PTL_RETRY_KEEP_TAIL_GROUPS,
738
+ session_service_provider=provider,
739
+ )
740
+ except RuntimeCircuitOpen as circuit_exc:
741
+ await append_run_status_event(
742
+ session_id=prepared.session_id,
743
+ author=runner_name,
744
+ status=_failed_status_for_resume(resume_input),
745
+ invocation_id=prepared.invocation_id,
746
+ detail=str(circuit_exc),
747
+ metadata={"governance": circuit_exc.metadata},
748
+ session_service_provider=provider,
749
+ run_mode=run_mode,
750
+ run_trigger=run_trigger,
751
+ )
752
+ await _persist_accumulated_reasoning()
753
+ yield {"type": "error", "message": str(circuit_exc) or "Agent 运行失败"}
754
+ return
755
+ if checkpoint:
756
+ yield {
757
+ "type": "compaction",
758
+ "phase": "done",
759
+ "trigger": "prompt_too_long",
760
+ "compacted_until_seq_id": int(
761
+ (checkpoint.metadata or {}).get("compacted_until_seq_id") or 0
762
+ )
763
+ or None,
764
+ }
765
+ prepared = await _refresh_history(
766
+ prepared, session_service_provider=provider
767
+ )
768
+ runtime_context.history = list(prepared.history)
769
+ continue
770
+ if attempt == 0 and not emitted_anything:
771
+ fallback_model = fallback_model_for_exception(exc, current_model=model or "")
772
+ if fallback_model:
773
+ model = fallback_model
774
+ prepare_runner(runner, fallback_model)
775
+ prepared.model_options = {
776
+ **prepared.model_options,
777
+ **model_policy_options_for_model(fallback_model),
778
+ }
779
+ runtime_context.model = fallback_model
780
+ runtime_context.model_options = prepared.model_options
781
+ _set_span_attribute(span, "ksadk.model.fallback", fallback_model)
782
+ await append_run_status_event(
783
+ session_id=prepared.session_id,
784
+ author=runner_name,
785
+ status="in_progress",
786
+ invocation_id=prepared.invocation_id,
787
+ detail=f"fallback_model:{fallback_model}",
788
+ session_service_provider=provider,
789
+ run_mode=run_mode,
790
+ run_trigger=run_trigger,
791
+ )
792
+ continue
793
+ await append_run_status_event(
794
+ session_id=prepared.session_id,
795
+ author=runner_name,
796
+ status=_failed_status_for_resume(resume_input),
797
+ invocation_id=prepared.invocation_id,
798
+ detail=str(exc),
799
+ metadata=(
800
+ {"governance": exc.metadata}
801
+ if isinstance(exc, RuntimeCircuitOpen)
802
+ else None
803
+ ),
804
+ session_service_provider=provider,
805
+ run_mode=run_mode,
806
+ run_trigger=run_trigger,
807
+ )
808
+ await _persist_accumulated_reasoning()
809
+ yield {"type": "error", "message": str(exc) or "Agent 运行失败"}
810
+ return
811
+
812
+ request_metadata_without_agentengine = {
813
+ key: value for key, value in prepared.request_metadata.items() if key != "agentengine"
814
+ }
815
+ assistant_metadata = {
816
+ **trace_metadata,
817
+ **request_metadata_without_agentengine,
818
+ **_merge_agentengine_metadata(prepared.request_metadata, runner_agentengine_metadata),
819
+ }
820
+ if responses_output:
821
+ assistant_metadata["responses_output"] = responses_output
822
+ if stream_usage:
823
+ assistant_metadata["usage"] = stream_usage
824
+ if stream_last_usage:
825
+ assistant_metadata["last_usage"] = stream_last_usage
826
+ elif stream_usage:
827
+ assistant_metadata["last_usage"] = stream_usage
828
+ if responses_response_id:
829
+ assistant_metadata["response_id"] = responses_response_id
830
+ if emitted_anything and not saw_final_chunk and not accumulated_text:
831
+ await append_run_status_event(
832
+ session_id=prepared.session_id,
833
+ author=runner_name,
834
+ status=_failed_status_for_resume(resume_input),
835
+ invocation_id=prepared.invocation_id,
836
+ detail="runner_stream_ended_without_final_output",
837
+ session_service_provider=provider,
838
+ run_mode=run_mode,
839
+ run_trigger=run_trigger,
840
+ )
841
+ await _persist_accumulated_reasoning()
842
+ _finish_span()
843
+ yield {
844
+ "type": "error",
845
+ "message": "Agent 运行流已结束,但没有返回最终输出。",
846
+ "session_id": prepared.session_id,
847
+ "metadata": {
848
+ **assistant_metadata,
849
+ "detail": "runner_stream_ended_without_final_output",
850
+ },
851
+ }
852
+ return
853
+ _set_conversation_output_attributes(span, accumulated_text)
854
+
855
+ await _persist_accumulated_reasoning()
856
+ await append_conversation_event(
857
+ session_id=prepared.session_id,
858
+ author=runner_name,
859
+ role="model",
860
+ text=accumulated_text,
861
+ invocation_id=prepared.invocation_id,
862
+ event_type="assistant_message",
863
+ metadata=assistant_metadata or None,
864
+ session_service_provider=provider,
865
+ )
866
+ await _update_session_metadata_after_assistant_turn(
867
+ service=provider(),
868
+ session_id=prepared.session_id,
869
+ assistant_text=accumulated_text,
870
+ model=model,
871
+ )
872
+ await _auto_save_ltm_turn(
873
+ agent_id=agent_id,
874
+ user_id=user_id,
875
+ prepared=prepared,
876
+ output_text=accumulated_text,
877
+ runner_type=runtime_context.runner_type,
878
+ model=model,
879
+ )
880
+ await append_run_status_event(
881
+ session_id=prepared.session_id,
882
+ author=runner_name,
883
+ status="completed",
884
+ invocation_id=prepared.invocation_id,
885
+ session_service_provider=provider,
886
+ run_mode=run_mode,
887
+ run_trigger=run_trigger,
888
+ )
889
+ _set_conversation_usage_attributes(span, assistant_metadata.get("usage"))
890
+ _finish_span()
891
+ yield {
892
+ "type": "completed",
893
+ "output_text": accumulated_text,
894
+ "model": model,
895
+ "session_id": prepared.session_id,
896
+ "metadata": assistant_metadata,
897
+ "responses_output": responses_output,
898
+ "response_id": responses_response_id,
899
+ "usage": assistant_metadata.get("usage"),
900
+ }
901
+ finally:
902
+ _finish_span()