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
ksadk/cli/cmd_web.py CHANGED
@@ -1,10 +1,13 @@
1
1
  """ksadk web - 启动统一本地 Web UI。"""
2
2
 
3
- import click
3
+ import asyncio
4
+ import os
4
5
  import webbrowser
5
6
  from pathlib import Path
6
- import os
7
+
8
+ import click
7
9
  import yaml
10
+
8
11
  from ksadk.cli.error_utils import ensure_json_output_supported, print_exception
9
12
  from ksadk.cli.local_runtime import reexec_with_project_venv_if_needed
10
13
  from ksadk.cli.ui import (
@@ -13,12 +16,12 @@ from ksadk.cli.ui import (
13
16
  print_kv,
14
17
  print_success,
15
18
  print_title,
19
+ print_warn,
16
20
  )
17
21
  from ksadk.configs import setup_environment
18
22
  from ksadk.detection import FrameworkDetector
19
23
  from ksadk.runners.factory import create_runner
20
24
 
21
-
22
25
  _PERSISTENT_STM_FRAMEWORKS = {"adk", "langgraph", "langchain", "deepagents"}
23
26
  _STM_ENV_NAMES = (
24
27
  "KSADK_STM_BACKEND",
@@ -179,6 +182,47 @@ def _default_project_stm_if_unset(
179
182
  )
180
183
 
181
184
 
185
+ def configure_local_runtime_persistence(
186
+ agent_path: Path,
187
+ framework: str,
188
+ *,
189
+ explicit_session_env_names: set[str] | None = None,
190
+ explicit_checkpoint_env_names: set[str] | None = None,
191
+ explicit_local_ui_env_names: set[str] | None = None,
192
+ ) -> None:
193
+ """Bind locally-run agent state to its project unless the shell overrides it."""
194
+
195
+ project_dotenv = _project_dotenv_values(agent_path)
196
+ if explicit_session_env_names is None:
197
+ explicit_session_env_names = _explicit_env_names_excluding_project_dotenv(
198
+ (*_STM_ENV_NAMES, *_SESSION_ENV_NAMES),
199
+ project_dotenv,
200
+ )
201
+ if explicit_checkpoint_env_names is None:
202
+ explicit_checkpoint_env_names = _explicit_env_names_excluding_project_dotenv(
203
+ _CHECKPOINT_ENV_NAMES,
204
+ project_dotenv,
205
+ )
206
+ if explicit_local_ui_env_names is None:
207
+ explicit_local_ui_env_names = _explicit_env_names_excluding_project_dotenv(
208
+ _LOCAL_UI_ENV_NAMES,
209
+ project_dotenv,
210
+ )
211
+
212
+ os.environ["KSADK_PROJECT_DIR"] = str(agent_path)
213
+ local_ui_dir = str(agent_path / ".agentengine" / "ui")
214
+ if "AGENTENGINE_UI_DIR" not in explicit_local_ui_env_names:
215
+ os.environ["AGENTENGINE_UI_DIR"] = local_ui_dir
216
+ else:
217
+ os.environ.setdefault("AGENTENGINE_UI_DIR", local_ui_dir)
218
+ _default_project_stm_if_unset(
219
+ framework,
220
+ agent_path,
221
+ explicit_session_env_names=explicit_session_env_names,
222
+ explicit_checkpoint_env_names=explicit_checkpoint_env_names,
223
+ )
224
+
225
+
182
226
  @click.command(context_settings=dict(help_option_names=["-h", "--help"]))
183
227
  @click.argument("agent_dir", default=".", type=click.Path(exists=True))
184
228
  @click.option("--port", "-p", default=8080, help="Web UI 端口")
@@ -197,13 +241,18 @@ def web(agent_dir: str, port: int, model: str, no_open: bool):
197
241
  """
198
242
  ensure_json_output_supported(
199
243
  "agentengine web",
200
- suggestion="请改用 `agentengine dashboard open` 或 `agentengine agent status --output json`。",
244
+ suggestion=(
245
+ "请改用 `agentengine dashboard open` 或 " "`agentengine agent status --output json`。"
246
+ ),
201
247
  )
202
248
 
203
249
  agent_path = Path(agent_dir).resolve()
204
250
  command_args = ["web", str(agent_path), "--port", str(port)]
205
251
  if model:
206
252
  command_args.extend(["--model", model])
253
+ if no_open:
254
+ # re-exec 进项目 venv 时透传 --no-open,否则子进程仍会打开浏览器
255
+ command_args.append("--no-open")
207
256
  reexec_with_project_venv_if_needed(agent_path, command_args)
208
257
  project_dotenv = _project_dotenv_values(agent_path)
209
258
  explicit_session_env_names = _explicit_env_names_excluding_project_dotenv(
@@ -238,28 +287,55 @@ def web(agent_dir: str, port: int, model: str, no_open: bool):
238
287
  print_error("未检测到支持的框架")
239
288
  raise SystemExit(1)
240
289
 
290
+ if result.type.value == "codex":
291
+ raw_config = getattr(result, "raw_config", None) or {}
292
+ if str(raw_config.get("artifact_type") or "").strip().lower() == "managedruntime":
293
+ from ksadk.managed_runtime import (
294
+ ManagedRuntimeError,
295
+ resolve_local_managed_runtime,
296
+ )
297
+
298
+ try:
299
+ resolved_runtime = asyncio.run(
300
+ resolve_local_managed_runtime(
301
+ raw_config,
302
+ region=os.getenv("KSYUN_REGION", "cn-beijing-6"),
303
+ )
304
+ )
305
+ except ManagedRuntimeError as exc:
306
+ print_error(str(exc))
307
+ raise SystemExit(1) from exc
308
+ runtime_config = raw_config.setdefault("runtime", {})
309
+ if isinstance(runtime_config, dict):
310
+ runtime_config["version"] = resolved_runtime.version
311
+ print_kv(
312
+ "Runtime",
313
+ f"{resolved_runtime.name}@{resolved_runtime.version}",
314
+ value_style="#58a6ff",
315
+ )
316
+ if resolved_runtime.source == "installed-unlocked":
317
+ print_warn(
318
+ "离线使用本机已安装 Runtime;云端构建前请显式锁定版本"
319
+ "或连接 AgentEngine 获取默认版本"
320
+ )
321
+
241
322
  # Map framework types to display names
242
323
  framework_map = {
243
324
  "adk": "ADK",
244
325
  "langchain": "LangChain",
245
326
  "langgraph": "LangGraph",
246
327
  "deepagents": "DeepAgents",
328
+ "codex": "Codex",
247
329
  }
248
330
  display_name = framework_map.get(result.type.value, result.name)
249
331
  print_kv("框架", display_name, value_style="#2da44e")
250
332
 
251
- # 本地 UI 的持久化目录与项目根绑定
252
- os.environ["KSADK_PROJECT_DIR"] = str(agent_path)
253
- local_ui_dir = str(agent_path / ".agentengine" / "ui")
254
- if "AGENTENGINE_UI_DIR" not in explicit_local_ui_env_names:
255
- os.environ["AGENTENGINE_UI_DIR"] = local_ui_dir
256
- else:
257
- os.environ.setdefault("AGENTENGINE_UI_DIR", local_ui_dir)
258
- _default_project_stm_if_unset(
259
- result.type.value,
333
+ configure_local_runtime_persistence(
260
334
  agent_path,
335
+ result.type.value,
261
336
  explicit_session_env_names=explicit_session_env_names,
262
337
  explicit_checkpoint_env_names=explicit_checkpoint_env_names,
338
+ explicit_local_ui_env_names=explicit_local_ui_env_names,
263
339
  )
264
340
  launch_path = _configure_custom_ui_env(agent_path)
265
341
 
ksadk/cli/deploy_utils.py CHANGED
@@ -1,28 +1,28 @@
1
1
  import os
2
+
2
3
  import click
4
+
3
5
  from ksadk.api import AgentEngineClient
4
6
 
7
+
5
8
  async def auto_release_version(agent_id: str, region: str, deploy_name: str):
6
9
  """部署成功后自动创建版本快照"""
7
- from datetime import datetime
8
-
10
+
9
11
  access_key = os.getenv("KSYUN_ACCESS_KEY") or os.getenv("KS3_ACCESS_KEY")
10
12
  secret_key = os.getenv("KSYUN_SECRET_KEY") or os.getenv("KS3_SECRET_KEY")
11
-
13
+
12
14
  client = AgentEngineClient(
13
15
  access_key=access_key,
14
16
  secret_key=secret_key,
15
17
  region=region,
16
18
  )
17
-
19
+
18
20
  try:
19
21
  description = "部署后自动发布"
20
22
  result = await client.release_version(
21
- agent_id=agent_id,
22
- tag=None, # 自动生成
23
- description=description
23
+ agent_id=agent_id, tag=None, description=description # 自动生成
24
24
  )
25
-
25
+
26
26
  click.echo("")
27
27
  click.secho(f"✓ 版本快照已创建: {result.get('tag')}", fg="green")
28
28
  except Exception as e:
@@ -34,53 +34,53 @@ async def auto_release_version(agent_id: str, region: str, deploy_name: str):
34
34
 
35
35
  async def auto_rollback_to_previous(agent_id: str, region: str):
36
36
  """部署失败时自动回滚到上一版本"""
37
-
37
+
38
38
  access_key = os.getenv("KSYUN_ACCESS_KEY") or os.getenv("KS3_ACCESS_KEY")
39
39
  secret_key = os.getenv("KSYUN_SECRET_KEY") or os.getenv("KS3_SECRET_KEY")
40
-
40
+
41
41
  client = AgentEngineClient(
42
42
  access_key=access_key,
43
43
  secret_key=secret_key,
44
44
  region=region,
45
45
  )
46
-
46
+
47
47
  try:
48
48
  # 获取版本列表,找到最近的历史版本
49
49
  versions_result = await client.list_versions(agent_id, page=1, size=5)
50
50
  versions = versions_result.get("versions", [])
51
-
51
+
52
52
  # 找到需要回滚的目标版本 (统一 snake_case)
53
53
  target_version = None
54
54
  for v in versions:
55
55
  if (v.get("status") or "").lower() == "current":
56
56
  target_version = v
57
57
  break
58
-
58
+
59
59
  # 如果没有 Current,则找最新的 Historical
60
60
  if not target_version:
61
61
  for v in versions:
62
62
  if (v.get("status") or "").lower() == "historical":
63
63
  target_version = v
64
64
  break
65
-
65
+
66
66
  if not target_version:
67
67
  click.secho("⚠ 无可用稳定版本,跳过自动回滚", fg="yellow")
68
68
  return
69
-
69
+
70
70
  target_tag = target_version.get("tag")
71
71
  click.echo("")
72
72
  click.secho(f"⏪ 正在自动回滚到版本: {target_tag}...", fg="yellow")
73
-
73
+
74
74
  # 执行回滚
75
- result = await client.rollback_version(
75
+ await client.rollback_version(
76
76
  agent_id=agent_id,
77
77
  target_tag=target_tag,
78
78
  ks3_access_key=access_key,
79
- ks3_secret_key=secret_key
79
+ ks3_secret_key=secret_key,
80
80
  )
81
-
81
+
82
82
  click.secho(f"✓ 已回滚到版本: {target_tag}", fg="green")
83
-
83
+
84
84
  except Exception as e:
85
85
  click.secho(f"⚠ 自动回滚失败: {e}", fg="red")
86
86
  finally:
ksadk/cli/dry_run.py CHANGED
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import json
7
7
  import os
8
- from typing import Any, Awaitable, Callable, Optional, TypeVar
8
+ from typing import Any, Callable, Coroutine, Optional, TypeVar
9
9
 
10
10
  import click
11
11
  from click.core import ParameterSource
@@ -172,7 +172,7 @@ def sanitize_dry_run_request(payload: dict[str, Any] | None) -> dict[str, Any]:
172
172
 
173
173
 
174
174
  def run_async_with_dry_run(
175
- coro: Awaitable[_T],
175
+ coro: Coroutine[Any, Any, _T],
176
176
  *,
177
177
  dry_run: bool,
178
178
  done_message: str = _DEFAULT_DONE_MSG,
@@ -200,7 +200,9 @@ def run_async_with_dry_run(
200
200
  )
201
201
  elif safe_payload:
202
202
  click.echo("=" * 60)
203
- click.echo(f"Dry Run Mode: {safe_payload.get('method', 'REQUEST')} {safe_payload.get('url', '')}")
203
+ method = safe_payload.get("method", "REQUEST")
204
+ url = safe_payload.get("url", "")
205
+ click.echo(f"Dry Run Mode: {method} {url}")
204
206
  click.echo("=" * 60)
205
207
  click.echo(f"Headers: {safe_payload.get('headers')}")
206
208
  if safe_payload.get("body") is not None:
ksadk/cli/error_utils.py CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from dataclasses import dataclass, field
6
5
  import os
7
6
  import re
8
7
  import sys
8
+ from dataclasses import dataclass, field
9
9
  from typing import Any, Optional, Sequence, Tuple
10
10
 
11
11
  import click
@@ -128,9 +128,16 @@ def _looks_like_invalid_cloud_credentials(details: dict[str, Any], msg_lower: st
128
128
  return any(marker in msg_lower for marker in markers)
129
129
 
130
130
 
131
- def _looks_like_runtime_permission_error(details: dict[str, Any], msg_lower: str, code: int | None) -> bool:
131
+ def _looks_like_runtime_permission_error(
132
+ details: dict[str, Any], msg_lower: str, code: int | None
133
+ ) -> bool:
132
134
  remote_code = str(details.get("remote_error_code") or "").strip().lower()
133
- if remote_code in {"accessdenied", "accessdeniedexception", "unauthorized", "unauthorizedoperation"}:
135
+ if remote_code in {
136
+ "accessdenied",
137
+ "accessdeniedexception",
138
+ "unauthorized",
139
+ "unauthorizedoperation",
140
+ }:
134
141
  return True
135
142
  if code in {401, 403} and (
136
143
  ("权限" in msg_lower)
@@ -145,7 +152,8 @@ def _looks_like_runtime_permission_error(details: dict[str, Any], msg_lower: str
145
152
 
146
153
  def _credential_setup_hints() -> list[str]:
147
154
  return [
148
- "请检查当前 shell 或项目 `.env` 中是否设置了 `KSYUN_ACCESS_KEY` / `KSYUN_SECRET_KEY`(兼容 `KS3_ACCESS_KEY` / `KS3_SECRET_KEY`)。",
155
+ "请检查当前 shell 或项目 `.env` 中是否设置了 `KSYUN_ACCESS_KEY` / "
156
+ "`KSYUN_SECRET_KEY`(兼容 `KS3_ACCESS_KEY` / `KS3_SECRET_KEY`)。",
149
157
  "先到 AgentEngine Runtime 控制台确认账号是否具备运行时权限: https://ksp.console.ksyun.com/#/agentEngineRuntime",
150
158
  "如当前子账号没有权限,请到 IAM 授权页授权: https://uc.console.ksyun.com/pro/iam/#/permission/authorize",
151
159
  "如果还没有金山云 AK/SK,请让主账号先到 IAM 控制台创建子账号并生成访问密钥: https://uc.console.ksyun.com/pro/iam/",
@@ -154,7 +162,8 @@ def _credential_setup_hints() -> list[str]:
154
162
 
155
163
  def _invalid_credential_hints() -> list[str]:
156
164
  return [
157
- "请检查当前 shell 或项目 `.env` 中的 `KSYUN_ACCESS_KEY` / `KSYUN_SECRET_KEY` 是否填写正确,且没有多余空格。",
165
+ "请检查当前 shell 或项目 `.env` 中的 `KSYUN_ACCESS_KEY` / "
166
+ "`KSYUN_SECRET_KEY` 是否填写正确,且没有多余空格。",
158
167
  "确认该 AK/SK 未被禁用、删除或重置,并且属于当前要操作的金山云账号。",
159
168
  "如需确认账号是否具备 AgentEngine Runtime 权限,可先查看: https://ksp.console.ksyun.com/#/agentEngineRuntime",
160
169
  "如果凭证属于子账号但仍然被拒绝,请到 IAM 授权页检查授权: https://uc.console.ksyun.com/pro/iam/#/permission/authorize",
@@ -188,7 +197,9 @@ def _matches_resource_not_found(msg_lower: str, args: Sequence[str], *, resource
188
197
  return args[0] == resource
189
198
 
190
199
 
191
- def explain_exception(err: Exception, argv: Optional[Sequence[str]] = None) -> Tuple[str, list[str]]:
200
+ def explain_exception(
201
+ err: Exception, argv: Optional[Sequence[str]] = None
202
+ ) -> Tuple[str, list[str]]:
192
203
  cli_error = cli_error_from_exception(err, argv=argv)
193
204
  return cli_error.message, cli_error.hints
194
205
 
@@ -384,7 +395,9 @@ def cli_error_from_exception(
384
395
 
385
396
  if code == 404 and len(args) >= 2 and args[0] == "dashboard" and args[1] == "share":
386
397
  summary = "未找到 Dashboard 分享链接或目标 Agent。"
387
- hints.append("请先执行 `agentengine dashboard share list --agent <AgentName|AgentId>` 查看分享链接。")
398
+ hints.append(
399
+ "请先执行 `agentengine dashboard share list --agent <AgentName|AgentId>` 查看分享链接。"
400
+ )
388
401
  hints.append("如需先确认 Agent,请执行 `agentengine agent list`。")
389
402
  error_code = "resolution_error"
390
403
  exit_code = EXIT_CODE_RESOLUTION
@@ -396,22 +409,34 @@ def cli_error_from_exception(
396
409
  exit_code = EXIT_CODE_RESOLUTION
397
410
  elif code == 404 and _matches_resource_not_found(msg_lower, args, resource="agent"):
398
411
  summary = "未找到 Agent。"
399
- hints.append("请确认 Agent 名称/ID 是否正确,可先执行 `agentengine agent list` 查看已部署 Agent。")
412
+ hints.append(
413
+ "请确认 Agent 名称/ID 是否正确,可先执行 `agentengine agent list` 查看已部署 Agent。"
414
+ )
400
415
  if len(args) >= 2 and args[0] == "dashboard" and args[1] == "list":
401
416
  hints.append("`agentengine dashboard list` 不是有效命令。")
402
- hints.append("如果要查看分享链接,请使用 `agentengine dashboard share list --agent <AgentName|AgentId>`。")
417
+ hints.append(
418
+ "如果要查看分享链接,请使用 "
419
+ "`agentengine dashboard share list --agent <AgentName|AgentId>`。"
420
+ )
403
421
  elif args and args[0] == "dashboard":
404
- hints.append("可显式指定 Agent:`agentengine dashboard open --agent <AgentName|AgentId>`。")
422
+ hints.append(
423
+ "可显式指定 Agent:`agentengine dashboard open --agent <AgentName|AgentId>`。"
424
+ )
405
425
  error_code = "resolution_error"
406
426
  exit_code = EXIT_CODE_RESOLUTION
407
427
  elif code == 404 and _matches_resource_not_found(msg_lower, args, resource="mcp"):
408
428
  summary = "未找到 MCP。"
409
- hints.append("请确认 MCP 名称/ID 是否正确,可先执行 `agentengine mcp list` 查看已部署 MCP。")
429
+ hints.append(
430
+ "请确认 MCP 名称/ID 是否正确,可先执行 `agentengine mcp list` 查看已部署 MCP。"
431
+ )
410
432
  error_code = "resolution_error"
411
433
  exit_code = EXIT_CODE_RESOLUTION
412
434
  elif code == 404 and _matches_resource_not_found(msg_lower, args, resource="openclaw"):
413
435
  summary = "未找到 OpenClaw。"
414
- hints.append("请确认 OpenClaw 名称/ID 是否正确,可先执行 `agentengine openclaw list` 查看已部署实例。")
436
+ hints.append(
437
+ "请确认 OpenClaw 名称/ID 是否正确,可先执行 "
438
+ "`agentengine openclaw list` 查看已部署实例。"
439
+ )
415
440
  error_code = "resolution_error"
416
441
  exit_code = EXIT_CODE_RESOLUTION
417
442
  elif _looks_like_missing_cloud_credentials(details, msg_lower):
@@ -10,8 +10,7 @@ from ksadk.cli.ui import build_no_color_click_option, build_output_click_option
10
10
 
11
11
  def _has_long_option(command: click.Command, option_name: str) -> bool:
12
12
  return any(
13
- isinstance(param, click.Option) and option_name in param.opts
14
- for param in command.params
13
+ isinstance(param, click.Option) and option_name in param.opts for param in command.params
15
14
  )
16
15
 
17
16
 
@@ -3,12 +3,11 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from pathlib import Path
7
6
  import site
8
7
  import sys
8
+ from pathlib import Path
9
9
  from typing import Sequence
10
10
 
11
-
12
11
  LOCAL_RUNTIME_VENV_REEXEC_ENV = "AGENTENGINE_LOCAL_RUNTIME_VENV_REEXEC"
13
12
  LEGACY_WEB_VENV_REEXEC_ENV = "AGENTENGINE_WEB_VENV_REEXEC"
14
13
 
@@ -116,7 +116,9 @@ async def fetch_provider_model_catalog(
116
116
  normalized: list[dict[str, Any]] = []
117
117
  for raw_model in _extract_catalog_items(payload):
118
118
  item = normalize_model_metadata(raw_model)
119
- item["_provider_raw_model"] = raw_model if isinstance(raw_model, Mapping) else {"id": str(raw_model)}
119
+ item["_provider_raw_model"] = (
120
+ raw_model if isinstance(raw_model, Mapping) else {"id": str(raw_model)}
121
+ )
120
122
  normalized.append(item)
121
123
  return normalized
122
124
 
@@ -128,7 +130,9 @@ async def fetch_provider_model_metadata(
128
130
  model: str | None,
129
131
  timeout: float = 10.0,
130
132
  ) -> dict[str, Any] | None:
131
- catalog = await fetch_provider_model_catalog(api_base=api_base, api_key=api_key, timeout=timeout)
133
+ catalog = await fetch_provider_model_catalog(
134
+ api_base=api_base, api_key=api_key, timeout=timeout
135
+ )
132
136
  raw_models = [item.get("_provider_raw_model") or item for item in catalog]
133
137
  raw_match = find_model_in_catalog(raw_models, model)
134
138
  if raw_match is None:
@@ -38,7 +38,10 @@ def network_options(func):
38
38
  click.option(
39
39
  "--enable-public-access/--disable-public-access",
40
40
  default=None,
41
- help="是否开启公网访问;创建时默认开启,更新已有 Agent 时未指定则保留现有配置(显式传入才覆盖)",
41
+ help=(
42
+ "是否开启公网访问;创建时默认开启,更新已有 Agent 时未指定则保留现有配置"
43
+ "(显式传入才覆盖)"
44
+ ),
42
45
  ),
43
46
  click.option("--enable-vpc-access", is_flag=True, default=False, help="开启 VPC 私网访问"),
44
47
  click.option("--vpc-id", default=None, help="VPC ID(开启 VPC 访问时必填)"),
@@ -75,7 +78,8 @@ def extract_network_config(config: Mapping[str, Any] | None) -> dict[str, Any]:
75
78
  """Read network from top-level `network` or `deploy.network`."""
76
79
  if not isinstance(config, Mapping):
77
80
  return {}
78
- deploy_config = config.get("deploy") if isinstance(config.get("deploy"), Mapping) else {}
81
+ deploy_value = config.get("deploy")
82
+ deploy_config: Mapping[str, Any] = deploy_value if isinstance(deploy_value, Mapping) else {}
79
83
  raw_network = config.get("network") or deploy_config.get("network") or {}
80
84
  return dict(raw_network) if isinstance(raw_network, Mapping) else {}
81
85
 
@@ -98,7 +102,12 @@ def apply_network_config(config: Mapping[str, Any] | None, deploy_target: "Deplo
98
102
  if _picked_public_access is not None:
99
103
  deploy_target.network.enable_public_access = bool(_picked_public_access)
100
104
  deploy_target.network.enable_vpc_access = bool(
101
- _pick("enable_vpc_access", "enableVpcAccess", "EnableVpcAccess", default=deploy_target.network.enable_vpc_access)
105
+ _pick(
106
+ "enable_vpc_access",
107
+ "enableVpcAccess",
108
+ "EnableVpcAccess",
109
+ default=deploy_target.network.enable_vpc_access,
110
+ )
102
111
  )
103
112
  deploy_target.network.vpc_id = str(
104
113
  _pick("vpc_id", "vpcId", "VpcId", default=deploy_target.network.vpc_id) or ""
@@ -136,7 +145,9 @@ def apply_network_cli_overrides(deploy_target: "DeployTarget", **network_kwargs:
136
145
  value = network_kwargs.get(field)
137
146
  if value is not None:
138
147
  setattr(deploy_target.network, field, str(value or "").strip())
139
- if any(str(getattr(deploy_target.network, field, "") or "").strip() for field in _VPC_ID_FIELDS):
148
+ if any(
149
+ str(getattr(deploy_target.network, field, "") or "").strip() for field in _VPC_ID_FIELDS
150
+ ):
140
151
  deploy_target.network.enable_vpc_access = True
141
152
 
142
153
 
@@ -145,7 +156,9 @@ def validate_deploy_target_network(deploy_target: "DeployTarget") -> None:
145
156
  values = {
146
157
  "vpc_id": str(getattr(deploy_target.network, "vpc_id", "") or "").strip(),
147
158
  "subnet_id": str(getattr(deploy_target.network, "subnet_id", "") or "").strip(),
148
- "security_group_id": str(getattr(deploy_target.network, "security_group_id", "") or "").strip(),
159
+ "security_group_id": str(
160
+ getattr(deploy_target.network, "security_group_id", "") or ""
161
+ ).strip(),
149
162
  }
150
163
  has_any_vpc_id = any(values.values())
151
164
  if not (bool(getattr(deploy_target.network, "enable_vpc_access", False)) or has_any_vpc_id):
@@ -156,7 +169,8 @@ def validate_deploy_target_network(deploy_target: "DeployTarget") -> None:
156
169
  "开启 VPC 访问时必须同时提供 VpcId、SubnetId、SecurityGroupId。",
157
170
  details={"missing": missing},
158
171
  hints=[
159
- "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`,或在配置文件 network/deploy.network 中同时设置这三个字段。",
172
+ "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`,"
173
+ "或在配置文件 network/deploy.network 中同时设置这三个字段。",
160
174
  "`--availability-zone` 是可选字段,不替代子网或安全组。",
161
175
  ],
162
176
  )
@@ -191,8 +205,7 @@ def resolve_deploy_target_network(
191
205
  print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
192
206
  else:
193
207
  print_warn(
194
- "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
195
- "`--availability-zone`。"
208
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 " "`--availability-zone`。"
196
209
  )
197
210
 
198
211
 
@@ -234,7 +247,9 @@ def _validate_network_payload(payload: Mapping[str, Any]) -> None:
234
247
  )
235
248
 
236
249
 
237
- def _fill_network_availability_zone(payload: dict[str, Any], network_kwargs: Mapping[str, Any]) -> None:
250
+ def _fill_network_availability_zone(
251
+ payload: dict[str, Any], network_kwargs: Mapping[str, Any]
252
+ ) -> None:
238
253
  if str(payload.get("availability_zone") or "").strip():
239
254
  return
240
255
  if not bool(payload.get("enable_vpc_access")):
@@ -254,8 +269,7 @@ def _fill_network_availability_zone(payload: dict[str, Any], network_kwargs: Map
254
269
  print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
255
270
  else:
256
271
  print_warn(
257
- "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
258
- "`--availability-zone`。"
272
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 " "`--availability-zone`。"
259
273
  )
260
274
 
261
275
 
@@ -270,7 +284,9 @@ def _resolve_subnet_availability_zone(*, subnet_id: str, region: str) -> str | N
270
284
  return None
271
285
 
272
286
  try:
273
- VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile = _import_vpc_sdk()
287
+ VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile = (
288
+ _import_vpc_sdk()
289
+ )
274
290
  except Exception as exc:
275
291
  print_warn(f"缺少 VPC 子网查询 SDK,跳过可用区自动推断: {exc}")
276
292
  return None
@@ -328,8 +344,12 @@ def _resolve_ksyun_credentials() -> tuple[str, str]:
328
344
  except Exception:
329
345
  global_env = {}
330
346
 
331
- access_key = access_key or global_env.get("KSYUN_ACCESS_KEY") or global_env.get("KS3_ACCESS_KEY") or ""
332
- secret_key = secret_key or global_env.get("KSYUN_SECRET_KEY") or global_env.get("KS3_SECRET_KEY") or ""
347
+ access_key = (
348
+ access_key or global_env.get("KSYUN_ACCESS_KEY") or global_env.get("KS3_ACCESS_KEY") or ""
349
+ )
350
+ secret_key = (
351
+ secret_key or global_env.get("KSYUN_SECRET_KEY") or global_env.get("KS3_SECRET_KEY") or ""
352
+ )
333
353
  return str(access_key or "").strip(), str(secret_key or "").strip()
334
354
 
335
355
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from dataclasses import dataclass, field
6
5
  import re
6
+ from dataclasses import dataclass, field
7
7
  from typing import Any, Callable, Iterable, Sequence, TypeVar
8
8
 
9
9
  import click
@@ -181,6 +181,7 @@ def confirm_destructive(
181
181
  details={"prompt": prompt},
182
182
  )
183
183
  )
184
+ return False
184
185
  if click.confirm(prompt):
185
186
  return True
186
187
  from ksadk.cli.error_utils import abort_with_cli_error, cancelled_error
@@ -192,6 +193,7 @@ def confirm_destructive(
192
193
  details={"prompt": prompt},
193
194
  )
194
195
  )
196
+ return False
195
197
 
196
198
 
197
199
  def print_list_summary(*, total: int, page: int, size: int, noun: str) -> None:
@@ -244,7 +246,9 @@ def get_descriptor_resource_key(descriptor: ResourceDescriptor) -> str:
244
246
  return descriptor.resource_key or _resource_key(descriptor.name) or "resource"
245
247
 
246
248
 
247
- def _legacy_action_descriptors(descriptor: ResourceDescriptor) -> tuple[ResourceActionDescriptor, ...]:
249
+ def _legacy_action_descriptors(
250
+ descriptor: ResourceDescriptor,
251
+ ) -> tuple[ResourceActionDescriptor, ...]:
248
252
  action_set = descriptor.actions
249
253
  if not isinstance(action_set, ResourceActionSet):
250
254
  return tuple(action_set)
ksadk/cli/storage.py CHANGED
@@ -6,7 +6,6 @@ from typing import Optional
6
6
 
7
7
  import click
8
8
 
9
-
10
9
  DEFAULT_STORAGE_SIZE_GI = 20
11
10
  MIN_STORAGE_SIZE_GI = 20
12
11
  MAX_STORAGE_SIZE_GI = 500
ksadk/cli/ui.py CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from contextlib import contextmanager, redirect_stderr, redirect_stdout
6
- from dataclasses import dataclass
7
5
  import io
8
6
  import json
9
7
  import os
10
8
  import sys
9
+ from contextlib import contextmanager, redirect_stderr, redirect_stdout
10
+ from dataclasses import dataclass
11
11
  from typing import Iterator
12
12
 
13
13
  import click
@@ -303,7 +303,9 @@ def no_color_option(*, hidden: bool = False, expose_value: bool = False):
303
303
  )
304
304
 
305
305
 
306
- def build_no_color_click_option(*, hidden: bool = False, expose_value: bool = False) -> click.Option:
306
+ def build_no_color_click_option(
307
+ *, hidden: bool = False, expose_value: bool = False
308
+ ) -> click.Option:
307
309
  """Build a shared no-color option for command injection."""
308
310
  return click.Option(
309
311
  ["--no-color", "no_color"],