agentengine-sdk-python 0.6.9__py3-none-any.whl → 0.8.0__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 (384) hide show
  1. {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +41 -23
  2. agentengine_sdk_python-0.8.0.dist-info/RECORD +578 -0
  3. ksadk/a2a/__init__.py +178 -11
  4. ksadk/a2a/bootstrap.py +334 -0
  5. ksadk/a2a/card.py +120 -0
  6. ksadk/a2a/context_store.py +203 -0
  7. ksadk/a2a/control_plane.py +818 -0
  8. ksadk/a2a/credential.py +99 -0
  9. ksadk/a2a/event_adapter.py +149 -0
  10. ksadk/a2a/executor.py +406 -89
  11. ksadk/a2a/external_transport.py +516 -0
  12. ksadk/a2a/identity.py +304 -0
  13. ksadk/a2a/ids.py +22 -0
  14. ksadk/a2a/langgraph.py +285 -0
  15. ksadk/a2a/resume_store.py +201 -0
  16. ksadk/a2a/routes.py +105 -0
  17. ksadk/a2a/server.py +107 -60
  18. ksadk/a2a/space_client.py +1101 -0
  19. ksadk/a2a/task_adapter.py +423 -0
  20. ksadk/a2a/task_event_dispatcher.py +167 -0
  21. ksadk/a2a/task_event_outbox.py +326 -0
  22. ksadk/a2a/task_store.py +206 -0
  23. ksadk/a2ui/__init__.py +27 -0
  24. ksadk/a2ui/core.py +186 -0
  25. ksadk/a2ui/models.py +166 -0
  26. ksadk/a2ui/renderer.py +198 -0
  27. ksadk/agui/__init__.py +9 -0
  28. ksadk/agui/a2ui_projection.py +92 -0
  29. ksadk/agui/agent.py +857 -0
  30. ksadk/agui/config.py +86 -0
  31. ksadk/agui/routes.py +55 -0
  32. ksadk/api/client.py +252 -191
  33. ksadk/builders/__init__.py +2 -0
  34. ksadk/builders/base.py +16 -14
  35. ksadk/builders/code_builder.py +318 -236
  36. ksadk/builders/container_builder.py +187 -167
  37. ksadk/builders/framework_requirements.py +29 -11
  38. ksadk/builders/ks3_uploader.py +58 -27
  39. ksadk/builders/managed_runtime_builder.py +145 -0
  40. ksadk/builders/mcp_builder.py +91 -92
  41. ksadk/builders/requirements_utils.py +1 -5
  42. ksadk/cli/__init__.py +89 -171
  43. ksadk/cli/cmd_a2a.py +254 -70
  44. ksadk/cli/cmd_agent.py +19 -5
  45. ksadk/cli/cmd_build.py +158 -29
  46. ksadk/cli/cmd_completion.py +47 -35
  47. ksadk/cli/cmd_config.py +267 -198
  48. ksadk/cli/cmd_create.py +533 -726
  49. ksadk/cli/cmd_dashboard.py +120 -45
  50. ksadk/cli/cmd_deploy.py +117 -58
  51. ksadk/cli/cmd_destroy.py +44 -14
  52. ksadk/cli/cmd_files.py +63 -24
  53. ksadk/cli/cmd_hermes.py +173 -90
  54. ksadk/cli/cmd_invoke.py +388 -159
  55. ksadk/cli/cmd_launch.py +64 -28
  56. ksadk/cli/cmd_mcp.py +103 -64
  57. ksadk/cli/cmd_model.py +14 -5
  58. ksadk/cli/cmd_openclaw.py +488 -228
  59. ksadk/cli/cmd_replay.py +71 -0
  60. ksadk/cli/cmd_run.py +44 -14
  61. ksadk/cli/cmd_status.py +80 -31
  62. ksadk/cli/cmd_version.py +20 -13
  63. ksadk/cli/cmd_web.py +89 -13
  64. ksadk/cli/deploy_utils.py +20 -20
  65. ksadk/cli/dry_run.py +5 -3
  66. ksadk/cli/error_utils.py +37 -12
  67. ksadk/cli/global_options.py +1 -2
  68. ksadk/cli/local_runtime.py +1 -2
  69. ksadk/cli/model_catalog.py +6 -2
  70. ksadk/cli/network_options.py +38 -16
  71. ksadk/cli/resource_common.py +6 -2
  72. ksadk/cli/storage.py +0 -1
  73. ksadk/cli/ui.py +5 -3
  74. ksadk/cli/workflow_common.py +51 -17
  75. ksadk/codex/__init__.py +12 -0
  76. ksadk/codex/client.py +408 -0
  77. ksadk/codex/phase.py +143 -0
  78. ksadk/codex/runtime.py +449 -0
  79. ksadk/common/aicp_env.py +0 -1
  80. ksadk/common/auth.py +2 -2
  81. ksadk/common/constants.py +1 -3
  82. ksadk/common/llm_utils.py +17 -13
  83. ksadk/compat/__init__.py +5 -0
  84. ksadk/compat/adk_compat.py +200 -0
  85. ksadk/compat/copilotkit_a2ui.py +330 -0
  86. ksadk/configs/__init__.py +12 -12
  87. ksadk/configs/env_registry.py +501 -100
  88. ksadk/configs/global_config.py +2 -1
  89. ksadk/configs/settings.py +151 -124
  90. ksadk/conversations/__init__.py +7 -5
  91. ksadk/conversations/attachment_storage.py +16 -11
  92. ksadk/conversations/attachments.py +44 -36
  93. ksadk/conversations/compaction_pipeline.py +12 -12
  94. ksadk/conversations/compaction_prompt.py +9 -5
  95. ksadk/conversations/context.py +221 -6
  96. ksadk/conversations/message_projection.py +656 -0
  97. ksadk/conversations/model_context.py +22 -6
  98. ksadk/conversations/model_options.py +0 -1
  99. ksadk/conversations/normalize.py +20 -16
  100. ksadk/conversations/reasoning_markup.py +1 -1
  101. ksadk/conversations/runtime.py +339 -5187
  102. ksadk/conversations/runtime_compaction.py +333 -0
  103. ksadk/conversations/runtime_constants.py +27 -0
  104. ksadk/conversations/runtime_governance.py +185 -0
  105. ksadk/conversations/runtime_input.py +652 -0
  106. ksadk/conversations/runtime_invocation.py +395 -0
  107. ksadk/conversations/runtime_metadata.py +475 -0
  108. ksadk/conversations/runtime_observability.py +355 -0
  109. ksadk/conversations/runtime_payloads.py +272 -0
  110. ksadk/conversations/runtime_persistence.py +440 -0
  111. ksadk/conversations/runtime_preparation.py +418 -0
  112. ksadk/conversations/runtime_resume.py +816 -0
  113. ksadk/conversations/runtime_stream_events.py +902 -0
  114. ksadk/conversations/runtime_streaming.py +547 -0
  115. ksadk/conversations/semantic_summary.py +17 -5
  116. ksadk/conversations/session_title.py +6 -3
  117. ksadk/deployment/__init__.py +15 -16
  118. ksadk/deployment/agent_access.py +12 -23
  119. ksadk/deployment/base.py +52 -39
  120. ksadk/deployment/manager.py +63 -65
  121. ksadk/deployment/providers/serverless.py +326 -209
  122. ksadk/deployment/registry.py +38 -32
  123. ksadk/deployment/state.py +11 -11
  124. ksadk/deployment/ui_config.py +1 -1
  125. ksadk/detection/__init__.py +1 -1
  126. ksadk/detection/detector.py +146 -83
  127. ksadk/detection/mcp_detector.py +9 -6
  128. ksadk/events/__init__.py +25 -0
  129. ksadk/events/parser.py +191 -0
  130. ksadk/events/replay.py +37 -0
  131. ksadk/events/runtime_event.py +264 -0
  132. ksadk/events/store.py +317 -0
  133. ksadk/harness/__init__.py +34 -0
  134. ksadk/harness/app.py +278 -0
  135. ksadk/harness/config.py +181 -0
  136. ksadk/harness/reasoner.py +105 -0
  137. ksadk/harness/runner.py +211 -0
  138. ksadk/harness/sandbox.py +141 -0
  139. ksadk/harness/tools.py +222 -0
  140. ksadk/hermes_terminal.py +23 -12
  141. ksadk/identity/resolver.py +15 -9
  142. ksadk/ids.py +32 -0
  143. ksadk/knowledge_base/adk_tool.py +1 -1
  144. ksadk/knowledge_base/client.py +23 -29
  145. ksadk/managed_runtime.py +188 -0
  146. ksadk/markdown.py +5 -2
  147. ksadk/mcp_runtime/__init__.py +9 -6
  148. ksadk/memory/__init__.py +1 -1
  149. ksadk/memory/adk/__init__.py +2 -0
  150. ksadk/memory/adk/backends/base_ltm_backend.py +2 -6
  151. ksadk/memory/adk/backends/http_ltm_backend.py +13 -21
  152. ksadk/memory/adk/backends/inmemory_ltm_backend.py +7 -13
  153. ksadk/memory/adk/backends/sdk_ltm_backend.py +26 -33
  154. ksadk/memory/adk/long_term_memory.py +31 -35
  155. ksadk/memory/adk/resilient_session_service.py +267 -0
  156. ksadk/memory/adk/short_term_memory.py +33 -27
  157. ksadk/memory/adk_tool.py +3 -2
  158. ksadk/memory/backends/base.py +19 -19
  159. ksadk/memory/backends/memory.py +24 -25
  160. ksadk/memory/backends/redis.py +31 -30
  161. ksadk/memory/langchain_tool.py +2 -1
  162. ksadk/memory/manager.py +52 -47
  163. ksadk/memory/service.py +10 -8
  164. ksadk/model_policy.py +15 -7
  165. ksadk/model_proxy/__init__.py +51 -0
  166. ksadk/model_proxy/bootstrap.py +80 -0
  167. ksadk/model_proxy/cache.py +165 -0
  168. ksadk/model_proxy/config.py +45 -0
  169. ksadk/model_proxy/demo_webui.py +115 -0
  170. ksadk/model_proxy/detect.py +145 -0
  171. ksadk/model_proxy/gate.py +68 -0
  172. ksadk/model_proxy/namespace.py +173 -0
  173. ksadk/model_proxy/protocol_proxy.py +22 -0
  174. ksadk/model_proxy/server.py +300 -0
  175. ksadk/model_proxy/transform.py +691 -0
  176. ksadk/openclaw_gateway.py +29 -14
  177. ksadk/runners/adk_runner.py +1248 -164
  178. ksadk/runners/base_runner.py +46 -29
  179. ksadk/runners/codex_runner.py +132 -0
  180. ksadk/runners/deepagents_runner.py +0 -1
  181. ksadk/runners/factory.py +17 -5
  182. ksadk/runners/langchain_runner.py +29 -530
  183. ksadk/runners/langgraph_runner.py +490 -95
  184. ksadk/runners/patch_langchain.py +16 -16
  185. ksadk/runners/remote_runner.py +264 -38
  186. ksadk/runners/usage_accumulator.py +1 -0
  187. ksadk/runners/utils/langfuse.py +3 -3
  188. ksadk/runners/utils/loader.py +7 -7
  189. ksadk/runtime/__init__.py +41 -0
  190. ksadk/runtime/adapter.py +345 -0
  191. ksadk/runtime/framework_adapters.py +124 -0
  192. ksadk/runtime/preprocessing.py +118 -0
  193. ksadk/runtime/runner_adapter.py +873 -0
  194. ksadk/runtime_context.py +18 -3
  195. ksadk/runtime_state.py +0 -1
  196. ksadk/sandbox/__init__.py +4 -1
  197. ksadk/sandbox/backends/__init__.py +4 -1
  198. ksadk/sandbox/backends/e2b.py +13 -5
  199. ksadk/sandbox/backends/local_process.py +11 -3
  200. ksadk/sandbox/base.py +10 -15
  201. ksadk/sandbox/factory.py +14 -4
  202. ksadk/sandbox/registry.py +57 -6
  203. ksadk/server/api_models.py +15 -5
  204. ksadk/server/app.py +455 -3743
  205. ksadk/server/composition.py +21 -0
  206. ksadk/server/factory.py +624 -0
  207. ksadk/server/routes/__init__.py +1 -0
  208. ksadk/server/routes/checkpoint_resolution.py +116 -0
  209. ksadk/server/routes/common.py +713 -0
  210. ksadk/server/routes/control.py +327 -0
  211. ksadk/server/routes/dependencies.py +98 -0
  212. ksadk/server/routes/misc.py +448 -0
  213. ksadk/server/routes/models.py +443 -0
  214. ksadk/server/routes/openai_compat.py +207 -0
  215. ksadk/server/routes/projection.py +795 -0
  216. ksadk/server/routes/routers.py +52 -0
  217. ksadk/server/routes/run.py +726 -0
  218. ksadk/server/routes/sessions.py +649 -0
  219. ksadk/server/routes/streaming.py +223 -0
  220. ksadk/server/routes/workspace.py +381 -0
  221. ksadk/server/static/assets/{ArtifactsPanel-C0meuOdi.js → ArtifactsPanel-Cjnqt-8W.js} +1 -1
  222. ksadk/server/static/assets/CodeBlock-BqyqZfuB.js +9 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-BpH7jiFM.js +8 -0
  224. ksadk/server/static/assets/MermaidBlock-DWuxETaJ.js +303 -0
  225. ksadk/server/static/assets/NativeTerminalPanel-MDTopWMO.js +1 -0
  226. ksadk/server/static/assets/{arc-bj2rZnP5.js → arc-CFKwSk_B.js} +1 -1
  227. ksadk/server/static/assets/architecture-7EHR7CIX-CynqOWjZ.js +1 -0
  228. ksadk/server/static/assets/{architectureDiagram-3BPJPVTR-2u1ltDIj.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
  229. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-D6fvdK20.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
  230. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-BK82L5n5.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
  231. ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
  232. ksadk/server/static/assets/{chunk-2J33WTMH-DLVdkeyQ.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
  233. ksadk/server/static/assets/{chunk-4BX2VUAB-BbwsYcbW.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
  234. ksadk/server/static/assets/{chunk-55IACEB6-DOairxzw.js → chunk-55IACEB6-BK8paA20.js} +1 -1
  235. ksadk/server/static/assets/{chunk-727SXJPM-hCO487gs.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
  236. ksadk/server/static/assets/{chunk-AQP2D5EJ-XU8vDOuG.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
  237. ksadk/server/static/assets/{chunk-FMBD7UC4-PrapyfMu.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
  238. ksadk/server/static/assets/{chunk-ND2GUHAM-CboKhTZ3.js → chunk-ND2GUHAM-D98vPd-E.js} +1 -1
  239. ksadk/server/static/assets/chunk-QZHKN3VN-YQIEXeF6.js +1 -0
  240. ksadk/server/static/assets/classDiagram-4FO5ZUOK-CDAUuoXK.js +1 -0
  241. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-CDAUuoXK.js +1 -0
  242. ksadk/server/static/assets/{cose-bilkent-S5V4N54A-_N8bJ-EU.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
  243. ksadk/server/static/assets/{dagre-BM42HDAG-FoDlo5J2.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
  244. ksadk/server/static/assets/{diagram-2AECGRRQ-BBp6ebBw.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
  245. ksadk/server/static/assets/{diagram-5GNKFQAL-CqOvG1PR.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
  246. ksadk/server/static/assets/{diagram-KO2AKTUF-O9T3t6ba.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
  247. ksadk/server/static/assets/{diagram-LMA3HP47-CGG8ekBO.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
  248. ksadk/server/static/assets/{diagram-OG6HWLK6-4BmH1EEg.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
  249. ksadk/server/static/assets/{dist-CiZHB6ZW.js → dist-6CVKuTAe.js} +1 -1
  250. ksadk/server/static/assets/{dist-BMKM66B4.js → dist-BUHRxvDG.js} +1 -1
  251. ksadk/server/static/assets/{dist-CZ6C3x8B.js → dist-BZ9n9AjO.js} +1 -1
  252. ksadk/server/static/assets/{dist-DbaH3p5h.js → dist-BibcG1V9.js} +1 -1
  253. ksadk/server/static/assets/{dist-BVzcWa6D.js → dist-Bs-jQcRX.js} +1 -1
  254. ksadk/server/static/assets/{dist-D99wf6_X.js → dist-C2xjE7cO.js} +1 -1
  255. ksadk/server/static/assets/{dist-DLMjL01k.js → dist-C7-3jInC.js} +1 -1
  256. ksadk/server/static/assets/{dist-DI-oVAXw.js → dist-C99THtIA.js} +1 -1
  257. ksadk/server/static/assets/{dist-BkJjNih3.js → dist-CGcp2ex8.js} +1 -1
  258. ksadk/server/static/assets/{dist-D5JGcxBx.js → dist-CVQRZjPu.js} +1 -1
  259. ksadk/server/static/assets/{dist-CWiTDN_V.js → dist-Cf23NY4L.js} +1 -1
  260. ksadk/server/static/assets/{dist-DLeM1OCK.js → dist-CgF3fj15.js} +1 -1
  261. ksadk/server/static/assets/{dist-BmuTWcm7.js → dist-Cwt7koer.js} +1 -1
  262. ksadk/server/static/assets/{dist-C2DKRFVK.js → dist-D82mtD2s.js} +1 -1
  263. ksadk/server/static/assets/{dist-B67uF2uK.js → dist-DF06ORQo.js} +1 -1
  264. ksadk/server/static/assets/{dist-Cwhk4lwI.js → dist-DHn6nBzr.js} +1 -1
  265. ksadk/server/static/assets/{dist-S4klkK5W.js → dist-Djgl2wVZ.js} +1 -1
  266. ksadk/server/static/assets/{dist-DCpZrjaK.js → dist-DlzCRy0S.js} +1 -1
  267. ksadk/server/static/assets/{dist-Cp1_jKwf.js → dist-DqNnNFrw.js} +1 -1
  268. ksadk/server/static/assets/{dist-6kSZvCZh.js → dist-DyvYLMW9.js} +1 -1
  269. ksadk/server/static/assets/{dist-DM0rEQPk.js → dist-eoW6tZXA.js} +1 -1
  270. ksadk/server/static/assets/{dist-Bk1l05Ni.js → dist-ivOya1LD.js} +1 -1
  271. ksadk/server/static/assets/{erDiagram-TEJ5UH35-oJhaci7S.js → erDiagram-TEJ5UH35-CnfRcY2M.js} +1 -1
  272. ksadk/server/static/assets/eventmodeling-FCH6USID-ChYO-ijM.js +1 -0
  273. ksadk/server/static/assets/{flowDiagram-I6XJVG4X-DtTmUan-.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
  274. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BSsb_eij.js → ganttDiagram-6RSMTGT7-DpCoB2g9.js} +1 -1
  275. ksadk/server/static/assets/gitGraph-WXDBUCRP-BN_0Fk-j.js +1 -0
  276. ksadk/server/static/assets/{gitGraphDiagram-PVQCEYII-BR5s6Pws.js → gitGraphDiagram-PVQCEYII-9IKVFBVT.js} +1 -1
  277. ksadk/server/static/assets/index-QSwCHuB8.js +177 -0
  278. ksadk/server/static/assets/index-jOPmTOZH.css +2 -0
  279. ksadk/server/static/assets/info-J43DQDTF-Cp6o3vId.js +1 -0
  280. ksadk/server/static/assets/{infoDiagram-5YYISTIA-DYPc5cvh.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
  281. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-MoBdALDg.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
  282. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-DgLiQT8l.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
  283. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-CsFx112F.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
  284. ksadk/server/static/assets/{katex-DRsiwpM2.js → katex-DATssjp1.js} +1 -1
  285. ksadk/server/static/assets/{linear-TNRQ5Orv.js → linear-CvMBw9cA.js} +1 -1
  286. ksadk/server/static/assets/{mermaid-parser.core-D2eMVOgo.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
  287. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-BtByYFhL.js → mindmap-definition-RKZ34NQL-CSAQxEAe.js} +1 -1
  288. ksadk/server/static/assets/packet-YPE3B663-wQzct3cT.js +1 -0
  289. ksadk/server/static/assets/pie-LRSECV5Y-BgTQiv-9.js +1 -0
  290. ksadk/server/static/assets/{pieDiagram-4H26LBE5-DPnuCB8c.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
  291. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-miFpCPv4.js → quadrantDiagram-W4KKPZXB-CxIR4JXI.js} +1 -1
  292. ksadk/server/static/assets/radar-GUYGQ44K-BIq5fXsn.js +1 -0
  293. ksadk/server/static/assets/{requirementDiagram-4Y6WPE33-mjB_yYkW.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
  294. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-D7hSlZZZ.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
  295. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-D9Cx6hC3.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
  296. ksadk/server/static/assets/{stateDiagram-AJRCARHV-D_zrg47o.js → stateDiagram-AJRCARHV-DGpd9yFG.js} +1 -1
  297. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-B3o579IQ.js +1 -0
  298. ksadk/server/static/assets/{timeline-definition-PNZ67QCA-CwSec0Wa.js → timeline-definition-PNZ67QCA-jqoYs3jQ.js} +1 -1
  299. ksadk/server/static/assets/treeView-BLDUP644-Dqi-E0EM.js +1 -0
  300. ksadk/server/static/assets/treemap-LRROVOQU-ClQP9CJ9.js +1 -0
  301. ksadk/server/static/assets/{vennDiagram-CIIHVFJN-agCVobiF.js → vennDiagram-CIIHVFJN-l3Z7-wbP.js} +1 -1
  302. ksadk/server/static/assets/wardley-L42UT6IY-8XLvnNIs.js +1 -0
  303. ksadk/server/static/assets/{wardleyDiagram-YWT4CUSO-TmrlhWNt.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
  304. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-DV71V-ah.js → xychartDiagram-2RQKCTM6-SkiH8GsK.js} +1 -1
  305. ksadk/server/static/index.html +2 -2
  306. ksadk/server/terminal_sessions.py +111 -58
  307. ksadk/sessions/__init__.py +86 -40
  308. ksadk/sessions/base.py +31 -11
  309. ksadk/sessions/continuity.py +28 -5
  310. ksadk/sessions/in_memory.py +46 -2
  311. ksadk/sessions/local_service.py +148 -17
  312. ksadk/sessions/postgres_service.py +216 -35
  313. ksadk/sessions/resilience.py +52 -0
  314. ksadk/sessions/resilient.py +388 -0
  315. ksadk/skills/models.py +17 -5
  316. ksadk/skills/package_store.py +5 -2
  317. ksadk/skills/runtime/agent.py +20 -5
  318. ksadk/skills/runtime/artifacts.py +1 -5
  319. ksadk/skills/runtime/backends/e2b.py +10 -4
  320. ksadk/skills/runtime/backends/local.py +15 -3
  321. ksadk/skills/runtime/base.py +1 -2
  322. ksadk/skills/runtime/executor.py +10 -3
  323. ksadk/skills/runtime/factory.py +4 -2
  324. ksadk/skills/runtime/loader.py +1 -2
  325. ksadk/skills/runtime/registry.py +15 -10
  326. ksadk/skills/runtime/request.py +3 -1
  327. ksadk/skills/service_client.py +38 -17
  328. ksadk/skills/tool_defs.py +15 -10
  329. ksadk/terminal_exec_policy.py +3 -4
  330. ksadk/tools/gateway.py +92 -15
  331. ksadk/tools/result_budget.py +12 -4
  332. ksadk/toolsets/__init__.py +136 -36
  333. ksadk/toolsets/platform.py +21 -5
  334. ksadk/toolsets/sandbox.py +82 -16
  335. ksadk/toolsets/skills.py +200 -39
  336. ksadk/toolsets/web.py +123 -26
  337. ksadk/toolsets/workspace.py +264 -114
  338. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  339. ksadk/tracing/exporters/langfuse_exporter.py +91 -76
  340. ksadk/tracing/setup.py +132 -53
  341. ksadk/tracing/span_utils.py +5 -2
  342. ksadk/tui/__init__.py +22 -7
  343. ksadk/tui/loop.py +1925 -0
  344. ksadk/tui/stream_render.py +69 -0
  345. ksadk/ui_config.py +5 -3
  346. ksadk/version.py +1 -1
  347. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  348. agentengine_sdk_python-0.6.9.dist-info/RECORD +0 -487
  349. ksadk/server/static/assets/CodeBlock-BbI4HPtJ.js +0 -9
  350. ksadk/server/static/assets/MathMessageMarkdown-DMLQYoLp.js +0 -8
  351. ksadk/server/static/assets/MermaidBlock-DCR8WZ17.js +0 -303
  352. ksadk/server/static/assets/NativeTerminalPanel-CKUvWhUz.js +0 -1
  353. ksadk/server/static/assets/architecture-7EHR7CIX-Cr6Xz1_c.js +0 -1
  354. ksadk/server/static/assets/channel-BSSOwFIb.js +0 -1
  355. ksadk/server/static/assets/chunk-QZHKN3VN-XXpdiwUL.js +0 -1
  356. ksadk/server/static/assets/classDiagram-4FO5ZUOK-C5HvGiyK.js +0 -1
  357. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-C5HvGiyK.js +0 -1
  358. ksadk/server/static/assets/eventmodeling-FCH6USID-CIgwHJLL.js +0 -1
  359. ksadk/server/static/assets/gitGraph-WXDBUCRP-BVAJ7uo0.js +0 -1
  360. ksadk/server/static/assets/index-BH7-pC0B.js +0 -165
  361. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  362. ksadk/server/static/assets/info-J43DQDTF-MT80V4ge.js +0 -1
  363. ksadk/server/static/assets/packet-YPE3B663-BLKhbXZB.js +0 -1
  364. ksadk/server/static/assets/pie-LRSECV5Y-DFOikjSY.js +0 -1
  365. ksadk/server/static/assets/radar-GUYGQ44K-095b1Ikw.js +0 -1
  366. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-J9kCb0nC.js +0 -1
  367. ksadk/server/static/assets/treeView-BLDUP644-yinfJEY6.js +0 -1
  368. ksadk/server/static/assets/treemap-LRROVOQU-DosUqN1Q.js +0 -1
  369. ksadk/server/static/assets/wardley-L42UT6IY-Bvp7-5uH.js +0 -1
  370. ksadk/tui/app.py +0 -400
  371. ksadk/tui/clipboard.py +0 -100
  372. ksadk/tui/widgets/__init__.py +0 -22
  373. ksadk/tui/widgets/assistant.py +0 -89
  374. ksadk/tui/widgets/base.py +0 -54
  375. ksadk/tui/widgets/chat_input.py +0 -246
  376. ksadk/tui/widgets/history.py +0 -156
  377. ksadk/tui/widgets/system.py +0 -87
  378. ksadk/tui/widgets/thinking.py +0 -110
  379. ksadk/tui/widgets/tool_call.py +0 -161
  380. ksadk/tui/widgets/user.py +0 -37
  381. {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
  382. {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
  383. {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
  384. {agentengine_sdk_python-0.6.9.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,547 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import time
5
+ import uuid
6
+ from typing import Any, AsyncIterator, Callable, Dict, Mapping, Optional, Sequence
7
+
8
+ from ksadk.conversations.run_kinds import (
9
+ RUN_MODE_FOREGROUND,
10
+ )
11
+ from ksadk.conversations.runtime_invocation import _response_sse
12
+ from ksadk.conversations.runtime_payloads import (
13
+ build_compaction_sse_event,
14
+ build_responses_payload,
15
+ )
16
+ from ksadk.conversations.runtime_stream_events import _iter_conversation_turn_events
17
+
18
+
19
+ async def stream_conversation_turn(
20
+ *,
21
+ runner: Any,
22
+ agent_id: str,
23
+ user_id: str,
24
+ session_id: Optional[str],
25
+ messages: Sequence[Dict[str, Any]],
26
+ model: Optional[str],
27
+ prepare_runner: Callable[[Any, Optional[str]], None],
28
+ model_metadata: Mapping[str, Any] | None = None,
29
+ model_options: Mapping[str, Any] | None = None,
30
+ state_delta: Optional[dict[str, Any]] = None,
31
+ instructions: Optional[str] = None,
32
+ request_metadata: Mapping[str, Any] | None = None,
33
+ custom_metadata: Mapping[str, Any] | None = None,
34
+ resume_input: Mapping[str, Any] | None = None,
35
+ account_id: str | None = None,
36
+ invocation_id: Optional[str] = None,
37
+ session_service_provider: Callable[[], Any] | None = None,
38
+ run_mode: str = RUN_MODE_FOREGROUND,
39
+ ) -> AsyncIterator[str]:
40
+ """Legacy ksadk response SSE stream used by hosted chat and chat-completions."""
41
+ async for event in _iter_conversation_turn_events(
42
+ runner=runner,
43
+ agent_id=agent_id,
44
+ user_id=user_id,
45
+ session_id=session_id,
46
+ messages=messages,
47
+ model=model,
48
+ prepare_runner=prepare_runner,
49
+ model_metadata=model_metadata,
50
+ model_options=model_options,
51
+ state_delta=state_delta,
52
+ instructions=instructions,
53
+ request_metadata=request_metadata,
54
+ custom_metadata=custom_metadata,
55
+ resume_input=resume_input,
56
+ account_id=account_id,
57
+ invocation_id=invocation_id,
58
+ session_service_provider=session_service_provider,
59
+ run_mode=run_mode,
60
+ ):
61
+ event_type = event.get("type")
62
+ if event_type == "compaction":
63
+ yield build_compaction_sse_event(
64
+ phase=str(event.get("phase") or "start"),
65
+ trigger=str(event.get("trigger") or "auto"),
66
+ compacted_until_seq_id=event.get("compacted_until_seq_id"),
67
+ total_chars=event.get("total_chars"),
68
+ total_estimated_tokens=event.get("total_estimated_tokens"),
69
+ group_count=event.get("group_count"),
70
+ threshold_percentage=event.get("threshold_percentage"),
71
+ )
72
+ elif event_type == "thinking":
73
+ yield _response_sse("response.reasoning.delta", {"delta": event.get("delta", "")})
74
+ elif event_type == "text":
75
+ text_payload: dict[str, Any] = {"delta": event.get("delta", "")}
76
+ if event.get("replace"):
77
+ text_payload["replace"] = True
78
+ yield _response_sse("response.output_text.delta", text_payload)
79
+ elif event_type == "tool_call":
80
+ yield _response_sse(
81
+ "response.tool_call",
82
+ {
83
+ "name": event.get("name"),
84
+ "args": event.get("args", {}),
85
+ "run_id": event.get("run_id"),
86
+ "stage": event.get("stage"),
87
+ "event_kind": event.get("event_kind"),
88
+ "display_title": event.get("display_title"),
89
+ "display_summary": event.get("display_summary"),
90
+ },
91
+ )
92
+ elif event_type == "tool_result":
93
+ yield _response_sse(
94
+ "response.tool_result",
95
+ {
96
+ "name": event.get("name"),
97
+ "output": event.get("output", ""),
98
+ "run_id": event.get("run_id"),
99
+ },
100
+ )
101
+ elif event_type in {"stage_tool_call", "stage_tool_result"}:
102
+ yield _response_sse(
103
+ f"response.ksadk.{event_type}",
104
+ {
105
+ "type": event_type,
106
+ "name": event.get("name"),
107
+ "args": event.get("args", {}),
108
+ "output": event.get("output", ""),
109
+ "run_id": event.get("run_id"),
110
+ "stage": event.get("stage"),
111
+ "event_kind": event.get("event_kind"),
112
+ "display_title": event.get("display_title"),
113
+ "display_summary": event.get("display_summary"),
114
+ },
115
+ )
116
+ elif event_type == "interrupt":
117
+ yield _response_sse(
118
+ "response.approval_request", {"interrupt_info": event.get("interrupt_info")}
119
+ )
120
+ elif event_type == "error":
121
+ yield _response_sse(
122
+ "response.error", {"message": event.get("message") or "Agent 运行失败"}
123
+ )
124
+ elif event_type == "cancelled":
125
+ yield _response_sse("response.cancelled", {"status": "cancelled"})
126
+ elif event_type == "completed":
127
+ final_payload = build_responses_payload(
128
+ output_text=str(event.get("output_text") or ""),
129
+ model=event.get("model") or model,
130
+ session_id=str(event.get("session_id") or session_id or ""),
131
+ metadata=(
132
+ event.get("metadata") if isinstance(event.get("metadata"), Mapping) else None
133
+ ),
134
+ usage=event.get("usage") if isinstance(event.get("usage"), Mapping) else None,
135
+ )
136
+ yield _response_sse("response.completed", final_payload)
137
+
138
+
139
+ async def stream_responses_conversation_turn(
140
+ *,
141
+ runner: Any,
142
+ agent_id: str,
143
+ user_id: str,
144
+ session_id: Optional[str],
145
+ messages: Sequence[Dict[str, Any]],
146
+ model: Optional[str],
147
+ prepare_runner: Callable[[Any, Optional[str]], None],
148
+ model_metadata: Mapping[str, Any] | None = None,
149
+ model_options: Mapping[str, Any] | None = None,
150
+ state_delta: Optional[dict[str, Any]] = None,
151
+ instructions: Optional[str] = None,
152
+ request_metadata: Mapping[str, Any] | None = None,
153
+ custom_metadata: Mapping[str, Any] | None = None,
154
+ include_agentengine_metadata: bool = False,
155
+ resume_input: Mapping[str, Any] | None = None,
156
+ account_id: str | None = None,
157
+ invocation_id: Optional[str] = None,
158
+ session_service_provider: Callable[[], Any] | None = None,
159
+ run_mode: str = RUN_MODE_FOREGROUND,
160
+ ) -> AsyncIterator[str]:
161
+ """OpenAI Responses-style SSE stream."""
162
+ response_id = f"resp_{uuid.uuid4().hex}"
163
+ created_at = int(time.time())
164
+ response_metadata = dict(custom_metadata or {})
165
+
166
+ message_item_id = f"msg_{uuid.uuid4().hex[:12]}"
167
+ reasoning_item_id = f"rs_{uuid.uuid4().hex[:12]}"
168
+ next_output_index = 0
169
+ text_output_index: int | None = None
170
+ reasoning_output_index: int | None = None
171
+ message_started = False
172
+ content_started = False
173
+ reasoning_started = False
174
+ completed_text = ""
175
+ lifecycle_started = False
176
+
177
+ def _start_response_lifecycle(current_session_id: str | None = None) -> list[str]:
178
+ nonlocal lifecycle_started, response_metadata
179
+ if lifecycle_started:
180
+ return []
181
+ lifecycle_started = True
182
+ initial_payload = build_responses_payload(
183
+ output_text="",
184
+ model=model,
185
+ session_id=current_session_id or session_id or "",
186
+ response_id=response_id,
187
+ created_at=created_at,
188
+ status="in_progress",
189
+ metadata=response_metadata,
190
+ )
191
+ return [
192
+ _response_sse("response.created", initial_payload),
193
+ _response_sse("response.in_progress", initial_payload),
194
+ ]
195
+
196
+ def _message_item(status: str, text: str = "") -> dict[str, Any]:
197
+ content = [{"type": "output_text", "text": text}] if text or status == "completed" else []
198
+ return {
199
+ "id": message_item_id,
200
+ "type": "message",
201
+ "status": status,
202
+ "role": "assistant",
203
+ "content": content,
204
+ }
205
+
206
+ def _reasoning_item(status: str) -> dict[str, Any]:
207
+ return {
208
+ "id": reasoning_item_id,
209
+ "type": "reasoning",
210
+ "status": status,
211
+ "summary": [],
212
+ }
213
+
214
+ def _next_output_index() -> int:
215
+ nonlocal next_output_index
216
+ output_index = next_output_index
217
+ next_output_index += 1
218
+ return output_index
219
+
220
+ async for event in _iter_conversation_turn_events(
221
+ runner=runner,
222
+ agent_id=agent_id,
223
+ user_id=user_id,
224
+ session_id=session_id,
225
+ messages=messages,
226
+ model=model,
227
+ prepare_runner=prepare_runner,
228
+ model_metadata=model_metadata,
229
+ model_options=model_options,
230
+ state_delta=state_delta,
231
+ instructions=instructions,
232
+ request_metadata=request_metadata,
233
+ custom_metadata=custom_metadata,
234
+ resume_input=resume_input,
235
+ response_id=response_id,
236
+ account_id=account_id,
237
+ invocation_id=invocation_id,
238
+ session_service_provider=session_service_provider,
239
+ run_mode=run_mode,
240
+ ):
241
+ if include_agentengine_metadata:
242
+ event_metadata = event.get("metadata")
243
+ agentengine_metadata = (
244
+ event_metadata.get("agentengine") if isinstance(event_metadata, Mapping) else None
245
+ )
246
+ if isinstance(agentengine_metadata, Mapping):
247
+ response_metadata["agentengine"] = dict(agentengine_metadata)
248
+ if not lifecycle_started:
249
+ for lifecycle_chunk in _start_response_lifecycle(str(event.get("session_id") or "")):
250
+ yield lifecycle_chunk
251
+ event_type = event.get("type")
252
+ if event_type == "compaction":
253
+ yield build_compaction_sse_event(
254
+ phase=str(event.get("phase") or "start"),
255
+ trigger=str(event.get("trigger") or "auto"),
256
+ compacted_until_seq_id=event.get("compacted_until_seq_id"),
257
+ total_chars=event.get("total_chars"),
258
+ total_estimated_tokens=event.get("total_estimated_tokens"),
259
+ group_count=event.get("group_count"),
260
+ threshold_percentage=event.get("threshold_percentage"),
261
+ )
262
+ continue
263
+
264
+ if event_type == "thinking":
265
+ if not reasoning_started:
266
+ reasoning_started = True
267
+ reasoning_output_index = _next_output_index()
268
+ yield _response_sse(
269
+ "response.output_item.added",
270
+ {
271
+ "output_index": reasoning_output_index,
272
+ "item": _reasoning_item("in_progress"),
273
+ },
274
+ )
275
+ yield _response_sse(
276
+ "response.reasoning.delta",
277
+ {
278
+ "item_id": reasoning_item_id,
279
+ "output_index": reasoning_output_index,
280
+ "delta": event.get("delta", ""),
281
+ },
282
+ )
283
+ continue
284
+
285
+ if event_type == "text":
286
+ if not message_started:
287
+ message_started = True
288
+ text_output_index = _next_output_index()
289
+ yield _response_sse(
290
+ "response.output_item.added",
291
+ {"output_index": text_output_index, "item": _message_item("in_progress")},
292
+ )
293
+ if not content_started:
294
+ content_started = True
295
+ yield _response_sse(
296
+ "response.content_part.added",
297
+ {
298
+ "item_id": message_item_id,
299
+ "output_index": text_output_index,
300
+ "content_index": 0,
301
+ "part": {"type": "output_text", "text": ""},
302
+ },
303
+ )
304
+ delta = str(event.get("delta") or "")
305
+ replace = bool(event.get("replace"))
306
+ completed_text = delta if replace else completed_text + delta
307
+ text_delta_payload: dict[str, Any] = {
308
+ "item_id": message_item_id,
309
+ "output_index": text_output_index,
310
+ "content_index": 0,
311
+ "delta": delta,
312
+ }
313
+ if replace:
314
+ text_delta_payload["replace"] = True
315
+ yield _response_sse(
316
+ "response.output_text.delta",
317
+ text_delta_payload,
318
+ )
319
+ continue
320
+
321
+ if event_type == "tool_call":
322
+ args_json = json.dumps(event.get("args", {}) or {}, ensure_ascii=False)
323
+ call_id = str(event.get("run_id") or f"call_{uuid.uuid4().hex[:12]}")
324
+ item_id = f"fc_{uuid.uuid4().hex[:12]}"
325
+ call_output_index = _next_output_index()
326
+ item = {
327
+ "id": item_id,
328
+ "type": "function_call",
329
+ "status": "in_progress",
330
+ "call_id": call_id,
331
+ "name": event.get("name") or "unknown",
332
+ "arguments": "",
333
+ }
334
+ yield _response_sse(
335
+ "response.output_item.added", {"output_index": call_output_index, "item": item}
336
+ )
337
+ yield _response_sse(
338
+ "response.function_call_arguments.delta",
339
+ {"item_id": item_id, "output_index": call_output_index, "delta": args_json},
340
+ )
341
+ item["arguments"] = args_json
342
+ item["status"] = "completed"
343
+ yield _response_sse(
344
+ "response.function_call_arguments.done",
345
+ {"item_id": item_id, "output_index": call_output_index, "arguments": args_json},
346
+ )
347
+ yield _response_sse(
348
+ "response.output_item.done", {"output_index": call_output_index, "item": item}
349
+ )
350
+ if event.get("display_title") or event.get("display_summary"):
351
+ yield _response_sse(
352
+ "response.ksadk.tool_call",
353
+ {
354
+ "type": "tool_call",
355
+ "name": event.get("name"),
356
+ "args": event.get("args", {}),
357
+ "run_id": event.get("run_id"),
358
+ "stage": event.get("stage"),
359
+ "event_kind": event.get("event_kind"),
360
+ "display_title": event.get("display_title"),
361
+ "display_summary": event.get("display_summary"),
362
+ },
363
+ )
364
+ continue
365
+
366
+ if event_type == "tool_result":
367
+ yield _response_sse(
368
+ "response.ksadk.tool_result",
369
+ {
370
+ "name": event.get("name"),
371
+ "output": event.get("output", ""),
372
+ "run_id": event.get("run_id"),
373
+ },
374
+ )
375
+ continue
376
+
377
+ if event_type in {"stage_tool_call", "stage_tool_result"}:
378
+ yield _response_sse(
379
+ f"response.ksadk.{event_type}",
380
+ {
381
+ "type": event_type,
382
+ "name": event.get("name"),
383
+ "args": event.get("args", {}),
384
+ "output": event.get("output", ""),
385
+ "run_id": event.get("run_id"),
386
+ "stage": event.get("stage"),
387
+ "event_kind": event.get("event_kind"),
388
+ "display_title": event.get("display_title"),
389
+ "display_summary": event.get("display_summary"),
390
+ },
391
+ )
392
+ continue
393
+
394
+ if event_type == "interrupt":
395
+ interrupt_info = event.get("interrupt_info")
396
+ if isinstance(interrupt_info, Mapping) and interrupt_info.get("tool_name"):
397
+ raw_arguments = (
398
+ interrupt_info.get("arguments")
399
+ or interrupt_info.get("tool_args")
400
+ or interrupt_info.get("args")
401
+ or {}
402
+ )
403
+ arguments = (
404
+ raw_arguments
405
+ if isinstance(raw_arguments, str)
406
+ else json.dumps(raw_arguments, ensure_ascii=False)
407
+ )
408
+ approval_item = {
409
+ "id": str(
410
+ interrupt_info.get("approval_request_id")
411
+ or interrupt_info.get("id")
412
+ or f"appr_{uuid.uuid4().hex[:12]}"
413
+ ),
414
+ "type": "mcp_approval_request",
415
+ "name": str(interrupt_info.get("tool_name")),
416
+ "arguments": arguments,
417
+ "server_label": str(interrupt_info.get("server_label") or "ksadk"),
418
+ }
419
+ approval_output_index = _next_output_index()
420
+ yield _response_sse(
421
+ "response.output_item.added",
422
+ {"output_index": approval_output_index, "item": approval_item},
423
+ )
424
+ yield _response_sse(
425
+ "response.output_item.done",
426
+ {"output_index": approval_output_index, "item": approval_item},
427
+ )
428
+ else:
429
+ yield _response_sse(
430
+ "response.ksadk.approval_request", {"interrupt_info": interrupt_info}
431
+ )
432
+ incomplete_payload = build_responses_payload(
433
+ output_text=completed_text,
434
+ model=model,
435
+ session_id=str(event.get("session_id") or session_id or ""),
436
+ response_id=response_id,
437
+ created_at=created_at,
438
+ status="incomplete",
439
+ metadata=response_metadata,
440
+ incomplete_details={
441
+ "reason": "approval_required",
442
+ "ksadk_interrupt": interrupt_info,
443
+ },
444
+ )
445
+ yield _response_sse("response.incomplete", incomplete_payload)
446
+ return
447
+
448
+ if event_type == "error":
449
+ failed_payload = build_responses_payload(
450
+ output_text=completed_text,
451
+ model=model,
452
+ session_id=session_id or "",
453
+ response_id=response_id,
454
+ created_at=created_at,
455
+ status="failed",
456
+ metadata=response_metadata,
457
+ usage=event.get("usage") if isinstance(event.get("usage"), Mapping) else None,
458
+ error={"message": event.get("message") or "Agent 运行失败"},
459
+ )
460
+ yield _response_sse("response.failed", failed_payload)
461
+ return
462
+
463
+ if event_type == "cancelled":
464
+ cancelled_payload = build_responses_payload(
465
+ output_text=completed_text,
466
+ model=model,
467
+ session_id=str(event.get("session_id") or session_id or ""),
468
+ response_id=response_id,
469
+ created_at=created_at,
470
+ status="cancelled",
471
+ metadata=response_metadata,
472
+ usage=event.get("usage") if isinstance(event.get("usage"), Mapping) else None,
473
+ )
474
+ yield _response_sse("response.cancelled", cancelled_payload)
475
+ return
476
+
477
+ if event_type == "completed":
478
+ completed_text = str(event.get("output_text") or completed_text)
479
+ if completed_text and not message_started:
480
+ message_started = True
481
+ text_output_index = _next_output_index()
482
+ yield _response_sse(
483
+ "response.output_item.added",
484
+ {"output_index": text_output_index, "item": _message_item("in_progress")},
485
+ )
486
+ content_started = True
487
+ yield _response_sse(
488
+ "response.content_part.added",
489
+ {
490
+ "item_id": message_item_id,
491
+ "output_index": text_output_index,
492
+ "content_index": 0,
493
+ "part": {"type": "output_text", "text": ""},
494
+ },
495
+ )
496
+ if message_started:
497
+ yield _response_sse(
498
+ "response.output_text.done",
499
+ {
500
+ "item_id": message_item_id,
501
+ "output_index": text_output_index,
502
+ "content_index": 0,
503
+ "text": completed_text,
504
+ },
505
+ )
506
+ yield _response_sse(
507
+ "response.content_part.done",
508
+ {
509
+ "item_id": message_item_id,
510
+ "output_index": text_output_index,
511
+ "content_index": 0,
512
+ "part": {"type": "output_text", "text": completed_text},
513
+ },
514
+ )
515
+ yield _response_sse(
516
+ "response.output_item.done",
517
+ {
518
+ "output_index": text_output_index,
519
+ "item": _message_item("completed", completed_text),
520
+ },
521
+ )
522
+ if reasoning_started:
523
+ yield _response_sse(
524
+ "response.output_item.done",
525
+ {"output_index": reasoning_output_index, "item": _reasoning_item("completed")},
526
+ )
527
+ final_payload = build_responses_payload(
528
+ output_text=completed_text,
529
+ model=event.get("model") or model,
530
+ session_id=str(event.get("session_id") or session_id or ""),
531
+ response_id=str(event.get("response_id") or response_id),
532
+ created_at=created_at,
533
+ status="completed",
534
+ metadata=response_metadata,
535
+ usage=event.get("usage") if isinstance(event.get("usage"), Mapping) else None,
536
+ output_items=(
537
+ event.get("responses_output")
538
+ if isinstance(event.get("responses_output"), Sequence)
539
+ else None
540
+ ),
541
+ )
542
+ yield _response_sse("response.completed", final_payload)
543
+ return
544
+
545
+ if not lifecycle_started:
546
+ for lifecycle_chunk in _start_response_lifecycle():
547
+ yield lifecycle_chunk
@@ -11,7 +11,11 @@ from ksadk.conversations.compaction_prompt import (
11
11
  build_compaction_prompt_messages,
12
12
  extract_summary_text,
13
13
  )
14
- from ksadk.conversations.context import canonical_event_type, extract_event_text, summarize_event_groups
14
+ from ksadk.conversations.context import (
15
+ canonical_event_type,
16
+ extract_event_text,
17
+ summarize_event_groups,
18
+ )
15
19
  from ksadk.sessions.base import SessionEvent
16
20
 
17
21
  SUMMARY_VERSION = "v1"
@@ -25,7 +29,8 @@ SUMMARY_PREFIX = "Earlier conversation summary:"
25
29
  # 已知局限(有意取舍,对齐 Claude Code 行为):
26
30
  # - 默认 0(opt-in),避免 transient 失败永久禁用 semantic;用户显式设 N>0 才启用。
27
31
  # - 打开后无 half-open 探测,需进程重启或显式 _reset_semantic_failures 恢复(CC 同样如此)。
28
- # - 计数为模块级全局,跨 session/model 共享;per-model key 化留作 follow-up(对齐 governance per-session 范式)。
32
+ # - 计数为模块级全局,跨 session/model 共享。
33
+ # - per-model key 化留作 follow-up(对齐 governance per-session 范式)。
29
34
  _semantic_summary_failures: int = 0
30
35
 
31
36
 
@@ -118,7 +123,9 @@ class SummaryModelClient:
118
123
  }
119
124
  timeout_seconds = max(1.0, float(timeout_ms) / 1000.0)
120
125
  async with httpx.AsyncClient(timeout=timeout_seconds) as client:
121
- response = await client.post(self._chat_completions_url(), headers=headers, json=payload)
126
+ response = await client.post(
127
+ self._chat_completions_url(), headers=headers, json=payload
128
+ )
122
129
  response.raise_for_status()
123
130
  data = response.json()
124
131
 
@@ -280,7 +287,9 @@ def _build_semantic_input(
280
287
  if len(selected_groups) > max_groups:
281
288
  skipped_groups = selected_groups[:-max_groups]
282
289
  selected_groups = selected_groups[-max_groups:]
283
- skipped_summary = summarize_event_groups(skipped_groups, previous_summary=merged_previous_summary)
290
+ skipped_summary = summarize_event_groups(
291
+ skipped_groups, previous_summary=merged_previous_summary
292
+ )
284
293
  merged_previous_summary = skipped_summary
285
294
  return merged_previous_summary, selected_groups
286
295
 
@@ -295,7 +304,10 @@ async def summarize_compaction(
295
304
  ) -> CompactionSummaryResult:
296
305
  """语义摘要优先,失败后自动回退到 extractive。"""
297
306
 
298
- fallback_summary = summarize_event_groups(list(groups_to_compact), previous_summary=previous_summary)
307
+ fallback_summary = summarize_event_groups(
308
+ [list(group) for group in groups_to_compact],
309
+ previous_summary=previous_summary,
310
+ )
299
311
  if semantic_compaction_disabled():
300
312
  return CompactionSummaryResult(
301
313
  summary_text=fallback_summary,
@@ -112,7 +112,6 @@ def build_heuristic_title(*, first_prompt: str, assistant_text: str) -> str:
112
112
  prompt = _normalize_source_text(first_prompt)
113
113
  assistant = _normalize_source_text(assistant_text)
114
114
  combined = f"{prompt} {assistant}".strip()
115
- prompt_lower = prompt.lower()
116
115
  combined_lower = combined.lower()
117
116
 
118
117
  if _SELF_INTRO_RE.search(prompt):
@@ -126,7 +125,9 @@ def build_heuristic_title(*, first_prompt: str, assistant_text: str) -> str:
126
125
  if _RECRUIT_RE.search(combined_lower):
127
126
  if "简历" in combined_lower or "候选人" in combined_lower:
128
127
  return "简历分析"
129
- if "面试" in combined_lower and (_ANALYZE_RE.search(combined) or _FILE_RE.search(combined_lower)):
128
+ if "面试" in combined_lower and (
129
+ _ANALYZE_RE.search(combined) or _FILE_RE.search(combined_lower)
130
+ ):
130
131
  return "面试分析"
131
132
 
132
133
  if _FILE_RE.search(combined_lower):
@@ -230,7 +231,9 @@ class SessionTitleClient:
230
231
  }
231
232
  timeout_seconds = max(1.0, float(timeout_ms) / 1000.0)
232
233
  async with httpx.AsyncClient(timeout=timeout_seconds) as client:
233
- response = await client.post(self._chat_completions_url(), headers=headers, json=payload)
234
+ response = await client.post(
235
+ self._chat_completions_url(), headers=headers, json=payload
236
+ )
234
237
  response.raise_for_status()
235
238
  data = response.json()
236
239