agentengine-sdk-python 0.7.0__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 (371) hide show
  1. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/METADATA +36 -20
  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 +233 -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 +500 -720
  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 +168 -89
  54. ksadk/cli/cmd_invoke.py +184 -122
  55. ksadk/cli/cmd_launch.py +64 -28
  56. ksadk/cli/cmd_mcp.py +98 -64
  57. ksadk/cli/cmd_model.py +14 -5
  58. ksadk/cli/cmd_openclaw.py +483 -227
  59. ksadk/cli/cmd_replay.py +71 -0
  60. ksadk/cli/cmd_run.py +33 -10
  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 +34 -14
  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 +500 -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 +438 -51
  97. ksadk/conversations/model_context.py +12 -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 -5255
  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 +51 -38
  120. ksadk/deployment/manager.py +63 -65
  121. ksadk/deployment/providers/serverless.py +309 -202
  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 +4 -5
  156. ksadk/memory/adk/short_term_memory.py +12 -21
  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 +345 -120
  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 -742
  183. ksadk/runners/langgraph_runner.py +352 -90
  184. ksadk/runners/patch_langchain.py +16 -16
  185. ksadk/runners/remote_runner.py +134 -33
  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 -3885
  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-D-SSn2ee.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-BA13sHc9.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-DzJzgVoL.js → architectureDiagram-3BPJPVTR-Dej8jX8c.js} +1 -1
  229. ksadk/server/static/assets/{blockDiagram-GPEHLZMM-UTdVcZhn.js → blockDiagram-GPEHLZMM-1F64jqvy.js} +1 -1
  230. ksadk/server/static/assets/{c4Diagram-AAUBKEIU-Dix0GD4m.js → c4Diagram-AAUBKEIU-9q7AUAKb.js} +1 -1
  231. ksadk/server/static/assets/channel-iUGv2N24.js +1 -0
  232. ksadk/server/static/assets/{chunk-2J33WTMH-C2JxuZ42.js → chunk-2J33WTMH-6qgwJm7Q.js} +1 -1
  233. ksadk/server/static/assets/{chunk-4BX2VUAB-Be57QPgD.js → chunk-4BX2VUAB-CsWIQRhc.js} +1 -1
  234. ksadk/server/static/assets/{chunk-55IACEB6-WjSuy4nv.js → chunk-55IACEB6-BK8paA20.js} +1 -1
  235. ksadk/server/static/assets/{chunk-727SXJPM-BOovP-b5.js → chunk-727SXJPM-B-JEhy7h.js} +1 -1
  236. ksadk/server/static/assets/{chunk-AQP2D5EJ-DOmZNmWj.js → chunk-AQP2D5EJ-DYBvMHAa.js} +1 -1
  237. ksadk/server/static/assets/{chunk-FMBD7UC4-DzwlodkU.js → chunk-FMBD7UC4-BGhvzDYt.js} +1 -1
  238. ksadk/server/static/assets/{chunk-ND2GUHAM-DMqAikEU.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-Zhy2GBnP.js → cose-bilkent-S5V4N54A-CX3yotHq.js} +1 -1
  243. ksadk/server/static/assets/{dagre-BM42HDAG-CbKrtIUz.js → dagre-BM42HDAG-C7TguAWo.js} +1 -1
  244. ksadk/server/static/assets/{diagram-2AECGRRQ-BRApgQRK.js → diagram-2AECGRRQ-Dd17_kws.js} +1 -1
  245. ksadk/server/static/assets/{diagram-5GNKFQAL-D0xbnDiK.js → diagram-5GNKFQAL-DVIClIil.js} +1 -1
  246. ksadk/server/static/assets/{diagram-KO2AKTUF-CVugVI9L.js → diagram-KO2AKTUF-Df_3gYQa.js} +1 -1
  247. ksadk/server/static/assets/{diagram-LMA3HP47-DozUGgee.js → diagram-LMA3HP47-BhLk6ZtA.js} +1 -1
  248. ksadk/server/static/assets/{diagram-OG6HWLK6-ZOYsKlru.js → diagram-OG6HWLK6-D4GNGvuu.js} +1 -1
  249. ksadk/server/static/assets/{dist-DmFaq_Iy.js → dist-6CVKuTAe.js} +1 -1
  250. ksadk/server/static/assets/{dist-8EEyGgDx.js → dist-BUHRxvDG.js} +1 -1
  251. ksadk/server/static/assets/{dist-B0NP_Z0z.js → dist-BZ9n9AjO.js} +1 -1
  252. ksadk/server/static/assets/{dist-DMezvBGJ.js → dist-BibcG1V9.js} +1 -1
  253. ksadk/server/static/assets/{dist-C3HIIaN5.js → dist-Bs-jQcRX.js} +1 -1
  254. ksadk/server/static/assets/{dist-BrCcQ47T.js → dist-C2xjE7cO.js} +1 -1
  255. ksadk/server/static/assets/{dist-Dp0k7bWI.js → dist-C7-3jInC.js} +1 -1
  256. ksadk/server/static/assets/{dist-D-xOD048.js → dist-C99THtIA.js} +1 -1
  257. ksadk/server/static/assets/{dist-CkEKJFtk.js → dist-CGcp2ex8.js} +1 -1
  258. ksadk/server/static/assets/{dist-DyOkZmze.js → dist-CVQRZjPu.js} +1 -1
  259. ksadk/server/static/assets/{dist-BssVmjIo.js → dist-Cf23NY4L.js} +1 -1
  260. ksadk/server/static/assets/{dist-BIJVDMuB.js → dist-CgF3fj15.js} +1 -1
  261. ksadk/server/static/assets/{dist-2hInLS_J.js → dist-Cwt7koer.js} +1 -1
  262. ksadk/server/static/assets/{dist-DyWsb78Q.js → dist-D82mtD2s.js} +1 -1
  263. ksadk/server/static/assets/{dist-D-JMdWPQ.js → dist-DF06ORQo.js} +1 -1
  264. ksadk/server/static/assets/{dist-BmlMPsCc.js → dist-DHn6nBzr.js} +1 -1
  265. ksadk/server/static/assets/{dist-gX6GOLKq.js → dist-Djgl2wVZ.js} +1 -1
  266. ksadk/server/static/assets/{dist-DpKtt4Bo.js → dist-DlzCRy0S.js} +1 -1
  267. ksadk/server/static/assets/{dist-8_SfK1IP.js → dist-DqNnNFrw.js} +1 -1
  268. ksadk/server/static/assets/{dist-D57wnGWd.js → dist-DyvYLMW9.js} +1 -1
  269. ksadk/server/static/assets/{dist-CPBtqRTW.js → dist-eoW6tZXA.js} +1 -1
  270. ksadk/server/static/assets/{dist-DL_NKc_z.js → dist-ivOya1LD.js} +1 -1
  271. ksadk/server/static/assets/{erDiagram-TEJ5UH35-Bk-9bgE5.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-Dn9kZVuZ.js → flowDiagram-I6XJVG4X-DGaJjGNJ.js} +1 -1
  274. ksadk/server/static/assets/{ganttDiagram-6RSMTGT7-BGxXlJqm.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-C7Q0X-wi.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-BO_CSqq5.js → infoDiagram-5YYISTIA-CYIIsb8y.js} +1 -1
  281. ksadk/server/static/assets/{ishikawaDiagram-YF4QCWOH-eYLPLd46.js → ishikawaDiagram-YF4QCWOH-DLOHGvWw.js} +1 -1
  282. ksadk/server/static/assets/{journeyDiagram-JHISSGLW-De9geSb0.js → journeyDiagram-JHISSGLW-BIzKeejT.js} +1 -1
  283. ksadk/server/static/assets/{kanban-definition-UN3LZRKU-Cs80kQto.js → kanban-definition-UN3LZRKU-BWHoFSw2.js} +1 -1
  284. ksadk/server/static/assets/{katex-DSrCFD8n.js → katex-DATssjp1.js} +1 -1
  285. ksadk/server/static/assets/{linear-CN9sbKTF.js → linear-CvMBw9cA.js} +1 -1
  286. ksadk/server/static/assets/{mermaid-parser.core-DlgSBU8l.js → mermaid-parser.core-mGAcEwcq.js} +2 -2
  287. ksadk/server/static/assets/{mindmap-definition-RKZ34NQL-9afz7Oug.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-DPv_VstN.js → pieDiagram-4H26LBE5-By-ra07M.js} +1 -1
  291. ksadk/server/static/assets/{quadrantDiagram-W4KKPZXB-o77wZ1XK.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-BYVw81VC.js → requirementDiagram-4Y6WPE33-DpW90iu3.js} +1 -1
  294. ksadk/server/static/assets/{sankeyDiagram-5OEKKPKP-B7nZFMKT.js → sankeyDiagram-5OEKKPKP-DpGa6EAV.js} +1 -1
  295. ksadk/server/static/assets/{sequenceDiagram-3UESZ5HK-BGRRrFw5.js → sequenceDiagram-3UESZ5HK-NTKNGGe5.js} +1 -1
  296. ksadk/server/static/assets/{stateDiagram-AJRCARHV-BUfHCoPs.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-FbCTGrf9.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-DWgwtPsJ.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-2x8G-tTM.js → wardleyDiagram-YWT4CUSO-BR54GPmr.js} +1 -1
  304. ksadk/server/static/assets/{xychartDiagram-2RQKCTM6-Drma3AYl.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 +69 -19
  308. ksadk/sessions/base.py +31 -11
  309. ksadk/sessions/continuity.py +2 -3
  310. ksadk/sessions/in_memory.py +46 -2
  311. ksadk/sessions/local_service.py +148 -17
  312. ksadk/sessions/postgres_service.py +143 -25
  313. ksadk/sessions/resilient.py +36 -8
  314. ksadk/skills/models.py +17 -5
  315. ksadk/skills/package_store.py +5 -2
  316. ksadk/skills/runtime/agent.py +20 -5
  317. ksadk/skills/runtime/artifacts.py +1 -5
  318. ksadk/skills/runtime/backends/e2b.py +10 -4
  319. ksadk/skills/runtime/backends/local.py +15 -3
  320. ksadk/skills/runtime/base.py +1 -2
  321. ksadk/skills/runtime/executor.py +10 -3
  322. ksadk/skills/runtime/factory.py +4 -2
  323. ksadk/skills/runtime/loader.py +1 -2
  324. ksadk/skills/runtime/registry.py +15 -10
  325. ksadk/skills/runtime/request.py +3 -1
  326. ksadk/skills/service_client.py +38 -17
  327. ksadk/skills/tool_defs.py +15 -10
  328. ksadk/terminal_exec_policy.py +3 -4
  329. ksadk/tools/gateway.py +92 -15
  330. ksadk/tools/result_budget.py +12 -4
  331. ksadk/toolsets/__init__.py +134 -36
  332. ksadk/toolsets/platform.py +21 -5
  333. ksadk/toolsets/sandbox.py +82 -16
  334. ksadk/toolsets/skills.py +200 -39
  335. ksadk/toolsets/web.py +123 -26
  336. ksadk/toolsets/workspace.py +212 -101
  337. ksadk/tracing/exporters/inmemory_exporter.py +62 -51
  338. ksadk/tracing/exporters/langfuse_exporter.py +91 -76
  339. ksadk/tracing/setup.py +69 -53
  340. ksadk/tracing/span_utils.py +5 -2
  341. ksadk/tui/loop.py +78 -30
  342. ksadk/tui/stream_render.py +1 -0
  343. ksadk/ui_config.py +5 -3
  344. ksadk/version.py +1 -1
  345. ksadk_runtime_common/schemas/runtime_event_v1.json +95 -0
  346. agentengine_sdk_python-0.7.0.dist-info/RECORD +0 -482
  347. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +0 -9
  348. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +0 -8
  349. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +0 -303
  350. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +0 -1
  351. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +0 -1
  352. ksadk/server/static/assets/channel-CTuydARX.js +0 -1
  353. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +0 -1
  354. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +0 -1
  355. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +0 -1
  356. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +0 -1
  357. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +0 -1
  358. ksadk/server/static/assets/index-C00Lwg3L.js +0 -165
  359. ksadk/server/static/assets/index-DAURbCsP.css +0 -1
  360. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +0 -1
  361. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +0 -1
  362. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +0 -1
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +0 -1
  364. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +0 -1
  365. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +0 -1
  366. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +0 -1
  367. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +0 -1
  368. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/WHEEL +0 -0
  369. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/entry_points.txt +0 -0
  370. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/licenses/LICENSE +0 -0
  371. {agentengine_sdk_python-0.7.0.dist-info → agentengine_sdk_python-0.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,21 @@
1
+ """Runtime app route composition independent from the default app facade."""
2
+
3
+ from fastapi import FastAPI
4
+
5
+ from ksadk.server.factory import RuntimeAppState
6
+ from ksadk.server.routes.common import _register_integrated_routers
7
+ from ksadk.server.routes.routers import GROUP_ROUTERS, load_route_modules
8
+
9
+
10
+ def configure_runtime_app(app: FastAPI, state: RuntimeAppState, groups: set[str]) -> None:
11
+ """Attach integrated resources and the selected route groups to one app."""
12
+ load_route_modules()
13
+ _register_integrated_routers(app, state)
14
+
15
+ ordered = sorted(group for group in groups if group != "health_meta")
16
+ if "health_meta" in groups:
17
+ ordered.append("health_meta")
18
+ for group in ordered:
19
+ router = GROUP_ROUTERS.get(group)
20
+ if router is not None:
21
+ app.include_router(router)
@@ -0,0 +1,624 @@
1
+ """create_runtime_app — 普通 runtime 与 HarnessApp 共用的 app factory (goal-01)。
2
+
3
+ H2 §4.2:这是三线公共装配入口,替代 `ksadk/server/app.py` 的模块级单例 +
4
+ `set_runner` 全局态。纯结构性重构,不动业务逻辑。
5
+
6
+ 设计要点:
7
+
8
+ - **per-app state**:runner / runner_loaded / detached-stream registry 全部挂在
9
+ `app.state.runtime`(:class:`RuntimeAppState`)上,每个 app 实例一份,普通 app 与
10
+ HarnessApp 互不共享。不再有模块级 ``runner`` / ``_DETACHED_*`` 全局可变态。
11
+ - **请求级桥接**:中间件把当前 app 的 state 写入 :data:`current_state` 的
12
+ contextvar,handler 内既有辅助函数经 :func:`get_state` 取 state,从而**不必逐个
13
+ 改写约 30 个 handler 的签名**。后台 detached task 脱离请求上下文,在创建时
14
+ 从 state 捕获 registry(见 ``_detached_streaming_response``)。
15
+ - **route group 化**:路由按域拆成 APIRouter,factory 按 ``config.route_groups``
16
+ 可插拔装配;数据面 group 进 HarnessApp,控制面(cancel/resume/builder/debug)
17
+ 不进。
18
+ - **薄兼容壳**:`ksadk/server/app.py` 仍以 ``app`` / ``set_runner`` 暴露,内部
19
+ 改为调用本 factory,老调用方(TestClient / run_server / builders / deploy
20
+ manager)零改动。
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ import asyncio
26
+ import contextvars
27
+ import logging
28
+ from contextlib import contextmanager
29
+ from typing import TYPE_CHECKING, Any, Callable, Iterator, Optional, cast
30
+
31
+ from fastapi import FastAPI
32
+
33
+ from ksadk.runners.base_runner import BaseRunner
34
+ from ksadk.sandbox.registry import (
35
+ SandboxRegistry,
36
+ bind_sandbox_registry,
37
+ set_fallback_sandbox_registry,
38
+ )
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+ if TYPE_CHECKING:
43
+ from ksadk.server.terminal_sessions import TerminalSessionManager
44
+
45
+
46
+ # ---------------------------------------------------------------------------
47
+ # route group 注册表(冻结稿 G0.1):数据面 vs 控制面
48
+ # ---------------------------------------------------------------------------
49
+
50
+ #: 数据面 route group —— 可插拔装配进 HarnessApp。
51
+ DATA_PLANE_GROUPS: frozenset[str] = frozenset(
52
+ {
53
+ "health_meta",
54
+ "sessions",
55
+ "sessions_adk_compat",
56
+ "run",
57
+ "openai_compat",
58
+ "workspace",
59
+ "models",
60
+ "feedback",
61
+ "tools",
62
+ "ui_bootstrap",
63
+ "agui",
64
+ }
65
+ )
66
+
67
+ #: 控制面 route group —— 不进入 HarnessApp(H2 §4.2:控制面 action 不进入)。
68
+ CONTROL_PLANE_GROUPS: frozenset[str] = frozenset(
69
+ {
70
+ "control", # cancel / resume / checkpoint-resume-preview
71
+ "builder",
72
+ "debug",
73
+ }
74
+ )
75
+
76
+ #: 全部 group(普通 runtime app 默认装配)。
77
+ ALL_GROUPS: frozenset[str] = DATA_PLANE_GROUPS | CONTROL_PLANE_GROUPS
78
+
79
+
80
+ class StreamRegistry:
81
+ """per-app detached SSE stream + resume-key 状态。
82
+
83
+ 替代 `app.py` 曾经的模块级 ``_DETACHED_STREAMS`` / ``_DETACHED_STREAMS_BY_INVOCATION``
84
+ / ``_DETACHED_RESUME_KEYS_BY_INVOCATION`` / ``_ACTIVE_DETACHED_RESUME_INVOCATION_BY_KEY``。
85
+ 生命周期绑定所属 app(lifespan 清理)。SSE/cancel 行为与旧模块级实现逐点一致。
86
+ """
87
+
88
+ def __init__(self) -> None:
89
+ self.streams: set[asyncio.Task[Any]] = set()
90
+ self.streams_by_invocation: dict[str, Any] = {}
91
+ self.resume_keys_by_invocation: dict[str, tuple[str, str]] = {}
92
+ self.active_resume_invocation_by_key: dict[tuple[str, str], str] = {}
93
+
94
+ def clear(self) -> None:
95
+ self.streams.clear()
96
+ self.streams_by_invocation.clear()
97
+ self.resume_keys_by_invocation.clear()
98
+ self.active_resume_invocation_by_key.clear()
99
+
100
+
101
+ class RuntimeAppState:
102
+ """per-app 运行时状态及其拥有的可清理资源。"""
103
+
104
+ def __init__(
105
+ self,
106
+ runner: Optional[BaseRunner] = None,
107
+ *,
108
+ session_service_provider: Callable[[], Any] | None = None,
109
+ session_backend_provider: Callable[[], dict[str, Any]] | None = None,
110
+ ) -> None:
111
+ self.app: Optional[FastAPI] = None
112
+ self.runner: Optional[BaseRunner] = runner
113
+ self.runner_loaded: bool = False
114
+ self.stream_registry = StreamRegistry()
115
+ self.sandbox_registry = SandboxRegistry()
116
+ self.session_service: Any = None
117
+ self._session_services_by_loop: dict[asyncio.AbstractEventLoop, Any] = {}
118
+ self._sync_session_service: Any = None
119
+ # The legacy ``server.app`` facade exposes monkeypatchable providers.
120
+ # New factory callers leave these unset and get per-app owned services.
121
+ self._session_service_provider = session_service_provider
122
+ self._session_backend_provider = session_backend_provider
123
+ # app.py 在装配 terminal routes 时创建,避免 factory 反向依赖 server。
124
+ self.terminal_manager: Optional[TerminalSessionManager] = None
125
+ # A2A 装配产物(config.a2a.enabled 时由 _wire_a2a_if_enabled 写入)。
126
+ self.a2a_server: Any = None
127
+ self.a2a_bootstrap: Any = None
128
+ # AG-UI endpoint 及其 app-owned RuntimeAdapter handle registry。
129
+ self.agui_agent: Any = None
130
+ self.agui_config: Any = None
131
+
132
+ def resolve_session_service(self) -> Any:
133
+ """Return this app's session service for the current execution loop."""
134
+ if self.session_service is not None:
135
+ return self.session_service
136
+ if self._session_service_provider is not None:
137
+ return self._session_service_provider()
138
+
139
+ from ksadk.sessions import create_session_service
140
+
141
+ try:
142
+ loop = asyncio.get_running_loop()
143
+ except RuntimeError:
144
+ if self._sync_session_service is None:
145
+ self._sync_session_service = create_session_service()
146
+ return self._sync_session_service
147
+
148
+ service = self._session_services_by_loop.get(loop)
149
+ if service is None:
150
+ service = create_session_service()
151
+ self._session_services_by_loop[loop] = service
152
+ return service
153
+
154
+ def session_services(self) -> list[Any]:
155
+ """Return all unique services owned by this app for shutdown."""
156
+ candidates = [
157
+ self.session_service,
158
+ self._sync_session_service,
159
+ *self._session_services_by_loop.values(),
160
+ ]
161
+ services: list[Any] = []
162
+ for service in candidates:
163
+ if service is not None and all(service is not item for item in services):
164
+ services.append(service)
165
+ return services
166
+
167
+ def describe_session_backend(self) -> dict[str, Any]:
168
+ if self._session_backend_provider is not None:
169
+ return dict(self._session_backend_provider())
170
+ from ksadk.sessions import describe_session_backend
171
+
172
+ return dict(describe_session_backend())
173
+
174
+
175
+ class RuntimeAppConfig:
176
+ """create_runtime_app 的装配配置。
177
+
178
+ - ``runner``:依赖注入的 runner(替代 set_runner 全局态);可在装配后由
179
+ 兼容壳 ``set_runner`` 再写入 ``app.state.runtime.runner``。
180
+ - ``runtime_type``:runtime 类型标识(普通 / harness / codex ...)。
181
+ - ``route_groups``:要装配的 route group 集合;默认 :data:`ALL_GROUPS`,
182
+ HarnessApp 传 :data:`DATA_PLANE_GROUPS`。
183
+ """
184
+
185
+ def __init__(
186
+ self,
187
+ runner: Optional[BaseRunner] = None,
188
+ *,
189
+ runtime_type: str = "local",
190
+ route_groups: Optional[set[str]] = None,
191
+ a2a: Optional[Any] = None,
192
+ runtime_adapter: Any = None,
193
+ agui: Optional[Any] = None,
194
+ session_service_provider: Callable[[], Any] | None = None,
195
+ session_backend_provider: Callable[[], dict[str, Any]] | None = None,
196
+ ) -> None:
197
+ self.runner = runner
198
+ self.runtime_type = runtime_type
199
+ self.route_groups: set[str] = (
200
+ set(route_groups) if route_groups is not None else set(ALL_GROUPS)
201
+ )
202
+ # A2A 协议装配配置(``ksadk.a2a.routes.A2AConfig``);enabled 时 factory 装配
203
+ # A2A 数据面端点(契约 §8)。用 Any 避免本模块硬依赖可选的 a2a-sdk。
204
+ self.a2a = a2a
205
+ self.runtime_adapter = runtime_adapter
206
+ self.agui = agui
207
+ self.session_service_provider = session_service_provider
208
+ self.session_backend_provider = session_backend_provider
209
+
210
+
211
+ # ---------------------------------------------------------------------------
212
+ # 请求级 state 桥接
213
+ # ---------------------------------------------------------------------------
214
+
215
+ _current_state: contextvars.ContextVar[Optional[RuntimeAppState]] = contextvars.ContextVar(
216
+ "ksadk_runtime_app_state", default=None
217
+ )
218
+
219
+ # 非请求上下文(直接调用内部 helper 的测试 / run_server 启动前)的兜底 state。
220
+ # 由 app.py 在 factory 建 app 后指向 ``app.state.runtime``。
221
+ _fallback_state: RuntimeAppState = RuntimeAppState()
222
+
223
+
224
+ def set_fallback_state(state: RuntimeAppState) -> None:
225
+ """把兜底 state 指向某个 app 的 state(兼容壳用)。"""
226
+ global _fallback_state
227
+ _fallback_state = state
228
+ set_fallback_sandbox_registry(state.sandbox_registry)
229
+
230
+
231
+ def get_state() -> RuntimeAppState:
232
+ """取当前请求对应的 app state;非请求上下文退回兜底 state。"""
233
+ state = _current_state.get()
234
+ return state if state is not None else _fallback_state
235
+
236
+
237
+ @contextmanager
238
+ def bind_runtime_state(state: RuntimeAppState) -> Iterator[None]:
239
+ """Bind one app state for non-HTTP scopes such as WebSockets."""
240
+ token = _current_state.set(state)
241
+ try:
242
+ with bind_sandbox_registry(state.sandbox_registry):
243
+ yield
244
+ finally:
245
+ _current_state.reset(token)
246
+
247
+
248
+ def get_runner() -> BaseRunner:
249
+ """取当前 app 的 runner(懒加载 agent)。等价旧的 ``_resolve_active_runner``。"""
250
+ from fastapi import HTTPException
251
+
252
+ state = get_state()
253
+ runner = state.runner
254
+ if runner is None:
255
+ raise HTTPException(status_code=500, detail="Runner 未初始化")
256
+ if not state.runner_loaded:
257
+ try:
258
+ runner.load_agent()
259
+ except HTTPException:
260
+ raise
261
+ except Exception as exc: # noqa: BLE001
262
+ logger.warning("Runner 加载失败: %s", exc)
263
+ raise HTTPException(status_code=500, detail=str(exc) or "Runner 加载失败") from exc
264
+ state.runner_loaded = True
265
+ return runner
266
+
267
+
268
+ # ---------------------------------------------------------------------------
269
+ # factory
270
+ # ---------------------------------------------------------------------------
271
+
272
+ # configure 回调签名:由 app.py 提供,负责把各 domain router 挂到 app 上。
273
+ ConfigureApp = Callable[[FastAPI, RuntimeAppState, set[str]], None]
274
+
275
+
276
+ async def shutdown_runtime_resources(state: RuntimeAppState) -> None:
277
+ """Close only resources owned by one runtime app."""
278
+ manager = state.terminal_manager
279
+ if manager is not None:
280
+ try:
281
+ await manager.close()
282
+ except Exception:
283
+ logger.exception("failed to close terminal sessions on shutdown")
284
+
285
+ registry = state.stream_registry
286
+ pending_streams = list(registry.streams)
287
+ for task in pending_streams:
288
+ task.cancel()
289
+ if pending_streams:
290
+ await asyncio.gather(*pending_streams, return_exceptions=True)
291
+ registry.clear()
292
+
293
+ active_runner = state.runner
294
+ if active_runner is not None:
295
+ close = getattr(active_runner, "close", None)
296
+ if callable(close):
297
+ try:
298
+ await close()
299
+ except Exception:
300
+ logger.exception("failed to close runner on shutdown")
301
+
302
+ for service in state.session_services():
303
+ close = getattr(service, "aclose", None)
304
+ if callable(close):
305
+ try:
306
+ await close()
307
+ except Exception:
308
+ logger.exception("failed to close app session service on shutdown")
309
+
310
+ try:
311
+ state.sandbox_registry.close()
312
+ except Exception:
313
+ logger.exception("failed to clear sandbox registry on shutdown")
314
+
315
+
316
+ def create_runtime_app(
317
+ config: RuntimeAppConfig,
318
+ configure: Optional[ConfigureApp] = None,
319
+ ) -> FastAPI:
320
+ """装配一个 runtime app。
321
+
322
+ 参数:
323
+ config: :class:`RuntimeAppConfig`(runner / runtime_type / route_groups)。
324
+ configure: 路由装配回调 ``configure(app, state, route_groups)``;由
325
+ ``ksadk/server/app.py`` 提供,负责按 group 把 domain router include 进 app。
326
+ factory 自身只负责 FastAPI 实例、state、中间件、lifespan、异常处理器,
327
+ 不 import 全局 ``base_app`` 再过滤复制路由(H2 禁止)。
328
+ """
329
+ from contextlib import asynccontextmanager
330
+ from typing import AsyncIterator
331
+
332
+ from fastapi.middleware.cors import CORSMiddleware
333
+ from fastapi.responses import Response
334
+
335
+ state = RuntimeAppState(
336
+ runner=config.runner,
337
+ session_service_provider=config.session_service_provider,
338
+ session_backend_provider=config.session_backend_provider,
339
+ )
340
+
341
+ @asynccontextmanager
342
+ async def _lifespan(app: FastAPI) -> AsyncIterator[None]:
343
+ try:
344
+ if state.a2a_bootstrap is not None:
345
+ await state.a2a_bootstrap.start()
346
+ yield
347
+ finally:
348
+ if state.a2a_bootstrap is not None:
349
+ await state.a2a_bootstrap.stop()
350
+ await shutdown_runtime_resources(state)
351
+
352
+ app = FastAPI(
353
+ title="ADK Core API",
354
+ description="Agent Development Kit HTTP API",
355
+ version="1.0.0",
356
+ lifespan=_lifespan,
357
+ )
358
+ state.app = app
359
+ app.state.runtime = state
360
+
361
+ # 中间件:把当前 app 的 state 写入请求级 contextvar(handler 经 get_state() 取)。
362
+ @app.middleware("http")
363
+ async def _runtime_state_bridge(request, call_next):
364
+ from ksadk.server.routes.dependencies import bind_session_service
365
+
366
+ with (
367
+ bind_runtime_state(state),
368
+ bind_session_service(
369
+ state.resolve_session_service(),
370
+ backend=state.describe_session_backend(),
371
+ ),
372
+ ):
373
+ # 保持旧行为:前端入口禁缓存。
374
+ response = await call_next(request)
375
+ path = request.url.path
376
+ if path == "/" or path.endswith(".html"):
377
+ response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
378
+ response.headers["Pragma"] = "no-cache"
379
+ response.headers["Expires"] = "0"
380
+ return response
381
+
382
+ # CORS(与旧 app 一致,默认对 ADK 工具放开)。
383
+ app.add_middleware(
384
+ CORSMiddleware,
385
+ allow_origins=["*"],
386
+ allow_credentials=True,
387
+ allow_methods=["*"],
388
+ allow_headers=["*"],
389
+ )
390
+
391
+ # 异常处理器(与旧 app 一致)。
392
+ import json as _json
393
+
394
+ from ksadk.sessions.errors import SessionBackendUnavailable
395
+
396
+ @app.exception_handler(SessionBackendUnavailable)
397
+ async def session_backend_unavailable_handler(_request, exc: SessionBackendUnavailable):
398
+ return Response(
399
+ content=_json.dumps(
400
+ {"detail": {"code": "session_backend_unavailable", "message": str(exc)}},
401
+ ensure_ascii=False,
402
+ ),
403
+ status_code=503,
404
+ media_type="application/json",
405
+ )
406
+
407
+ # A2A 端点须在 configure 之前装配:health_meta 含 GET catch-all ``/{requested_path:path}``,
408
+ # 若 A2A 后挂,A2A 的 GET 路由(agent-card / tasks/{id})会被 catch-all 遮蔽成 404。
409
+ _wire_a2a_if_enabled(app, state, config)
410
+ _wire_agui_if_enabled(app, state, config)
411
+
412
+ if configure is not None:
413
+ configure(app, state, set(config.route_groups))
414
+
415
+ return app
416
+
417
+
418
+ class _LazyRunnerProxy:
419
+ """把 app.state 的 runner 以惰性方式暴露给 A2A executor/adapter。
420
+
421
+ 兼容壳常在 factory 建 app 后才 ``set_runner`` 写入真实 runner,因此不能在装配期
422
+ 固化 runner 引用。代理在每次调用时从 ``state`` 解析真实 runner 并懒加载,
423
+ 接口与 ``BaseRunner`` 对齐(load_agent / stream / invoke,其余属性经 __getattr__
424
+ 转发)。
425
+ """
426
+
427
+ def __init__(self, state: RuntimeAppState) -> None:
428
+ self.__dict__["_state"] = state
429
+
430
+ def _real(self) -> BaseRunner:
431
+ state: RuntimeAppState = self.__dict__["_state"]
432
+ runner = state.runner
433
+ if runner is None:
434
+ raise RuntimeError("A2A: runner 尚未装配(set_runner 未调用)")
435
+ if not state.runner_loaded:
436
+ runner.load_agent()
437
+ state.runner_loaded = True
438
+ return runner
439
+
440
+ def load_agent(self) -> BaseRunner:
441
+ return self._real()
442
+
443
+ def stream(self, input_data: Any) -> Any:
444
+ # 与普通方法(非 async def)返回真实 runner.stream 的结果(async gen 或 coroutine),
445
+ # 由 RunnerRuntimeAdapter/executor 按既有分支处理。
446
+ return self._real().stream(input_data)
447
+
448
+ async def invoke(self, input_data: Any) -> Any:
449
+ return await self._real().invoke(input_data)
450
+
451
+ def __getattr__(self, name: str) -> Any:
452
+ return getattr(self._real(), name)
453
+
454
+
455
+ def _wire_a2a_if_enabled(app: FastAPI, state: RuntimeAppState, config: RuntimeAppConfig) -> None:
456
+ """契约 §8:``config.a2a.enabled`` 时把 A2A 协议端点装配进 app(数据面)。
457
+
458
+ runner 经 :class:`_LazyRunnerProxy` 惰性解析;RuntimeAdapter 用通用
459
+ ``RunnerRuntimeAdapter``(经 P0-2 后 cancel 走真实 asyncio 任务中断)。
460
+ """
461
+ a2a_cfg = config.a2a
462
+ if a2a_cfg is None:
463
+ return
464
+ from ksadk.a2a.bootstrap import AgentEngineA2ABootstrap
465
+
466
+ if isinstance(a2a_cfg, AgentEngineA2ABootstrap):
467
+ from ksadk.runtime.runner_adapter import RunnerRuntimeAdapter
468
+
469
+ proxy = _LazyRunnerProxy(state)
470
+ runtime_adapter = config.runtime_adapter or RunnerRuntimeAdapter(
471
+ cast("BaseRunner", proxy),
472
+ runtime_type=config.runtime_type,
473
+ )
474
+ server = a2a_cfg.mount(
475
+ app,
476
+ runner=proxy,
477
+ runtime_adapter=runtime_adapter,
478
+ runtime_type=config.runtime_type,
479
+ )
480
+ state.a2a_bootstrap = a2a_cfg
481
+ state.a2a_server = server
482
+ logger.info(
483
+ "managed A2A Runtime mounted(agent=%s inbound_enabled=%s)",
484
+ a2a_cfg.runtime_metadata.agent_id,
485
+ a2a_cfg.inbound_enabled,
486
+ )
487
+ return
488
+ if not getattr(a2a_cfg, "enabled", False):
489
+ return
490
+ from ksadk.a2a.routes import add_a2a_protocol_routes
491
+ from ksadk.a2a.task_adapter import A2ARuntimeTaskAdapter
492
+ from ksadk.runtime.runner_adapter import RunnerRuntimeAdapter
493
+
494
+ proxy = _LazyRunnerProxy(state)
495
+ adapter = RunnerRuntimeAdapter(cast("BaseRunner", proxy), runtime_type=config.runtime_type)
496
+ task_adapter = A2ARuntimeTaskAdapter(adapter, runtime_type=config.runtime_type)
497
+ server = add_a2a_protocol_routes(app, proxy, a2a_cfg, task_adapter=task_adapter)
498
+ state.a2a_server = server
499
+ logger.info("A2A 协议端点已装配进 runtime app(agent=%s)", a2a_cfg.agent_name)
500
+
501
+
502
+ def _wire_agui_if_enabled(app: FastAPI, state: RuntimeAppState, config: RuntimeAppConfig) -> None:
503
+ """Mount the optional official AG-UI endpoint before the static catch-all."""
504
+ agui_cfg = config.agui
505
+ if (
506
+ agui_cfg is None
507
+ or not getattr(agui_cfg, "enabled", False)
508
+ or "agui" not in config.route_groups
509
+ ):
510
+ return
511
+
512
+ from ksadk.agui.config import require_agui_dependencies
513
+
514
+ require_agui_dependencies()
515
+
516
+ from ksadk.agui.routes import add_ksadk_agui_endpoint
517
+ from ksadk.events.store import RuntimeEventStore
518
+ from ksadk.server.routes import dependencies as route_dependencies
519
+
520
+ proxy = _LazyRunnerProxy(state)
521
+
522
+ class _AutoSessionRuntimeEventStore:
523
+ """Create a session on first AG-UI event when HttpAgent starts fresh."""
524
+
525
+ def __init__(self, service: Any) -> None:
526
+ self._service = service
527
+ self._store = RuntimeEventStore(service)
528
+
529
+ async def append_one(self, event: Any) -> Any:
530
+ existing = await self._service.get_session(event.session_id)
531
+ if existing is None:
532
+ await self._service.create_session(
533
+ event.agent_id,
534
+ event.user_id,
535
+ event.session_id,
536
+ )
537
+ return await self._store.append_one(event)
538
+
539
+ async def reserve_once(self, event: Any) -> Any:
540
+ existing = await self._service.get_session(event.session_id)
541
+ if existing is None:
542
+ await self._service.create_session(
543
+ event.agent_id,
544
+ event.user_id,
545
+ event.session_id,
546
+ )
547
+ return await self._store.reserve_once(event)
548
+
549
+ async def list(self, session_id: str, **kwargs: Any) -> Any:
550
+ return await self._store.list(session_id, **kwargs)
551
+
552
+ agent = add_ksadk_agui_endpoint(
553
+ app,
554
+ cast("BaseRunner", proxy),
555
+ agui_cfg,
556
+ event_store_factory=lambda: _AutoSessionRuntimeEventStore(
557
+ route_dependencies.resolve_session_service()
558
+ ),
559
+ session_service_factory=route_dependencies.resolve_session_service,
560
+ )
561
+ state.agui_agent = agent
562
+ state.agui_config = agui_cfg
563
+ logger.info("AG-UI endpoint mounted at %s", agui_cfg.path)
564
+
565
+
566
+ def wire_default_agui_for_runner(state: RuntimeAppState, runner: BaseRunner) -> None:
567
+ """Mount AG-UI for legacy ``app`` + ``set_runner`` production entrypoints.
568
+
569
+ Those entrypoints create the FastAPI app before the framework runner exists.
570
+ Mounting immediately after ``set_runner`` is still startup-time wiring. New
571
+ protocol routes are moved ahead of the static catch-all to preserve routing
572
+ order exactly as the normal factory path does.
573
+ """
574
+ if state.app is None or state.agui_agent is not None:
575
+ return
576
+
577
+ from ksadk.agui.config import default_agui_config
578
+
579
+ agui_config = default_agui_config(runner)
580
+ if not agui_config.enabled:
581
+ return
582
+
583
+ app = state.app
584
+ routes = app.router.routes
585
+ previous_count = len(routes)
586
+ _wire_agui_if_enabled(
587
+ app,
588
+ state,
589
+ RuntimeAppConfig(
590
+ runner=runner,
591
+ runtime_type=agui_config.runtime_type,
592
+ route_groups={"agui"},
593
+ agui=agui_config,
594
+ ),
595
+ )
596
+ new_routes = routes[previous_count:]
597
+ if not new_routes:
598
+ return
599
+ del routes[previous_count:]
600
+ catch_all_index = next(
601
+ (
602
+ index
603
+ for index, route in enumerate(routes)
604
+ if getattr(route, "path", None) == "/{requested_path:path}"
605
+ ),
606
+ len(routes),
607
+ )
608
+ routes[catch_all_index:catch_all_index] = new_routes
609
+
610
+
611
+ __all__ = [
612
+ "ALL_GROUPS",
613
+ "CONTROL_PLANE_GROUPS",
614
+ "DATA_PLANE_GROUPS",
615
+ "RuntimeAppConfig",
616
+ "RuntimeAppState",
617
+ "bind_runtime_state",
618
+ "StreamRegistry",
619
+ "create_runtime_app",
620
+ "get_runner",
621
+ "get_state",
622
+ "set_fallback_state",
623
+ "wire_default_agui_for_runner",
624
+ ]
@@ -0,0 +1 @@
1
+ """Domain routers used by the runtime app composition root."""