agentengine-sdk-python 0.6.4__py3-none-any.whl → 0.7.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 (486) hide show
  1. agentengine_sdk_python-0.7.0.dist-info/METADATA +181 -0
  2. agentengine_sdk_python-0.7.0.dist-info/RECORD +482 -0
  3. {agentengine_sdk_python-0.6.4.dist-info → agentengine_sdk_python-0.7.0.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.7.0.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.7.0.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.7.0.dist-info/top_level.txt +2 -0
  7. ksadk/__init__.py +13 -0
  8. ksadk/__main__.py +4 -0
  9. ksadk/a2a/__init__.py +15 -0
  10. ksadk/a2a/card_builder.py +64 -0
  11. ksadk/a2a/client.py +309 -0
  12. ksadk/a2a/executor.py +201 -0
  13. ksadk/a2a/server.py +79 -0
  14. ksadk/agents/__init__.py +20 -0
  15. ksadk/agents/base.py +370 -0
  16. ksadk/agents/context.py +38 -0
  17. ksadk/agents/event.py +35 -0
  18. ksadk/agents/loop_agent.py +71 -0
  19. ksadk/agents/parallel_agent.py +109 -0
  20. ksadk/agents/runner_adapter.py +24 -0
  21. ksadk/agents/sequential_agent.py +34 -0
  22. ksadk/api/__init__.py +3 -0
  23. ksadk/api/client.py +2246 -0
  24. ksadk/builders/__init__.py +20 -0
  25. ksadk/builders/base.py +66 -0
  26. ksadk/builders/code_builder.py +1990 -0
  27. ksadk/builders/container_builder.py +786 -0
  28. ksadk/builders/framework_requirements.py +59 -0
  29. ksadk/builders/ks3_uploader.py +389 -0
  30. ksadk/builders/mcp_builder.py +476 -0
  31. ksadk/builders/requirements_utils.py +75 -0
  32. ksadk/cli/__init__.py +531 -0
  33. ksadk/cli/__main__.py +4 -0
  34. ksadk/cli/agent_ref.py +204 -0
  35. ksadk/cli/cmd_a2a.py +167 -0
  36. ksadk/cli/cmd_agent.py +201 -0
  37. ksadk/cli/cmd_build.py +270 -0
  38. ksadk/cli/cmd_completion.py +304 -0
  39. ksadk/cli/cmd_config.py +758 -0
  40. ksadk/cli/cmd_create.py +2304 -0
  41. ksadk/cli/cmd_dashboard.py +900 -0
  42. ksadk/cli/cmd_deploy.py +704 -0
  43. ksadk/cli/cmd_destroy.py +345 -0
  44. ksadk/cli/cmd_files.py +1227 -0
  45. ksadk/cli/cmd_hermes.py +1263 -0
  46. ksadk/cli/cmd_invoke.py +1503 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1179 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3922 -0
  51. ksadk/cli/cmd_run.py +239 -0
  52. ksadk/cli/cmd_status.py +588 -0
  53. ksadk/cli/cmd_version.py +522 -0
  54. ksadk/cli/cmd_web.py +288 -0
  55. ksadk/cli/deploy_utils.py +87 -0
  56. ksadk/cli/dry_run.py +214 -0
  57. ksadk/cli/env_options.py +82 -0
  58. ksadk/cli/error_utils.py +525 -0
  59. ksadk/cli/global_options.py +31 -0
  60. ksadk/cli/local_runtime.py +97 -0
  61. ksadk/cli/model_catalog.py +136 -0
  62. ksadk/cli/network_options.py +412 -0
  63. ksadk/cli/resource_common.py +621 -0
  64. ksadk/cli/storage.py +84 -0
  65. ksadk/cli/ui.py +431 -0
  66. ksadk/cli/workflow_common.py +552 -0
  67. ksadk/common/__init__.py +14 -0
  68. ksadk/common/aicp_env.py +128 -0
  69. ksadk/common/auth.py +190 -0
  70. ksadk/common/constants.py +84 -0
  71. ksadk/common/llm_utils.py +61 -0
  72. ksadk/configs/__init__.py +61 -0
  73. ksadk/configs/env_registry.py +343 -0
  74. ksadk/configs/global_config.py +200 -0
  75. ksadk/configs/settings.py +706 -0
  76. ksadk/conversations/__init__.py +95 -0
  77. ksadk/conversations/attachment_storage.py +379 -0
  78. ksadk/conversations/attachments.py +774 -0
  79. ksadk/conversations/compaction_pipeline.py +387 -0
  80. ksadk/conversations/compaction_prompt.py +128 -0
  81. ksadk/conversations/context.py +303 -0
  82. ksadk/conversations/message_projection.py +269 -0
  83. ksadk/conversations/model_context.py +370 -0
  84. ksadk/conversations/model_options.py +136 -0
  85. ksadk/conversations/normalize.py +446 -0
  86. ksadk/conversations/reasoning_markup.py +91 -0
  87. ksadk/conversations/run_kinds.py +61 -0
  88. ksadk/conversations/run_status.py +53 -0
  89. ksadk/conversations/runtime.py +5276 -0
  90. ksadk/conversations/semantic_summary.py +359 -0
  91. ksadk/conversations/session_title.py +254 -0
  92. ksadk/deployment/__init__.py +83 -0
  93. ksadk/deployment/agent_access.py +226 -0
  94. ksadk/deployment/base.py +229 -0
  95. ksadk/deployment/manager.py +332 -0
  96. ksadk/deployment/providers/__init__.py +10 -0
  97. ksadk/deployment/providers/serverless.py +1115 -0
  98. ksadk/deployment/registry.py +120 -0
  99. ksadk/deployment/state.py +78 -0
  100. ksadk/deployment/ui_config.py +21 -0
  101. ksadk/detection/__init__.py +7 -0
  102. ksadk/detection/detector.py +431 -0
  103. ksadk/detection/mcp_detector.py +250 -0
  104. ksadk/hermes_terminal.py +467 -0
  105. ksadk/identity/__init__.py +17 -0
  106. ksadk/identity/resolver.py +385 -0
  107. ksadk/knowledge_base/__init__.py +62 -0
  108. ksadk/knowledge_base/adk_tool.py +47 -0
  109. ksadk/knowledge_base/client.py +297 -0
  110. ksadk/knowledge_base/langchain_tool.py +55 -0
  111. ksadk/knowledge_base/service.py +66 -0
  112. ksadk/knowledge_base/tool.py +50 -0
  113. ksadk/markdown.py +169 -0
  114. ksadk/mcp_runtime/__init__.py +231 -0
  115. ksadk/memory/__init__.py +57 -0
  116. ksadk/memory/adk/__init__.py +51 -0
  117. ksadk/memory/adk/backends/__init__.py +5 -0
  118. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  119. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  120. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  121. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  122. ksadk/memory/adk/long_term_memory.py +273 -0
  123. ksadk/memory/adk/resilient_session_service.py +268 -0
  124. ksadk/memory/adk/short_term_memory.py +304 -0
  125. ksadk/memory/adk_tool.py +31 -0
  126. ksadk/memory/backends/__init__.py +6 -0
  127. ksadk/memory/backends/base.py +103 -0
  128. ksadk/memory/backends/memory.py +112 -0
  129. ksadk/memory/backends/redis.py +146 -0
  130. ksadk/memory/langchain_tool.py +39 -0
  131. ksadk/memory/ltm_backend_factory.py +24 -0
  132. ksadk/memory/manager.py +215 -0
  133. ksadk/memory/service.py +172 -0
  134. ksadk/memory/tool.py +96 -0
  135. ksadk/model_policy.py +223 -0
  136. ksadk/openclaw_gateway.py +378 -0
  137. ksadk/runners/__init__.py +8 -0
  138. ksadk/runners/adk_runner.py +1994 -0
  139. ksadk/runners/base_runner.py +305 -0
  140. ksadk/runners/deepagents_runner.py +13 -0
  141. ksadk/runners/factory.py +73 -0
  142. ksadk/runners/langchain_runner.py +751 -0
  143. ksadk/runners/langgraph_runner.py +985 -0
  144. ksadk/runners/patch_langchain.py +187 -0
  145. ksadk/runners/remote_runner.py +792 -0
  146. ksadk/runners/usage_accumulator.py +38 -0
  147. ksadk/runners/utils/__init__.py +19 -0
  148. ksadk/runners/utils/langfuse.py +230 -0
  149. ksadk/runners/utils/loader.py +62 -0
  150. ksadk/runtime_context.py +166 -0
  151. ksadk/runtime_state.py +25 -0
  152. ksadk/sandbox/__init__.py +28 -0
  153. ksadk/sandbox/backends/__init__.py +9 -0
  154. ksadk/sandbox/backends/e2b.py +154 -0
  155. ksadk/sandbox/backends/local_process.py +131 -0
  156. ksadk/sandbox/base.py +101 -0
  157. ksadk/sandbox/factory.py +53 -0
  158. ksadk/sandbox/registry.py +187 -0
  159. ksadk/server/__init__.py +7 -0
  160. ksadk/server/api_models.py +73 -0
  161. ksadk/server/app.py +3931 -0
  162. ksadk/server/static/assets/ArtifactsPanel-D-SSn2ee.js +1 -0
  163. ksadk/server/static/assets/CodeBlock-P16VOLYi.js +9 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  165. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  166. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  171. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  172. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  177. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  189. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  190. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  195. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  204. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  205. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  207. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  208. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  210. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  213. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  214. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  215. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  218. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  219. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  221. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  222. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  223. ksadk/server/static/assets/MathMessageMarkdown-CdGiQWHR.js +8 -0
  224. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  225. ksadk/server/static/assets/MermaidBlock-IOcal8cm.js +303 -0
  226. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  227. ksadk/server/static/assets/NativeTerminalPanel-DGSDWsei.js +1 -0
  228. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  229. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  230. ksadk/server/static/assets/arc-BA13sHc9.js +1 -0
  231. ksadk/server/static/assets/architecture-7EHR7CIX-BvUlsA6l.js +1 -0
  232. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-DzJzgVoL.js +36 -0
  233. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  234. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  235. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  236. ksadk/server/static/assets/blockDiagram-GPEHLZMM-UTdVcZhn.js +132 -0
  237. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  238. ksadk/server/static/assets/c4Diagram-AAUBKEIU-Dix0GD4m.js +10 -0
  239. ksadk/server/static/assets/channel-CTuydARX.js +1 -0
  240. ksadk/server/static/assets/chunk-2J33WTMH-C2JxuZ42.js +1 -0
  241. ksadk/server/static/assets/chunk-4BX2VUAB-Be57QPgD.js +1 -0
  242. ksadk/server/static/assets/chunk-55IACEB6-WjSuy4nv.js +1 -0
  243. ksadk/server/static/assets/chunk-727SXJPM-BOovP-b5.js +206 -0
  244. ksadk/server/static/assets/chunk-AQP2D5EJ-DOmZNmWj.js +231 -0
  245. ksadk/server/static/assets/chunk-FMBD7UC4-DzwlodkU.js +15 -0
  246. ksadk/server/static/assets/chunk-ND2GUHAM-DMqAikEU.js +1 -0
  247. ksadk/server/static/assets/chunk-QZHKN3VN-BnCydivS.js +1 -0
  248. ksadk/server/static/assets/classDiagram-4FO5ZUOK-BNHg45Be.js +1 -0
  249. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-BNHg45Be.js +1 -0
  250. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  251. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  252. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  253. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  254. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  255. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  256. ksadk/server/static/assets/cose-bilkent-S5V4N54A-Zhy2GBnP.js +1 -0
  257. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  258. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  259. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  260. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  261. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  262. ksadk/server/static/assets/dagre-BM42HDAG-CbKrtIUz.js +4 -0
  263. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  264. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  265. ksadk/server/static/assets/diagram-2AECGRRQ-BRApgQRK.js +43 -0
  266. ksadk/server/static/assets/diagram-5GNKFQAL-D0xbnDiK.js +10 -0
  267. ksadk/server/static/assets/diagram-KO2AKTUF-CVugVI9L.js +3 -0
  268. ksadk/server/static/assets/diagram-LMA3HP47-DozUGgee.js +24 -0
  269. ksadk/server/static/assets/diagram-OG6HWLK6-ZOYsKlru.js +24 -0
  270. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  271. ksadk/server/static/assets/dist-2hInLS_J.js +9 -0
  272. ksadk/server/static/assets/dist-8EEyGgDx.js +1 -0
  273. ksadk/server/static/assets/dist-8_SfK1IP.js +1 -0
  274. ksadk/server/static/assets/dist-B0NP_Z0z.js +23 -0
  275. ksadk/server/static/assets/dist-BIJVDMuB.js +1 -0
  276. ksadk/server/static/assets/dist-BmlMPsCc.js +2 -0
  277. ksadk/server/static/assets/dist-BrCcQ47T.js +1 -0
  278. ksadk/server/static/assets/dist-BssVmjIo.js +6 -0
  279. ksadk/server/static/assets/dist-C3HIIaN5.js +1 -0
  280. ksadk/server/static/assets/dist-CPBtqRTW.js +1 -0
  281. ksadk/server/static/assets/dist-CkEKJFtk.js +1 -0
  282. ksadk/server/static/assets/dist-D-JMdWPQ.js +1 -0
  283. ksadk/server/static/assets/dist-D-xOD048.js +1 -0
  284. ksadk/server/static/assets/dist-D57wnGWd.js +1 -0
  285. ksadk/server/static/assets/dist-DL_NKc_z.js +1 -0
  286. ksadk/server/static/assets/dist-DMezvBGJ.js +1 -0
  287. ksadk/server/static/assets/dist-DmFaq_Iy.js +1 -0
  288. ksadk/server/static/assets/dist-Dp0k7bWI.js +1 -0
  289. ksadk/server/static/assets/dist-DpKtt4Bo.js +1 -0
  290. ksadk/server/static/assets/dist-DyOkZmze.js +11 -0
  291. ksadk/server/static/assets/dist-DyWsb78Q.js +1 -0
  292. ksadk/server/static/assets/dist-gX6GOLKq.js +1 -0
  293. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  294. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  295. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  296. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  297. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  298. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  299. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  300. ksadk/server/static/assets/erDiagram-TEJ5UH35-Bk-9bgE5.js +85 -0
  301. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  302. ksadk/server/static/assets/eventmodeling-FCH6USID-DsAgWnlf.js +1 -0
  303. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  304. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  305. ksadk/server/static/assets/flowDiagram-I6XJVG4X-Dn9kZVuZ.js +162 -0
  306. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  307. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  308. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BGxXlJqm.js +292 -0
  309. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  310. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  311. ksadk/server/static/assets/gitGraph-WXDBUCRP-BIao9Yjg.js +1 -0
  312. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-C7Q0X-wi.js +106 -0
  313. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  314. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  315. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  316. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  317. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  318. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  319. ksadk/server/static/assets/index-C00Lwg3L.js +165 -0
  320. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  321. ksadk/server/static/assets/info-J43DQDTF-CyipqGxU.js +1 -0
  322. ksadk/server/static/assets/infoDiagram-5YYISTIA-BO_CSqq5.js +2 -0
  323. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  324. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-eYLPLd46.js +70 -0
  325. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  326. ksadk/server/static/assets/journeyDiagram-JHISSGLW-De9geSb0.js +139 -0
  327. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  328. ksadk/server/static/assets/kanban-definition-UN3LZRKU-Cs80kQto.js +89 -0
  329. ksadk/server/static/assets/katex-DSrCFD8n.js +265 -0
  330. ksadk/server/static/assets/linear-CN9sbKTF.js +1 -0
  331. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  332. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  333. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  334. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  335. ksadk/server/static/assets/mermaid-parser.core-DlgSBU8l.js +161 -0
  336. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-9afz7Oug.js +96 -0
  337. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  338. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  339. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  340. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  341. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  342. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  343. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  344. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  345. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  346. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  347. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  348. ksadk/server/static/assets/packet-YPE3B663-CGkyRxlg.js +1 -0
  349. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  350. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  351. ksadk/server/static/assets/pie-LRSECV5Y-M0uWAf4n.js +1 -0
  352. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPv_VstN.js +30 -0
  353. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  354. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  355. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  356. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  357. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  358. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  359. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  360. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  361. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-o77wZ1XK.js +7 -0
  362. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  363. ksadk/server/static/assets/radar-GUYGQ44K-Bdbm24-x.js +1 -0
  364. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-BYVw81VC.js +84 -0
  365. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  366. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  367. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-B7nZFMKT.js +40 -0
  368. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  369. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  370. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-BGRRrFw5.js +162 -0
  371. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  372. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  373. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  374. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  375. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  376. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  377. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  378. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  379. ksadk/server/static/assets/stateDiagram-AJRCARHV-BUfHCoPs.js +1 -0
  380. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-8xBN_gLM.js +1 -0
  381. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  382. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  383. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  384. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  385. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  386. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  387. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  388. ksadk/server/static/assets/timeline-definition-PNZ67QCA-FbCTGrf9.js +120 -0
  389. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  390. ksadk/server/static/assets/treeView-BLDUP644-npMo0ak1.js +1 -0
  391. ksadk/server/static/assets/treemap-LRROVOQU-CHdzrrdo.js +1 -0
  392. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  393. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  394. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  395. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  396. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  397. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  398. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  399. ksadk/server/static/assets/vennDiagram-CIIHVFJN-DWgwtPsJ.js +34 -0
  400. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  401. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  402. ksadk/server/static/assets/wardley-L42UT6IY-BEQz7wyy.js +1 -0
  403. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-2x8G-tTM.js +78 -0
  404. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  405. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  406. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  407. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-Drma3AYl.js +7 -0
  408. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  409. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  410. ksadk/server/static/favicon.svg +1 -0
  411. ksadk/server/static/icons.svg +24 -0
  412. ksadk/server/static/index.html +14 -0
  413. ksadk/server/terminal_sessions.py +551 -0
  414. ksadk/sessions/__init__.py +279 -0
  415. ksadk/sessions/base.py +354 -0
  416. ksadk/sessions/continuity.py +337 -0
  417. ksadk/sessions/errors.py +7 -0
  418. ksadk/sessions/in_memory.py +273 -0
  419. ksadk/sessions/local_service.py +949 -0
  420. ksadk/sessions/postgres_service.py +901 -0
  421. ksadk/sessions/resilience.py +52 -0
  422. ksadk/sessions/resilient.py +360 -0
  423. ksadk/sessions/sqlite_service.py +13 -0
  424. ksadk/skills/__init__.py +9 -0
  425. ksadk/skills/loader.py +46 -0
  426. ksadk/skills/models.py +120 -0
  427. ksadk/skills/package_store.py +104 -0
  428. ksadk/skills/runtime/__init__.py +17 -0
  429. ksadk/skills/runtime/agent.py +183 -0
  430. ksadk/skills/runtime/artifacts.py +39 -0
  431. ksadk/skills/runtime/backends/__init__.py +1 -0
  432. ksadk/skills/runtime/backends/disabled.py +8 -0
  433. ksadk/skills/runtime/backends/e2b.py +168 -0
  434. ksadk/skills/runtime/backends/local.py +95 -0
  435. ksadk/skills/runtime/base.py +103 -0
  436. ksadk/skills/runtime/executor.py +219 -0
  437. ksadk/skills/runtime/factory.py +37 -0
  438. ksadk/skills/runtime/loader.py +131 -0
  439. ksadk/skills/runtime/registry.py +150 -0
  440. ksadk/skills/runtime/request.py +67 -0
  441. ksadk/skills/service_client.py +239 -0
  442. ksadk/skills/service_env.py +58 -0
  443. ksadk/skills/tool_defs.py +221 -0
  444. ksadk/terminal_client.py +69 -0
  445. ksadk/terminal_exec_policy.py +229 -0
  446. ksadk/tools/__init__.py +17 -0
  447. ksadk/tools/gateway.py +230 -0
  448. ksadk/tools/result_budget.py +154 -0
  449. ksadk/toolsets/__init__.py +854 -0
  450. ksadk/toolsets/_langchain.py +11 -0
  451. ksadk/toolsets/platform.py +93 -0
  452. ksadk/toolsets/sandbox.py +310 -0
  453. ksadk/toolsets/skills.py +217 -0
  454. ksadk/toolsets/web.py +266 -0
  455. ksadk/toolsets/workspace.py +917 -0
  456. ksadk/toolsets/workspace_state.py +44 -0
  457. ksadk/tracing/__init__.py +37 -0
  458. ksadk/tracing/exporters/__init__.py +1 -0
  459. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  460. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  461. ksadk/tracing/setup.py +892 -0
  462. ksadk/tracing/span_utils.py +114 -0
  463. ksadk/tui/__init__.py +27 -0
  464. ksadk/tui/loop.py +1877 -0
  465. ksadk/tui/stream_render.py +68 -0
  466. ksadk/ui_config.py +168 -0
  467. ksadk/version.py +4 -0
  468. ksadk_runtime_common/__init__.py +20 -0
  469. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  470. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  471. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  472. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  473. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  474. ksadk_runtime_common/memory_backend/registry.py +56 -0
  475. ksadk_runtime_common/memory_backend/render.py +71 -0
  476. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  477. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  478. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  479. ksadk_runtime_common/workspace_files/constants.py +9 -0
  480. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  481. ksadk_runtime_common/workspace_files/preview.py +96 -0
  482. ksadk_runtime_common/workspace_files/router.py +254 -0
  483. agentengine_sdk_python/__init__.py +0 -3
  484. agentengine_sdk_python-0.6.4.dist-info/METADATA +0 -48
  485. agentengine_sdk_python-0.6.4.dist-info/RECORD +0 -5
  486. agentengine_sdk_python-0.6.4.dist-info/top_level.txt +0 -1
@@ -0,0 +1,758 @@
1
+ import os
2
+ from pathlib import Path
3
+ import re
4
+ import click
5
+ from dotenv import dotenv_values
6
+ import questionary
7
+ from questionary import Style
8
+ import yaml
9
+
10
+ from ksadk.cli.error_utils import (
11
+ abort_with_cli_error,
12
+ cancelled_error,
13
+ ensure_json_output_supported,
14
+ usage_error,
15
+ )
16
+ from ksadk.cli.resource_common import CONTEXT_SETTINGS, build_result_envelope, build_status_envelope
17
+ from ksadk.cli.ui import (
18
+ emit_json,
19
+ is_color_disabled,
20
+ is_json_output,
21
+ is_stdout_tty,
22
+ output_option as cli_output_option,
23
+ print_error,
24
+ print_info,
25
+ print_kv,
26
+ print_rule,
27
+ print_success,
28
+ print_title,
29
+ print_warn,
30
+ )
31
+
32
+ # 自定义样式,确保选中项高亮可见
33
+ custom_style = Style([
34
+ ('qmark', 'fg:#5f819d bold'), # 略深一点的蓝青色
35
+ ('question', 'bold'),
36
+ ('answer', 'fg:#69f0ae bold'), # 浅绿色 (替代深红)
37
+ ('pointer', 'fg:#fbc02d bold'), # 略深的金色/暗黄色
38
+ ('highlighted', 'fg:#fbc02d bold'), # 同上
39
+ ('selected', 'fg:#69f0ae'), # 浅绿色
40
+ ('separator', 'fg:#69f0ae'), # 浅绿色
41
+ ('instruction', ''),
42
+ ('text', ''),
43
+ ('disabled', 'fg:#858585 italic')
44
+ ])
45
+
46
+
47
+ def _questionary_style():
48
+ return None if is_color_disabled() else custom_style
49
+
50
+
51
+ def _ensure_interactive_command(command: str, *, hints: list[str]) -> None:
52
+ if is_stdout_tty():
53
+ return
54
+ abort_with_cli_error(
55
+ usage_error(
56
+ f"`{command}` 需要交互式终端 (TTY)。",
57
+ hints=hints,
58
+ ),
59
+ argv=command.split()[1:],
60
+ )
61
+
62
+
63
+ def _load_env_file(path: Path) -> dict:
64
+ """Safely load .env file if exists"""
65
+ if path.exists():
66
+ # 使用 utf-8-sig 自动处理 BOM,确保 Windows 兼容性
67
+ return dotenv_values(path, encoding="utf-8-sig")
68
+ return {}
69
+
70
+
71
+ def _update_env_file(path: Path, updates: dict):
72
+ """Update .env file preserving existing keys/comments where possible"""
73
+ lines = []
74
+ if path.exists():
75
+ # 使用 utf-8-sig 自动处理 BOM,确保 Windows 兼容性
76
+ content = path.read_text(encoding="utf-8-sig")
77
+ lines = content.splitlines()
78
+
79
+ # Track which keys we've updated
80
+ updated_keys = set()
81
+ new_lines = []
82
+
83
+ for line in lines:
84
+ stripped = line.strip()
85
+ # Skip comments and empty lines
86
+ if not stripped or stripped.startswith('#'):
87
+ new_lines.append(line)
88
+ continue
89
+
90
+ # Parse key=value
91
+ if '=' in stripped:
92
+ key = stripped.split('=', 1)[0].strip()
93
+ if key in updates:
94
+ new_lines.append(f"{key}={updates[key]}")
95
+ updated_keys.add(key)
96
+ else:
97
+ new_lines.append(line)
98
+ else:
99
+ new_lines.append(line)
100
+
101
+ # Append new keys
102
+ added_new = False
103
+ for key, value in updates.items():
104
+ if key not in updated_keys and value:
105
+ # Add a newline before new keys if the file wasn't empty and didn't end with one
106
+ if not added_new and lines and lines[-1].strip():
107
+ new_lines.append("")
108
+ new_lines.append(f"{key}={value}")
109
+ added_new = True
110
+
111
+ # 使用 utf-8-sig 编码 (带 BOM),确保 Windows 程序正确识别为 UTF-8
112
+ path.write_text("\n".join(new_lines) + "\n", encoding="utf-8-sig")
113
+
114
+
115
+ def _load_yaml_file(path: Path) -> dict:
116
+ if not path.exists():
117
+ return {}
118
+ try:
119
+ with open(path, "r", encoding="utf-8-sig") as f:
120
+ return yaml.safe_load(f) or {}
121
+ except Exception:
122
+ return {}
123
+
124
+
125
+ def _default_project_config_path() -> Path:
126
+ canonical = Path("agentengine.yaml")
127
+ if canonical.exists():
128
+ return canonical
129
+ legacy = Path("ksadk.yaml")
130
+ if legacy.exists():
131
+ return legacy
132
+ return canonical
133
+
134
+
135
+ def _stringify_value(value) -> str:
136
+ if isinstance(value, (dict, list, tuple)):
137
+ return yaml.safe_dump(value, default_flow_style=True, allow_unicode=True).strip()
138
+ return str(value)
139
+
140
+
141
+ _ENV_VAR_KEY_PATTERN = re.compile(r"^[A-Z_][A-Z0-9_]*$")
142
+
143
+
144
+ def _is_env_assignment_key(key: str) -> bool:
145
+ return bool(_ENV_VAR_KEY_PATTERN.fullmatch(key))
146
+
147
+
148
+ def _parse_set_items(set_items: tuple) -> tuple[dict, dict, list[str]]:
149
+ """Parse KEY=VALUE assignments into project/env updates."""
150
+ updates_yaml = {}
151
+ updates_env = {}
152
+ invalid_items: list[str] = []
153
+
154
+ for item in set_items:
155
+ if "=" not in item:
156
+ invalid_items.append(str(item))
157
+ continue
158
+
159
+ key, value = item.split("=", 1)
160
+ key = key.strip()
161
+ value = value.strip()
162
+
163
+ if _is_env_assignment_key(key):
164
+ updates_env[key] = value
165
+ if key == "KSYUN_REGION":
166
+ updates_yaml["region"] = value
167
+ elif key == "region":
168
+ updates_yaml["region"] = value
169
+ updates_env["KSYUN_REGION"] = value
170
+ else:
171
+ updates_yaml[key] = value
172
+ return updates_yaml, updates_env, invalid_items
173
+
174
+
175
+ def _apply_set_command(set_items: tuple, output_path: Path, env_path: Path, is_global: bool) -> dict:
176
+ """Apply non-interactive config mutations and return a structured summary."""
177
+ updates_yaml, updates_env, invalid_items = _parse_set_items(set_items)
178
+ if not updates_yaml and not updates_env and invalid_items:
179
+ raise usage_error(
180
+ "至少提供一个有效的 KEY=VALUE 配置项。",
181
+ hints=["示例: `agentengine config set region=cn-beijing-6 OPENAI_MODEL_NAME=glm-5.2`"],
182
+ )
183
+
184
+ result = {
185
+ "project_config_path": str(output_path),
186
+ "project_env_path": str(env_path),
187
+ "updated_project_keys": [],
188
+ "updated_env_keys": [],
189
+ "invalid_items": invalid_items,
190
+ "global_updated": False,
191
+ "global_config_path": None,
192
+ }
193
+
194
+ if updates_env:
195
+ _update_env_file(env_path, updates_env)
196
+ result["updated_env_keys"] = sorted(updates_env.keys())
197
+
198
+ if updates_yaml:
199
+ current_yaml = _load_yaml_file(output_path)
200
+ current_yaml.update(updates_yaml)
201
+
202
+ with open(output_path, "w", encoding="utf-8-sig") as f:
203
+ yaml.dump(current_yaml, f, default_flow_style=False, allow_unicode=True)
204
+ result["updated_project_keys"] = sorted(updates_yaml.keys())
205
+
206
+ if is_global:
207
+ from ksadk.configs.global_config import (
208
+ build_global_config_from_env,
209
+ get_global_config_path
210
+ )
211
+
212
+ from ksadk.configs.global_config import get_env_from_global_config, save_global_config
213
+
214
+ current_global_env = get_env_from_global_config()
215
+ current_global_env.update(updates_env)
216
+ if "region" in updates_yaml and "KSYUN_REGION" not in current_global_env:
217
+ current_global_env["KSYUN_REGION"] = updates_yaml["region"]
218
+ new_global_config = build_global_config_from_env(current_global_env)
219
+ if save_global_config(new_global_config):
220
+ result["global_updated"] = True
221
+ result["global_config_path"] = str(get_global_config_path())
222
+ return result
223
+
224
+
225
+ def _collect_config_snapshot(output_path: Path, env_path: Path) -> dict:
226
+ from ksadk.configs.global_config import get_env_from_global_config, get_global_config_path, load_global_config
227
+
228
+ project_config = _load_yaml_file(output_path)
229
+ project_env = {k: v for k, v in _load_env_file(env_path).items() if v not in (None, "")}
230
+ global_config = load_global_config()
231
+ global_env = get_env_from_global_config()
232
+ effective_env = dict(global_env)
233
+ effective_env.update(project_env)
234
+ return {
235
+ "project_config_path": str(output_path),
236
+ "project_env_path": str(env_path),
237
+ "global_config_path": str(get_global_config_path()),
238
+ "project_config": project_config,
239
+ "project_env": project_env,
240
+ "global_config": global_config,
241
+ "global_env": global_env,
242
+ "effective_env": effective_env,
243
+ }
244
+
245
+
246
+ def _render_config_snapshot(snapshot: dict) -> None:
247
+ emit_json(build_status_envelope(resource="config", item=snapshot))
248
+
249
+
250
+ def _render_config_snapshot_pretty(snapshot: dict) -> None:
251
+ print_title("配置概览")
252
+ print_kv("项目配置文件", snapshot["project_config_path"])
253
+ print_kv("环境文件", snapshot["project_env_path"])
254
+ print_kv("全局配置文件", snapshot["global_config_path"])
255
+
256
+ print_rule("项目配置")
257
+ if snapshot["project_config"]:
258
+ for key, value in snapshot["project_config"].items():
259
+ print_kv(str(key), _stringify_value(value))
260
+ else:
261
+ print_info("未检测到项目配置。")
262
+
263
+ print_rule("项目环境变量")
264
+ if snapshot["project_env"]:
265
+ for key, value in snapshot["project_env"].items():
266
+ print_kv(str(key), _stringify_value(value))
267
+ else:
268
+ print_info("未检测到项目 .env 配置。")
269
+
270
+ print_rule("全局配置")
271
+ if snapshot["global_env"]:
272
+ for key, value in snapshot["global_env"].items():
273
+ print_kv(str(key), _stringify_value(value))
274
+ else:
275
+ print_info("未检测到全局配置。")
276
+
277
+ print_rule("生效环境变量")
278
+ if snapshot["effective_env"]:
279
+ for key, value in snapshot["effective_env"].items():
280
+ print_kv(str(key), _stringify_value(value))
281
+ else:
282
+ print_info("当前没有可用的生效环境变量。")
283
+
284
+
285
+ def _render_config_set_result(result: dict) -> None:
286
+ emit_json(
287
+ build_result_envelope(
288
+ resource="config",
289
+ action="set",
290
+ result=result,
291
+ hints=[],
292
+ )
293
+ )
294
+
295
+
296
+ def _render_config_set_result_pretty(result: dict) -> None:
297
+ print_success("配置已更新")
298
+ print_kv("项目配置文件", result["project_config_path"])
299
+ print_kv("环境文件", result["project_env_path"])
300
+ if result["updated_project_keys"]:
301
+ print_kv("更新的项目键", ", ".join(result["updated_project_keys"]))
302
+ if result["updated_env_keys"]:
303
+ print_kv("更新的环境变量", ", ".join(result["updated_env_keys"]))
304
+ if result["invalid_items"]:
305
+ print_warn(f"已忽略无效配置项: {', '.join(result['invalid_items'])}")
306
+ if result["global_updated"]:
307
+ print_kv("全局配置", result["global_config_path"] or "~/.agentengine/settings.json")
308
+
309
+
310
+ def _run_config_set_command(*, set_items: tuple, output_path: Path, env_path: Path, is_global: bool) -> dict:
311
+ if not set_items:
312
+ raise usage_error(
313
+ "请至少提供一个 KEY=VALUE 配置项。",
314
+ hints=["示例: `agentengine config set region=cn-beijing-6 OPENAI_MODEL_NAME=glm-5.2`"],
315
+ )
316
+ return _apply_set_command(set_items, output_path, env_path, is_global)
317
+
318
+ def run_config_wizard(config_file: str | None, set_items: tuple, is_global: bool):
319
+ """通过交互式向导配置 agentengine.yaml 和 .env 文件
320
+
321
+ 支持:
322
+ 1. 配置 Agent 基础信息 (名称、框架等)
323
+ 2. 配置 模型服务 (API Key, Base URL)
324
+ 3. 配置 云厂商凭证 (KSYUN AK/SK)
325
+
326
+ 参数:
327
+ --set: 非交互式设置配置项 (如 --set name=MyAgent --set KSYUN_REGION=cn-beijing-6)
328
+ --global: 强制更新全局配置 (~/.agentengine/settings.json)
329
+ """
330
+ output_path = Path(config_file) if config_file else _default_project_config_path()
331
+ env_path = Path(".env")
332
+
333
+ # === 0. 处理 --set 非交互模式 ===
334
+ if set_items:
335
+ print_warn("`agentengine config wizard --set ...` 是兼容入口,推荐改用 `agentengine config set KEY=VALUE ...`。")
336
+ result = _run_config_set_command(
337
+ set_items=set_items,
338
+ output_path=output_path,
339
+ env_path=env_path,
340
+ is_global=is_global,
341
+ )
342
+ if is_json_output():
343
+ _render_config_set_result(result)
344
+ else:
345
+ _render_config_set_result_pretty(result)
346
+ return
347
+
348
+ ensure_json_output_supported(
349
+ "agentengine config wizard",
350
+ suggestion="请改用 `agentengine config show --output json` 或 `agentengine config set KEY=VALUE`。",
351
+ )
352
+ _ensure_interactive_command(
353
+ "agentengine config wizard",
354
+ hints=[
355
+ "查看当前配置请使用 `agentengine config show`。",
356
+ "非交互修改请使用 `agentengine config set KEY=VALUE ...`。",
357
+ ],
358
+ )
359
+ print_title("AgentEngine 配置向导")
360
+
361
+ # === 1. 加载现有配置 ===
362
+ existing_config = {}
363
+ if output_path.exists():
364
+ try:
365
+ # 使用 utf-8-sig 自动处理 BOM,确保 Windows 兼容性
366
+ with open(output_path, 'r', encoding='utf-8-sig') as f:
367
+ existing_config = yaml.safe_load(f) or {}
368
+ print_info(f"检测到现有配置文件: {output_path}")
369
+ except Exception:
370
+ pass
371
+
372
+ existing_env = _load_env_file(env_path)
373
+ if existing_env:
374
+ print_info(f"检测到现有环境变量: {env_path}")
375
+
376
+ print_rule()
377
+
378
+ # Helper to clean code and handle Ctrl+C
379
+ def _ask_or_exit(question):
380
+ result = question.ask()
381
+ if result is None:
382
+ raise cancelled_error("取消配置")
383
+ return result
384
+
385
+ new_config = {}
386
+ new_env = {}
387
+
388
+ # === 2. 基础配置 (agentengine.yaml) ===
389
+ print_rule("基础配置")
390
+
391
+ # 智能默认值: 优先读文件 -> 其次用目录名 -> 最后 my-agent
392
+ default_name = existing_config.get('name')
393
+ if not default_name:
394
+ default_name = Path.cwd().name
395
+
396
+ new_config['name'] = _ask_or_exit(questionary.text(
397
+ "Agent 名称:",
398
+ default=default_name,
399
+ style=_questionary_style()
400
+ ))
401
+
402
+ new_config['description'] = _ask_or_exit(questionary.text(
403
+ "Agent 描述:",
404
+ default=existing_config.get('description', ''),
405
+ style=_questionary_style()
406
+ ))
407
+
408
+ frameworks = ['langgraph', 'langchain', 'deepagents', 'adk', 'openclaw']
409
+ default_framework = existing_config.get('framework', 'langgraph')
410
+ if default_framework and default_framework not in frameworks:
411
+ frameworks.append(default_framework)
412
+ new_config['framework'] = _ask_or_exit(questionary.select(
413
+ "选择开发框架:",
414
+ choices=frameworks,
415
+ default=default_framework,
416
+ style=_questionary_style()
417
+ ))
418
+
419
+ print_rule()
420
+
421
+ # === 3. 模型配置 (.env) ===
422
+ print_rule("模型配置")
423
+ print_info("配置用于推理的大模型服务 (OpenAI 兼容接口)")
424
+
425
+ # 向后兼容: 如果是从旧版模板生成的,可能包含 'your-api-key-here' 占位符,视为空
426
+ default_api_key = existing_env.get('OPENAI_API_KEY', '')
427
+ if default_api_key == "your-api-key-here":
428
+ default_api_key = ""
429
+
430
+ new_env['OPENAI_API_KEY'] = _ask_or_exit(questionary.password(
431
+ "API Key (OPENAI_API_KEY):",
432
+ default=default_api_key,
433
+ style=_questionary_style()
434
+ ))
435
+
436
+ new_env['OPENAI_BASE_URL'] = _ask_or_exit(questionary.text(
437
+ "Base URL (OPENAI_BASE_URL) [选填,默认使用金山云星流平台URL]:",
438
+ default=existing_env.get('OPENAI_BASE_URL', ''),
439
+ style=_questionary_style()
440
+ ))
441
+
442
+ new_env['OPENAI_MODEL_NAME'] = _ask_or_exit(questionary.text(
443
+ "模型名称 (OPENAI_MODEL_NAME) [选填,默认使用金山云星流平台glm-5.2]:",
444
+ default=existing_env.get('OPENAI_MODEL_NAME', ''),
445
+ style=_questionary_style()
446
+ ))
447
+
448
+ print_rule()
449
+
450
+ # === 4. 云厂商配置 (.env) ===
451
+ print_rule("金山云配置 (可选)")
452
+ print_info("用于 agentengine deploy 部署到云端环境")
453
+
454
+ should_config_ksyun = _ask_or_exit(questionary.confirm(
455
+ "是否配置金山云凭证?",
456
+ default=bool(existing_env.get('KSYUN_ACCESS_KEY')),
457
+ style=_questionary_style()
458
+ ))
459
+
460
+ if should_config_ksyun:
461
+ new_env['KSYUN_ACCESS_KEY'] = _ask_or_exit(questionary.password(
462
+ "Access Key (AK):",
463
+ default=existing_env.get('KSYUN_ACCESS_KEY', ''),
464
+ style=_questionary_style()
465
+ ))
466
+
467
+ new_env['KSYUN_SECRET_KEY'] = _ask_or_exit(questionary.password(
468
+ "Secret Key (SK):",
469
+ default=existing_env.get('KSYUN_SECRET_KEY', ''),
470
+ style=_questionary_style()
471
+ ))
472
+
473
+ new_env['KSYUN_ACCOUNT_ID'] = _ask_or_exit(questionary.text(
474
+ "Account ID (账户ID):",
475
+ default=existing_env.get('KSYUN_ACCOUNT_ID', ''),
476
+ style=_questionary_style()
477
+ ))
478
+
479
+
480
+
481
+ # 内部默认区域逻辑
482
+ default_region = existing_env.get('KSYUN_REGION')
483
+ if not default_region:
484
+ default_region = existing_config.get('region', 'cn-beijing-6')
485
+
486
+ # 标准区域列表
487
+ standard_regions = ['cn-beijing-6', 'cn-guangzhou-1']
488
+ CUSTOM_OPTION = "⚙️ Custom (手动输入,金山云自定义区域请参考文档确认是否支持)"
489
+
490
+ choices = standard_regions.copy()
491
+
492
+ # Idempotency: 如果现有值是自定义的(比如 pre-online),加入列表作为默认选项,防止报错且方便确认
493
+ if default_region and default_region not in standard_regions:
494
+ choices.append(default_region)
495
+
496
+ choices.append(CUSTOM_OPTION)
497
+
498
+ selected_region = _ask_or_exit(questionary.select(
499
+ "默认区域 (Region):",
500
+ choices=choices,
501
+ default=default_region if default_region in choices else standard_regions[0],
502
+ style=_questionary_style()
503
+ ))
504
+
505
+ # 如果选择了自定义,或者是点击了之前保留的自定义值,这里逻辑是这样的:
506
+ # 1. 如果选了标准值 -> 直接用
507
+ # 2. 如果选了 CUSTOM_OPTION -> 弹框让用户输
508
+ # 3. 如果选了列表里已有的自定义值 (如 pre-online) -> 直接用
509
+
510
+ if selected_region == CUSTOM_OPTION:
511
+ selected_region = _ask_or_exit(questionary.text(
512
+ "请输入区域 Code (如 cn-shanghai-2):",
513
+ default=default_region if default_region not in standard_regions else "",
514
+ style=_questionary_style()
515
+ ))
516
+
517
+ new_env['KSYUN_REGION'] = selected_region
518
+
519
+ # 同步回 agentengine.yaml 的 region 字段,保持一致
520
+ new_config['region'] = new_env['KSYUN_REGION']
521
+ else:
522
+ # 如果不配置,保留原值或设为默认
523
+ new_config['region'] = existing_config.get('region', 'cn-beijing-6')
524
+
525
+ print_rule()
526
+
527
+ # === 4.5 容器镜像仓库认证 (仅 container 模式需要) ===
528
+ print_rule("容器镜像部署 (可选)")
529
+ print_info("如果计划使用 container 模式 (agentengine build -m container),需要配置镜像仓库认证")
530
+
531
+ should_config_registry = _ask_or_exit(questionary.confirm(
532
+ "是否使用 container 模式部署?",
533
+ default=bool(existing_env.get('KCR_USERNAME')),
534
+ style=_questionary_style()
535
+ ))
536
+
537
+ if should_config_registry:
538
+ new_env['KCR_USERNAME'] = _ask_or_exit(questionary.text(
539
+ "KCR 用户名 (企业版请填写访问凭证用户名):",
540
+ default=existing_env.get('KCR_USERNAME', ''),
541
+ style=_questionary_style()
542
+ ))
543
+
544
+ new_env['KCR_PASSWORD'] = _ask_or_exit(questionary.password(
545
+ "KCR 密码或 Token:",
546
+ default=existing_env.get('KCR_PASSWORD', ''),
547
+ style=_questionary_style()
548
+ ))
549
+
550
+ default_registry = existing_env.get('KCR_REGISTRY', '')
551
+ custom_registry = _ask_or_exit(questionary.text(
552
+ "镜像仓库地址 [选填,如: agenthzzqy-vpc.ksyunkcr.com/testagent-pub]:",
553
+ default=default_registry,
554
+ style=_questionary_style()
555
+ ))
556
+
557
+ if custom_registry:
558
+ new_env['KCR_REGISTRY'] = custom_registry
559
+
560
+ print_info("提示:")
561
+ print_info("个人版 KCR 可留空 KCR_USERNAME,运行时使用 KSYUN_ACCOUNT_ID 作为用户名兜底")
562
+ print_info("企业版 KCR 和第三方镜像仓库必须配置 KCR_USERNAME + KCR_PASSWORD")
563
+ print_info("KCR 访问凭证获取: https://kcr.console.ksyun.com/ → 访问凭证")
564
+
565
+ print_rule()
566
+
567
+ # === 5. 写入文件 ===
568
+
569
+ # 5.1 构造完整的 YAML (保留原有的其他配置)
570
+ final_config = existing_config.copy()
571
+ final_config.update(new_config)
572
+
573
+ # 确保结构完整 (补全 config 命令中未询问但必须的字段,如果不存在的话)
574
+ if 'entry_point' not in final_config:
575
+ final_config['entry_point'] = f"{new_config['name'].replace('-', '_')}/agent.py"
576
+ if 'agent_variable' not in final_config:
577
+ final_config['agent_variable'] = "root_agent"
578
+ if 'version' not in final_config:
579
+ final_config['version'] = "1.0.0"
580
+
581
+ # 5.2 写入 agentengine.yaml
582
+ # 使用 utf-8-sig 编码 (带 BOM),确保 Windows 程序正确识别为 UTF-8
583
+ with open(output_path, 'w', encoding='utf-8-sig') as f:
584
+ # 简单的字典转 YAML 可能丢失注释,但这是预期行为
585
+ # 为了更好的体验,我们手动排版几个关键字段,其他用 dump
586
+
587
+ f.write(f"# AgentEngine Project Config\n")
588
+ f.write(f"name: {final_config['name']}\n")
589
+ f.write(f"version: \"{final_config.get('version', '1.0.0')}\"\n\n")
590
+
591
+ f.write(f"# Framework\n")
592
+ f.write(f"framework: {final_config['framework']}\n")
593
+ f.write(f"entry_point: {final_config['entry_point']}\n")
594
+ f.write(f"agent_variable: {final_config['agent_variable']}\n\n")
595
+
596
+ f.write(f"# Deployment\n")
597
+ f.write(f"region: {final_config.get('region', 'cn-beijing-6')}\n")
598
+
599
+ # 处理其他复杂对象如 resources, scaling 等,如果存在
600
+ remaining = {k: v for k, v in final_config.items() if k not in [
601
+ 'name', 'version', 'framework', 'entry_point', 'agent_variable', 'region'
602
+ ]}
603
+ if remaining:
604
+ f.write("\n# Advanced Settings\n")
605
+ yaml.dump(remaining, f, default_flow_style=False)
606
+
607
+ # 5.3 写入 .env
608
+ _update_env_file(env_path, new_env)
609
+
610
+ print_success("配置完成")
611
+ print_kv("配置文件", str(output_path))
612
+ print_kv("环境凭证", str(env_path))
613
+
614
+ # 5.4 处理全局配置保存逻辑
615
+ print_rule()
616
+ from ksadk.configs.global_config import (
617
+ save_global_config,
618
+ build_global_config_from_env,
619
+ get_global_config_path,
620
+ global_config_exists,
621
+ )
622
+
623
+ should_save_global = False
624
+
625
+ # 情况1: 用户显式指定 --global -> 总是保存 (或确认后保存)
626
+ if is_global:
627
+ should_save_global = True
628
+
629
+ # 情况2: 全局配置不存在 -> 首次运行,提示保存
630
+ elif not global_config_exists():
631
+ should_save_global = _ask_or_exit(questionary.confirm(
632
+ "是否保存到全局配置 (后续新项目可自动复用)?",
633
+ default=True,
634
+ style=_questionary_style()
635
+ ))
636
+
637
+ # 情况3: 全局配置已存在 且 未指定 --global -> 静默跳过,不打扰用户
638
+ else:
639
+ should_save_global = False
640
+
641
+ if should_save_global:
642
+ global_config = build_global_config_from_env(new_env)
643
+ if save_global_config(global_config):
644
+ print_success(f"已保存到全局配置: {get_global_config_path()}")
645
+ else:
646
+ print_warn("保存全局配置失败")
647
+
648
+
649
+ @click.group("config", context_settings=CONTEXT_SETTINGS, invoke_without_command=True)
650
+ @click.option("--set", "-s", "set_items", multiple=True, hidden=True, help="(兼容) 设置配置项 key=value")
651
+ @click.option("--global", "is_global", is_flag=True, default=False, hidden=True, help="(兼容) 强制更新全局配置")
652
+ @cli_output_option(hidden=True)
653
+ @click.pass_context
654
+ def config(ctx: click.Context, set_items: tuple, is_global: bool, output_mode: str | None):
655
+ """配置命令组。
656
+
657
+ 直接运行 `agentengine config` 会进入向导。
658
+ 标准子命令为 `wizard` / `show` / `set` / `model`。
659
+ """
660
+ _ = output_mode
661
+ if ctx.invoked_subcommand is not None:
662
+ return
663
+
664
+ if set_items:
665
+ print_warn("`agentengine config --set ...` 是兼容入口,推荐改用 `agentengine config set KEY=VALUE ...`。")
666
+ result = _run_config_set_command(
667
+ set_items=set_items,
668
+ output_path=_default_project_config_path(),
669
+ env_path=Path(".env"),
670
+ is_global=is_global,
671
+ )
672
+ if is_json_output():
673
+ _render_config_set_result(result)
674
+ else:
675
+ _render_config_set_result_pretty(result)
676
+ return
677
+
678
+ ensure_json_output_supported(
679
+ "agentengine config",
680
+ suggestion="请改用 `agentengine config show --output json` 或 `agentengine config set KEY=VALUE`。",
681
+ )
682
+ run_config_wizard(config_file=None, set_items=(), is_global=is_global)
683
+
684
+
685
+ @config.command("wizard", context_settings=CONTEXT_SETTINGS)
686
+ @click.option("--file", "config_file", default=None, help="配置文件路径(默认自动复用 agentengine.yaml/ksadk.yaml)")
687
+ @click.option('--set', '-s', 'set_items', multiple=True, help='设置配置项 key=value')
688
+ @click.option('--global', 'is_global', is_flag=True, default=False, help='强制更新全局配置')
689
+ @cli_output_option(hidden=True)
690
+ def config_wizard(config_file: str | None, set_items: tuple, is_global: bool, output_mode: str | None):
691
+ """通过交互式向导配置项目。"""
692
+ _ = output_mode
693
+ run_config_wizard(config_file=config_file, set_items=set_items, is_global=is_global)
694
+
695
+
696
+ @config.command("show", context_settings=CONTEXT_SETTINGS)
697
+ @cli_output_option()
698
+ def config_show(output_mode: str | None):
699
+ """查看项目配置、全局配置与当前生效环境变量。"""
700
+ _ = output_mode
701
+ snapshot = _collect_config_snapshot(_default_project_config_path(), Path(".env"))
702
+ if is_json_output():
703
+ _render_config_snapshot(snapshot)
704
+ else:
705
+ _render_config_snapshot_pretty(snapshot)
706
+
707
+
708
+ @config.command("set", context_settings=CONTEXT_SETTINGS)
709
+ @click.argument("set_items", nargs=-1)
710
+ @click.option("--global", "is_global", is_flag=True, default=False, help="同时更新全局配置")
711
+ @cli_output_option()
712
+ def config_set(set_items: tuple, is_global: bool, output_mode: str | None):
713
+ """非交互式设置配置项。
714
+
715
+ \b
716
+ 示例:
717
+ agentengine config set region=cn-beijing-6
718
+ agentengine config set OPENAI_MODEL_NAME=glm-5.2 OPENAI_BASE_URL=https://example.com/v1
719
+ agentengine config set KSYUN_REGION=cn-beijing-6 --global
720
+ """
721
+ _ = output_mode
722
+ result = _run_config_set_command(
723
+ set_items=set_items,
724
+ output_path=_default_project_config_path(),
725
+ env_path=Path(".env"),
726
+ is_global=is_global,
727
+ )
728
+ if is_json_output():
729
+ _render_config_set_result(result)
730
+ else:
731
+ _render_config_set_result_pretty(result)
732
+
733
+
734
+ @config.command("model", context_settings=CONTEXT_SETTINGS)
735
+ @click.option("--multi", is_flag=True, help="交互式多选模型,并按当前框架写入模型 allowlist")
736
+ @click.option(
737
+ "--env",
738
+ "env_models",
739
+ default=None,
740
+ help="按模型列表生成环境变量,逗号分隔;首个模型作为默认模型,不写入 .env",
741
+ )
742
+ @click.option(
743
+ "--framework",
744
+ type=click.Choice(["auto", "openclaw", "hermes", "generic"], case_sensitive=False),
745
+ default="auto",
746
+ show_default=True,
747
+ help="allowlist 变量选择策略;auto 会读取当前目录框架",
748
+ )
749
+ def config_model(multi: bool, env_models: str | None, framework: str):
750
+ """切换默认模型。"""
751
+ if not env_models:
752
+ ensure_json_output_supported(
753
+ "agentengine config model",
754
+ suggestion="请改用 `agentengine config show --output json` 查看当前配置。",
755
+ )
756
+ from ksadk.cli.cmd_model import run_model_command
757
+
758
+ run_model_command(multi=multi, env_models=env_models, framework=framework)