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,786 @@
1
+ """
2
+ Container Builder - Docker 镜像构建
3
+ """
4
+
5
+ import os
6
+ import subprocess
7
+ import shutil
8
+ import time
9
+ import platform
10
+ import asyncio
11
+ from pathlib import Path
12
+ from typing import Optional
13
+
14
+ import click
15
+
16
+ from ksadk.builders.base import BaseBuilder, BuildResult
17
+ from ksadk.builders.code_builder import CodeBuilder
18
+ from ksadk.builders.framework_requirements import (
19
+ FASTAPI_REQUIREMENT,
20
+ requirements_for_framework,
21
+ )
22
+ from ksadk.builders.requirements_utils import (
23
+ exclude_requirement_names,
24
+ merge_requirement_lists,
25
+ parse_requirements_text,
26
+ )
27
+
28
+
29
+ def _registry_host(registry: str | None) -> str:
30
+ value = str(registry or "").strip()
31
+ for prefix in ("http://", "https://"):
32
+ if value.startswith(prefix):
33
+ value = value[len(prefix):]
34
+ break
35
+ return value.split("/", 1)[0].strip()
36
+
37
+
38
+ def _registry_kind(registry: str | None) -> str:
39
+ host = _registry_host(registry)
40
+ if host.endswith(".ksyunkcr.com"):
41
+ return "enterprise_kcr"
42
+ if host.endswith(".kce.ksyun.com"):
43
+ return "personal_kcr"
44
+ return "third_party"
45
+
46
+
47
+ def registry_kind_label(kind: str) -> str:
48
+ if kind == "personal_kcr":
49
+ return "个人版 KCR"
50
+ if kind == "enterprise_kcr":
51
+ return "企业版 KCR"
52
+ return "第三方镜像仓库"
53
+
54
+
55
+ def resolve_registry_credentials(
56
+ registry: str | None,
57
+ *,
58
+ environ: Optional[dict[str, str]] = None,
59
+ ) -> tuple[str, str, str]:
60
+ """Resolve registry credentials.
61
+
62
+ Returns (username, password, kind). Personal KCR keeps the historical
63
+ KSYUN_ACCOUNT_ID fallback; enterprise KCR and third-party registries require
64
+ explicit registry credentials.
65
+ """
66
+ env = environ if environ is not None else os.environ
67
+ kind = _registry_kind(registry)
68
+ password = str(env.get("KCR_PASSWORD") or "")
69
+ username = str(env.get("KCR_USERNAME") or "")
70
+ if kind == "personal_kcr" and not username:
71
+ username = str(env.get("KSYUN_ACCOUNT_ID") or "")
72
+ return username, password, kind
73
+
74
+
75
+ def print_registry_credentials_help(registry: str | None, *, kind: str | None = None) -> None:
76
+ kind = kind or _registry_kind(registry)
77
+ click.echo("")
78
+ if kind == "personal_kcr":
79
+ click.secho("❌ 缺少个人版 KCR 镜像仓库凭证。", fg="red")
80
+ click.echo("个人版 KCR 可使用 KSYUN_ACCOUNT_ID 作为用户名兜底,并配置 KCR_PASSWORD。")
81
+ click.echo("")
82
+ click.echo("请设置:")
83
+ click.echo(" KSYUN_ACCOUNT_ID=<金山云账号ID>")
84
+ click.echo(" KCR_PASSWORD=<个人版 KCR 访问凭证密码或 Token>")
85
+ else:
86
+ click.secho("❌ 缺少企业版或第三方镜像仓库凭证。", fg="red")
87
+ click.echo("企业版或第三方镜像仓库必须配置 KCR_USERNAME 和 KCR_PASSWORD。")
88
+ click.echo("KSYUN_ACCOUNT_ID 只会作为个人版 KCR 的用户名兜底。")
89
+ click.echo("")
90
+ click.echo("请设置:")
91
+ click.echo(" KCR_USERNAME=<镜像仓库访问凭证用户名>")
92
+ click.echo(" KCR_PASSWORD=<镜像仓库访问凭证密码或 Token>")
93
+ click.echo("")
94
+ click.echo("可选设置默认构建仓库:")
95
+ click.echo(" KCR_REGISTRY=<registry>/<namespace>")
96
+ if registry:
97
+ click.echo("")
98
+ click.echo(f"当前目标 registry: {_registry_host(registry)}")
99
+
100
+
101
+ def ensure_docker_running() -> bool:
102
+ """确保 Docker 正在运行"""
103
+ if not shutil.which('docker'):
104
+ click.secho("❌ 未找到 docker 命令", fg='red')
105
+ click.echo("")
106
+ click.echo("请先安装 Docker:")
107
+ if platform.system() == "Darwin":
108
+ click.echo(" • 下载 Docker Desktop: https://www.docker.com/products/docker-desktop/")
109
+ click.echo(" • 或使用 Homebrew: brew install --cask docker")
110
+ elif platform.system() == "Linux":
111
+ click.echo(" • Ubuntu/Debian: sudo apt-get install docker.io")
112
+ click.echo(" • CentOS/RHEL: sudo yum install docker")
113
+ else:
114
+ click.echo(" • 下载 Docker Desktop: https://www.docker.com/products/docker-desktop/")
115
+ return False
116
+
117
+ try:
118
+ result = subprocess.run(['docker', 'info'], capture_output=True, timeout=10)
119
+ if result.returncode == 0:
120
+ return True
121
+ except:
122
+ pass
123
+
124
+ click.secho("⚠️ Docker daemon 未运行", fg='yellow')
125
+
126
+ system_name = platform.system()
127
+ if system_name == "Darwin":
128
+ click.echo("🚀 正在启动 Docker Desktop...")
129
+ try:
130
+ subprocess.run(['open', '-a', 'Docker'], check=True)
131
+ for i in range(60):
132
+ time.sleep(1)
133
+ try:
134
+ result = subprocess.run(['docker', 'info'], capture_output=True, timeout=5)
135
+ if result.returncode == 0:
136
+ click.secho("✅ Docker Desktop 已启动", fg='green')
137
+ return True
138
+ except:
139
+ pass
140
+ if i % 5 == 0 and i > 0:
141
+ click.echo(f" 等待 Docker 启动中... ({i}秒)")
142
+ click.secho("❌ Docker Desktop 启动超时", fg='red')
143
+ return False
144
+ except:
145
+ click.secho("❌ 无法启动 Docker Desktop", fg='red')
146
+ return False
147
+ elif system_name == "Windows":
148
+ click.echo("请启动 Docker Desktop,然后重试当前命令。")
149
+ return False
150
+ else:
151
+ click.echo("请启动 Docker daemon: sudo systemctl start docker")
152
+ return False
153
+
154
+
155
+ class ContainerBuilder(BaseBuilder):
156
+ """Docker 镜像构建器"""
157
+
158
+ def __init__(self, project_dir: Path, config: dict = None,
159
+ tag: str = None, registry: str = None, no_cache: bool = False):
160
+ super().__init__(project_dir, config)
161
+ self.tag = tag
162
+ self.registry = registry
163
+ self.no_cache = no_cache
164
+
165
+ def _get_smart_kcr_endpoint(self, region: str) -> str:
166
+ """智能选择 KCR endpoint
167
+
168
+ 使用企业版 KCR (hub.kce.ksyun.com/agentengine/)。
169
+ 优先使用内网 VPC endpoint,如果内网不可达则使用公网。
170
+ """
171
+ from ksadk.configs.settings import check_endpoint_reachable
172
+
173
+ # 企业版 KCR 地址 (带 agentengine 命名空间)
174
+ vpc_endpoint = "hub-vpc.kce.ksyun.com/agentengine"
175
+ public_endpoint = "hub.kce.ksyun.com/agentengine"
176
+
177
+ click.echo(f"🔍 检测 KCR 内网连通性...")
178
+
179
+ # 检测 VPC 内网是否可达 (端口 443 for HTTPS registry)
180
+ if check_endpoint_reachable("hub-vpc.kce.ksyun.com", port=443, timeout=2.0):
181
+ click.secho(f" ✅ 使用内网: {vpc_endpoint}", fg='green')
182
+ return vpc_endpoint
183
+ else:
184
+ click.echo(f" ℹ️ 使用公网: {public_endpoint}")
185
+ return public_endpoint
186
+
187
+ def _optimize_kcr_endpoint(self, registry: str) -> str:
188
+ """优化 KCR endpoint
189
+
190
+ 如果是金山云 KCR 公网地址,且内网可达,则替换为内网地址。
191
+ """
192
+ from ksadk.configs.settings import check_endpoint_reachable
193
+
194
+ # 已经是内网地址
195
+ if 'hub-vpc' in registry:
196
+ return registry
197
+
198
+ # 匹配企业版 KCR: hub.kce.ksyun.com
199
+ if 'hub.kce.ksyun.com' in registry:
200
+ click.echo(f"🔍 检测 KCR 内网连通性...")
201
+ if check_endpoint_reachable("hub-vpc.kce.ksyun.com", port=443, timeout=2.0):
202
+ optimized = registry.replace("hub.kce.ksyun.com", "hub-vpc.kce.ksyun.com")
203
+ click.secho(f" ✅ 优化为内网: {optimized}", fg='green')
204
+ return optimized
205
+ else:
206
+ click.echo(f" ℹ️ 使用公网: {registry}")
207
+
208
+ return registry
209
+
210
+ def _package(self, detection_result) -> 'PackageInfo':
211
+ """打包项目 - 复制文件并生成 Dockerfile/requirements/entrypoint"""
212
+ from ksadk.deployment.base import PackageInfo
213
+
214
+ project_path = self.project_dir
215
+ output_dir = project_path / ".agentengine" / "build"
216
+ output_dir.mkdir(parents=True, exist_ok=True)
217
+
218
+ package_name = Path(detection_result.package_path).name
219
+ is_container_first_template = (
220
+ getattr(getattr(detection_result, "type", None), "value", "") == "hermes"
221
+ and (project_path / "Dockerfile").exists()
222
+ and (project_path / "entrypoint.sh").exists()
223
+ )
224
+
225
+ # 复制项目文件。真实 .env 只通过 deploy payload 注入,不进入镜像上下文。
226
+ for item in project_path.iterdir():
227
+ if CodeBuilder._is_real_dotenv_file(item.name):
228
+ continue
229
+ if (
230
+ (item.name.startswith('.') and item.name != '.env.example')
231
+ or item.name in ('__pycache__', '.git', 'node_modules')
232
+ ):
233
+ continue
234
+ dest = output_dir / item.name
235
+ if item.is_dir():
236
+ if dest.exists():
237
+ shutil.rmtree(dest)
238
+ shutil.copytree(
239
+ item,
240
+ dest,
241
+ ignore=shutil.ignore_patterns(
242
+ "__pycache__",
243
+ "*.pyc",
244
+ "node_modules",
245
+ ".pytest_cache",
246
+ ".mypy_cache",
247
+ ".ruff_cache",
248
+ ),
249
+ )
250
+ else:
251
+ shutil.copy2(item, dest)
252
+
253
+ # 复制 ksadk 源码 (确保容器内可用)
254
+ import ksadk
255
+ ksadk_src = Path(ksadk.__file__).parent
256
+ ksadk_dest = output_dir / "ksadk"
257
+ if ksadk_dest.exists():
258
+ shutil.rmtree(ksadk_dest)
259
+
260
+ def _ignore_ksadk_source(current_dir: str, names: list[str]):
261
+ ignored = set(
262
+ shutil.ignore_patterns(
263
+ "__pycache__",
264
+ "*.pyc",
265
+ "*.pyd",
266
+ "*.so",
267
+ "*.dylib",
268
+ "*.bin",
269
+ )(current_dir, names)
270
+ )
271
+ relative_dir = Path(current_dir).resolve().relative_to(ksadk_src.resolve())
272
+ if relative_dir == Path("server") and "web-ui" in names:
273
+ ignored.add("web-ui")
274
+ return ignored
275
+
276
+ shutil.copytree(
277
+ ksadk_src,
278
+ ksadk_dest,
279
+ ignore=_ignore_ksadk_source,
280
+ )
281
+
282
+ # 复制 ksadk_runtime_common (如果存在)
283
+ try:
284
+ import ksadk_runtime_common
285
+ runtime_common_src = Path(ksadk_runtime_common.__file__).parent
286
+ runtime_common_dest = output_dir / "ksadk_runtime_common"
287
+ if runtime_common_dest.exists():
288
+ shutil.rmtree(runtime_common_dest)
289
+ shutil.copytree(
290
+ runtime_common_src,
291
+ runtime_common_dest,
292
+ ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
293
+ )
294
+ except ImportError:
295
+ # 旧版本 ksadk 没有 ksadk_runtime_common,从源码目录复制
296
+ # 这个分支处理从 master 迁移到 main 后,环境中安装的是旧版本的情况
297
+ source_runtime_common = Path(ksadk_src).parent / "ksadk_runtime_common"
298
+ if source_runtime_common.exists():
299
+ runtime_common_dest = output_dir / "ksadk_runtime_common"
300
+ if runtime_common_dest.exists():
301
+ shutil.rmtree(runtime_common_dest)
302
+ shutil.copytree(
303
+ source_runtime_common,
304
+ runtime_common_dest,
305
+ ignore=shutil.ignore_patterns("__pycache__", "*.pyc"),
306
+ )
307
+ else:
308
+ click.echo(click.style(
309
+ "⚠️ 警告: 未找到 ksadk_runtime_common,镜像可能无法正常运行",
310
+ fg="yellow"
311
+ ))
312
+
313
+ dockerfile_path = output_dir / "Dockerfile"
314
+ if not is_container_first_template:
315
+ dockerfile = self._generate_dockerfile(detection_result)
316
+ dockerfile_path.write_text(dockerfile)
317
+
318
+ # 生成 requirements.txt (合并用户依赖)
319
+ requirements = self._generate_requirements(detection_result, project_path)
320
+ requirements_path = output_dir / "requirements.txt"
321
+ requirements_path.write_text(requirements)
322
+
323
+ # 生成启动脚本
324
+ if is_container_first_template:
325
+ entrypoint_path = output_dir / "entrypoint.sh"
326
+ else:
327
+ entrypoint = self._generate_entrypoint(detection_result, package_name)
328
+ entrypoint_path = output_dir / "entrypoint.py"
329
+ entrypoint_path.write_text(entrypoint)
330
+
331
+ return PackageInfo(
332
+ name=detection_result.name or project_path.name,
333
+ framework=detection_result.type.value,
334
+ build_dir=str(output_dir),
335
+ project_dir=str(project_path),
336
+ dockerfile=str(dockerfile_path),
337
+ entry_point=detection_result.entry_point,
338
+ metadata={
339
+ "package_name": package_name,
340
+ "requirements": str(requirements_path),
341
+ "entrypoint": str(entrypoint_path),
342
+ }
343
+ )
344
+
345
+ def _generate_dockerfile(self, detection_result) -> str:
346
+ """生成优化的 Dockerfile"""
347
+ base_image = "python:3.12-slim"
348
+
349
+ return f'''FROM {base_image}
350
+
351
+ # 设置环境变量
352
+ ENV PYTHONUNBUFFERED=1 \\
353
+ PYTHONDONTWRITEBYTECODE=1 \\
354
+ PIP_NO_CACHE_DIR=1 \\
355
+ PIP_DISABLE_PIP_VERSION_CHECK=1
356
+
357
+ WORKDIR /app
358
+
359
+ # 先复制依赖文件 (利用 Docker Layer 缓存)
360
+ COPY requirements.txt .
361
+
362
+ # 使用清华镜像源加速安装
363
+ RUN pip install -r requirements.txt -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
364
+
365
+ # 复制应用代码
366
+ COPY . .
367
+
368
+ # 创建非 root 用户 (安全最佳实践)
369
+ RUN useradd -m -u 1000 agent && chown -R agent:agent /app
370
+ USER agent
371
+
372
+ EXPOSE 8080
373
+
374
+ # 使用 exec 形式确保信号正确传递
375
+ CMD ["python", "entrypoint.py"]
376
+ '''
377
+
378
+ def _generate_requirements(self, detection_result, project_path: Path = None) -> str:
379
+ """生成 requirements.txt"""
380
+ base_deps = [
381
+ # Core
382
+ FASTAPI_REQUIREMENT,
383
+ "uvicorn>=0.23.0",
384
+ "python-dotenv>=1.0.0",
385
+ "pydantic>=2.0.0",
386
+ "pyyaml>=6.0.0",
387
+ "httpx>=0.24.0",
388
+ # Tracing
389
+ "opentelemetry-api>=1.37.0",
390
+ "opentelemetry-sdk>=1.37.0",
391
+ "opentelemetry-exporter-otlp>=1.37.0",
392
+ "openinference-instrumentation-langchain>=0.1.0",
393
+ "langfuse>=2.0.0",
394
+ ]
395
+
396
+ framework = detection_result.type.value
397
+ base_deps += requirements_for_framework(framework)
398
+
399
+ base_deps = merge_requirement_lists(
400
+ base_deps,
401
+ CodeBuilder(project_path or self.project_dir)._bundled_runtime_requirements(),
402
+ )
403
+
404
+ # 合并用户 requirements.txt (如果存在)
405
+ if project_path:
406
+ user_requirements = project_path / "requirements.txt"
407
+ if user_requirements.exists():
408
+ user_content = user_requirements.read_text()
409
+ user_deps = exclude_requirement_names(
410
+ parse_requirements_text(user_content),
411
+ excluded_names={"ksadk"},
412
+ )
413
+ base_deps = merge_requirement_lists(base_deps, user_deps)
414
+
415
+ return "\n".join(base_deps)
416
+
417
+ def _generate_entrypoint(self, detection_result, package_name: str) -> str:
418
+ """生成 entrypoint.py"""
419
+ return f'''"""
420
+ AgentEngine Container 模式入口
421
+ """
422
+
423
+ import sys
424
+ import os
425
+ import logging
426
+ from pathlib import Path
427
+
428
+ # ========== 日志配置 ==========
429
+ LOG_LEVEL = os.environ.get("LOG_LEVEL", "INFO").upper()
430
+
431
+ logging.basicConfig(
432
+ level=getattr(logging, LOG_LEVEL, logging.INFO),
433
+ format="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
434
+ datefmt="%Y-%m-%d %H:%M:%S",
435
+ stream=sys.stdout,
436
+ force=True,
437
+ )
438
+
439
+ logger = logging.getLogger("entrypoint")
440
+ logger.info(f"日志级别: {{LOG_LEVEL}}")
441
+
442
+ # 配置第三方库日志级别
443
+ if LOG_LEVEL != "DEBUG":
444
+ logging.getLogger("httpx").setLevel(logging.WARNING)
445
+ logging.getLogger("httpcore").setLevel(logging.WARNING)
446
+
447
+ # ========== 路径设置 ==========
448
+ sys.path.insert(0, "/app")
449
+ os.chdir("/app")
450
+
451
+ logger.info("=" * 60)
452
+ logger.info("AgentEngine 启动 (Container 模式)")
453
+ logger.info("=" * 60)
454
+ logger.info(f"Python: {{sys.version}}")
455
+
456
+ # 加载环境变量
457
+ try:
458
+ from dotenv import load_dotenv
459
+ if os.path.exists("/app/.env"):
460
+ load_dotenv("/app/.env")
461
+ logger.info("加载 .env 文件")
462
+ except ImportError:
463
+ pass
464
+
465
+ env_keys = [
466
+ "AGENT_RUNTIME_NAME", "AGENT_RUNTIME_ID", "ACCOUNT_ID", "PORT",
467
+ "LANGFUSE_BASE_URL", "LANGFUSE_HOST", "LANGFUSE_PUBLIC_KEY",
468
+ "LANGFUSE_SECRET_KEY", "LANGFUSE_USE_CALLBACK",
469
+ "OTEL_EXPORTER_OTLP_ENDPOINT", "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
470
+ "OTEL_EXPORTER_OTLP_HEADERS", "OTEL_EXPORTER_OTLP_TRACES_HEADERS",
471
+ "OTEL_SERVICE_NAME", "CLOUD_MONITOR_APP_KEY",
472
+ "CLOUD_MONITOR_OTLP_ENABLED", "CLOUD_MONITOR_OTLP_ENDPOINT",
473
+ "CLOUD_MONITOR_OTLP_TRACES_ENDPOINT", "CLOUD_MONITOR_OTLP_HEADERS",
474
+ "CLOUD_MONITOR_LANGFUSE_HOST", "CLOUD_MONITOR_LANGFUSE_PUBLIC_KEY",
475
+ "CLOUD_MONITOR_LANGFUSE_SECRET_KEY", "CLOUD_MONITOR_LANGFUSE_ENABLED",
476
+ "LANGCHAIN_TRACING_V2", "MODEL_NAME",
477
+ ]
478
+ for key in env_keys:
479
+ value = os.environ.get(key)
480
+ if value:
481
+ if "KEY" in key or "SECRET" in key or "HEADERS" in key:
482
+ value = value[:8] + "****" if len(value) > 8 else "****"
483
+ logger.info(f" {{key}}: {{value}}")
484
+
485
+ # ========== 加载 Agent ==========
486
+ from ksadk.configs import setup_environment
487
+ setup_environment(Path("/app"))
488
+
489
+ try:
490
+ from ksadk.runners.patch_langchain import apply_patch as apply_langchain_patch
491
+ apply_langchain_patch()
492
+ except ImportError:
493
+ pass
494
+
495
+ from ksadk.runners import create_runner
496
+ from ksadk.detection import DetectionResult, FrameworkType
497
+ from ksadk.server import app, set_runner
498
+ import uvicorn
499
+
500
+ # 检测结果 (构建时固化)
501
+ detection_result = DetectionResult(
502
+ type=FrameworkType.{detection_result.type.name},
503
+ name="{detection_result.name}",
504
+ entry_point="{detection_result.entry_point}",
505
+ package_path="/app/{package_name}",
506
+ agent_variable="{detection_result.agent_variable}",
507
+ runner_class="{getattr(detection_result, 'runner_class', '')}"
508
+ )
509
+
510
+ logger.info(f"框架: {{detection_result.name}}")
511
+ logger.info(f"入口: {{detection_result.entry_point}}")
512
+
513
+ # 初始化 Tracing (如果配置了 Langfuse、标准 OTLP HTTP 或 CloudMonitor OTLP)
514
+ has_otlp = bool(os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT") or os.environ.get("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"))
515
+ has_cloud_monitor_otlp = bool(
516
+ os.environ.get("CLOUD_MONITOR_APP_KEY")
517
+ or os.environ.get("CLOUD_MONITOR_OTLP_ENDPOINT")
518
+ or os.environ.get("CLOUD_MONITOR_OTLP_TRACES_ENDPOINT")
519
+ )
520
+ has_cloud_monitor_langfuse = bool(
521
+ os.environ.get("CLOUD_MONITOR_LANGFUSE_PUBLIC_KEY")
522
+ or os.environ.get("CLOUD_MONITOR_LANGFUSE_SECRET_KEY")
523
+ or os.environ.get("CLOUD_MONITOR_LANGFUSE_HOST")
524
+ )
525
+ if os.environ.get("LANGFUSE_PUBLIC_KEY") or has_otlp or has_cloud_monitor_otlp or has_cloud_monitor_langfuse:
526
+ try:
527
+ from ksadk.tracing import setup_tracing
528
+ use_callback_only = os.environ.get("LANGFUSE_USE_CALLBACK", "").strip().lower() in ("1", "true", "yes", "on")
529
+ setup_tracing(use_callback_only=use_callback_only)
530
+ logger.info(
531
+ f"Tracing 已启用 (OTLP={{has_otlp}}, "
532
+ f"CloudMonitorOTLP={{has_cloud_monitor_otlp}}, "
533
+ f"CloudMonitorLangfuse={{has_cloud_monitor_langfuse}}, "
534
+ f"CallbackOnly={{use_callback_only}})"
535
+ )
536
+ except Exception as e:
537
+ logger.warning(f"Tracing 初始化失败: {{e}}")
538
+
539
+ # 创建 Runner 并加载 Agent
540
+ logger.info("正在加载 Agent...")
541
+ runner = create_runner(detection_result, "/app")
542
+ runner.load_agent()
543
+ set_runner(runner)
544
+ logger.info("Agent 加载成功!")
545
+
546
+ if __name__ == "__main__":
547
+ port = int(os.environ.get("PORT", 8080))
548
+ logger.info(f"启动 HTTP Server: 0.0.0.0:{{port}}")
549
+ uvicorn.run(app, host="0.0.0.0", port=port, log_level=LOG_LEVEL.lower())
550
+ '''
551
+
552
+ def build(self) -> BuildResult:
553
+ """构建 Docker 镜像"""
554
+ from ksadk.detection import FrameworkDetector
555
+
556
+ self._load_dotenv()
557
+ config = self._load_config()
558
+
559
+ # 检测框架
560
+ detector = FrameworkDetector(str(self.project_dir))
561
+ result = detector.detect()
562
+
563
+ if result.type.value == "unknown":
564
+ return BuildResult(
565
+ success=False,
566
+ error_message="未检测到支持的框架"
567
+ )
568
+
569
+ click.echo(f"📦 框架: {click.style(result.name, fg='green')}")
570
+
571
+ # 确定镜像名称
572
+ image_name = config.get('name', self.project_dir.name).replace('-', '_').replace('.', '_')
573
+
574
+ # Tag 优先级: 命令行 > agentengine.yaml version > config image.tag > latest
575
+ image_tag = self.tag
576
+ if not image_tag:
577
+ image_tag = config.get('version', '') # 使用项目版本作为 tag
578
+ if not image_tag:
579
+ image_tag = config.get('image', {}).get('tag', 'latest')
580
+
581
+ # Registry 优先级: 命令行 > .env KCR_REGISTRY > agentengine.yaml > 默认企业版 KCR
582
+ import os
583
+ image_registry = self.registry
584
+ if not image_registry:
585
+ image_registry = os.getenv('KCR_REGISTRY', '')
586
+ if not image_registry:
587
+ image_registry = config.get('image', {}).get('registry', '')
588
+ if not image_registry:
589
+ # 默认使用企业版 KCR,智能选择内网/公网
590
+ image_registry = self._get_smart_kcr_endpoint(os.getenv('KSYUN_REGION', 'cn-beijing-6'))
591
+ else:
592
+ # 即使设置了 registry,如果是金山云公网地址,也尝试优化为内网
593
+ image_registry = self._optimize_kcr_endpoint(image_registry)
594
+
595
+ full_image = f"{image_registry}/{image_name}:{image_tag}"
596
+
597
+ click.echo(f"🏷️ 镜像名称: {full_image}")
598
+
599
+ # 打包 (内置打包逻辑,不再依赖 DockerProvider)
600
+ click.echo("\n📦 打包中...")
601
+ try:
602
+ package_info = self._package(result)
603
+ click.echo("✅ 打包完成")
604
+ except Exception as e:
605
+ return BuildResult(
606
+ success=False,
607
+ error_message=f"打包失败: {e}"
608
+ )
609
+
610
+ # Docker 构建
611
+ if not ensure_docker_running():
612
+ return BuildResult(
613
+ success=False,
614
+ error_message="Docker 未运行"
615
+ )
616
+
617
+ click.echo("\n🔨 构建 Docker 镜像 (目标平台: linux/amd64)...")
618
+ try:
619
+ cmd = ['docker', 'build', '--platform', 'linux/amd64', '-t', full_image]
620
+ if self.no_cache:
621
+ cmd.append('--no-cache')
622
+ cmd.append(package_info.build_dir)
623
+
624
+ quiet_mode = os.getenv("AGENTENGINE_OUTPUT_MODE", "").strip().lower() == "json"
625
+ subprocess.run(
626
+ cmd,
627
+ check=True,
628
+ capture_output=quiet_mode,
629
+ text=quiet_mode,
630
+ )
631
+ click.secho(f"\n✅ 镜像构建成功: {full_image}", fg='green')
632
+
633
+ return BuildResult(
634
+ success=True,
635
+ artifact_path=None, # Docker 镜像没有本地文件路径
636
+ metadata={
637
+ "image": full_image,
638
+ "framework": result.type.value,
639
+ "build_dir": package_info.build_dir
640
+ }
641
+ )
642
+ except subprocess.CalledProcessError as e:
643
+ error_message = f"镜像构建失败: {e}"
644
+ if quiet_mode:
645
+ stderr = (e.stderr or "").strip()
646
+ stdout = (e.stdout or "").strip()
647
+ detail = stderr or stdout
648
+ if detail:
649
+ error_message = f"{error_message}: {detail}"
650
+ return BuildResult(
651
+ success=False,
652
+ error_message=error_message
653
+ )
654
+
655
+ def push(self, image_name: str) -> bool:
656
+ """推送镜像到仓库"""
657
+ # 检查镜像仓库认证
658
+ registry = self._extract_registry(image_name)
659
+
660
+ # 尝试使用 .env 中的认证信息自动登录
661
+ if registry:
662
+ if not self._auto_login_from_env(registry):
663
+ # 自动登录失败,检查是否已有认证
664
+ if not self._check_registry_auth(registry):
665
+ return False
666
+
667
+ click.echo(f"\n📤 推送镜像...")
668
+ try:
669
+ result = subprocess.run(
670
+ ['docker', 'push', image_name],
671
+ capture_output=True,
672
+ text=True
673
+ )
674
+ if result.returncode != 0:
675
+ # 检查是否是认证问题
676
+ if 'denied' in result.stderr.lower() or 'unauthorized' in result.stderr.lower():
677
+ self._print_auth_help(registry or 'docker.io')
678
+ return False
679
+ click.secho(f"❌ 镜像推送失败: {result.stderr}", fg='red')
680
+ return False
681
+
682
+ click.secho(f"✅ 镜像推送成功", fg='green')
683
+ return True
684
+ except subprocess.CalledProcessError as e:
685
+ click.secho(f"❌ 镜像推送失败: {e}", fg='red')
686
+ return False
687
+
688
+ def _auto_login_from_env(self, registry: str) -> bool:
689
+ """尝试使用 .env 中的凭证自动登录"""
690
+ import os
691
+ from dotenv import load_dotenv
692
+
693
+ # 加载 .env
694
+ load_dotenv()
695
+
696
+ # KCR_REGISTRY is a generic registry/namespace target used for KCR and third-party registries.
697
+ kcr_registry = os.getenv('KCR_REGISTRY', '')
698
+ if not kcr_registry:
699
+ kcr_registry = "hub.kce.ksyun.com/agentengine"
700
+
701
+ kcr_username, kcr_password, registry_kind = resolve_registry_credentials(registry)
702
+
703
+ # 检查是否匹配当前 registry (支持部分匹配)
704
+ if registry not in kcr_registry and kcr_registry not in registry:
705
+ return False
706
+
707
+ if not kcr_username or not kcr_password:
708
+ print_registry_credentials_help(registry, kind=registry_kind)
709
+ return False
710
+
711
+ click.echo(f"🔐 使用 .env 中的凭证登录 {registry}...")
712
+ try:
713
+ result = subprocess.run(
714
+ ['docker', 'login', registry, '-u', kcr_username, '--password-stdin'],
715
+ input=kcr_password,
716
+ capture_output=True,
717
+ text=True,
718
+ timeout=30
719
+ )
720
+ if result.returncode == 0:
721
+ click.secho(f"✅ 登录成功", fg='green')
722
+ return True
723
+ else:
724
+ click.secho(f"⚠️ 自动登录失败: {result.stderr.strip()}", fg='yellow')
725
+ return False
726
+ except Exception as e:
727
+ click.secho(f"⚠️ 自动登录异常: {e}", fg='yellow')
728
+ return False
729
+
730
+ def get_registry_credentials(self, registry: str | None = None) -> dict:
731
+ """获取镜像仓库凭证 (用于传给 Serverless)
732
+
733
+ 返回扁平化结构: {"username": "...", "password": "..."}
734
+ """
735
+ import os
736
+ from dotenv import load_dotenv
737
+
738
+ load_dotenv()
739
+
740
+ registry = registry or os.getenv("KCR_REGISTRY", "")
741
+ username, password, _ = resolve_registry_credentials(registry)
742
+
743
+ if username and password:
744
+ return {
745
+ 'username': username,
746
+ 'password': password
747
+ }
748
+ return {}
749
+
750
+ def _extract_registry(self, image_name: str) -> Optional[str]:
751
+ """从镜像名称提取仓库地址"""
752
+ # 格式: registry/namespace/image:tag 或 namespace/image:tag (默认 docker.io)
753
+ parts = image_name.split('/')
754
+ if len(parts) >= 2 and ('.' in parts[0] or ':' in parts[0]):
755
+ return parts[0]
756
+ return None # 使用默认 docker.io
757
+
758
+ def _check_registry_auth(self, registry: str) -> bool:
759
+ """检查是否已登录镜像仓库"""
760
+ try:
761
+ # 尝试获取 docker 配置
762
+ import json
763
+ from pathlib import Path
764
+
765
+ docker_config = Path.home() / '.docker' / 'config.json'
766
+ if docker_config.exists():
767
+ with open(docker_config) as f:
768
+ config = json.load(f)
769
+ auths = config.get('auths', {})
770
+ # 检查是否有该仓库的认证信息
771
+ if registry in auths or f'https://{registry}' in auths:
772
+ return True
773
+
774
+ # 没有找到认证信息,提示用户
775
+ click.secho(f"\n⚠️ 未检测到 {registry} 的登录凭证", fg='yellow')
776
+ self._print_auth_help(registry)
777
+ return False
778
+ except Exception:
779
+ # 无法检查,继续尝试推送
780
+ return True
781
+
782
+ def _print_auth_help(self, registry: str):
783
+ """打印认证帮助信息"""
784
+ print_registry_credentials_help(registry)
785
+ click.echo("也可以先手动登录:")
786
+ click.echo(f" docker login {registry or 'docker.io'}")