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,136 @@
1
+ """OpenAI-compatible model catalog helpers for product runtimes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Mapping
6
+
7
+ import httpx
8
+
9
+ from ksadk.conversations.model_context import normalize_model_metadata
10
+
11
+
12
+ def _models_url(api_base: str) -> str:
13
+ base = str(api_base or "").strip().rstrip("/")
14
+ if base.endswith("/models"):
15
+ return base
16
+ if base.endswith("/v1"):
17
+ return f"{base}/models"
18
+ return f"{base}/v1/models"
19
+
20
+
21
+ def _extract_catalog_items(payload: Any) -> list[Any]:
22
+ if isinstance(payload, list):
23
+ return payload
24
+ if not isinstance(payload, Mapping):
25
+ return []
26
+
27
+ data = payload.get("data")
28
+ if isinstance(data, list):
29
+ return data
30
+ if isinstance(data, Mapping):
31
+ for key in ("models", "Models", "items", "Items", "data"):
32
+ value = data.get(key)
33
+ if isinstance(value, list):
34
+ return value
35
+
36
+ nested = payload.get("Data")
37
+ if isinstance(nested, Mapping):
38
+ for key in ("Models", "models", "Items", "items", "data"):
39
+ value = nested.get(key)
40
+ if isinstance(value, list):
41
+ return value
42
+
43
+ for key in ("models", "Models", "items", "Items"):
44
+ value = payload.get(key)
45
+ if isinstance(value, list):
46
+ return value
47
+
48
+ if payload.get("id") or payload.get("name"):
49
+ return [payload]
50
+ return []
51
+
52
+
53
+ def _model_identity_candidates(raw_model: Any) -> set[str]:
54
+ if isinstance(raw_model, Mapping):
55
+ values = [
56
+ raw_model.get("id"),
57
+ raw_model.get("name"),
58
+ raw_model.get("model"),
59
+ raw_model.get("display_name"),
60
+ raw_model.get("displayName"),
61
+ ]
62
+ else:
63
+ values = [raw_model]
64
+
65
+ candidates: set[str] = set()
66
+ for value in values:
67
+ text = str(value or "").strip()
68
+ if not text:
69
+ continue
70
+ candidates.add(text)
71
+ if "/" in text:
72
+ candidates.add(text.split("/", 1)[1])
73
+ return candidates
74
+
75
+
76
+ def find_model_in_catalog(raw_models: list[Any], model: str | None) -> Any | None:
77
+ requested = _model_identity_candidates(model)
78
+ if not requested:
79
+ return None
80
+ requested_lower = {item.lower() for item in requested}
81
+ for raw_model in raw_models:
82
+ identities = _model_identity_candidates(raw_model)
83
+ if identities & requested:
84
+ return raw_model
85
+ if {item.lower() for item in identities} & requested_lower:
86
+ return raw_model
87
+ return None
88
+
89
+
90
+ async def fetch_provider_model_catalog(
91
+ *,
92
+ api_base: str | None,
93
+ api_key: str | None = None,
94
+ timeout: float = 10.0,
95
+ ) -> list[dict[str, Any]]:
96
+ """Fetch and normalize an OpenAI-compatible `/v1/models` catalog.
97
+
98
+ The function intentionally treats provider failures as "no catalog" so deploy
99
+ commands can keep working with explicit env/config fallback.
100
+ """
101
+
102
+ if not api_base:
103
+ return []
104
+ headers = {}
105
+ if api_key:
106
+ headers["Authorization"] = f"Bearer {api_key}"
107
+
108
+ try:
109
+ async with httpx.AsyncClient(verify=False, timeout=timeout) as client:
110
+ response = await client.get(_models_url(api_base), headers=headers)
111
+ response.raise_for_status()
112
+ payload = response.json()
113
+ except Exception:
114
+ return []
115
+
116
+ normalized: list[dict[str, Any]] = []
117
+ for raw_model in _extract_catalog_items(payload):
118
+ item = normalize_model_metadata(raw_model)
119
+ item["_provider_raw_model"] = raw_model if isinstance(raw_model, Mapping) else {"id": str(raw_model)}
120
+ normalized.append(item)
121
+ return normalized
122
+
123
+
124
+ async def fetch_provider_model_metadata(
125
+ *,
126
+ api_base: str | None,
127
+ api_key: str | None,
128
+ model: str | None,
129
+ timeout: float = 10.0,
130
+ ) -> dict[str, Any] | None:
131
+ catalog = await fetch_provider_model_catalog(api_base=api_base, api_key=api_key, timeout=timeout)
132
+ raw_models = [item.get("_provider_raw_model") or item for item in catalog]
133
+ raw_match = find_model_in_catalog(raw_models, model)
134
+ if raw_match is None:
135
+ return None
136
+ return normalize_model_metadata(raw_match)
@@ -0,0 +1,412 @@
1
+ """Shared CLI helpers for AgentEngine network configuration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ from typing import TYPE_CHECKING, Any, Mapping, Optional
8
+
9
+ import click
10
+
11
+ from ksadk.cli.error_utils import validation_error
12
+ from ksadk.cli.ui import print_info, print_warn
13
+
14
+ if TYPE_CHECKING:
15
+ from ksadk.deployment.base import DeployTarget
16
+
17
+
18
+ NETWORK_OPTION_PARAMS = (
19
+ "enable_public_access",
20
+ "enable_vpc_access",
21
+ "vpc_id",
22
+ "subnet_id",
23
+ "security_group_id",
24
+ "availability_zone",
25
+ )
26
+
27
+ _VPC_ID_FIELDS = ("vpc_id", "subnet_id", "security_group_id")
28
+ _VPC_ID_LABELS = {
29
+ "vpc_id": "VpcId",
30
+ "subnet_id": "SubnetId",
31
+ "security_group_id": "SecurityGroupId",
32
+ }
33
+
34
+
35
+ def network_options(func):
36
+ """Attach common network options to a Click command."""
37
+ options = [
38
+ click.option(
39
+ "--enable-public-access/--disable-public-access",
40
+ default=None,
41
+ help="是否开启公网访问;创建时默认开启,更新已有 Agent 时未指定则保留现有配置(显式传入才覆盖)",
42
+ ),
43
+ click.option("--enable-vpc-access", is_flag=True, default=False, help="开启 VPC 私网访问"),
44
+ click.option("--vpc-id", default=None, help="VPC ID(开启 VPC 访问时必填)"),
45
+ click.option("--subnet-id", default=None, help="子网 ID(开启 VPC 访问时必填)"),
46
+ click.option("--security-group-id", default=None, help="安全组 ID(开启 VPC 访问时必填)"),
47
+ click.option("--availability-zone", default=None, help="可用区(可选)"),
48
+ ]
49
+ for option in reversed(options):
50
+ func = option(func)
51
+ return func
52
+
53
+
54
+ def network_cli_kwargs(
55
+ *,
56
+ enable_public_access: Optional[bool] = None,
57
+ enable_vpc_access: bool = False,
58
+ vpc_id: Optional[str] = None,
59
+ subnet_id: Optional[str] = None,
60
+ security_group_id: Optional[str] = None,
61
+ availability_zone: Optional[str] = None,
62
+ ) -> dict[str, Any]:
63
+ """Return normalized kwargs for passing between Click entrypoints and async functions."""
64
+ return {
65
+ "enable_public_access": enable_public_access,
66
+ "enable_vpc_access": bool(enable_vpc_access),
67
+ "vpc_id": vpc_id,
68
+ "subnet_id": subnet_id,
69
+ "security_group_id": security_group_id,
70
+ "availability_zone": availability_zone,
71
+ }
72
+
73
+
74
+ def extract_network_config(config: Mapping[str, Any] | None) -> dict[str, Any]:
75
+ """Read network from top-level `network` or `deploy.network`."""
76
+ if not isinstance(config, Mapping):
77
+ return {}
78
+ deploy_config = config.get("deploy") if isinstance(config.get("deploy"), Mapping) else {}
79
+ raw_network = config.get("network") or deploy_config.get("network") or {}
80
+ return dict(raw_network) if isinstance(raw_network, Mapping) else {}
81
+
82
+
83
+ def apply_network_config(config: Mapping[str, Any] | None, deploy_target: "DeployTarget") -> None:
84
+ """Apply file-based network config to a DeployTarget."""
85
+ raw_network = extract_network_config(config)
86
+ if not raw_network:
87
+ return
88
+
89
+ def _pick(*keys: str, default=None):
90
+ for key in keys:
91
+ if key in raw_network and raw_network[key] is not None:
92
+ return raw_network[key]
93
+ return default
94
+
95
+ _picked_public_access = _pick(
96
+ "enable_public_access", "enablePublicAccess", "EnablePublicAccess", default=None
97
+ )
98
+ if _picked_public_access is not None:
99
+ deploy_target.network.enable_public_access = bool(_picked_public_access)
100
+ deploy_target.network.enable_vpc_access = bool(
101
+ _pick("enable_vpc_access", "enableVpcAccess", "EnableVpcAccess", default=deploy_target.network.enable_vpc_access)
102
+ )
103
+ deploy_target.network.vpc_id = str(
104
+ _pick("vpc_id", "vpcId", "VpcId", default=deploy_target.network.vpc_id) or ""
105
+ ).strip()
106
+ deploy_target.network.subnet_id = str(
107
+ _pick("subnet_id", "subnetId", "SubnetId", default=deploy_target.network.subnet_id) or ""
108
+ ).strip()
109
+ deploy_target.network.security_group_id = str(
110
+ _pick(
111
+ "security_group_id",
112
+ "securityGroupId",
113
+ "SecurityGroupId",
114
+ default=deploy_target.network.security_group_id,
115
+ )
116
+ or ""
117
+ ).strip()
118
+ deploy_target.network.availability_zone = str(
119
+ _pick(
120
+ "availability_zone",
121
+ "availabilityZone",
122
+ "AvailabilityZone",
123
+ default=deploy_target.network.availability_zone,
124
+ )
125
+ or ""
126
+ ).strip()
127
+
128
+
129
+ def apply_network_cli_overrides(deploy_target: "DeployTarget", **network_kwargs: Any) -> None:
130
+ """Apply explicit CLI network overrides to a DeployTarget."""
131
+ if network_kwargs.get("enable_public_access") is not None:
132
+ deploy_target.network.enable_public_access = bool(network_kwargs["enable_public_access"])
133
+ if network_kwargs.get("enable_vpc_access"):
134
+ deploy_target.network.enable_vpc_access = True
135
+ for field in ("vpc_id", "subnet_id", "security_group_id", "availability_zone"):
136
+ value = network_kwargs.get(field)
137
+ if value is not None:
138
+ 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):
140
+ deploy_target.network.enable_vpc_access = True
141
+
142
+
143
+ def validate_deploy_target_network(deploy_target: "DeployTarget") -> None:
144
+ """Require VPC identifiers as an atomic group when VPC access is requested."""
145
+ values = {
146
+ "vpc_id": str(getattr(deploy_target.network, "vpc_id", "") or "").strip(),
147
+ "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(),
149
+ }
150
+ has_any_vpc_id = any(values.values())
151
+ if not (bool(getattr(deploy_target.network, "enable_vpc_access", False)) or has_any_vpc_id):
152
+ return
153
+ missing = [_VPC_ID_LABELS[field] for field, value in values.items() if not value]
154
+ if missing:
155
+ raise validation_error(
156
+ "开启 VPC 访问时必须同时提供 VpcId、SubnetId、SecurityGroupId。",
157
+ details={"missing": missing},
158
+ hints=[
159
+ "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`,或在配置文件 network/deploy.network 中同时设置这三个字段。",
160
+ "`--availability-zone` 是可选字段,不替代子网或安全组。",
161
+ ],
162
+ )
163
+
164
+
165
+ def resolve_deploy_target_network(
166
+ deploy_target: "DeployTarget",
167
+ *,
168
+ region: str | None = None,
169
+ dry_run: bool = False,
170
+ ) -> None:
171
+ """Fill optional network fields on a DeployTarget when they can be inferred."""
172
+ network = getattr(deploy_target, "network", None)
173
+ if network is None:
174
+ return
175
+ if str(getattr(network, "availability_zone", "") or "").strip():
176
+ return
177
+ if not bool(getattr(network, "enable_vpc_access", False)):
178
+ return
179
+ subnet_id = str(getattr(network, "subnet_id", "") or "").strip()
180
+ if not subnet_id or dry_run:
181
+ return
182
+ resolved_region = str(region or getattr(deploy_target, "region", "") or "").strip()
183
+ if not resolved_region:
184
+ return
185
+ availability_zone = _resolve_subnet_availability_zone(
186
+ subnet_id=subnet_id,
187
+ region=resolved_region,
188
+ )
189
+ if availability_zone:
190
+ network.availability_zone = availability_zone
191
+ print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
192
+ else:
193
+ print_warn(
194
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
195
+ "`--availability-zone`。"
196
+ )
197
+
198
+
199
+ def build_network_payload(**network_kwargs: Any) -> dict[str, Any] | None:
200
+ """Build lower-case network payload for AgentEngineClient create/update calls."""
201
+ payload: dict[str, Any] = {}
202
+ if network_kwargs.get("enable_public_access") is not None:
203
+ payload["enable_public_access"] = bool(network_kwargs["enable_public_access"])
204
+ if network_kwargs.get("enable_vpc_access"):
205
+ payload["enable_vpc_access"] = True
206
+ for field in ("vpc_id", "subnet_id", "security_group_id", "availability_zone"):
207
+ value = network_kwargs.get(field)
208
+ if value is not None and str(value or "").strip():
209
+ payload[field] = str(value or "").strip()
210
+ if not payload:
211
+ return None
212
+ if any(str(payload.get(field) or "").strip() for field in _VPC_ID_FIELDS):
213
+ payload["enable_vpc_access"] = True
214
+
215
+ _validate_network_payload(payload)
216
+ _fill_network_availability_zone(payload, network_kwargs)
217
+ return payload
218
+
219
+
220
+ def _validate_network_payload(payload: Mapping[str, Any]) -> None:
221
+ values = {field: str(payload.get(field) or "").strip() for field in _VPC_ID_FIELDS}
222
+ has_any_vpc_id = any(values.values())
223
+ if not (bool(payload.get("enable_vpc_access")) or has_any_vpc_id):
224
+ return
225
+ missing = [_VPC_ID_LABELS[field] for field, value in values.items() if not value]
226
+ if missing:
227
+ raise validation_error(
228
+ "开启 VPC 访问时必须同时提供 VpcId、SubnetId、SecurityGroupId。",
229
+ details={"missing": missing},
230
+ hints=[
231
+ "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`。",
232
+ "`--availability-zone` 是可选字段,不替代子网或安全组。",
233
+ ],
234
+ )
235
+
236
+
237
+ def _fill_network_availability_zone(payload: dict[str, Any], network_kwargs: Mapping[str, Any]) -> None:
238
+ if str(payload.get("availability_zone") or "").strip():
239
+ return
240
+ if not bool(payload.get("enable_vpc_access")):
241
+ return
242
+ subnet_id = str(payload.get("subnet_id") or "").strip()
243
+ if not subnet_id:
244
+ return
245
+ if bool(network_kwargs.get("dry_run")):
246
+ return
247
+ region = str(network_kwargs.get("region") or "").strip()
248
+ if not region:
249
+ return
250
+
251
+ availability_zone = _resolve_subnet_availability_zone(subnet_id=subnet_id, region=region)
252
+ if availability_zone:
253
+ payload["availability_zone"] = availability_zone
254
+ print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
255
+ else:
256
+ print_warn(
257
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
258
+ "`--availability-zone`。"
259
+ )
260
+
261
+
262
+ def _resolve_subnet_availability_zone(*, subnet_id: str, region: str) -> str | None:
263
+ subnet_id = str(subnet_id or "").strip()
264
+ region = str(region or "").strip()
265
+ if not subnet_id or not region:
266
+ return None
267
+
268
+ access_key, secret_key = _resolve_ksyun_credentials()
269
+ if not access_key or not secret_key:
270
+ return None
271
+
272
+ try:
273
+ VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile = _import_vpc_sdk()
274
+ except Exception as exc:
275
+ print_warn(f"缺少 VPC 子网查询 SDK,跳过可用区自动推断: {exc}")
276
+ return None
277
+
278
+ response = None
279
+ last_error: Exception | None = None
280
+ for endpoint, protocol in ((None, None), ("vpc.inner.api.ksyun.com", "http")):
281
+ if endpoint and not _should_retry_inner_vpc_endpoint(last_error):
282
+ break
283
+ try:
284
+ profile = ClientProfile(
285
+ httpProfile=HttpProfile(reqTimeout=10, endpoint=endpoint, protocol=protocol)
286
+ )
287
+ client = VpcClient(Credential(access_key, secret_key), region, profile)
288
+ request = DescribeSubnetsRequest()
289
+ request.SubnetId = {"1": subnet_id}
290
+ response = client.DescribeSubnets(request)
291
+ break
292
+ except Exception as exc:
293
+ last_error = exc
294
+
295
+ if response is None:
296
+ print_warn(f"查询子网 {subnet_id} 可用区失败,跳过自动推断: {last_error}")
297
+ return None
298
+
299
+ return _extract_subnet_availability_zone(response, subnet_id)
300
+
301
+
302
+ def _import_vpc_sdk():
303
+ from ksyun.client.vpc.v20160304.client import VpcClient
304
+ from ksyun.client.vpc.v20160304.models import DescribeSubnetsRequest
305
+ from ksyun.common.credential import Credential
306
+ from ksyun.common.profile.client_profile import ClientProfile
307
+ from ksyun.common.profile.http_profile import HttpProfile
308
+
309
+ return VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile
310
+
311
+
312
+ def _should_retry_inner_vpc_endpoint(error: Exception | None) -> bool:
313
+ if error is None:
314
+ return False
315
+ return "InnerAccountCanOnlyAccessThroughIntranet" in str(error)
316
+
317
+
318
+ def _resolve_ksyun_credentials() -> tuple[str, str]:
319
+ access_key = os.getenv("KSYUN_ACCESS_KEY") or os.getenv("KS3_ACCESS_KEY") or ""
320
+ secret_key = os.getenv("KSYUN_SECRET_KEY") or os.getenv("KS3_SECRET_KEY") or ""
321
+ if access_key and secret_key:
322
+ return access_key.strip(), secret_key.strip()
323
+
324
+ try:
325
+ from ksadk.configs.global_config import get_env_from_global_config
326
+
327
+ global_env = get_env_from_global_config()
328
+ except Exception:
329
+ global_env = {}
330
+
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 ""
333
+ return str(access_key or "").strip(), str(secret_key or "").strip()
334
+
335
+
336
+ def _extract_subnet_availability_zone(response: Any, subnet_id: str) -> str | None:
337
+ if isinstance(response, str):
338
+ try:
339
+ response = json.loads(response)
340
+ except json.JSONDecodeError:
341
+ return None
342
+ if not isinstance(response, Mapping):
343
+ return None
344
+
345
+ wanted_subnet_id = str(subnet_id or "").strip()
346
+ subnets = list(_iter_subnet_dicts(response))
347
+ for subnet in subnets:
348
+ current_subnet_id = _pick_text(
349
+ subnet,
350
+ "SubnetId",
351
+ "subnetId",
352
+ "subnet_id",
353
+ "id",
354
+ "Id",
355
+ )
356
+ if current_subnet_id and current_subnet_id != wanted_subnet_id:
357
+ continue
358
+ availability_zone = _pick_text(
359
+ subnet,
360
+ "AvailabilityZone",
361
+ "AvailabilityZoneName",
362
+ "availabilityZone",
363
+ "availabilityZoneName",
364
+ "availability_zone",
365
+ "availability_zone_name",
366
+ "Zone",
367
+ "zone",
368
+ )
369
+ if availability_zone:
370
+ return availability_zone
371
+
372
+ if len(subnets) == 1:
373
+ return _pick_text(
374
+ subnets[0],
375
+ "AvailabilityZone",
376
+ "AvailabilityZoneName",
377
+ "availabilityZone",
378
+ "availabilityZoneName",
379
+ "availability_zone",
380
+ "availability_zone_name",
381
+ "Zone",
382
+ "zone",
383
+ )
384
+ return None
385
+
386
+
387
+ def _iter_subnet_dicts(value: Any):
388
+ if isinstance(value, Mapping):
389
+ subnet_keys = ("SubnetId", "subnetId", "subnet_id")
390
+ zone_keys = (
391
+ "AvailabilityZone",
392
+ "AvailabilityZoneName",
393
+ "availabilityZone",
394
+ "availabilityZoneName",
395
+ "availability_zone",
396
+ "availability_zone_name",
397
+ )
398
+ if any(key in value for key in subnet_keys) or any(key in value for key in zone_keys):
399
+ yield value
400
+ for child in value.values():
401
+ yield from _iter_subnet_dicts(child)
402
+ elif isinstance(value, list):
403
+ for item in value:
404
+ yield from _iter_subnet_dicts(item)
405
+
406
+
407
+ def _pick_text(data: Mapping[str, Any], *keys: str) -> str:
408
+ for key in keys:
409
+ value = data.get(key)
410
+ if value is not None and str(value).strip():
411
+ return str(value).strip()
412
+ return ""