agentengine-sdk-python 0.6.2__py3-none-any.whl → 0.6.9__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 (490) hide show
  1. agentengine_sdk_python-0.6.9.dist-info/METADATA +179 -0
  2. agentengine_sdk_python-0.6.9.dist-info/RECORD +487 -0
  3. {agentengine_sdk_python-0.6.2.dist-info → agentengine_sdk_python-0.6.9.dist-info}/WHEEL +1 -1
  4. agentengine_sdk_python-0.6.9.dist-info/entry_points.txt +3 -0
  5. agentengine_sdk_python-0.6.9.dist-info/licenses/LICENSE +175 -0
  6. agentengine_sdk_python-0.6.9.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 +2227 -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 +2277 -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 +1259 -0
  46. ksadk/cli/cmd_invoke.py +1336 -0
  47. ksadk/cli/cmd_launch.py +564 -0
  48. ksadk/cli/cmd_mcp.py +1174 -0
  49. ksadk/cli/cmd_model.py +302 -0
  50. ksadk/cli/cmd_openclaw.py +3918 -0
  51. ksadk/cli/cmd_run.py +232 -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 +410 -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 +342 -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/model_context.py +360 -0
  83. ksadk/conversations/model_options.py +136 -0
  84. ksadk/conversations/normalize.py +446 -0
  85. ksadk/conversations/reasoning_markup.py +91 -0
  86. ksadk/conversations/run_kinds.py +61 -0
  87. ksadk/conversations/run_status.py +53 -0
  88. ksadk/conversations/runtime.py +5208 -0
  89. ksadk/conversations/semantic_summary.py +359 -0
  90. ksadk/conversations/session_title.py +254 -0
  91. ksadk/deployment/__init__.py +83 -0
  92. ksadk/deployment/agent_access.py +226 -0
  93. ksadk/deployment/base.py +229 -0
  94. ksadk/deployment/manager.py +332 -0
  95. ksadk/deployment/providers/__init__.py +10 -0
  96. ksadk/deployment/providers/serverless.py +1105 -0
  97. ksadk/deployment/registry.py +120 -0
  98. ksadk/deployment/state.py +78 -0
  99. ksadk/deployment/ui_config.py +21 -0
  100. ksadk/detection/__init__.py +7 -0
  101. ksadk/detection/detector.py +431 -0
  102. ksadk/detection/mcp_detector.py +250 -0
  103. ksadk/hermes_terminal.py +467 -0
  104. ksadk/identity/__init__.py +17 -0
  105. ksadk/identity/resolver.py +385 -0
  106. ksadk/knowledge_base/__init__.py +62 -0
  107. ksadk/knowledge_base/adk_tool.py +47 -0
  108. ksadk/knowledge_base/client.py +297 -0
  109. ksadk/knowledge_base/langchain_tool.py +55 -0
  110. ksadk/knowledge_base/service.py +66 -0
  111. ksadk/knowledge_base/tool.py +50 -0
  112. ksadk/markdown.py +169 -0
  113. ksadk/mcp_runtime/__init__.py +231 -0
  114. ksadk/memory/__init__.py +57 -0
  115. ksadk/memory/adk/__init__.py +51 -0
  116. ksadk/memory/adk/backends/__init__.py +5 -0
  117. ksadk/memory/adk/backends/base_ltm_backend.py +52 -0
  118. ksadk/memory/adk/backends/http_ltm_backend.py +183 -0
  119. ksadk/memory/adk/backends/inmemory_ltm_backend.py +96 -0
  120. ksadk/memory/adk/backends/sdk_ltm_backend.py +456 -0
  121. ksadk/memory/adk/long_term_memory.py +273 -0
  122. ksadk/memory/adk/short_term_memory.py +289 -0
  123. ksadk/memory/adk_tool.py +31 -0
  124. ksadk/memory/backends/__init__.py +6 -0
  125. ksadk/memory/backends/base.py +103 -0
  126. ksadk/memory/backends/memory.py +112 -0
  127. ksadk/memory/backends/redis.py +146 -0
  128. ksadk/memory/langchain_tool.py +39 -0
  129. ksadk/memory/ltm_backend_factory.py +24 -0
  130. ksadk/memory/manager.py +215 -0
  131. ksadk/memory/service.py +172 -0
  132. ksadk/memory/tool.py +96 -0
  133. ksadk/model_policy.py +223 -0
  134. ksadk/openclaw_gateway.py +378 -0
  135. ksadk/runners/__init__.py +8 -0
  136. ksadk/runners/adk_runner.py +1135 -0
  137. ksadk/runners/base_runner.py +305 -0
  138. ksadk/runners/deepagents_runner.py +13 -0
  139. ksadk/runners/factory.py +73 -0
  140. ksadk/runners/langchain_runner.py +539 -0
  141. ksadk/runners/langgraph_runner.py +852 -0
  142. ksadk/runners/patch_langchain.py +187 -0
  143. ksadk/runners/remote_runner.py +667 -0
  144. ksadk/runners/usage_accumulator.py +38 -0
  145. ksadk/runners/utils/__init__.py +19 -0
  146. ksadk/runners/utils/langfuse.py +230 -0
  147. ksadk/runners/utils/loader.py +62 -0
  148. ksadk/runtime_context.py +166 -0
  149. ksadk/runtime_state.py +25 -0
  150. ksadk/sandbox/__init__.py +28 -0
  151. ksadk/sandbox/backends/__init__.py +9 -0
  152. ksadk/sandbox/backends/e2b.py +154 -0
  153. ksadk/sandbox/backends/local_process.py +131 -0
  154. ksadk/sandbox/base.py +101 -0
  155. ksadk/sandbox/factory.py +53 -0
  156. ksadk/sandbox/registry.py +187 -0
  157. ksadk/server/__init__.py +7 -0
  158. ksadk/server/api_models.py +73 -0
  159. ksadk/server/app.py +3789 -0
  160. ksadk/server/static/assets/ArtifactsPanel-C0meuOdi.js +1 -0
  161. ksadk/server/static/assets/CodeBlock-BbI4HPtJ.js +9 -0
  162. ksadk/server/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  163. ksadk/server/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  164. ksadk/server/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  165. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  166. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  167. ksadk/server/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  168. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  169. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  170. ksadk/server/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  171. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  172. ksadk/server/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  173. ksadk/server/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  174. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  175. ksadk/server/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  176. ksadk/server/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  177. ksadk/server/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  178. ksadk/server/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  179. ksadk/server/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  180. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  181. ksadk/server/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  182. ksadk/server/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  183. ksadk/server/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  184. ksadk/server/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  185. ksadk/server/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  186. ksadk/server/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  187. ksadk/server/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  188. ksadk/server/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  189. ksadk/server/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  190. ksadk/server/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  191. ksadk/server/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  192. ksadk/server/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  193. ksadk/server/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  194. ksadk/server/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  195. ksadk/server/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  196. ksadk/server/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  197. ksadk/server/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  198. ksadk/server/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  199. ksadk/server/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  200. ksadk/server/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  201. ksadk/server/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  202. ksadk/server/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  203. ksadk/server/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  204. ksadk/server/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  205. ksadk/server/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  206. ksadk/server/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  207. ksadk/server/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  208. ksadk/server/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  209. ksadk/server/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  210. ksadk/server/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  211. ksadk/server/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  212. ksadk/server/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  213. ksadk/server/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  214. ksadk/server/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  215. ksadk/server/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  216. ksadk/server/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  217. ksadk/server/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  218. ksadk/server/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  219. ksadk/server/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  220. ksadk/server/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  221. ksadk/server/static/assets/MathMessageMarkdown-DMLQYoLp.js +8 -0
  222. ksadk/server/static/assets/MathMessageMarkdown-DeYh8QPr.css +1 -0
  223. ksadk/server/static/assets/MermaidBlock-DCR8WZ17.js +303 -0
  224. ksadk/server/static/assets/NativeTerminalPanel-CHOd7Rch.css +1 -0
  225. ksadk/server/static/assets/NativeTerminalPanel-CKUvWhUz.js +1 -0
  226. ksadk/server/static/assets/addon-fit-DthTIhi3.js +1 -0
  227. ksadk/server/static/assets/apl-CnwPGSsG.js +1 -0
  228. ksadk/server/static/assets/arc-bj2rZnP5.js +1 -0
  229. ksadk/server/static/assets/architecture-7EHR7CIX-Cr6Xz1_c.js +1 -0
  230. ksadk/server/static/assets/architectureDiagram-3BPJPVTR-2u1ltDIj.js +36 -0
  231. ksadk/server/static/assets/asciiarmor-qTkVPQu6.js +1 -0
  232. ksadk/server/static/assets/asn1-Dr8qZg38.js +1 -0
  233. ksadk/server/static/assets/asterisk-Bja0s6e1.js +1 -0
  234. ksadk/server/static/assets/blockDiagram-GPEHLZMM-D6fvdK20.js +132 -0
  235. ksadk/server/static/assets/brainfuck-D5EjA2JK.js +1 -0
  236. ksadk/server/static/assets/c4Diagram-AAUBKEIU-BK82L5n5.js +10 -0
  237. ksadk/server/static/assets/channel-BSSOwFIb.js +1 -0
  238. ksadk/server/static/assets/chunk-2J33WTMH-DLVdkeyQ.js +1 -0
  239. ksadk/server/static/assets/chunk-4BX2VUAB-BbwsYcbW.js +1 -0
  240. ksadk/server/static/assets/chunk-55IACEB6-DOairxzw.js +1 -0
  241. ksadk/server/static/assets/chunk-727SXJPM-hCO487gs.js +206 -0
  242. ksadk/server/static/assets/chunk-AQP2D5EJ-XU8vDOuG.js +231 -0
  243. ksadk/server/static/assets/chunk-FMBD7UC4-PrapyfMu.js +15 -0
  244. ksadk/server/static/assets/chunk-ND2GUHAM-CboKhTZ3.js +1 -0
  245. ksadk/server/static/assets/chunk-QZHKN3VN-XXpdiwUL.js +1 -0
  246. ksadk/server/static/assets/classDiagram-4FO5ZUOK-C5HvGiyK.js +1 -0
  247. ksadk/server/static/assets/classDiagram-v2-Q7XG4LA2-C5HvGiyK.js +1 -0
  248. ksadk/server/static/assets/clike-DHH8Ad3s.js +1 -0
  249. ksadk/server/static/assets/clojure-BflJGmDX.js +1 -0
  250. ksadk/server/static/assets/cmake-CyVbuzPu.js +1 -0
  251. ksadk/server/static/assets/cobol-B_OZ4V-R.js +1 -0
  252. ksadk/server/static/assets/coffeescript-B2pKbFk8.js +1 -0
  253. ksadk/server/static/assets/commonlisp-CcllspGY.js +1 -0
  254. ksadk/server/static/assets/cose-bilkent-S5V4N54A-_N8bJ-EU.js +1 -0
  255. ksadk/server/static/assets/crystal-M5-qzICs.js +1 -0
  256. ksadk/server/static/assets/css-CYpP4FRV.js +1 -0
  257. ksadk/server/static/assets/cypher-p9eYesGn.js +1 -0
  258. ksadk/server/static/assets/cytoscape.esm-DelgaX4f.js +321 -0
  259. ksadk/server/static/assets/d-BhMjBjQP.js +1 -0
  260. ksadk/server/static/assets/dagre-BM42HDAG-FoDlo5J2.js +4 -0
  261. ksadk/server/static/assets/dagre-Bx709z4p.js +1 -0
  262. ksadk/server/static/assets/defaultLocale-C8Fc0cco.js +1 -0
  263. ksadk/server/static/assets/diagram-2AECGRRQ-BBp6ebBw.js +43 -0
  264. ksadk/server/static/assets/diagram-5GNKFQAL-CqOvG1PR.js +10 -0
  265. ksadk/server/static/assets/diagram-KO2AKTUF-O9T3t6ba.js +3 -0
  266. ksadk/server/static/assets/diagram-LMA3HP47-CGG8ekBO.js +24 -0
  267. ksadk/server/static/assets/diagram-OG6HWLK6-4BmH1EEg.js +24 -0
  268. ksadk/server/static/assets/diff-ChtP43wD.js +1 -0
  269. ksadk/server/static/assets/dist-6kSZvCZh.js +1 -0
  270. ksadk/server/static/assets/dist-B67uF2uK.js +1 -0
  271. ksadk/server/static/assets/dist-BMKM66B4.js +1 -0
  272. ksadk/server/static/assets/dist-BVzcWa6D.js +1 -0
  273. ksadk/server/static/assets/dist-Bk1l05Ni.js +1 -0
  274. ksadk/server/static/assets/dist-BkJjNih3.js +1 -0
  275. ksadk/server/static/assets/dist-BmuTWcm7.js +9 -0
  276. ksadk/server/static/assets/dist-C2DKRFVK.js +1 -0
  277. ksadk/server/static/assets/dist-CWiTDN_V.js +6 -0
  278. ksadk/server/static/assets/dist-CZ6C3x8B.js +23 -0
  279. ksadk/server/static/assets/dist-CiZHB6ZW.js +1 -0
  280. ksadk/server/static/assets/dist-Cp1_jKwf.js +1 -0
  281. ksadk/server/static/assets/dist-Cwhk4lwI.js +2 -0
  282. ksadk/server/static/assets/dist-D5JGcxBx.js +11 -0
  283. ksadk/server/static/assets/dist-D99wf6_X.js +1 -0
  284. ksadk/server/static/assets/dist-DCpZrjaK.js +1 -0
  285. ksadk/server/static/assets/dist-DI-oVAXw.js +1 -0
  286. ksadk/server/static/assets/dist-DLMjL01k.js +1 -0
  287. ksadk/server/static/assets/dist-DLeM1OCK.js +1 -0
  288. ksadk/server/static/assets/dist-DM0rEQPk.js +1 -0
  289. ksadk/server/static/assets/dist-DbaH3p5h.js +1 -0
  290. ksadk/server/static/assets/dist-S4klkK5W.js +1 -0
  291. ksadk/server/static/assets/dockerfile-BLkNEvjs.js +1 -0
  292. ksadk/server/static/assets/dtd-DTF72YNO.js +1 -0
  293. ksadk/server/static/assets/dylan-C6jEEEk-.js +1 -0
  294. ksadk/server/static/assets/ebnf-D4c0_ac3.js +1 -0
  295. ksadk/server/static/assets/ecl-BSZaIHnp.js +1 -0
  296. ksadk/server/static/assets/eiffel-BEjRio4Q.js +1 -0
  297. ksadk/server/static/assets/elm-Cshzl8qu.js +1 -0
  298. ksadk/server/static/assets/erDiagram-TEJ5UH35-oJhaci7S.js +85 -0
  299. ksadk/server/static/assets/erlang-DaB2Rkuy.js +1 -0
  300. ksadk/server/static/assets/eventmodeling-FCH6USID-CIgwHJLL.js +1 -0
  301. ksadk/server/static/assets/factor-D7LVTn2l.js +1 -0
  302. ksadk/server/static/assets/fcl-ClOhbFR7.js +1 -0
  303. ksadk/server/static/assets/flowDiagram-I6XJVG4X-DtTmUan-.js +162 -0
  304. ksadk/server/static/assets/forth-Cezjo90N.js +1 -0
  305. ksadk/server/static/assets/fortran-Bt6PBEDR.js +1 -0
  306. ksadk/server/static/assets/ganttDiagram-6RSMTGT7-BSsb_eij.js +292 -0
  307. ksadk/server/static/assets/gas-BHEdbvp9.js +1 -0
  308. ksadk/server/static/assets/gherkin-oBAE_ms0.js +1 -0
  309. ksadk/server/static/assets/gitGraph-WXDBUCRP-BVAJ7uo0.js +1 -0
  310. ksadk/server/static/assets/gitGraphDiagram-PVQCEYII-BR5s6Pws.js +106 -0
  311. ksadk/server/static/assets/graphlib-B8gBHxth.js +1 -0
  312. ksadk/server/static/assets/groovy-BC3IOsC8.js +1 -0
  313. ksadk/server/static/assets/haskell-BRsoo5mP.js +1 -0
  314. ksadk/server/static/assets/haxe-DIz0ZZqd.js +1 -0
  315. ksadk/server/static/assets/http-CLVgA2GD.js +1 -0
  316. ksadk/server/static/assets/idl-BUZw3wgd.js +1 -0
  317. ksadk/server/static/assets/index-BH7-pC0B.js +165 -0
  318. ksadk/server/static/assets/index-DAURbCsP.css +1 -0
  319. ksadk/server/static/assets/info-J43DQDTF-MT80V4ge.js +1 -0
  320. ksadk/server/static/assets/infoDiagram-5YYISTIA-DYPc5cvh.js +2 -0
  321. ksadk/server/static/assets/init-D6jRqBbL.js +1 -0
  322. ksadk/server/static/assets/ishikawaDiagram-YF4QCWOH-MoBdALDg.js +70 -0
  323. ksadk/server/static/assets/javascript-9Tg8ixDm.js +1 -0
  324. ksadk/server/static/assets/journeyDiagram-JHISSGLW-DgLiQT8l.js +139 -0
  325. ksadk/server/static/assets/julia-CQfgDRfP.js +1 -0
  326. ksadk/server/static/assets/kanban-definition-UN3LZRKU-CsFx112F.js +89 -0
  327. ksadk/server/static/assets/katex-DRsiwpM2.js +265 -0
  328. ksadk/server/static/assets/linear-TNRQ5Orv.js +1 -0
  329. ksadk/server/static/assets/livescript-BXxG0Yva.js +1 -0
  330. ksadk/server/static/assets/lua-CiA1ziua.js +1 -0
  331. ksadk/server/static/assets/mathematica-u8YMmbU0.js +1 -0
  332. ksadk/server/static/assets/mbox-BEMVcqjs.js +1 -0
  333. ksadk/server/static/assets/mermaid-parser.core-D2eMVOgo.js +161 -0
  334. ksadk/server/static/assets/mindmap-definition-RKZ34NQL-BtByYFhL.js +96 -0
  335. ksadk/server/static/assets/mirc-C9zpzAZU.js +1 -0
  336. ksadk/server/static/assets/mllike-B45xgp2S.js +1 -0
  337. ksadk/server/static/assets/modelica-CqHI_q-D.js +1 -0
  338. ksadk/server/static/assets/mscgen-qgSLujhx.js +1 -0
  339. ksadk/server/static/assets/mumps-CW_TBmxz.js +1 -0
  340. ksadk/server/static/assets/nginx-BMaDbqW3.js +1 -0
  341. ksadk/server/static/assets/nsis-AQ_alPln.js +1 -0
  342. ksadk/server/static/assets/ntriples-d28e9m0E.js +1 -0
  343. ksadk/server/static/assets/octave-D2Q8cUp1.js +1 -0
  344. ksadk/server/static/assets/ordinal-hYBb2elL.js +1 -0
  345. ksadk/server/static/assets/oz-BwTct_5T.js +1 -0
  346. ksadk/server/static/assets/packet-YPE3B663-BLKhbXZB.js +1 -0
  347. ksadk/server/static/assets/pascal-Dp_KdFgX.js +1 -0
  348. ksadk/server/static/assets/perl-CdEHsPfU.js +1 -0
  349. ksadk/server/static/assets/pie-LRSECV5Y-DFOikjSY.js +1 -0
  350. ksadk/server/static/assets/pieDiagram-4H26LBE5-DPnuCB8c.js +30 -0
  351. ksadk/server/static/assets/pig-AF4Hwhju.js +1 -0
  352. ksadk/server/static/assets/powershell-CzG71I4L.js +1 -0
  353. ksadk/server/static/assets/properties-C357ku5U.js +1 -0
  354. ksadk/server/static/assets/protobuf-D1ij_kNL.js +1 -0
  355. ksadk/server/static/assets/pug-Bugr-47h.js +1 -0
  356. ksadk/server/static/assets/puppet-B4hC2X4m.js +1 -0
  357. ksadk/server/static/assets/python-BqYw9LYJ.js +1 -0
  358. ksadk/server/static/assets/q-B9NhS7L_.js +1 -0
  359. ksadk/server/static/assets/quadrantDiagram-W4KKPZXB-miFpCPv4.js +7 -0
  360. ksadk/server/static/assets/r-DADKenSm.js +1 -0
  361. ksadk/server/static/assets/radar-GUYGQ44K-095b1Ikw.js +1 -0
  362. ksadk/server/static/assets/requirementDiagram-4Y6WPE33-mjB_yYkW.js +84 -0
  363. ksadk/server/static/assets/rpm-gpDK5sbt.js +1 -0
  364. ksadk/server/static/assets/ruby-DsYpTuWg.js +1 -0
  365. ksadk/server/static/assets/sankeyDiagram-5OEKKPKP-D7hSlZZZ.js +40 -0
  366. ksadk/server/static/assets/sas-C2OyD2Y6.js +1 -0
  367. ksadk/server/static/assets/scheme-CyDdOh7e.js +1 -0
  368. ksadk/server/static/assets/sequenceDiagram-3UESZ5HK-D9Cx6hC3.js +162 -0
  369. ksadk/server/static/assets/shell-Du5Qg9im.js +1 -0
  370. ksadk/server/static/assets/sieve-BAxa3IjF.js +1 -0
  371. ksadk/server/static/assets/simple-mode-DRpGK0lJ.js +1 -0
  372. ksadk/server/static/assets/smalltalk-BLp5-jwC.js +1 -0
  373. ksadk/server/static/assets/solr-BBopId9w.js +1 -0
  374. ksadk/server/static/assets/sparql-Dz-mlCAC.js +1 -0
  375. ksadk/server/static/assets/spreadsheet-CTIncYxj.js +1 -0
  376. ksadk/server/static/assets/sql-DcCJ9jop.js +1 -0
  377. ksadk/server/static/assets/stateDiagram-AJRCARHV-D_zrg47o.js +1 -0
  378. ksadk/server/static/assets/stateDiagram-v2-BHNVJYJU-J9kCb0nC.js +1 -0
  379. ksadk/server/static/assets/stex-sDrdk2BW.js +1 -0
  380. ksadk/server/static/assets/stylus-DLLZ8dgm.js +1 -0
  381. ksadk/server/static/assets/swift-DKB6_1j6.js +1 -0
  382. ksadk/server/static/assets/tcl-BGfruO1u.js +1 -0
  383. ksadk/server/static/assets/textile-DWBqthVk.js +1 -0
  384. ksadk/server/static/assets/tiddlywiki-VlUiK86J.js +1 -0
  385. ksadk/server/static/assets/tiki-CxVlf5KZ.js +1 -0
  386. ksadk/server/static/assets/timeline-definition-PNZ67QCA-CwSec0Wa.js +120 -0
  387. ksadk/server/static/assets/toml-LvoKBwCs.js +1 -0
  388. ksadk/server/static/assets/treeView-BLDUP644-yinfJEY6.js +1 -0
  389. ksadk/server/static/assets/treemap-LRROVOQU-DosUqN1Q.js +1 -0
  390. ksadk/server/static/assets/troff-C2dAgh7P.js +1 -0
  391. ksadk/server/static/assets/ttcn-BePYh-hG.js +1 -0
  392. ksadk/server/static/assets/ttcn-cfg-CY0aot7Q.js +1 -0
  393. ksadk/server/static/assets/turtle-BDLWE2cD.js +1 -0
  394. ksadk/server/static/assets/vb-BthdM_4N.js +1 -0
  395. ksadk/server/static/assets/vbscript-D9f6rSsU.js +1 -0
  396. ksadk/server/static/assets/velocity-CqftRsjg.js +1 -0
  397. ksadk/server/static/assets/vennDiagram-CIIHVFJN-agCVobiF.js +34 -0
  398. ksadk/server/static/assets/verilog-D-x6ne0Z.js +1 -0
  399. ksadk/server/static/assets/vhdl-CMrOq2q1.js +1 -0
  400. ksadk/server/static/assets/wardley-L42UT6IY-Bvp7-5uH.js +1 -0
  401. ksadk/server/static/assets/wardleyDiagram-YWT4CUSO-TmrlhWNt.js +78 -0
  402. ksadk/server/static/assets/webidl-D5jiJvOU.js +1 -0
  403. ksadk/server/static/assets/xquery-fj_R-kMw.js +1 -0
  404. ksadk/server/static/assets/xterm-DooSxjI5.js +36 -0
  405. ksadk/server/static/assets/xychartDiagram-2RQKCTM6-DV71V-ah.js +7 -0
  406. ksadk/server/static/assets/yacas-CXXgtw0p.js +1 -0
  407. ksadk/server/static/assets/z80-CL1naaMV.js +1 -0
  408. ksadk/server/static/favicon.svg +1 -0
  409. ksadk/server/static/icons.svg +24 -0
  410. ksadk/server/static/index.html +14 -0
  411. ksadk/server/terminal_sessions.py +551 -0
  412. ksadk/sessions/__init__.py +283 -0
  413. ksadk/sessions/base.py +354 -0
  414. ksadk/sessions/continuity.py +313 -0
  415. ksadk/sessions/errors.py +7 -0
  416. ksadk/sessions/in_memory.py +273 -0
  417. ksadk/sessions/local_service.py +949 -0
  418. ksadk/sessions/postgres_service.py +838 -0
  419. ksadk/sessions/sqlite_service.py +13 -0
  420. ksadk/skills/__init__.py +9 -0
  421. ksadk/skills/loader.py +46 -0
  422. ksadk/skills/models.py +120 -0
  423. ksadk/skills/package_store.py +104 -0
  424. ksadk/skills/runtime/__init__.py +17 -0
  425. ksadk/skills/runtime/agent.py +183 -0
  426. ksadk/skills/runtime/artifacts.py +39 -0
  427. ksadk/skills/runtime/backends/__init__.py +1 -0
  428. ksadk/skills/runtime/backends/disabled.py +8 -0
  429. ksadk/skills/runtime/backends/e2b.py +168 -0
  430. ksadk/skills/runtime/backends/local.py +95 -0
  431. ksadk/skills/runtime/base.py +103 -0
  432. ksadk/skills/runtime/executor.py +219 -0
  433. ksadk/skills/runtime/factory.py +37 -0
  434. ksadk/skills/runtime/loader.py +131 -0
  435. ksadk/skills/runtime/registry.py +150 -0
  436. ksadk/skills/runtime/request.py +67 -0
  437. ksadk/skills/service_client.py +239 -0
  438. ksadk/skills/service_env.py +58 -0
  439. ksadk/skills/tool_defs.py +221 -0
  440. ksadk/terminal_client.py +69 -0
  441. ksadk/terminal_exec_policy.py +229 -0
  442. ksadk/tools/__init__.py +17 -0
  443. ksadk/tools/gateway.py +230 -0
  444. ksadk/tools/result_budget.py +154 -0
  445. ksadk/toolsets/__init__.py +852 -0
  446. ksadk/toolsets/_langchain.py +11 -0
  447. ksadk/toolsets/platform.py +93 -0
  448. ksadk/toolsets/sandbox.py +310 -0
  449. ksadk/toolsets/skills.py +217 -0
  450. ksadk/toolsets/web.py +266 -0
  451. ksadk/toolsets/workspace.py +878 -0
  452. ksadk/toolsets/workspace_state.py +44 -0
  453. ksadk/tracing/__init__.py +37 -0
  454. ksadk/tracing/exporters/__init__.py +1 -0
  455. ksadk/tracing/exporters/inmemory_exporter.py +116 -0
  456. ksadk/tracing/exporters/langfuse_exporter.py +445 -0
  457. ksadk/tracing/setup.py +829 -0
  458. ksadk/tracing/span_utils.py +114 -0
  459. ksadk/tui/__init__.py +12 -0
  460. ksadk/tui/app.py +400 -0
  461. ksadk/tui/clipboard.py +100 -0
  462. ksadk/tui/widgets/__init__.py +22 -0
  463. ksadk/tui/widgets/assistant.py +89 -0
  464. ksadk/tui/widgets/base.py +54 -0
  465. ksadk/tui/widgets/chat_input.py +246 -0
  466. ksadk/tui/widgets/history.py +156 -0
  467. ksadk/tui/widgets/system.py +87 -0
  468. ksadk/tui/widgets/thinking.py +110 -0
  469. ksadk/tui/widgets/tool_call.py +161 -0
  470. ksadk/tui/widgets/user.py +37 -0
  471. ksadk/ui_config.py +168 -0
  472. ksadk/version.py +4 -0
  473. ksadk_runtime_common/__init__.py +20 -0
  474. ksadk_runtime_common/memory_backend/__init__.py +29 -0
  475. ksadk_runtime_common/memory_backend/manifest.py +79 -0
  476. ksadk_runtime_common/memory_backend/providers/__init__.py +6 -0
  477. ksadk_runtime_common/memory_backend/providers/lancedb.py +151 -0
  478. ksadk_runtime_common/memory_backend/providers/mem0.py +74 -0
  479. ksadk_runtime_common/memory_backend/registry.py +56 -0
  480. ksadk_runtime_common/memory_backend/render.py +71 -0
  481. ksadk_runtime_common/schemas/memory_backend_manifest.schema.json +148 -0
  482. ksadk_runtime_common/workspace_files/__init__.py +29 -0
  483. ksadk_runtime_common/workspace_files/bootstrap.py +56 -0
  484. ksadk_runtime_common/workspace_files/constants.py +9 -0
  485. ksadk_runtime_common/workspace_files/path_utils.py +71 -0
  486. ksadk_runtime_common/workspace_files/preview.py +96 -0
  487. ksadk_runtime_common/workspace_files/router.py +254 -0
  488. agentengine_sdk_python-0.6.2.dist-info/METADATA +0 -46
  489. agentengine_sdk_python-0.6.2.dist-info/RECORD +0 -4
  490. agentengine_sdk_python-0.6.2.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,410 @@
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="是否开启公网访问;未指定时使用配置文件或平台默认值",
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
+ deploy_target.network.enable_public_access = bool(
96
+ _pick("enable_public_access", "enablePublicAccess", "EnablePublicAccess", default=deploy_target.network.enable_public_access)
97
+ )
98
+ deploy_target.network.enable_vpc_access = bool(
99
+ _pick("enable_vpc_access", "enableVpcAccess", "EnableVpcAccess", default=deploy_target.network.enable_vpc_access)
100
+ )
101
+ deploy_target.network.vpc_id = str(
102
+ _pick("vpc_id", "vpcId", "VpcId", default=deploy_target.network.vpc_id) or ""
103
+ ).strip()
104
+ deploy_target.network.subnet_id = str(
105
+ _pick("subnet_id", "subnetId", "SubnetId", default=deploy_target.network.subnet_id) or ""
106
+ ).strip()
107
+ deploy_target.network.security_group_id = str(
108
+ _pick(
109
+ "security_group_id",
110
+ "securityGroupId",
111
+ "SecurityGroupId",
112
+ default=deploy_target.network.security_group_id,
113
+ )
114
+ or ""
115
+ ).strip()
116
+ deploy_target.network.availability_zone = str(
117
+ _pick(
118
+ "availability_zone",
119
+ "availabilityZone",
120
+ "AvailabilityZone",
121
+ default=deploy_target.network.availability_zone,
122
+ )
123
+ or ""
124
+ ).strip()
125
+
126
+
127
+ def apply_network_cli_overrides(deploy_target: "DeployTarget", **network_kwargs: Any) -> None:
128
+ """Apply explicit CLI network overrides to a DeployTarget."""
129
+ if network_kwargs.get("enable_public_access") is not None:
130
+ deploy_target.network.enable_public_access = bool(network_kwargs["enable_public_access"])
131
+ if network_kwargs.get("enable_vpc_access"):
132
+ deploy_target.network.enable_vpc_access = True
133
+ for field in ("vpc_id", "subnet_id", "security_group_id", "availability_zone"):
134
+ value = network_kwargs.get(field)
135
+ if value is not None:
136
+ setattr(deploy_target.network, field, str(value or "").strip())
137
+ if any(str(getattr(deploy_target.network, field, "") or "").strip() for field in _VPC_ID_FIELDS):
138
+ deploy_target.network.enable_vpc_access = True
139
+
140
+
141
+ def validate_deploy_target_network(deploy_target: "DeployTarget") -> None:
142
+ """Require VPC identifiers as an atomic group when VPC access is requested."""
143
+ values = {
144
+ "vpc_id": str(getattr(deploy_target.network, "vpc_id", "") or "").strip(),
145
+ "subnet_id": str(getattr(deploy_target.network, "subnet_id", "") or "").strip(),
146
+ "security_group_id": str(getattr(deploy_target.network, "security_group_id", "") or "").strip(),
147
+ }
148
+ has_any_vpc_id = any(values.values())
149
+ if not (bool(getattr(deploy_target.network, "enable_vpc_access", False)) or has_any_vpc_id):
150
+ return
151
+ missing = [_VPC_ID_LABELS[field] for field, value in values.items() if not value]
152
+ if missing:
153
+ raise validation_error(
154
+ "开启 VPC 访问时必须同时提供 VpcId、SubnetId、SecurityGroupId。",
155
+ details={"missing": missing},
156
+ hints=[
157
+ "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`,或在配置文件 network/deploy.network 中同时设置这三个字段。",
158
+ "`--availability-zone` 是可选字段,不替代子网或安全组。",
159
+ ],
160
+ )
161
+
162
+
163
+ def resolve_deploy_target_network(
164
+ deploy_target: "DeployTarget",
165
+ *,
166
+ region: str | None = None,
167
+ dry_run: bool = False,
168
+ ) -> None:
169
+ """Fill optional network fields on a DeployTarget when they can be inferred."""
170
+ network = getattr(deploy_target, "network", None)
171
+ if network is None:
172
+ return
173
+ if str(getattr(network, "availability_zone", "") or "").strip():
174
+ return
175
+ if not bool(getattr(network, "enable_vpc_access", False)):
176
+ return
177
+ subnet_id = str(getattr(network, "subnet_id", "") or "").strip()
178
+ if not subnet_id or dry_run:
179
+ return
180
+ resolved_region = str(region or getattr(deploy_target, "region", "") or "").strip()
181
+ if not resolved_region:
182
+ return
183
+ availability_zone = _resolve_subnet_availability_zone(
184
+ subnet_id=subnet_id,
185
+ region=resolved_region,
186
+ )
187
+ if availability_zone:
188
+ network.availability_zone = availability_zone
189
+ print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
190
+ else:
191
+ print_warn(
192
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
193
+ "`--availability-zone`。"
194
+ )
195
+
196
+
197
+ def build_network_payload(**network_kwargs: Any) -> dict[str, Any] | None:
198
+ """Build lower-case network payload for AgentEngineClient create/update calls."""
199
+ payload: dict[str, Any] = {}
200
+ if network_kwargs.get("enable_public_access") is not None:
201
+ payload["enable_public_access"] = bool(network_kwargs["enable_public_access"])
202
+ if network_kwargs.get("enable_vpc_access"):
203
+ payload["enable_vpc_access"] = True
204
+ for field in ("vpc_id", "subnet_id", "security_group_id", "availability_zone"):
205
+ value = network_kwargs.get(field)
206
+ if value is not None and str(value or "").strip():
207
+ payload[field] = str(value or "").strip()
208
+ if not payload:
209
+ return None
210
+ if any(str(payload.get(field) or "").strip() for field in _VPC_ID_FIELDS):
211
+ payload["enable_vpc_access"] = True
212
+
213
+ _validate_network_payload(payload)
214
+ _fill_network_availability_zone(payload, network_kwargs)
215
+ return payload
216
+
217
+
218
+ def _validate_network_payload(payload: Mapping[str, Any]) -> None:
219
+ values = {field: str(payload.get(field) or "").strip() for field in _VPC_ID_FIELDS}
220
+ has_any_vpc_id = any(values.values())
221
+ if not (bool(payload.get("enable_vpc_access")) or has_any_vpc_id):
222
+ return
223
+ missing = [_VPC_ID_LABELS[field] for field, value in values.items() if not value]
224
+ if missing:
225
+ raise validation_error(
226
+ "开启 VPC 访问时必须同时提供 VpcId、SubnetId、SecurityGroupId。",
227
+ details={"missing": missing},
228
+ hints=[
229
+ "请同时传入 `--vpc-id`、`--subnet-id`、`--security-group-id`。",
230
+ "`--availability-zone` 是可选字段,不替代子网或安全组。",
231
+ ],
232
+ )
233
+
234
+
235
+ def _fill_network_availability_zone(payload: dict[str, Any], network_kwargs: Mapping[str, Any]) -> None:
236
+ if str(payload.get("availability_zone") or "").strip():
237
+ return
238
+ if not bool(payload.get("enable_vpc_access")):
239
+ return
240
+ subnet_id = str(payload.get("subnet_id") or "").strip()
241
+ if not subnet_id:
242
+ return
243
+ if bool(network_kwargs.get("dry_run")):
244
+ return
245
+ region = str(network_kwargs.get("region") or "").strip()
246
+ if not region:
247
+ return
248
+
249
+ availability_zone = _resolve_subnet_availability_zone(subnet_id=subnet_id, region=region)
250
+ if availability_zone:
251
+ payload["availability_zone"] = availability_zone
252
+ print_info(f"已根据子网 {subnet_id} 自动推断可用区: {availability_zone}")
253
+ else:
254
+ print_warn(
255
+ "未能根据子网自动推断可用区;如私网 ENI 调度失败,请显式传入 "
256
+ "`--availability-zone`。"
257
+ )
258
+
259
+
260
+ def _resolve_subnet_availability_zone(*, subnet_id: str, region: str) -> str | None:
261
+ subnet_id = str(subnet_id or "").strip()
262
+ region = str(region or "").strip()
263
+ if not subnet_id or not region:
264
+ return None
265
+
266
+ access_key, secret_key = _resolve_ksyun_credentials()
267
+ if not access_key or not secret_key:
268
+ return None
269
+
270
+ try:
271
+ VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile = _import_vpc_sdk()
272
+ except Exception as exc:
273
+ print_warn(f"缺少 VPC 子网查询 SDK,跳过可用区自动推断: {exc}")
274
+ return None
275
+
276
+ response = None
277
+ last_error: Exception | None = None
278
+ for endpoint, protocol in ((None, None), ("vpc.inner.api.ksyun.com", "http")):
279
+ if endpoint and not _should_retry_inner_vpc_endpoint(last_error):
280
+ break
281
+ try:
282
+ profile = ClientProfile(
283
+ httpProfile=HttpProfile(reqTimeout=10, endpoint=endpoint, protocol=protocol)
284
+ )
285
+ client = VpcClient(Credential(access_key, secret_key), region, profile)
286
+ request = DescribeSubnetsRequest()
287
+ request.SubnetId = {"1": subnet_id}
288
+ response = client.DescribeSubnets(request)
289
+ break
290
+ except Exception as exc:
291
+ last_error = exc
292
+
293
+ if response is None:
294
+ print_warn(f"查询子网 {subnet_id} 可用区失败,跳过自动推断: {last_error}")
295
+ return None
296
+
297
+ return _extract_subnet_availability_zone(response, subnet_id)
298
+
299
+
300
+ def _import_vpc_sdk():
301
+ from ksyun.client.vpc.v20160304.client import VpcClient
302
+ from ksyun.client.vpc.v20160304.models import DescribeSubnetsRequest
303
+ from ksyun.common.credential import Credential
304
+ from ksyun.common.profile.client_profile import ClientProfile
305
+ from ksyun.common.profile.http_profile import HttpProfile
306
+
307
+ return VpcClient, DescribeSubnetsRequest, Credential, ClientProfile, HttpProfile
308
+
309
+
310
+ def _should_retry_inner_vpc_endpoint(error: Exception | None) -> bool:
311
+ if error is None:
312
+ return False
313
+ return "InnerAccountCanOnlyAccessThroughIntranet" in str(error)
314
+
315
+
316
+ def _resolve_ksyun_credentials() -> tuple[str, str]:
317
+ access_key = os.getenv("KSYUN_ACCESS_KEY") or os.getenv("KS3_ACCESS_KEY") or ""
318
+ secret_key = os.getenv("KSYUN_SECRET_KEY") or os.getenv("KS3_SECRET_KEY") or ""
319
+ if access_key and secret_key:
320
+ return access_key.strip(), secret_key.strip()
321
+
322
+ try:
323
+ from ksadk.configs.global_config import get_env_from_global_config
324
+
325
+ global_env = get_env_from_global_config()
326
+ except Exception:
327
+ global_env = {}
328
+
329
+ access_key = access_key or global_env.get("KSYUN_ACCESS_KEY") or global_env.get("KS3_ACCESS_KEY") or ""
330
+ secret_key = secret_key or global_env.get("KSYUN_SECRET_KEY") or global_env.get("KS3_SECRET_KEY") or ""
331
+ return str(access_key or "").strip(), str(secret_key or "").strip()
332
+
333
+
334
+ def _extract_subnet_availability_zone(response: Any, subnet_id: str) -> str | None:
335
+ if isinstance(response, str):
336
+ try:
337
+ response = json.loads(response)
338
+ except json.JSONDecodeError:
339
+ return None
340
+ if not isinstance(response, Mapping):
341
+ return None
342
+
343
+ wanted_subnet_id = str(subnet_id or "").strip()
344
+ subnets = list(_iter_subnet_dicts(response))
345
+ for subnet in subnets:
346
+ current_subnet_id = _pick_text(
347
+ subnet,
348
+ "SubnetId",
349
+ "subnetId",
350
+ "subnet_id",
351
+ "id",
352
+ "Id",
353
+ )
354
+ if current_subnet_id and current_subnet_id != wanted_subnet_id:
355
+ continue
356
+ availability_zone = _pick_text(
357
+ subnet,
358
+ "AvailabilityZone",
359
+ "AvailabilityZoneName",
360
+ "availabilityZone",
361
+ "availabilityZoneName",
362
+ "availability_zone",
363
+ "availability_zone_name",
364
+ "Zone",
365
+ "zone",
366
+ )
367
+ if availability_zone:
368
+ return availability_zone
369
+
370
+ if len(subnets) == 1:
371
+ return _pick_text(
372
+ subnets[0],
373
+ "AvailabilityZone",
374
+ "AvailabilityZoneName",
375
+ "availabilityZone",
376
+ "availabilityZoneName",
377
+ "availability_zone",
378
+ "availability_zone_name",
379
+ "Zone",
380
+ "zone",
381
+ )
382
+ return None
383
+
384
+
385
+ def _iter_subnet_dicts(value: Any):
386
+ if isinstance(value, Mapping):
387
+ subnet_keys = ("SubnetId", "subnetId", "subnet_id")
388
+ zone_keys = (
389
+ "AvailabilityZone",
390
+ "AvailabilityZoneName",
391
+ "availabilityZone",
392
+ "availabilityZoneName",
393
+ "availability_zone",
394
+ "availability_zone_name",
395
+ )
396
+ if any(key in value for key in subnet_keys) or any(key in value for key in zone_keys):
397
+ yield value
398
+ for child in value.values():
399
+ yield from _iter_subnet_dicts(child)
400
+ elif isinstance(value, list):
401
+ for item in value:
402
+ yield from _iter_subnet_dicts(item)
403
+
404
+
405
+ def _pick_text(data: Mapping[str, Any], *keys: str) -> str:
406
+ for key in keys:
407
+ value = data.get(key)
408
+ if value is not None and str(value).strip():
409
+ return str(value).strip()
410
+ return ""