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,331 @@
1
+ """Cancel, resume, preview, and run-event subscription routes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import json
7
+ import time
8
+ import uuid
9
+ from collections.abc import AsyncIterator, Mapping
10
+ from typing import Any, Optional
11
+
12
+ from fastapi import HTTPException, Query
13
+ from fastapi.responses import StreamingResponse
14
+
15
+ from ksadk.conversations.run_kinds import (
16
+ RUN_MODE_BACKGROUND,
17
+ RUN_MODE_FOREGROUND,
18
+ RUN_TRIGGER_CHECKPOINT_RESUME,
19
+ )
20
+ from ksadk.conversations.runtime_payloads import build_responses_payload
21
+ from ksadk.conversations.runtime_streaming import stream_runtime_responses_conversation_turn
22
+ from ksadk.runtime.conversation_execution import invoke_runtime_conversation_once
23
+ from ksadk.server.factory import get_runtime_execution
24
+
25
+ from . import dependencies as deps
26
+ from .checkpoint_resolution import _find_session_checkpoint
27
+ from .common import _action_response
28
+ from .models import (
29
+ _MAX_PREVIEW_TOOL_RECEIPTS,
30
+ _RUN_TERMINAL_STATUSES,
31
+ GetCheckpointResumePreviewActionRequest,
32
+ ResumeRunActionRequest,
33
+ _run_agent_response_metadata,
34
+ _split_custom_metadata,
35
+ )
36
+ from .projection import (
37
+ _SIDE_EFFECT_TOOL_NAMES,
38
+ _build_checkpoint_resume_preview,
39
+ _checkpoint_resume_disabled_detail,
40
+ _event_to_action_payload,
41
+ _iter_session_event_pages,
42
+ _latest_invocation_status,
43
+ _oldest_unconsumed_session_events,
44
+ _require_action_session,
45
+ _session_contains_invocation,
46
+ _tool_receipt_event_to_action_payload,
47
+ )
48
+ from .routers import control_router, run_router
49
+ from .streaming import (
50
+ _detached_resume_key_from_input,
51
+ _reject_if_detached_resume_active,
52
+ )
53
+
54
+
55
+ @control_router.post("/agentengine/api/v1/GetCheckpointResumePreview")
56
+ async def get_checkpoint_resume_preview_action(request: GetCheckpointResumePreviewActionRequest):
57
+ service = deps.resolve_session_service()
58
+ await _require_action_session(
59
+ service,
60
+ session_id=request.SessionId,
61
+ agent_id=request.AgentId,
62
+ user_id=request.UserId,
63
+ )
64
+
65
+ checkpoint = await _find_session_checkpoint(
66
+ service=service,
67
+ session_id=request.SessionId,
68
+ run_id=str(request.RunId),
69
+ checkpoint_id=str(request.CheckpointId),
70
+ )
71
+ if checkpoint is None:
72
+ raise HTTPException(status_code=404, detail="Checkpoint not found")
73
+
74
+ checkpoint_seq_id = int(checkpoint.get("SeqId") or 0)
75
+ checkpoint_run_id = str(checkpoint.get("RunId") or "")
76
+ receipts: list[dict[str, Any]] = []
77
+ receipt_total = 0
78
+ side_effect_receipt_count = 0
79
+ failed_receipt_count = 0
80
+ async for page in _iter_session_event_pages(
81
+ service,
82
+ request.SessionId,
83
+ before_seq_id=checkpoint_seq_id + 1 if checkpoint_seq_id else None,
84
+ ):
85
+ for event in page:
86
+ receipt = _tool_receipt_event_to_action_payload(event)
87
+ if receipt is None:
88
+ continue
89
+ if checkpoint_run_id and receipt["RunId"] and receipt["RunId"] != checkpoint_run_id:
90
+ continue
91
+ receipt_total += 1
92
+ if receipt["ToolName"] in _SIDE_EFFECT_TOOL_NAMES:
93
+ side_effect_receipt_count += 1
94
+ if receipt["Status"] == "failed":
95
+ failed_receipt_count += 1
96
+ if len(receipts) < _MAX_PREVIEW_TOOL_RECEIPTS:
97
+ receipts.append(receipt)
98
+
99
+ return _action_response(
100
+ "GetCheckpointResumePreview",
101
+ {
102
+ "Preview": _build_checkpoint_resume_preview(
103
+ checkpoint=checkpoint,
104
+ receipts=receipts,
105
+ receipt_total=receipt_total,
106
+ side_effect_receipt_count=side_effect_receipt_count,
107
+ failed_receipt_count=failed_receipt_count,
108
+ )
109
+ },
110
+ )
111
+
112
+
113
+ @control_router.post("/agentengine/api/v1/ResumeRun")
114
+ async def resume_run_action(request: ResumeRunActionRequest):
115
+ executor, launch_context = get_runtime_execution()
116
+ service = deps.resolve_session_service()
117
+ session = await _require_action_session(
118
+ service,
119
+ session_id=request.SessionId,
120
+ agent_id=request.AgentId,
121
+ user_id=request.UserId,
122
+ )
123
+
124
+ checkpoint = await _find_session_checkpoint(
125
+ service=service,
126
+ session_id=request.SessionId,
127
+ run_id=str(request.RunId),
128
+ checkpoint_id=str(request.CheckpointId),
129
+ )
130
+ if checkpoint is None:
131
+ raise HTTPException(status_code=404, detail="Checkpoint not found")
132
+ disabled_detail = _checkpoint_resume_disabled_detail(checkpoint)
133
+ if disabled_detail is not None:
134
+ if disabled_detail.get("is_terminal"):
135
+ resume_attempt_id = str(request.ResumeAttemptId or f"resume_{uuid.uuid4().hex}")
136
+ invocation_id = str(request.InvocationId or resume_attempt_id)
137
+ await deps.conversation().append_run_resume_event(
138
+ session_id=request.SessionId,
139
+ author=request.AgentId,
140
+ run_id=str(request.RunId),
141
+ checkpoint_id=str(request.CheckpointId),
142
+ resume_attempt_id=resume_attempt_id,
143
+ framework=checkpoint["Framework"],
144
+ framework_ref=checkpoint["FrameworkRef"],
145
+ invocation_id=invocation_id,
146
+ session_service_provider=deps.resolve_session_service,
147
+ )
148
+ await deps.conversation().append_run_status_event(
149
+ session_id=request.SessionId,
150
+ author=request.AgentId,
151
+ status="completed",
152
+ invocation_id=invocation_id,
153
+ detail="resume_noop_terminal_checkpoint",
154
+ session_service_provider=deps.resolve_session_service,
155
+ run_mode=RUN_MODE_BACKGROUND,
156
+ run_trigger=RUN_TRIGGER_CHECKPOINT_RESUME,
157
+ )
158
+ return _action_response(
159
+ "ResumeRun",
160
+ {
161
+ "status": "noop",
162
+ "Reason": disabled_detail["reason"],
163
+ "CheckpointId": disabled_detail["checkpoint_id"],
164
+ "RunId": disabled_detail["run_id"],
165
+ "ResumeAttemptId": resume_attempt_id,
166
+ },
167
+ )
168
+ raise HTTPException(status_code=409, detail=disabled_detail)
169
+
170
+ resume_input = {
171
+ "type": "agentengine.resume_checkpoint",
172
+ "run_id": str(request.RunId),
173
+ "checkpoint_id": str(request.CheckpointId),
174
+ "resume_attempt_id": str(request.ResumeAttemptId or f"resume_{uuid.uuid4().hex}"),
175
+ "framework": checkpoint["Framework"],
176
+ "framework_ref": checkpoint["FrameworkRef"],
177
+ "metadata": dict(checkpoint.get("Metadata") or {}),
178
+ "checkpoint_metadata": dict(checkpoint.get("Metadata") or {}),
179
+ "resume_instruction_enabled": bool(getattr(request, "ResumeInstructionEnabled", False)),
180
+ "resume_instruction": str(getattr(request, "ResumeInstruction", "") or "").strip(),
181
+ }
182
+ user_id = session.user_id or "user"
183
+ custom_metadata, _metadata_runtime_controls = _split_custom_metadata(request.Metadata)
184
+ resume_request_metadata = {
185
+ "responses_conversation": True,
186
+ }
187
+
188
+ if request.Stream:
189
+ resume_invocation_id = str(request.InvocationId or resume_input["resume_attempt_id"])
190
+ resume_key = _detached_resume_key_from_input(request.SessionId, resume_input)
191
+ _reject_if_detached_resume_active(resume_key)
192
+ # 与 RunAgent Background 同款:返回 SSE 前同步落 resuming 起始事件。
193
+ # detached turn 的首个事件要等流被消费才写;UI 拿到响应头会立刻调
194
+ # SubscribeRunEvents,其 _session_contains_invocation 校验若抢在首次写入前
195
+ # 会误判 409 "InvocationId does not belong to SessionId"。
196
+ # append_run_status_event 按 (invocation_id, status) 幂等,turn 内的补写会去重。
197
+ await deps.conversation().append_run_status_event(
198
+ session_id=request.SessionId,
199
+ author=request.AgentId,
200
+ status="resuming",
201
+ invocation_id=resume_invocation_id,
202
+ detail="checkpoint_resume",
203
+ session_service_provider=deps.resolve_session_service,
204
+ run_mode=RUN_MODE_BACKGROUND,
205
+ run_trigger=RUN_TRIGGER_CHECKPOINT_RESUME,
206
+ )
207
+ return deps.detached_streaming_response(
208
+ stream_runtime_responses_conversation_turn(
209
+ executor=executor,
210
+ launch_context=launch_context,
211
+ agent_id=request.AgentId,
212
+ user_id=user_id,
213
+ messages=[],
214
+ session_id=request.SessionId,
215
+ model=request.Model,
216
+ model_metadata=request.ModelMetadata,
217
+ model_options=request.ModelOptions,
218
+ request_metadata=resume_request_metadata,
219
+ custom_metadata=custom_metadata,
220
+ include_agentengine_metadata=True,
221
+ resume_input=resume_input,
222
+ invocation_id=resume_invocation_id,
223
+ session_service_provider=deps.resolve_session_service,
224
+ run_mode=RUN_MODE_BACKGROUND,
225
+ ),
226
+ invocation_id=resume_invocation_id,
227
+ resume_key=resume_key,
228
+ run_mode=RUN_MODE_BACKGROUND,
229
+ run_trigger=RUN_TRIGGER_CHECKPOINT_RESUME,
230
+ )
231
+
232
+ response_id = f"resp_{uuid.uuid4().hex}"
233
+ resolved_session_id, result = await invoke_runtime_conversation_once(
234
+ executor=executor,
235
+ launch_context=launch_context,
236
+ agent_id=request.AgentId,
237
+ user_id=user_id,
238
+ messages=[],
239
+ session_id=request.SessionId,
240
+ model=request.Model,
241
+ model_metadata=request.ModelMetadata,
242
+ model_options=request.ModelOptions,
243
+ request_metadata=resume_request_metadata,
244
+ custom_metadata=custom_metadata,
245
+ resume_input=resume_input,
246
+ response_id=response_id,
247
+ invocation_id=str(resume_input["resume_attempt_id"]),
248
+ session_service_provider=deps.resolve_session_service,
249
+ run_mode=RUN_MODE_FOREGROUND,
250
+ )
251
+ payload = build_responses_payload(
252
+ output_text=result["output_text"],
253
+ model=request.Model,
254
+ session_id=resolved_session_id,
255
+ response_id=response_id,
256
+ metadata=_run_agent_response_metadata(custom_metadata, result),
257
+ usage=result.get("usage") if isinstance(result.get("usage"), Mapping) else None,
258
+ )
259
+ return _action_response("ResumeRun", payload)
260
+
261
+
262
+ @run_router.get("/agentengine/api/v1/SubscribeRunEvents", include_in_schema=False)
263
+ async def subscribe_run_events_action(
264
+ SessionId: str = Query(...),
265
+ InvocationId: str = Query(...),
266
+ AfterSeqId: int = Query(0),
267
+ AgentId: Optional[str] = Query(None),
268
+ UserId: Optional[str] = Query(None),
269
+ ):
270
+ session_id = str(SessionId or "").strip()
271
+ invocation_id = str(InvocationId or "").strip()
272
+ if not session_id or not invocation_id:
273
+ raise HTTPException(status_code=400, detail="SessionId and InvocationId are required")
274
+ service = deps.resolve_session_service()
275
+ await _require_action_session(
276
+ service,
277
+ session_id=session_id,
278
+ agent_id=AgentId,
279
+ user_id=UserId,
280
+ )
281
+ if not await _session_contains_invocation(service, session_id, invocation_id):
282
+ raise HTTPException(
283
+ status_code=409,
284
+ detail="InvocationId does not belong to SessionId",
285
+ )
286
+
287
+ async def event_generator() -> AsyncIterator[str]:
288
+ last_seq_id = int(AfterSeqId or 0)
289
+ deadline = time.monotonic() + 5 * 60
290
+ last_heartbeat_at = time.monotonic()
291
+ last_terminal_check_at = 0.0
292
+ while True:
293
+ events = await _oldest_unconsumed_session_events(
294
+ service,
295
+ session_id,
296
+ after_seq_id=last_seq_id,
297
+ )
298
+ for event in events:
299
+ last_seq_id = max(last_seq_id, event.seq_id)
300
+ if event.invocation_id != invocation_id:
301
+ continue
302
+ payload = _event_to_action_payload(event)
303
+ yield f"data: {json.dumps(payload, ensure_ascii=False)}\n\n"
304
+ last_heartbeat_at = time.monotonic()
305
+ if (
306
+ event.event_type == "run_status"
307
+ and str((event.content or {}).get("status") or "").strip().lower()
308
+ in _RUN_TERMINAL_STATUSES
309
+ ):
310
+ yield "data: [DONE]\n\n"
311
+ return
312
+
313
+ now = time.monotonic()
314
+ if not events and now - last_terminal_check_at >= deps.heartbeat_interval():
315
+ latest_status = await _latest_invocation_status(
316
+ service,
317
+ session_id,
318
+ invocation_id,
319
+ )
320
+ last_terminal_check_at = now
321
+ if latest_status in _RUN_TERMINAL_STATUSES:
322
+ yield "data: [DONE]\n\n"
323
+ return
324
+ if now - last_heartbeat_at >= deps.heartbeat_interval():
325
+ yield ": heartbeat\n\n"
326
+ last_heartbeat_at = now
327
+ if now > deadline:
328
+ return
329
+ await asyncio.sleep(0.25)
330
+
331
+ return StreamingResponse(event_generator(), media_type="text/event-stream")
@@ -0,0 +1,98 @@
1
+ """Explicit compatibility dependencies shared by extracted route modules.
2
+
3
+ The default app keeps a few historically monkeypatchable exports. Providers are
4
+ callbacks so route modules observe those replacements without importing the app
5
+ module back into the domain layer.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import contextvars
11
+ from contextlib import contextmanager
12
+ from dataclasses import dataclass
13
+ from typing import Any, Callable, Iterator
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ServerRouteDependencies:
18
+ resolve_session_service: Callable[[], Any]
19
+ describe_session_backend: Callable[[], dict[str, Any]]
20
+ resolve_agent_ui_spec: Callable[[], dict[str, Any]]
21
+ conversation: Callable[[], Any]
22
+ detached_streaming_response: Callable[..., Any]
23
+ detached_stream_class: Callable[[], type[Any]]
24
+ heartbeat_interval: Callable[[], float]
25
+ runtime_app: Callable[[], Any]
26
+
27
+
28
+ _dependencies: ServerRouteDependencies | None = None
29
+ _session_service_override: contextvars.ContextVar[Any | None] = contextvars.ContextVar(
30
+ "ksadk_route_session_service", default=None
31
+ )
32
+ _session_backend_override: contextvars.ContextVar[dict[str, Any] | None] = contextvars.ContextVar(
33
+ "ksadk_route_session_backend", default=None
34
+ )
35
+
36
+
37
+ def configure(dependencies: ServerRouteDependencies) -> None:
38
+ global _dependencies
39
+ _dependencies = dependencies
40
+
41
+
42
+ def current() -> ServerRouteDependencies:
43
+ if _dependencies is None:
44
+ raise RuntimeError("server route dependencies are not configured")
45
+ return _dependencies
46
+
47
+
48
+ def resolve_session_service() -> Any:
49
+ override = _session_service_override.get()
50
+ if override is not None:
51
+ return override
52
+ return current().resolve_session_service()
53
+
54
+
55
+ @contextmanager
56
+ def bind_session_service(service: Any, *, backend: dict[str, Any] | None = None) -> Iterator[None]:
57
+ """Bind an app-owned session service for one request context."""
58
+ from ksadk.sessions import bind_session_service as bind_runtime_session_service
59
+
60
+ service_token = _session_service_override.set(service)
61
+ backend_token = _session_backend_override.set(backend)
62
+ try:
63
+ with bind_runtime_session_service(service):
64
+ yield
65
+ finally:
66
+ _session_backend_override.reset(backend_token)
67
+ _session_service_override.reset(service_token)
68
+
69
+
70
+ def describe_session_backend() -> dict[str, Any]:
71
+ override = _session_backend_override.get()
72
+ if override is not None:
73
+ return dict(override)
74
+ return current().describe_session_backend()
75
+
76
+
77
+ def resolve_agent_ui_spec() -> dict[str, Any]:
78
+ return current().resolve_agent_ui_spec()
79
+
80
+
81
+ def conversation() -> Any:
82
+ return current().conversation()
83
+
84
+
85
+ def detached_streaming_response(*args: Any, **kwargs: Any) -> Any:
86
+ return current().detached_streaming_response(*args, **kwargs)
87
+
88
+
89
+ def detached_stream_class() -> type[Any]:
90
+ return current().detached_stream_class()
91
+
92
+
93
+ def heartbeat_interval() -> float:
94
+ return current().heartbeat_interval()
95
+
96
+
97
+ def runtime_app() -> Any:
98
+ return current().runtime_app()