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,71 @@
1
+ # -*- coding: utf-8 -*-
2
+ """ksadk replay — 基于 RuntimeEvent store + session 级订阅的历史回放 (goal-16)。
3
+
4
+ CLI 是消费 RuntimeAdapter/RuntimeEvent 的薄壳(不含 runtime 逻辑):replay 复用 goal-10
5
+ ``RuntimeEventStore`` 与 goal-12 共享 parser/replay,把某 session 的 RuntimeEvent 历史
6
+ 回放为确定性 transcript(text/reasoning/tool/artifact/run + a2ui/a2a extras)。
7
+
8
+ 注:回放的是经 RuntimeEvent 持久化的新事件模型(带 runtime marker);legacy SessionEvent
9
+ (旧 assistant_message 等)不在本模型内,不回放。
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ import json
16
+
17
+ import click
18
+
19
+ from ksadk.cli.resource_common import CONTEXT_SETTINGS
20
+ from ksadk.events.replay import replay_transcript
21
+ from ksadk.events.store import RuntimeEventStore
22
+
23
+ _HELP = dict(help_option_names=["-h", "--help"])
24
+
25
+
26
+ @click.command(
27
+ "replay", context_settings=CONTEXT_SETTINGS, help="回放某 session 的 RuntimeEvent 历史"
28
+ )
29
+ @click.argument("session_id")
30
+ @click.option(
31
+ "--after-seq-id", default=0, show_default=True, type=int, help="从该 seq cursor 之后回放"
32
+ )
33
+ @click.option("--before-seq-id", default=None, type=int, help="回放上界(不含该 seq)")
34
+ @click.option(
35
+ "--format", "fmt", type=click.Choice(["json", "text"]), default="text", show_default=True
36
+ )
37
+ def replay(session_id: str, after_seq_id: int, before_seq_id: int | None, fmt: str):
38
+ """回放 session 的 RuntimeEvent 历史(text/reasoning/tool/artifact/run)。"""
39
+ asyncio.run(_run(session_id, after_seq_id=after_seq_id, before_seq_id=before_seq_id, fmt=fmt))
40
+
41
+
42
+ async def _run(session_id: str, *, after_seq_id: int, before_seq_id: int | None, fmt: str) -> None:
43
+ from ksadk.sessions import resolve_session_service
44
+
45
+ store = RuntimeEventStore(resolve_session_service())
46
+ parser = await replay_transcript(
47
+ store, session_id, after_seq_id=after_seq_id, before_seq_id=before_seq_id
48
+ )
49
+ transcript = parser.transcript()
50
+ if fmt == "json":
51
+ click.echo(json.dumps(transcript, ensure_ascii=False, sort_keys=True))
52
+ return
53
+
54
+ items = transcript["items"]
55
+ if not items and not transcript["extras"]:
56
+ click.echo(f"session {session_id} 无 RuntimeEvent 历史(或该 session 未经新事件模型持久化)")
57
+ return
58
+ for item in items:
59
+ kind = item.get("kind")
60
+ if kind in ("text", "reasoning"):
61
+ marker = "▍final" if item.get("final") else "▍delta"
62
+ click.echo(f"[{kind}/{item.get('phase')}] {marker} {item.get('text')}")
63
+ elif kind == "tool_call":
64
+ done = "✓" if item.get("done") else "…"
65
+ click.echo(f"[tool] {done} {item.get('name')} ({item.get('call_id')})")
66
+ elif kind == "artifact":
67
+ click.echo(f"[artifact] {item.get('name')} v{item.get('version')}")
68
+ for inv, status in transcript["run_status"].items():
69
+ click.echo(f"[run] {inv}: {status}")
70
+ for extra in transcript["extras"]:
71
+ click.echo(f"[{extra['event_type']}] {json.dumps(extra['payload'], ensure_ascii=False)}")
ksadk/cli/cmd_run.py CHANGED
@@ -5,19 +5,21 @@ ksadk run - 本地运行 Agent
5
5
  对于 LangChain/LangGraph/DeepAgents 项目,使用自己的实现
6
6
  """
7
7
 
8
- import click
9
- import asyncio
8
+ import os
10
9
  import subprocess
11
10
  import sys
12
- import os
13
11
  from pathlib import Path
12
+
13
+ import click
14
+ import uvicorn
15
+
14
16
  from ksadk.cli.error_utils import ensure_json_output_supported, print_exception
15
17
  from ksadk.cli.local_runtime import reexec_with_project_venv_if_needed
18
+ from ksadk.cli.runtime_bootstrap import create_runtime_web_app
16
19
  from ksadk.cli.ui import (
17
20
  print_error,
18
21
  print_info,
19
22
  print_kv,
20
- print_rule,
21
23
  print_success,
22
24
  print_title,
23
25
  print_warn,
@@ -38,16 +40,28 @@ from ksadk.cli.ui import (
38
40
  is_flag=True,
39
41
  help="兼容参数;TUI 已默认使用 inline viewport 并保留终端 scrollback",
40
42
  )
41
- def run(agent_dir: str, port: int, interactive: bool, no_trace: bool, model: str, show_thinking: bool, no_stream: bool, no_alt_screen: bool):
43
+ def run(
44
+ agent_dir: str,
45
+ port: int,
46
+ interactive: bool,
47
+ no_trace: bool,
48
+ model: str,
49
+ show_thinking: bool,
50
+ no_stream: bool,
51
+ no_alt_screen: bool,
52
+ ):
42
53
  """运行 Agent (支持 LangChain / LangGraph / DeepAgents / ADK)
43
54
 
44
55
  AGENT_DIR: Agent 项目目录 (默认: 当前目录)
45
56
  """
46
57
  ensure_json_output_supported(
47
58
  "agentengine run",
48
- suggestion="请改用 `agentengine agent status --output json` 或 `agentengine build --output json` 获取结构化信息。",
59
+ suggestion=(
60
+ "请改用 `agentengine agent status --output json` 或 "
61
+ "`agentengine build --output json` 获取结构化信息。"
62
+ ),
49
63
  )
50
- from ksadk.detection import FrameworkDetector, FrameworkType
64
+ from ksadk.detection import FrameworkDetector
51
65
 
52
66
  agent_path = Path(agent_dir).resolve()
53
67
  command_args = ["run", str(agent_path), "--port", str(port)]
@@ -91,7 +105,7 @@ def run(agent_dir: str, port: int, interactive: bool, no_trace: bool, model: str
91
105
  "langchain": "LangChain",
92
106
  "langgraph": "LangGraph",
93
107
  "deepagents": "DeepAgents",
94
- "unknown": "Unknown"
108
+ "unknown": "Unknown",
95
109
  }
96
110
  framework_name = framework_map.get(result.type.value, result.type.value)
97
111
 
@@ -99,58 +113,50 @@ def run(agent_dir: str, port: int, interactive: bool, no_trace: bool, model: str
99
113
  print_kv("Agent 名称", str(result.name))
100
114
  print_kv("入口点", str(result.entry_point))
101
115
 
116
+ from ksadk.cli.cmd_web import configure_local_runtime_persistence
117
+
118
+ configure_local_runtime_persistence(agent_path, result.type.value)
119
+
102
120
  # 2. 根据框架类型选择处理方式
103
- # 所有框架统一使用 _run_custom() 以支持 Langfuse 自动插桩
104
- # (Langfuse instrumentation 需要在同一进程内生效)
105
- _run_custom(result, agent_path, port, interactive, no_trace, show_thinking, no_stream, no_alt_screen)
121
+ # 所有框架统一使用 _run_custom(),让 OTel instrumentation 在同一进程生效。
122
+ _run_custom(
123
+ result, agent_path, port, interactive, no_trace, show_thinking, no_stream, no_alt_screen
124
+ )
106
125
 
107
126
 
108
127
  def _run_adk_cli(agent_path: Path, port: int = 8080, command: str = "run"):
109
- """运行 ADK Agent,支持 Langfuse tracing
110
-
111
- 对于 Langfuse 集成,我们需要在同一进程内运行 ADK,
112
- 因为 OpenTelemetry instrumentation 只在进程内生效。
113
- """
128
+ """运行 ADK Agent,使用标准 OTLP 配置。"""
114
129
  import os
115
130
 
116
- has_langfuse = bool(os.getenv("LANGFUSE_PUBLIC_KEY"))
131
+ has_otlp = bool(
132
+ os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
133
+ or os.getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT")
134
+ or os.getenv("CLOUD_MONITOR_OTLP_ENDPOINT")
135
+ or os.getenv("CLOUD_MONITOR_OTLP_TRACES_ENDPOINT")
136
+ )
117
137
 
118
138
  # 必须先初始化 Tracing(在导入 ADK 之前)
119
- if has_langfuse:
139
+ if has_otlp:
120
140
  try:
121
141
  from ksadk.tracing import setup_tracing
122
142
 
123
143
  setup_tracing(
124
144
  enable_inmemory=False,
125
- enable_langfuse=True,
126
145
  enable_adk_instrumentation=True,
127
146
  )
128
- print_info("Tracing: Enabled (Langfuse + ADK Instrumentation)")
147
+ print_info("Tracing: Enabled (OTLP + ADK Instrumentation)")
129
148
  except Exception as e:
130
- print_warn(f"Langfuse 初始化失败: {e}")
149
+ print_warn(f"OTLP tracing 初始化失败: {e}")
131
150
 
132
151
  print_kv("调用 ADK 原生 CLI", f"adk {command}")
133
152
 
134
- # 使用 subprocess(Langfuse instrumentation 在子进程中不生效,但环境变量会传递)
135
- # ADK CLI 本身不支持 Langfuse,需要用户在项目中集成
153
+ # 子进程继承标准 OTLP 环境变量;项目内 instrumentation 负责创建 spans。
136
154
  if command == "run":
137
155
  cmd = [sys.executable, "-m", "google.adk.cli", "run", "."]
138
156
  else:
139
157
  cmd = [sys.executable, "-m", "google.adk.cli", "web", ".", "--port", str(port)]
140
158
 
141
- # 传递 Langfuse 环境变量
142
159
  env = os.environ.copy()
143
- langfuse_vars = ["LANGFUSE_PUBLIC_KEY", "LANGFUSE_SECRET_KEY", "LANGFUSE_BASE_URL"]
144
- for var in langfuse_vars:
145
- if var in os.environ:
146
- env[var] = os.environ[var]
147
-
148
- # 提示用户如何在 ADK 项目中启用 Langfuse
149
- if has_langfuse:
150
- print_rule("ADK 项目 Langfuse 集成提示")
151
- print_info("在 agent.py 中添加以下代码:")
152
- print_info("from openinference.instrumentation.google_adk import GoogleADKInstrumentor")
153
- print_info("GoogleADKInstrumentor().instrument()")
154
160
 
155
161
  try:
156
162
  subprocess.run(cmd, cwd=str(agent_path), check=True, env=env)
@@ -172,68 +178,47 @@ def _run_custom(
172
178
  no_stream: bool = False,
173
179
  no_alt_screen: bool = False,
174
180
  ):
175
- """使用自定义实现 (LangChain/LangGraph/DeepAgents)"""
176
- from ksadk.runners.factory import create_runner
181
+ """Run one detected project through the canonical RuntimeAdapter composition."""
177
182
 
178
183
  # 初始化 Tracing
179
184
  if not no_trace:
180
185
  try:
181
- from ksadk.tracing import setup_tracing
182
186
  import os
183
187
 
184
- has_langfuse = bool(os.getenv("LANGFUSE_PUBLIC_KEY"))
188
+ from ksadk.tracing import setup_tracing
189
+
185
190
  has_otlp = bool(
186
191
  os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
187
192
  or os.getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT")
188
193
  )
189
194
 
190
- use_callback_only = os.getenv("LANGFUSE_USE_CALLBACK", "").strip().lower() in (
191
- "1",
192
- "true",
193
- "yes",
194
- "on",
195
- )
196
-
197
195
  setup_tracing(
198
196
  enable_inmemory=True,
199
197
  enable_langfuse=None,
200
- use_callback_only=use_callback_only,
201
198
  )
202
199
 
203
200
  if has_otlp:
204
201
  print_info("Tracing: Enabled (InMemory + OTLP HTTP)")
205
- elif has_langfuse:
206
- print_info(f"Tracing: Enabled (InMemory + Langfuse, CallbackOnly={use_callback_only})")
207
202
  else:
208
203
  print_info("Tracing: Enabled")
209
204
  except Exception as e:
210
205
  print_warn(f"Tracing 初始化失败: {e}")
211
206
 
212
- # 创建 Runner
207
+ if interactive:
208
+ del show_thinking, no_stream, no_alt_screen
209
+ print_error(
210
+ "RuntimeAdapter TUI 尚未接通;请使用 `ksadk web` 或不带 --interactive 启动"
211
+ )
212
+ raise SystemExit(2)
213
+
213
214
  try:
214
- print_info("初始化 Runner...")
215
- runner = create_runner(result, str(agent_path))
216
- runner.load_agent()
217
- print_success("Agent 加载成功")
215
+ runtime_app = create_runtime_web_app(result, agent_path)
218
216
  except Exception as e:
219
- print_exception("Agent 加载失败", e)
220
- # import traceback
221
- # traceback.print_exc()
217
+ print_exception("RuntimeAdapter 初始化失败", e)
222
218
  raise SystemExit(1)
223
219
 
224
- # 运行
225
- if interactive:
226
- # TUI 交互模式
227
- from ksadk.tui.loop import run_tui
228
- run_tui(
229
- runner,
230
- show_thinking=show_thinking,
231
- project_dir=str(agent_path),
232
- no_alt_screen=no_alt_screen,
233
- )
234
- else:
235
- print_success(f"Server running at http://0.0.0.0:{port}")
236
- print_kv("API Docs", f"http://0.0.0.0:{port}/docs")
237
- print_kv("Chat API", f"http://0.0.0.0:{port}/chat")
238
- print_info("Press Ctrl+C to stop")
239
- runner.run_server(port=port)
220
+ print_success(f"Server running at http://127.0.0.1:{port}")
221
+ print_kv("API Docs", f"http://127.0.0.1:{port}/docs")
222
+ print_kv("Chat API", f"http://127.0.0.1:{port}/chat")
223
+ print_info("Press Ctrl+C to stop")
224
+ uvicorn.run(runtime_app, host="127.0.0.1", port=port)
ksadk/cli/cmd_status.py CHANGED
@@ -4,15 +4,17 @@ agentengine status - 查看 Agent 运行状态和 Endpoint
4
4
  支持 watch 模式实时刷新
5
5
  """
6
6
 
7
- import click
8
7
  import asyncio
9
8
  import time
10
- from pathlib import Path
11
9
  from datetime import datetime
10
+ from pathlib import Path
12
11
  from typing import Sequence
12
+
13
+ import click
14
+
13
15
  from ksadk.api.client import DryRunExit
14
16
  from ksadk.cli.agent_ref import merge_agent_inputs, resolve_agent_ref
15
- from ksadk.cli.dry_run import dry_run_option, run_async_with_dry_run, effective_dry_run
17
+ from ksadk.cli.dry_run import dry_run_option, effective_dry_run, run_async_with_dry_run
16
18
  from ksadk.cli.error_utils import print_exception, resolution_error, usage_error
17
19
  from ksadk.cli.resource_common import (
18
20
  CONTEXT_SETTINGS,
@@ -24,14 +26,10 @@ from ksadk.cli.resource_common import (
24
26
  from ksadk.cli.ui import (
25
27
  get_console,
26
28
  is_json_output,
27
- print_error,
28
29
  print_info,
29
- print_kv,
30
- print_title,
31
- print_warn,
30
+ replica_rich_style,
32
31
  status_click_color,
33
32
  status_rich_style,
34
- replica_rich_style,
35
33
  summary_panel,
36
34
  )
37
35
 
@@ -55,7 +53,9 @@ AGENT_LIST_HIDDEN_FRAMEWORK_LABELS = {
55
53
  @click.option("--watch", "-w", is_flag=True, help="Watch 模式,持续刷新")
56
54
  @click.option("--interval", "-i", default=2, help="Watch 刷新间隔 (秒)")
57
55
  @click.option("--region", "-r", default="cn-beijing-6", envvar="KSYUN_REGION", help="区域")
58
- @click.option("--account-id", envvar="KSYUN_ACCOUNT_ID", help="金山云账号 ID(可选;未设置时从 AK/SK 反查)")
56
+ @click.option(
57
+ "--account-id", envvar="KSYUN_ACCOUNT_ID", help="金山云账号 ID(可选;未设置时从 AK/SK 反查)"
58
+ )
59
59
  @dry_run_option()
60
60
  def status(
61
61
  agent_ref: str,
@@ -125,9 +125,12 @@ def run_status_command(
125
125
  if not resolved:
126
126
  raise resolution_error(
127
127
  "请指定 Agent(--agent 或位置参数),或在当前目录提供可解析的本地配置",
128
- hints=["自动解析顺序: .agentengine.state -> agentengine.yaml/ksadk.yaml", "请先执行 `agentengine agent list`。"],
128
+ hints=[
129
+ "自动解析顺序: .agentengine.state -> agentengine.yaml/ksadk.yaml",
130
+ "请先执行 `agentengine agent list`。",
131
+ ],
129
132
  )
130
- agent = resolved.value
133
+ agent = str(resolved.value)
131
134
  if resolved.source != "cli":
132
135
  print_info(f"未显式指定 Agent,使用 {resolved.source_text}: {agent}")
133
136
 
@@ -136,23 +139,34 @@ def run_status_command(
136
139
  if watch and dry_run:
137
140
  raise usage_error("Watch 模式不支持 dry-run,请去掉 --watch 或取消 dry-run。")
138
141
  if watch and is_json_output():
139
- raise usage_error("Watch 模式不支持 `--output json`。", hints=["请去掉 `--watch` 或改用 `agentengine agent status --output json`。"])
142
+ raise usage_error(
143
+ "Watch 模式不支持 `--output json`。",
144
+ hints=["请去掉 `--watch` 或改用 `agentengine agent status --output json`。"],
145
+ )
140
146
 
141
147
  # Dry Run 模式由 AgentEngineClient 处理
142
148
  # 只要传入 dry_run=True,底层 client 会抛出 DryRunExit 异常
143
149
 
150
+ resolved_account_id = account_id or ""
144
151
  if show_all:
145
152
  run_async_with_dry_run(
146
- _list_all_agents(region, account_id, dry_run, page=page, size=size, framework=framework),
153
+ _list_all_agents(
154
+ region,
155
+ resolved_account_id,
156
+ dry_run,
157
+ page=page,
158
+ size=size,
159
+ framework=framework,
160
+ ),
147
161
  dry_run=dry_run,
148
162
  dry_run_resource="agent",
149
163
  dry_run_action="list",
150
164
  )
151
165
  elif watch:
152
- _watch_status(agent, region, account_id, interval)
166
+ _watch_status(str(agent), region, resolved_account_id, interval)
153
167
  else:
154
168
  run_async_with_dry_run(
155
- _show_agent_status(agent, region, account_id, dry_run),
169
+ _show_agent_status(str(agent), region, resolved_account_id, dry_run),
156
170
  dry_run=dry_run,
157
171
  dry_run_resource="agent",
158
172
  dry_run_action="status",
@@ -170,7 +184,7 @@ def _watch_status(agent: str, region: str, account_id: str, interval: int):
170
184
  click.clear()
171
185
 
172
186
  # 显示标题
173
- click.secho(f"Agent Status Monitor", fg="blue", bold=True)
187
+ click.secho("Agent Status Monitor", fg="blue", bold=True)
174
188
  click.echo(f" Agent: {agent}")
175
189
  click.echo(f" Region: {region}")
176
190
  click.echo(f" 更新时间: {datetime.now().strftime('%H:%M:%S')}")
@@ -205,7 +219,9 @@ async def _show_agent_status(
205
219
  # 先按 ID 查询,失败后再按名称查询,避免依赖字符串前缀判断。
206
220
  result = await _get_agent_runtime(agent, region, account_id, dry_run, is_name=False)
207
221
  if result.get("status") == "Error":
208
- result_by_name = await _get_agent_runtime(agent, region, account_id, dry_run, is_name=True)
222
+ result_by_name = await _get_agent_runtime(
223
+ agent, region, account_id, dry_run, is_name=True
224
+ )
209
225
  if result_by_name.get("status") != "Error":
210
226
  result = result_by_name
211
227
 
@@ -219,14 +235,14 @@ async def _show_agent_status(
219
235
  langfuse_url = result.get("langfuseTraceUrl")
220
236
  from dateutil import parser
221
237
 
222
- created_at = result.get('createdAt')
238
+ created_at = result.get("createdAt")
223
239
  if created_at:
224
240
  dt = parser.parse(created_at)
225
241
  created_at = dt.astimezone().isoformat()
226
242
  else:
227
243
  created_at = "-"
228
244
 
229
- updated_at = result.get('updatedAt')
245
+ updated_at = result.get("updatedAt")
230
246
  if updated_at:
231
247
  dt = parser.parse(updated_at)
232
248
  updated_at = dt.astimezone().isoformat()
@@ -378,8 +394,8 @@ async def _list_all_agents(
378
394
  rows = []
379
395
  items = []
380
396
  for r in results:
381
- agent_id = (r.get("agentRuntimeId") or "N/A")
382
- name = (r.get("agentRuntimeName") or "N/A")
397
+ agent_id = r.get("agentRuntimeId") or "N/A"
398
+ name = r.get("agentRuntimeName") or "N/A"
383
399
  status_val = r.get("status", "Unknown")
384
400
  ready = int(r.get("readyReplicas", 0) or 0)
385
401
  replicas = int(r.get("replicas", 0) or 0)
@@ -419,8 +435,20 @@ async def _list_all_agents(
419
435
  columns=(
420
436
  {"header": "ID", "key": "id", "style": "#58a6ff", "no_wrap": True, "min_width": 24},
421
437
  {"header": "名称", "key": "name", "style": "#c9d1d9", "min_width": 20},
422
- {"header": "状态", "key": "status", "no_wrap": True, "justify": "center", "min_width": 10},
423
- {"header": "副本", "key": "replicas_display", "no_wrap": True, "justify": "center", "min_width": 8},
438
+ {
439
+ "header": "状态",
440
+ "key": "status",
441
+ "no_wrap": True,
442
+ "justify": "center",
443
+ "min_width": 10,
444
+ },
445
+ {
446
+ "header": "副本",
447
+ "key": "replicas_display",
448
+ "no_wrap": True,
449
+ "justify": "center",
450
+ "min_width": 8,
451
+ },
424
452
  {"header": "Endpoint", "key": "endpoint", "style": "#8b949e", "overflow": "ellipsis"},
425
453
  ),
426
454
  rows=rows,
@@ -446,7 +474,9 @@ async def _list_all_agents(
446
474
  ],
447
475
  )
448
476
  if not is_json_output():
449
- console.print(summary_panel(total=len(results), healthy=running, attention=unhealthy, noun="Agent"))
477
+ console.print(
478
+ summary_panel(total=len(results), healthy=running, attention=unhealthy, noun="Agent")
479
+ )
450
480
 
451
481
 
452
482
  def _get_status_color(status: str) -> str:
@@ -454,19 +484,24 @@ def _get_status_color(status: str) -> str:
454
484
  return status_click_color(status)
455
485
 
456
486
 
457
- async def _get_agent_runtime(agent: str, region: str, account_id: str, dry_run: bool = False, is_name: bool = False) -> dict:
487
+ async def _get_agent_runtime(
488
+ agent: str, region: str, account_id: str, dry_run: bool = False, is_name: bool = False
489
+ ) -> dict:
458
490
  """获取 Agent 运行时状态
459
491
 
460
492
  调用 AgentEngine Server API
461
493
  """
462
494
  from ksadk.api import AgentEngineClient
495
+
463
496
  try:
464
497
  extra_headers = {}
465
498
  # 传递 Account ID
466
499
  if account_id:
467
500
  extra_headers["X-Ksc-Account-Id"] = account_id
468
501
 
469
- async with AgentEngineClient(region=region, dry_run=dry_run, extra_headers=extra_headers) as client:
502
+ async with AgentEngineClient(
503
+ region=region, dry_run=dry_run, extra_headers=extra_headers
504
+ ) as client:
470
505
  if is_name:
471
506
  response = await client.get_agent(name=agent)
472
507
  else:
@@ -484,10 +519,21 @@ async def _get_agent_runtime(agent: str, region: str, account_id: str, dry_run:
484
519
  "description": basic.get("description", "") or response.get("description", ""),
485
520
  "status": basic.get("status", "") or response.get("status", "Unknown"),
486
521
  "phase": basic.get("phase", "") or response.get("phase", ""),
487
- "replicas": basic.get("replicas") if basic.get("replicas") is not None else response.get("replicas", deploy.get("scaling", {}).get("min_replicas", 1)),
488
- "readyReplicas": basic.get("ready_replicas") if basic.get("ready_replicas") is not None else response.get("ready_replicas", 0),
489
- "endpoint": quick.get("public_endpoint") or quick.get("private_endpoint") or response.get("endpoint", ""),
490
- "langfuseTraceUrl": adv.get("observability_url", "") or response.get("langfuse_trace_url", ""),
522
+ "replicas": (
523
+ basic.get("replicas")
524
+ if basic.get("replicas") is not None
525
+ else response.get("replicas", deploy.get("scaling", {}).get("min_replicas", 1))
526
+ ),
527
+ "readyReplicas": (
528
+ basic.get("ready_replicas")
529
+ if basic.get("ready_replicas") is not None
530
+ else response.get("ready_replicas", 0)
531
+ ),
532
+ "endpoint": quick.get("public_endpoint")
533
+ or quick.get("private_endpoint")
534
+ or response.get("endpoint", ""),
535
+ "langfuseTraceUrl": adv.get("observability_url", "")
536
+ or response.get("langfuse_trace_url", ""),
491
537
  "createdAt": basic.get("created_at", "") or response.get("created_at", ""),
492
538
  "updatedAt": basic.get("updated_at", "") or response.get("updated_at", ""),
493
539
  "message": basic.get("message", "") or response.get("message", ""),
@@ -517,13 +563,16 @@ async def _list_agent_runtimes(
517
563
  调用 AgentEngine Server API
518
564
  """
519
565
  from ksadk.api import AgentEngineClient
566
+
520
567
  try:
521
568
  extra_headers = {}
522
569
  # 传递 Account ID
523
570
  if account_id:
524
571
  extra_headers["X-Ksc-Account-Id"] = account_id
525
572
 
526
- async with AgentEngineClient(region=region, dry_run=dry_run, extra_headers=extra_headers) as client:
573
+ async with AgentEngineClient(
574
+ region=region, dry_run=dry_run, extra_headers=extra_headers
575
+ ) as client:
527
576
  response = await client.list_agents(
528
577
  region=region,
529
578
  framework=framework,
@@ -0,0 +1,110 @@
1
+ """agentengine studio - start the local-first Agent authoring control plane."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import secrets
7
+ import webbrowser
8
+ from pathlib import Path
9
+
10
+ import click
11
+ import uvicorn
12
+
13
+ from ksadk.cli.env_options import load_env_file
14
+ from ksadk.cli.ui import print_info, print_kv, print_success, print_title
15
+ from ksadk.studio.api import create_studio_app
16
+ from ksadk.studio.service import StudioService
17
+
18
+ _MODEL_ENV_KEYS = (
19
+ "OPENAI_API_BASE",
20
+ "OPENAI_API_KEY",
21
+ "OPENAI_MODEL_NAME",
22
+ )
23
+
24
+
25
+ @click.command(context_settings=dict(help_option_names=["-h", "--help"]))
26
+ @click.argument("workspace", default=".", type=click.Path())
27
+ @click.option("--port", "-p", default=8080, type=click.IntRange(1, 65535))
28
+ @click.option("--no-open", is_flag=True, help="仅打印 URL,不自动打开浏览器")
29
+ @click.option(
30
+ "--env-file",
31
+ type=click.Path(exists=True, dir_okay=False),
32
+ help="模型环境文件;只读取 OPENAI_API_BASE/API_KEY/MODEL_NAME",
33
+ )
34
+ @click.option(
35
+ "--codex-proxy",
36
+ type=click.Choice(["inherit", "auto", "forced", "direct"]),
37
+ default="inherit",
38
+ show_default=True,
39
+ help="Codex Responses→Chat 代理策略",
40
+ )
41
+ def studio(
42
+ workspace: str,
43
+ port: int,
44
+ no_open: bool,
45
+ env_file: str | None,
46
+ codex_proxy: str,
47
+ ) -> None:
48
+ """启动本地 AgentKit Studio。
49
+
50
+ \b
51
+ WORKSPACE: Agent 工作区目录,目录不存在时自动初始化。
52
+ """
53
+
54
+ root = Path(workspace).expanduser().resolve()
55
+ managed_keys = (*_MODEL_ENV_KEYS, "KSADK_CODEX_USE_PROXY")
56
+ previous = {key: os.environ.get(key) for key in managed_keys}
57
+ previously_present = {key for key in managed_keys if key in os.environ}
58
+ try:
59
+ if env_file:
60
+ try:
61
+ values = load_env_file(env_file)
62
+ except ValueError as exc:
63
+ raise click.ClickException(str(exc)) from exc
64
+ loaded = 0
65
+ for key, value in values.items():
66
+ if key not in _MODEL_ENV_KEYS or not value:
67
+ continue
68
+ loaded += 1
69
+ if key not in os.environ:
70
+ os.environ[key] = value
71
+ print_kv("模型环境", f"已安全加载 {loaded}/{len(_MODEL_ENV_KEYS)} 个字段")
72
+ if codex_proxy == "forced":
73
+ os.environ["KSADK_CODEX_USE_PROXY"] = "1"
74
+ elif codex_proxy == "direct":
75
+ os.environ["KSADK_CODEX_USE_PROXY"] = "0"
76
+ elif codex_proxy == "auto":
77
+ os.environ.pop("KSADK_CODEX_USE_PROXY", None)
78
+ session_token = os.environ.get("KSADK_STUDIO_SESSION_TOKEN") or secrets.token_urlsafe(32)
79
+ csrf_token = secrets.token_urlsafe(24)
80
+ service = StudioService(root)
81
+ app = create_studio_app(
82
+ root,
83
+ service=service,
84
+ session_token=session_token,
85
+ csrf_token=csrf_token,
86
+ security_enabled=os.environ.get("KSADK_STUDIO_NO_SECURITY") != "1",
87
+ )
88
+ base_url = f"http://127.0.0.1:{port}/"
89
+ launch_url = f"{base_url}#session={session_token}"
90
+
91
+ print_title("启动 AgentKit Local Studio")
92
+ print_kv("工作区", str(root))
93
+ print_kv("访问地址", launch_url, value_style="#58a6ff")
94
+ print_success("构建与运行均在本地执行")
95
+ print_info("按 Ctrl+C 停止")
96
+ if not no_open:
97
+ webbrowser.open(launch_url)
98
+ uvicorn.run(
99
+ app,
100
+ host="127.0.0.1",
101
+ port=port,
102
+ log_level="info",
103
+ access_log=False,
104
+ )
105
+ finally:
106
+ for key in managed_keys:
107
+ if key in previously_present:
108
+ os.environ[key] = previous[key] or ""
109
+ else:
110
+ os.environ.pop(key, None)